diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 4366ea34d1..afb4febf6f 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1691,6 +1691,13 @@ void init_xen_l4_slots(l4_pgentry_t *l4t, mfn_t l4mfn, l4t[l4_table_offset(PERDOMAIN_VIRT_START)] = l4e_from_page(d->arch.perdomain_l3_pg, __PAGE_HYPERVISOR_RW); + /* Slot 4: Per-domain mappings mirror. */ + BUILD_BUG_ON(IS_ENABLED(CONFIG_PV32) && + !l4_table_offset(PERDOMAIN_ALT_VIRT_START)); + if ( !is_pv_64bit_domain(d) ) + l4t[l4_table_offset(PERDOMAIN_ALT_VIRT_START)] = + l4t[l4_table_offset(PERDOMAIN_VIRT_START)]; + /* Slot 261-: text/data/bss, RW M2P, vmap, frametable, directmap. */ #ifndef NDEBUG if ( short_directmap && diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 74406f0239..883c2ef0df 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -170,7 +170,11 @@ extern unsigned char boot_edid_info[128]; * Guest-defined use. * 0x00000000f5800000 - 0x00000000ffffffff [168MB, PML4:0] * Read-only machine-to-phys translation table (GUEST ACCESSIBLE). - * 0x0000000100000000 - 0x00007fffffffffff [128TB-4GB, PML4:0-255] + * 0x0000000100000000 - 0x000001ffffffffff [2TB-4GB, PML4:0-3] + * Unused / Reserved for future use. + * 0x0000020000000000 - 0x0000027fffffffff [512GB, 2^39 bytes, PML4:4] + * Mirror of per-domain mappings (for argument translation area; also HVM). + * 0x0000028000000000 - 0x00007fffffffffff [125.5TB, PML4:5-255] * Unused / Reserved for future use. */ @@ -207,6 +211,8 @@ extern unsigned char boot_edid_info[128]; #define PERDOMAIN_SLOTS 3 #define PERDOMAIN_VIRT_SLOT(s) (PERDOMAIN_VIRT_START + (s) * \ (PERDOMAIN_SLOT_MBYTES << 20)) +/* Slot 4: mirror of per-domain mappings (for compat xlat area accesses). */ +#define PERDOMAIN_ALT_VIRT_START PML4_ADDR(4) /* Slot 261: machine-to-phys conversion table (256GB). */ #define RDWR_MPT_VIRT_START (PML4_ADDR(261)) #define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + MPT_VIRT_SIZE) diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index c48e57bf09..ba79f950fb 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -1,7 +1,17 @@ #ifndef __X86_64_UACCESS_H #define __X86_64_UACCESS_H -#define COMPAT_ARG_XLAT_VIRT_BASE ((void *)ARG_XLAT_START(current)) +/* + * With CONFIG_SPECULATIVE_HARDEN_GUEST_ACCESS (apparent) PV guest accesses + * are prohibited to touch the Xen private VA range. The compat argument + * translation area, therefore, can't live within this range. Domains + * (potentially) in need of argument translation (32-bit PV, possibly HVM) get + * a secondary mapping installed, which needs to be used for such accesses in + * the PV case, and will also be used for HVM to avoid extra conditionals. + */ +#define COMPAT_ARG_XLAT_VIRT_BASE ((void *)ARG_XLAT_START(current) + \ + (PERDOMAIN_ALT_VIRT_START - \ + PERDOMAIN_VIRT_START)) #define COMPAT_ARG_XLAT_SIZE (2*PAGE_SIZE) struct vcpu; int setup_compat_arg_xlat(struct vcpu *v);