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

[xen stable-4.17] x86/alternative: Support replacements when a feature is not present



commit 2aa9922c89839e8e28051db472cd02e91e0a6795
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Apr 21 15:52:56 2025 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Mon May 12 17:32:24 2025 +0100

    x86/alternative: Support replacements when a feature is not present
    
    Use the top bit of a->cpuid to express inverted polarity.  This requires
    stripping the top bit back out when performing the sanity checks.
    
    Despite only being used once, create a replace boolean to express the 
decision
    more clearly in _apply_alternatives().
    
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    (cherry picked from commit 328ed39c59e0af06d594f5e64a52b57aa0b02340)
---
 xen/arch/x86/alternative.c             | 12 ++++++++++--
 xen/arch/x86/include/asm/alternative.h |  9 ++++++++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/alternative.c b/xen/arch/x86/alternative.c
index 8356414be7..6eee6e501a 100644
--- a/xen/arch/x86/alternative.c
+++ b/xen/arch/x86/alternative.c
@@ -209,10 +209,12 @@ static void init_or_livepatch _apply_alternatives(struct 
alt_instr *start,
         uint8_t *repl = ALT_REPL_PTR(a);
         uint8_t buf[MAX_PATCH_LEN];
         unsigned int total_len = a->orig_len + a->pad_len;
+        unsigned int feat = a->cpuid & ~ALT_FLAG_NOT;
+        bool inv = a->cpuid & ALT_FLAG_NOT, replace;
 
         BUG_ON(a->repl_len > total_len);
         BUG_ON(total_len > sizeof(buf));
-        BUG_ON(a->cpuid >= NCAPINTS * 32);
+        BUG_ON(feat >= NCAPINTS * 32);
 
         /*
          * Detect sequences of alt_instr's patching the same origin site, and
@@ -235,8 +237,14 @@ static void init_or_livepatch _apply_alternatives(struct 
alt_instr *start,
             continue;
         }
 
+        /*
+         * Should a replacement be performed?  Most replacements have positive
+         * polarity, but we support negative polarity too.
+         */
+        replace = boot_cpu_has(feat) ^ inv;
+
         /* If there is no replacement to make, see about optimising the nops. 
*/
-        if ( !boot_cpu_has(a->cpuid) )
+        if ( !replace )
         {
             /* Origin site site already touched?  Don't nop anything. */
             if ( base->priv )
diff --git a/xen/arch/x86/include/asm/alternative.h 
b/xen/arch/x86/include/asm/alternative.h
index ee4cbe92cc..388e595786 100644
--- a/xen/arch/x86/include/asm/alternative.h
+++ b/xen/arch/x86/include/asm/alternative.h
@@ -1,6 +1,13 @@
 #ifndef __X86_ALTERNATIVE_H__
 #define __X86_ALTERNATIVE_H__
 
+/*
+ * Common to both C and ASM.  Express a replacement when a feature is not
+ * available.
+ */
+#define ALT_FLAG_NOT (1 << 15)
+#define ALT_NOT(x) (ALT_FLAG_NOT | (x))
+
 #ifdef __ASSEMBLY__
 #include <asm/alternative-asm.h>
 #else
@@ -11,7 +18,7 @@
 struct __packed alt_instr {
     int32_t  orig_offset;   /* original instruction */
     int32_t  repl_offset;   /* offset to replacement instruction */
-    uint16_t cpuid;         /* cpuid bit set for replacement */
+    uint16_t cpuid;         /* cpuid bit set for replacement (top bit is 
polarity) */
     uint8_t  orig_len;      /* length of original instruction */
     uint8_t  repl_len;      /* length of new instruction */
     uint8_t  pad_len;       /* length of build-time padding */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.17



 


Rackspace

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