[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH for-4.12 V2] x86/altp2m: fix HVMOP_altp2m_set_domain_state race
>>> On 08.02.19 at 18:02, <rcojocaru@xxxxxxxxxxxxxxx> wrote: > On 2/8/19 6:44 PM, Jan Beulich wrote: >>>>> On 08.02.19 at 17:30, <rcojocaru@xxxxxxxxxxxxxxx> wrote: >>> On 2/8/19 5:50 PM, Jan Beulich wrote: >>>>>>> On 08.02.19 at 15:00, <rcojocaru@xxxxxxxxxxxxxxx> wrote: >>>>> /* If the alternate p2m state has changed, handle appropriately >>>>> */ >>>>> - if ( d->arch.altp2m_active != ostate && >>>>> + if ( nstate != ostate && >>>>> (ostate || !(rc = p2m_init_altp2m_by_id(d, 0))) ) >>>>> { >>>>> + /* First mark altp2m as disabled, then >>>>> altp2m_vcpu_destroy(). */ >>>>> + if ( ostate ) >>>>> + d->arch.altp2m_active = false; >>>> >>>> Why the if()? In the opposite case you'd simply write false into >>>> what already holds false. >>> >>> The value written into d->arch.altp2m_active is not the point here. The >>> point is that if ( ostate ), then we are disabling altp2m (because the >>> if above this one makes sure ostate != nstate). >>> >>> So in the disable case, first I wanted to set d->arch.altp2m_active to >>> false (which immediately causes altp2m_active(d) to return false as >>> well), and then actually perform the work. >> >> Sure - I'm not asking to remove everything above, just the if() >> (and keep what is now the body). That is because >> - in the enable case the value is false and writing false into it is >> benign, >> - in the disable case you want to actively change from true to >> false. >> >>>>> @@ -4550,7 +4554,14 @@ static int do_altp2m_op( >>>>> >>>>> if ( ostate ) >>>>> p2m_flush_altp2m(d); >>>>> + else >>>>> + /* >>>>> + * Wait until altp2m_vcpu_initialise() is done before >>>>> marking >>>>> + * altp2m as being enabled for the domain. >>>>> + */ >>>>> + d->arch.altp2m_active = true; >>>> >>>> Similarly here you could omit the "else" and simply store "nstate" afaict. >>> >>> As above, in the enable case I wanted to first setup altp2m on all VCPUs >>> with altp2m_vcpu_initialise(), and only after that set >>> d->arch.altp2m_active = true. >>> >>> In summary, if ( ostate ) we want to set d->arch.altp2m_active before >>> the for (we're disabling altp2m), and if ( !ostate ) (which is the else >>> above) we want to set d->arch.altp2m_active after said for. >>> >>> We can indeed store nstate. I just thought things look clearer with >>> "true" and "false", but if you prefer there's no problem assigning nstate. >> >> Well, as always with mm and altp2m code, I'm not the maintainer, so >> I don't have the final say. It's just that I think unnecessary conditionals >> would better be avoided, even if they're not on a performance critical >> path. >> >[...] >> >> Hmm, according to the change further up in this patch, altp2m_active() >> returns false before v->p2midx can be set to INVALID_ALTP2M (you >> don't change this property). So (related to the change further up) >> there's a period of time during which p2m_get_altp2m() will return >> non-NULL despite altp2m_active() returning false. Afaict, that is. > > Right, I now understand what you meant by removing "if ( ostate )" - > you'd like d->arch.altp2m_active to only be set _after_ the for, for the > enable, as well as for the disable case. No, certainly not. Exactly because of ... > However, I wanted to keep both if()s to avoid another problem with this > code: >[...] > So for the disable case, I wanted altp2m_active(v->domain) to return > false immediately so that this code won't be triggered. Otherwise, > assuming the following scenario: ... this. Apparently "and keep what is now the body" was still not clear enough. Taking your original code, I mean if ( nstate != ostate && (ostate || !(rc = p2m_init_altp2m_by_id(d, 0))) ) { /* First mark altp2m as disabled, then altp2m_vcpu_destroy(). */ d->arch.altp2m_active = false; for_each_vcpu( d, v ) [...] if ( ostate ) p2m_flush_altp2m(d); /* * Wait until altp2m_vcpu_initialise() is done before marking * altp2m as being enabled for the domain. */ d->arch.altp2m_active = nstate; } > Now, you're right that p2m_get_altp2m() may hand over a pointer to an > altp2m between the moment where d->arch.altp2m_active is false and the > point where v->p2midx actually becomes INVALID_ALTP2M with my code; but > I think it can be argued that I should rather fix p2m_get_altp2m(), to > return NULL if altp2m_active() == false and keep the if()s (which I've > hopefully been more eloquent about now). Yes, that looks to be an option, provided it doesn't violate assumptions elsewhere. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |