|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V6 4/4] x86/altp2m: fix display frozen when switching to a new view early
On 11/16/18 2:10 PM, Razvan Cojocaru wrote:
> On 11/16/18 2:03 PM, George Dunlap wrote:
>> The code is definitely complicated enough, though, that I may have
>> missed something, which is why I asked Razvan if there was a reason he
>> changed it.
>>
>> For the purposes of this patch, I propose having p2m_altp2m_init_ept()
>> set max_mapped_pfn to 0 (if that works), and leaving "get rid of
>> max_remapped_pfn" for a future clean-up series.
>
> I've retraced my previous analysis and re-ran some tests, and I now
> remember (sorry it took a while) why the p2m->max_mapped_pfn =
> hostp2m->max_mapped_pfn was both necessary and not accidental.
>
> Let's say we set it to 0 in p2m_altp2m_init_ept(). Then,
> hap_track_dirty_vram() calls p2m_change_type_range(), which calls the
> newly added change_type_range().
>
> Change_type_range() looks like this:
>
> static void change_type_range(struct p2m_domain *p2m,
> unsigned long start, unsigned long end,
> p2m_type_t ot, p2m_type_t nt)
> {
> unsigned long gfn = start;
> struct domain *d = p2m->domain;
> int rc = 0;
>
> p2m->defer_nested_flush = 1;
>
> if ( unlikely(end > p2m->max_mapped_pfn) )
> {
> if ( !gfn )
> {
> p2m->change_entry_type_global(p2m, ot, nt);
> gfn = end;
> }
> end = p2m->max_mapped_pfn + 1;
> }
> if ( gfn < end )
> rc = p2m->change_entry_type_range(p2m, ot, nt, gfn, end - 1);
> if ( rc )
> {
> printk(XENLOG_G_ERR "Error %d changing Dom%d GFNs [%lx,%lx] from
> %d to %d\n",
> rc, d->domain_id, start, end - 1, ot, nt);
> domain_crash(d);
> }
>
> switch ( nt )
> {
> case p2m_ram_rw:
> if ( ot == p2m_ram_logdirty )
> rc = rangeset_remove_range(p2m->logdirty_ranges, start, end
> - 1);
> break;
> case p2m_ram_logdirty:
> if ( ot == p2m_ram_rw )
> rc = rangeset_add_range(p2m->logdirty_ranges, start, end - 1);
> break;
> default:
> break;
> }
> if ( rc )
> {
> printk(XENLOG_G_ERR "Error %d manipulating Dom%d's log-dirty
> ranges\n",
> rc, d->domain_id);
> domain_crash(d);
> }
>
> p2m->defer_nested_flush = 0;
> if ( nestedhvm_enabled(d) )
> p2m_flush_nestedp2m(d);
> }
>
> If we set p2m->max_mapped_pfn to 0, we're guaranteed to run into the if
> ( unlikely(end > p2m->max_mapped_pfn) ) body, where end =
> p2m->max_mapped_pfn + 1; will make end 1.
>
> Then, we will crash the hypervisor in rangeset_add_range(), where
> there's an ASSERT() stating that start <= end.
Ah, right, this was the original crash that you ran into several months
ago, which flagged up the whole logdirty range synchronization issue.
But that's partly a logic hole in change_entry_type_range(), which
assumes that start < p2m->max_mapped_pfn. It would be better to fix
that than to work around it by changing the meaning of max_mapped_pfn.
On the other hand, we want the logdirty rangesets to actually match the
host's rangesets; using altp2m->max_mapped_pfn for this is clearly
wrong. The easiest fix would be just to explicitly use the host's
max_mapped_pfn when calculating the clipping. A more complete fix would
involve calculating two different ranges -- a "rangeset" range and a
"invalidate" range, the second of which would be clipped on altp2ms by
{min,max}_remapped_gfn.
Something like the attached (compile-tested only). I'm partial to
having both patches applied, but I'd be open to arguments that we should
only use the first.
-George
Attachment:
0001-p2m-Always-use-hostp2m-when-clipping-rangesets.patch Attachment:
0002-p2m-change_range_type-Only-invalidate-remapped-gfns.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |