|
[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: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.
So my reasoning was that, since setting p2m->max_mapped_pfn =
hostp2m->max_mapped_pfn is both harmless (as both your and Jan's
analyses appear to confirm) and makes this code correct, that was the
way to go.
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 |