Hi Keir, we found invalid PDE entry in vmx domain will crash the whole
system, the code is in update_hl2e():
static inline void
update_hl2e(struct vcpu *v, unsigned long va)
{
int index = l2_table_offset(va);
unsigned long mfn;
l2_pgentry_t gl2e = v->arch.guest_vtable[index];
l1_pgentry_t old_hl2e, new_hl2e;
int need_flush = 0;
ASSERT(shadow_mode_translate(v->domain));
old_hl2e = v->arch.hl2_vtable[index];
if ( (l2e_get_flags(gl2e) & _PAGE_PRESENT) &&
VALID_MFN(mfn = get_mfn_from_pfn(l2e_get_pfn(gl2e))) )
new_hl2e = l1e_from_pfn(mfn, __PAGE_HYPERVISOR);
else
new_hl2e = l1e_empty();
... ...
}
Here, if there is an invalid PDE entry in VMX domain (For example, a VMX
domain only has 512M RAM, but a PDE entry is 0x40000063, the pfn is
beyond 512M RAM), so this invalid PDE entry will cause mfn =
get_mfn_from_pfn(l2e_get_pfn(gl2e)) return the invalid mfn = 0xFFFFFFFF,
and then a bad PTE is set into hl2 table, and later while trying to get
the gl1e of VMX guest, a page fault happened in Xen, and crashed the
system.
The problem here is, even there is an invalid PDE entry in VMX guest,
xen HV should not crash. We need a patch to protect Xen HV here, two
pieces of code need change:
1) if VALID_MFN(mfn = get_mfn_from_pfn(l2e_get_pfn(gl2e))) is true, this
function should fail. But seems xenlinux also uses this function, will
such change impact on xenlinux? Or only fail when it's external mode.
2) Jun suggested when accessing linear_pg_table, we should use
copy_from_user, change
orig_gpte = gpte = linear_pg_table[l1_linear_offset(va)];
To
if ( !(__copy_from_user(&gpte,
&linear_pg_table[l1_linear_offset(va)],
sizeof(gpte)) == 0) )
{
printk("Bad guest PDE entry: gpde = 0x%x, va = 0x%lx\n",
l2e_get_intpte(gpde), va);
//fail handling...
}
If you think it's OK, I will send a patch later.
-Xin
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|