diff mbox series

[v3,4.15] x86: mirror compat argument translation area for 32-bit PV

Message ID dbdb045d-42de-af94-64cc-0be7992b80b6@suse.com (mailing list archive)
State New
Headers show
Series [v3,4.15] x86: mirror compat argument translation area for 32-bit PV | expand

Commit Message

Jan Beulich Feb. 25, 2021, 9:30 a.m. UTC
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>
Release-Acked-by: Ian Jackson <iwj@xenproject.org>
---
v3: Use address range in lower half of address space.
v2: Rename PERDOMAIN2_VIRT_START to PERDOMAIN_ALT_VIRT_START.

Comments

Jan Beulich Feb. 25, 2021, 9:32 a.m. UTC | #1
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
Andrew Cooper Feb. 25, 2021, 12:52 p.m. UTC | #2
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
Jan Beulich Feb. 25, 2021, 12:58 p.m. UTC | #3
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
diff mbox series

Patch

--- 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);