Message ID | dbdb045d-42de-af94-64cc-0be7992b80b6@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3,4.15] x86: mirror compat argument translation area for 32-bit PV | expand |
On 25.02.2021 10:30, Jan Beulich wrote: > Now that we guard the entire Xen VA space against speculative abuse > through hypervisor accesses to guest memory, the argument translation > area's VA also needs to live outside this range, at least for 32-bit PV > guests. To avoid extra is_hvm_*() conditionals, use the alternative VA > uniformly. > > While this could be conditionalized upon CONFIG_PV32 && > CONFIG_SPECULATIVE_HARDEN_GUEST_ACCESS, omitting such extra conditionals > keeps the code more legible imo. > > Fixes: 4dc181599142 ("x86/PV: harden guest memory accesses against speculative abuse") > Signed-off-by: Jan Beulich <jbeulich@suse.com> > Acked-by: Roger Pau Monné <roger.pau@citrix.com> Roger - I would have dropped an R-b, but I've assumed keeping an A-b would be fine. Please let me know if this was wrong. Jan
On 25/02/2021 09:30, Jan Beulich wrote: > --- 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(260 % 256) 4. 260 % 256 is pure obfuscation. ~Andrew
On 25.02.2021 13:52, Andrew Cooper wrote: > On 25/02/2021 09:30, Jan Beulich wrote: >> --- 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(260 % 256) > > 4. > > 260 % 256 is pure obfuscation. Well, that's why the comment is there. The expression is to show why 4 isn't entirely arbitrary. But well, if there's no way to get this in without changing to 4, I will of course do so. Before I submit v4 - are there any other concerns? Jan
--- 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 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 && --- 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(260 % 256) /* 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) --- 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);