[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 6/6] x86: use MOV for PFN/PDX conversion when possible



... and (of course) also maddr / direct-map-offset ones.

Most x86 systems don't actually require the use of PDX compression. Now
that we have patching for the conversion code in place anyway, extend it
to use simple MOV when possible. Introduce a new pseudo-CPU-feature to
key the patching off of.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v2: Avoid quoted symbols; use gcc's new V operand modifier instead.
    Re-base.
---
This patch will only apply cleanly on top of "x86: NOP out XPTI
entry/exit code when it's not in use".

--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1410,6 +1410,9 @@ void __init noreturn __start_xen(unsigne
 
     numa_initmem_init(0, raw_max_page);
 
+    if ( !pfn_pdx_hole_shift )
+        setup_force_cpu_cap(X86_FEATURE_PFN_PDX_IDENT);
+
     if ( max_page - 1 > virt_to_mfn(HYPERVISOR_VIRT_END - 1) )
     {
         unsigned long limit = virt_to_mfn(HYPERVISOR_VIRT_END - 1);
--- a/xen/include/asm-x86/cpufeatures.h
+++ b/xen/include/asm-x86/cpufeatures.h
@@ -31,3 +31,4 @@ XEN_CPUFEATURE(XEN_IBRS_CLEAR,  (FSCAPIN
 XEN_CPUFEATURE(RSB_NATIVE,      (FSCAPINTS+0)*32+18) /* RSB overwrite needed 
for native */
 XEN_CPUFEATURE(RSB_VMEXIT,      (FSCAPINTS+0)*32+19) /* RSB overwrite needed 
for vmexit */
 XEN_CPUFEATURE(NO_XPTI,         (FSCAPINTS+0)*32+20) /* XPTI mitigation not in 
use */
+XEN_CPUFEATURE(PFN_PDX_IDENT,   (FSCAPINTS+0)*32+21) /* PFN <-> PDX mapping is 
1:1 */
--- a/xen/include/asm-x86/pdx.h
+++ b/xen/include/asm-x86/pdx.h
@@ -13,7 +13,7 @@ static always_inline unsigned long pdx_t
 
 #ifdef CONFIG_INDIRECT_THUNK /* V modifier available? */
 #define SYMNAME(pfx...) #pfx "pdx2pfn_%V[pfn]_%V[pdx]"
-    alternative_io("call " SYMNAME() "\n\t"
+    alternative_io_2("call " SYMNAME() "\n\t"
                    LINKONCE_PROLOGUE(SYMNAME) "\n\t"
                    "mov %[shift], %%ecx\n\t"
                    "mov %[pdx], %[pfn]\n\t"
@@ -24,6 +24,7 @@ static always_inline unsigned long pdx_t
                    "ret\n\t"
                    LINKONCE_EPILOGUE(SYMNAME),
                    "pdep %[mask], %[pdx], %[pfn]", X86_FEATURE_BMI2,
+                   "mov %[pdx], %[pfn]", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2([pfn] "=&r" (pfn), [pdx] "+r" (pdx)),
                    [mask] "m" (pfn_real_mask),
                    [shift] "m" (pfn_pdx_hole_shift),
@@ -32,11 +33,12 @@ static always_inline unsigned long pdx_t
                    : "ecx");
 #undef SYMNAME
 #else
-    alternative_io("call pdx2pfn",
+    alternative_io_2("call pdx2pfn",
                    /* pdep pfn_real_mask(%rip), %rdi, %rax */
                    ".byte 0xc4, 0xe2, 0xc3, 0xf5, 0x05\n\t"
                    ".long pfn_real_mask - 4 - .",
                    X86_FEATURE_BMI2,
+                   "mov %%rdi, %%rax", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2("=a" (pfn), "+D" (pdx)), "m" (pfn_real_mask)
                    : "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11");
 #endif
@@ -50,7 +52,7 @@ static always_inline unsigned long pfn_t
 
 #ifdef CONFIG_INDIRECT_THUNK /* V modifier available? */
 #define SYMNAME(pfx...) #pfx "pfn2pdx_%V[pdx]_%V[pfn]"
-    alternative_io("call " SYMNAME() "\n\t"
+    alternative_io_2("call " SYMNAME() "\n\t"
                    LINKONCE_PROLOGUE(SYMNAME) "\n\t"
                    "mov %[tmask], %[pdx]\n\t"
                    "mov %[shift], %%ecx\n\t"
@@ -61,6 +63,7 @@ static always_inline unsigned long pfn_t
                    "ret\n\t"
                    LINKONCE_EPILOGUE(SYMNAME),
                    "pext %[mask], %[pfn], %[pdx]", X86_FEATURE_BMI2,
+                   "mov %[pfn], %[pdx]", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2([pdx] "=&r" (pdx), [pfn] "+r" (pfn)),
                    [mask] "m" (pfn_real_mask),
                    [shift] "m" (pfn_pdx_hole_shift),
@@ -69,11 +72,12 @@ static always_inline unsigned long pfn_t
                    : "ecx");
 #undef SYMNAME
 #else
-    alternative_io("call pfn2pdx",
+    alternative_io_2("call pfn2pdx",
                    /* pext pfn_real_mask(%rip), %rdi, %rax */
                    ".byte 0xc4, 0xe2, 0xc2, 0xf5, 0x05\n\t"
                    ".long pfn_real_mask - 4 - .",
                    X86_FEATURE_BMI2,
+                   "mov %%rdi, %%rax", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2("=a" (pdx), "+D" (pfn)), "m" (pfn_real_mask)
                    : "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11");
 #endif
--- a/xen/include/asm-x86/x86_64/page.h
+++ b/xen/include/asm-x86/x86_64/page.h
@@ -75,7 +75,7 @@ static always_inline paddr_t __virt_to_m
 
 #ifdef CONFIG_INDIRECT_THUNK /* V modifier available? */
 #define SYMNAME(pfx...) #pfx "do2ma_%V[ma]_%V[off]"
-    alternative_io("call " SYMNAME() "\n\t"
+    alternative_io_2("call " SYMNAME() "\n\t"
                    LINKONCE_PROLOGUE(SYMNAME) "\n\t"
                    "mov %[shift], %%ecx\n\t"
                    "mov %[off], %[ma]\n\t"
@@ -86,6 +86,7 @@ static always_inline paddr_t __virt_to_m
                    "ret\n\t"
                    LINKONCE_EPILOGUE(SYMNAME),
                    "pdep %[mask], %[off], %[ma]", X86_FEATURE_BMI2,
+                   "mov %[off], %[ma]", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2([ma] "=&r" (ma), [off] "+r" (va)),
                    [mask] "m" (ma_real_mask),
                    [shift] "m" (pfn_pdx_hole_shift),
@@ -94,11 +95,12 @@ static always_inline paddr_t __virt_to_m
                    : "ecx");
 #undef SYMNAME
 #else
-    alternative_io("call do2ma",
+    alternative_io_2("call do2ma",
                    /* pdep ma_real_mask(%rip), %rdi, %rax */
                    ".byte 0xc4, 0xe2, 0xc3, 0xf5, 0x05\n\t"
                    ".long ma_real_mask - 4 - .",
                    X86_FEATURE_BMI2,
+                   "mov %%rdi, %%rax", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2("=a" (ma), "+D" (va)), "m" (ma_real_mask)
                    : "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11");
 #endif
@@ -114,7 +116,7 @@ static always_inline void *__maddr_to_vi
 
 #ifdef CONFIG_INDIRECT_THUNK /* V modifier available? */
 #define SYMNAME(pfx...) #pfx "ma2do_%V[off]_%V[ma]"
-    alternative_io("call " SYMNAME() "\n\t"
+    alternative_io_2("call " SYMNAME() "\n\t"
                    LINKONCE_PROLOGUE(SYMNAME) "\n\t"
                    "mov %[tmask], %[off]\n\t"
                    "mov %[shift], %%ecx\n\t"
@@ -125,6 +127,7 @@ static always_inline void *__maddr_to_vi
                    "ret\n\t"
                    LINKONCE_EPILOGUE(SYMNAME),
                    "pext %[mask], %[ma], %[off]", X86_FEATURE_BMI2,
+                   "mov %[ma], %[off]", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2([off] "=&r" (off), [ma] "+r" (ma)),
                    [mask] "m" (ma_real_mask),
                    [shift] "m" (pfn_pdx_hole_shift),
@@ -133,11 +136,12 @@ static always_inline void *__maddr_to_vi
                    : "ecx");
 #undef SYMNAME
 #else
-    alternative_io("call ma2do",
+    alternative_io_2("call ma2do",
                    /* pext ma_real_mask(%rip), %rdi, %rax */
                    ".byte 0xc4, 0xe2, 0xc2, 0xf5, 0x05\n\t"
                    ".long ma_real_mask - 4 - .",
                    X86_FEATURE_BMI2,
+                   "mov %%rdi, %%rax", X86_FEATURE_PFN_PDX_IDENT,
                    ASM_OUTPUT2("=a" (off), "+D" (ma)), "m" (ma_real_mask)
                    : "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11");
 #endif



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.