Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
xen.10697
59df64ff-x86-shadow-dont-create-self-lin-map-fo...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 59df64ff-x86-shadow-dont-create-self-lin-map-for-4-level-translated.patch of Package xen.10697
# Commit bf2b4eadcf379d0361b38de9725ea5f7a18a5205 # Date 2017-10-12 14:50:07 +0200 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Jan Beulich <jbeulich@suse.com> x86/shadow: Don't create self-linear shadow mappings for 4-level translated guests When initially creating a monitor table for 4-level translated guests, don't install a shadow-linear mapping. This mapping is actually self-linear, and trips up the writeable heuristic logic into following Xen's mappings, not the guests' shadows it was expecting to follow. A consequence of this is that sh_guess_wrmap() needs to cope with there being no shadow-linear mapping present, which in practice occurs once each time a vcpu switches to 4-level paging from a different paging mode. An appropriate shadow-linear slot will be inserted into the monitor table either while constructing lower level monitor tables, or by sh_update_cr3(). While fixing this, clarify the safety of the other mappings. Despite appearing unsafe, it is correct to create a guest-linear mapping for translated domains; this is self-linear and doesn't point into the translated domain. Drop a dead clause for translate != external guests. This is XSA-243. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: Tim Deegan <tim@xen.org> --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -1467,26 +1467,38 @@ void sh_install_xen_entries_in_l4(struct shadow_l4e_from_mfn(page_to_mfn(d->arch.perdomain_l3_pg), __PAGE_HYPERVISOR); - /* Shadow linear mapping for 4-level shadows. N.B. for 3-level - * shadows on 64-bit xen, this linear mapping is later replaced by the - * monitor pagetable structure, which is built in make_monitor_table - * and maintained by sh_update_linear_entries. */ - sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] = - shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR); - - /* Self linear mapping. */ - if ( shadow_mode_translate(v->domain) && !shadow_mode_external(v->domain) ) + /* + * Linear mapping slots: + * + * Calling this function with gl4mfn == sl4mfn is used to construct a + * monitor table for translated domains. In this case, gl4mfn forms the + * self-linear mapping (i.e. not pointing into the translated domain), and + * the shadow-linear slot is skipped. The shadow-linear slot is either + * filled when constructing lower level monitor tables, or via + * sh_update_cr3() for 4-level guests. + * + * Calling this function with gl4mfn != sl4mfn is used for non-translated + * guests, where the shadow-linear slot is actually self-linear, and the + * guest-linear slot points into the guests view of its pagetables. + */ + if ( shadow_mode_translate(d) ) { - // linear tables may not be used with translated PV guests - sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] = + ASSERT(mfn_x(gl4mfn) == mfn_x(sl4mfn)); + + sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] = shadow_l4e_empty(); } else { - sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] = - shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR); + ASSERT(mfn_x(gl4mfn) != mfn_x(sl4mfn)); + + sl4e[shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START)] = + shadow_l4e_from_mfn(sl4mfn, __PAGE_HYPERVISOR); } + sl4e[shadow_l4_table_offset(LINEAR_PT_VIRT_START)] = + shadow_l4e_from_mfn(gl4mfn, __PAGE_HYPERVISOR); + sh_unmap_domain_page(sl4e); } #endif @@ -4266,6 +4278,11 @@ static int sh_guess_wrmap(struct vcpu *v /* Carefully look in the shadow linear map for the l1e we expect */ #if SHADOW_PAGING_LEVELS >= 4 + /* Is a shadow linear map is installed in the first place? */ + sl4p = v->arch.paging.shadow.guest_vtable; + sl4p += shadow_l4_table_offset(SH_LINEAR_PT_VIRT_START); + if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) ) + return 0; sl4p = sh_linear_l4_table(v) + shadow_l4_linear_offset(vaddr); if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) ) return 0;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor