|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC] x86/altp2m: fix display frozen when switching to a new view early
On 9/19/18 3:44 PM, George Dunlap wrote:
> On 09/19/2018 01:15 PM, George Dunlap wrote:
>> On 09/03/2018 09:25 AM, Razvan Cojocaru wrote:
>>> When an new altp2m view is created very early on guest boot, the
>>> display will freeze (although the guest will run normally). This
>>> may also happen on resizing the display. The reason is the way
>>> Xen currently (mis)handles logdirty VGA: it intentionally
>>> misconfigures VGA pages so that they will fault.
>>>
>>> The problem is that it only does this in the host p2m. Once we
>>> switch to a new altp2m, the misconfigured entries will no longer
>>> fault, so the display will not be updated.
>>
>> Hey Razvan, thanks for doing this, and sorry it's taken so long to respond.
>>
>>> This patch:
>>>
>>> * updates ept_handle_misconfig() to use the active altp2m instead
>>> of the hostp2m;
>>
>> This is probably necessary.
>>
>>> * has p2m_init_altp2m_ept() copy over max_mapped_pfn,
>>> logdirty_ranges, global_logdirty, ept.ad and default_access
>>> from the hostp2m (the latter more for completeness than for any
>>> other reason).
>>
>> I think this is probably the right approach. These values change
>> rarely, but after a misconfig are read repeatedly. So it's probably a
>> lot more efficient to propagate changes when they happen, rather than
>> trying to keep a single master copy. However...
>>
>>> We should discuss if just copying over
>>> logdirty_ranges (which is a pointer) is sufficient, or if
>>> this code requires more synchronization).
>>
>> It's clearly not sufficient. :-) The logdirty_ranges struct is
>> protected by the lock of the p2m structure that contains it; if you
>> point to it from a different p2m structure, then you'll have
>> inconsistent logging, and you'll have problems if one vcpu is reading
>> the structure while another is modifying it.
>
> ...and therefore, if we believe that it's more efficient to duplicate
> structures than to share it and use a lock, we need to do a deep copy of
> the data structure on altp2m creation, and propagate changes as we do
> for the other "synced" data.
The biggest problem here is p2m->logdirty_ranges. This patch will
(justly) not work, because struct rangeset is only forward-declared in
xen/rangeset.h, so an incomplete type here:
-void p2m_init_altp2m_ept(struct domain *d, unsigned int i)
+int p2m_init_altp2m_ept(struct domain *d, unsigned int i)
{
struct p2m_domain *p2m = d->arch.altp2m_p2m[i];
struct p2m_domain *hostp2m = p2m_get_hostp2m(d);
struct ept_data *ept;
+ if ( !p2m->logdirty_ranges )
+ p2m->logdirty_ranges = rangeset_new(d, "log-dirty",
+ RANGESETF_prettyprint_hex);
+ if ( !p2m->logdirty_ranges )
+ return -ENOMEM;
+
+ *p2m->logdirty_ranges = *hostp2m->logdirty_ranges;
+
p2m->ept.ad = hostp2m->ept.ad;
+ p2m->max_mapped_pfn = hostp2m->max_mapped_pfn;
+ p2m->default_access = hostp2m->default_access;
+ p2m->domain = hostp2m->domain;
+
+ p2m->global_logdirty = hostp2m->global_logdirty;
p2m->min_remapped_gfn = gfn_x(INVALID_GFN);
p2m->max_remapped_gfn = 0;
ept = &p2m->ept;
ept->mfn = pagetable_get_pfn(p2m_get_pagetable(p2m));
d->arch.altp2m_eptp[i] = ept->eptp;
+
+ return 0;
+}
But that's not even the biggest problem: even if that would compile, it
would still be wrong, because logdirty_pages has pointers of its own,
which means that two bitwise-copied distinct rangesets can still point
to the same data and thus be vulnerable to race conditions and wanting
synchronization.
Furthermore there's no rangeset_copy() function in sight in rangeset.h
(though there is a rangeset_swap()).
Would you like me to add a rangeset_copy() function (presumably another
intermediary patch) and proceed in that manner?
Thanks,
Razvan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |