]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86: Move inlined GPR, CR, and DR helpers from x86.h to regs.h
authorSean Christopherson <seanjc@google.com>
Fri, 29 May 2026 22:21:50 +0000 (15:21 -0700)
committerSean Christopherson <seanjc@google.com>
Wed, 3 Jun 2026 12:35:19 +0000 (05:35 -0700)
Move inlined General Purpose Register, Control Register, and Debug
Register helpers from x86.h to the aptly named regs.h, to help trim
down x86.h (and x86.c in the future).

Move *very* select EFER functionality as well, but leave behind the bulk of
EFER handling and all other MSR handling.  There is more than enough MSR
code to carve out msrs.{c,h} in the future.  Give is_long_bit_mode()
special treatment as it's more along the lines of a CR4 bit check, but just
happens to be accessed through an MSR interface.  And more importantly,
because giving regs.h access to is_long_bit_mode() greatly simplifies
dependency chains.

No functional change intended.

Reviewed-by: Yosry Ahmed <yosry@kernel.org>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Link: https://patch.msgid.link/20260529222223.870923-8-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/regs.h
arch/x86/kvm/x86.h

index 4440f3992fceddb34c566293061264ba63e8f9b5..62cc9deea226f98c5ccf05a7c7bcf7b7d1131c16 100644 (file)
 
 static_assert(!(KVM_POSSIBLE_CR0_GUEST_BITS & X86_CR0_PDPTR_BITS));
 
+static inline bool is_long_mode(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_X86_64
+       return !!(vcpu->arch.efer & EFER_LMA);
+#else
+       return false;
+#endif
+}
+
+static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
+{
+       int cs_db, cs_l;
+
+       WARN_ON_ONCE(vcpu->arch.guest_state_protected);
+
+       if (!is_long_mode(vcpu))
+               return false;
+       kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
+       return cs_l;
+}
+
+static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu)
+{
+       /*
+        * If running with protected guest state, the CS register is not
+        * accessible. The hypercall register values will have had to been
+        * provided in 64-bit mode, so assume the guest is in 64-bit.
+        */
+       return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu);
+}
+
 #define BUILD_KVM_GPR_ACCESSORS(lname, uname)                                \
 static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)\
 {                                                                            \
@@ -143,6 +174,13 @@ static inline unsigned long kvm_register_read_raw(struct kvm_vcpu *vcpu, int reg
        return vcpu->arch.regs[reg];
 }
 
+static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg)
+{
+       unsigned long val = kvm_register_read_raw(vcpu, reg);
+
+       return is_64_bit_mode(vcpu) ? val : (u32)val;
+}
+
 static inline void kvm_register_write_raw(struct kvm_vcpu *vcpu, int reg,
                                          unsigned long val)
 {
@@ -153,6 +191,14 @@ static inline void kvm_register_write_raw(struct kvm_vcpu *vcpu, int reg,
        kvm_register_mark_dirty(vcpu, reg);
 }
 
+static inline void kvm_register_write(struct kvm_vcpu *vcpu,
+                                      int reg, unsigned long val)
+{
+       if (!is_64_bit_mode(vcpu))
+               val = (u32)val;
+       return kvm_register_write_raw(vcpu, reg, val);
+}
+
 static inline unsigned long kvm_rip_read(struct kvm_vcpu *vcpu)
 {
        if (!kvm_register_is_available(vcpu, VCPU_REG_RIP))
@@ -177,6 +223,12 @@ static inline void kvm_rsp_write(struct kvm_vcpu *vcpu, unsigned long val)
        kvm_register_write_raw(vcpu, VCPU_REGS_RSP, val);
 }
 
+static inline u64 kvm_read_edx_eax(struct kvm_vcpu *vcpu)
+{
+       return (kvm_rax_read(vcpu) & -1u)
+               | ((u64)(kvm_rdx_read(vcpu) & -1u) << 32);
+}
+
 static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
 {
        might_sleep();  /* on svm */
@@ -243,10 +295,75 @@ static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu)
        return kvm_read_cr4_bits(vcpu, ~0UL);
 }
 
-static inline u64 kvm_read_edx_eax(struct kvm_vcpu *vcpu)
+static inline bool __kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
-       return (kvm_rax_read(vcpu) & -1u)
-               | ((u64)(kvm_rdx_read(vcpu) & -1u) << 32);
+       return !(cr4 & vcpu->arch.cr4_guest_rsvd_bits);
+}
+
+#define __cr4_reserved_bits(__cpu_has, __c)             \
+({                                                      \
+       u64 __reserved_bits = CR4_RESERVED_BITS;        \
+                                                        \
+       if (!__cpu_has(__c, X86_FEATURE_XSAVE))         \
+               __reserved_bits |= X86_CR4_OSXSAVE;     \
+       if (!__cpu_has(__c, X86_FEATURE_SMEP))          \
+               __reserved_bits |= X86_CR4_SMEP;        \
+       if (!__cpu_has(__c, X86_FEATURE_SMAP))          \
+               __reserved_bits |= X86_CR4_SMAP;        \
+       if (!__cpu_has(__c, X86_FEATURE_FSGSBASE))      \
+               __reserved_bits |= X86_CR4_FSGSBASE;    \
+       if (!__cpu_has(__c, X86_FEATURE_PKU))           \
+               __reserved_bits |= X86_CR4_PKE;         \
+       if (!__cpu_has(__c, X86_FEATURE_LA57))          \
+               __reserved_bits |= X86_CR4_LA57;        \
+       if (!__cpu_has(__c, X86_FEATURE_UMIP))          \
+               __reserved_bits |= X86_CR4_UMIP;        \
+       if (!__cpu_has(__c, X86_FEATURE_VMX))           \
+               __reserved_bits |= X86_CR4_VMXE;        \
+       if (!__cpu_has(__c, X86_FEATURE_PCID))          \
+               __reserved_bits |= X86_CR4_PCIDE;       \
+       if (!__cpu_has(__c, X86_FEATURE_LAM))           \
+               __reserved_bits |= X86_CR4_LAM_SUP;     \
+       if (!__cpu_has(__c, X86_FEATURE_SHSTK) &&       \
+           !__cpu_has(__c, X86_FEATURE_IBT))           \
+               __reserved_bits |= X86_CR4_CET;         \
+       __reserved_bits;                                \
+})
+
+static inline bool is_protmode(struct kvm_vcpu *vcpu)
+{
+       return kvm_is_cr0_bit_set(vcpu, X86_CR0_PE);
+}
+
+static inline bool is_pae(struct kvm_vcpu *vcpu)
+{
+       return kvm_is_cr4_bit_set(vcpu, X86_CR4_PAE);
+}
+
+static inline bool is_pse(struct kvm_vcpu *vcpu)
+{
+       return kvm_is_cr4_bit_set(vcpu, X86_CR4_PSE);
+}
+
+static inline bool is_paging(struct kvm_vcpu *vcpu)
+{
+       return likely(kvm_is_cr0_bit_set(vcpu, X86_CR0_PG));
+}
+
+static inline bool is_pae_paging(struct kvm_vcpu *vcpu)
+{
+       return !is_long_mode(vcpu) && is_pae(vcpu) && is_paging(vcpu);
+}
+
+static inline bool kvm_dr7_valid(u64 data)
+{
+       /* Bits [63:32] are reserved */
+       return !(data >> 32);
+}
+static inline bool kvm_dr6_valid(u64 data)
+{
+       /* Bits [63:32] are reserved */
+       return !(data >> 32);
 }
 
 static inline void enter_guest_mode(struct kvm_vcpu *vcpu)
index fee92c603ad02e0cd94cf810c23925b3fb659cf3..e06f0ee63515280cf8ea108714356ab98cc30452 100644 (file)
@@ -243,42 +243,6 @@ static inline bool kvm_exception_is_soft(unsigned int nr)
        return (nr == BP_VECTOR) || (nr == OF_VECTOR);
 }
 
-static inline bool is_protmode(struct kvm_vcpu *vcpu)
-{
-       return kvm_is_cr0_bit_set(vcpu, X86_CR0_PE);
-}
-
-static inline bool is_long_mode(struct kvm_vcpu *vcpu)
-{
-#ifdef CONFIG_X86_64
-       return !!(vcpu->arch.efer & EFER_LMA);
-#else
-       return false;
-#endif
-}
-
-static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
-{
-       int cs_db, cs_l;
-
-       WARN_ON_ONCE(vcpu->arch.guest_state_protected);
-
-       if (!is_long_mode(vcpu))
-               return false;
-       kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
-       return cs_l;
-}
-
-static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu)
-{
-       /*
-        * If running with protected guest state, the CS register is not
-        * accessible. The hypercall register values will have had to been
-        * provided in 64-bit mode, so assume the guest is in 64-bit.
-        */
-       return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu);
-}
-
 static inline bool x86_exception_has_error_code(unsigned int vector)
 {
        static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) |
@@ -293,26 +257,6 @@ static inline bool mmu_is_nested(struct kvm_vcpu *vcpu)
        return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu;
 }
 
-static inline bool is_pae(struct kvm_vcpu *vcpu)
-{
-       return kvm_is_cr4_bit_set(vcpu, X86_CR4_PAE);
-}
-
-static inline bool is_pse(struct kvm_vcpu *vcpu)
-{
-       return kvm_is_cr4_bit_set(vcpu, X86_CR4_PSE);
-}
-
-static inline bool is_paging(struct kvm_vcpu *vcpu)
-{
-       return likely(kvm_is_cr0_bit_set(vcpu, X86_CR0_PG));
-}
-
-static inline bool is_pae_paging(struct kvm_vcpu *vcpu)
-{
-       return !is_long_mode(vcpu) && is_pae(vcpu) && is_paging(vcpu);
-}
-
 static inline u8 vcpu_virt_addr_bits(struct kvm_vcpu *vcpu)
 {
        return kvm_is_cr4_bit_set(vcpu, X86_CR4_LA57) ? 57 : 48;
@@ -421,21 +365,6 @@ static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
        return false;
 }
 
-static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu, int reg)
-{
-       unsigned long val = kvm_register_read_raw(vcpu, reg);
-
-       return is_64_bit_mode(vcpu) ? val : (u32)val;
-}
-
-static inline void kvm_register_write(struct kvm_vcpu *vcpu,
-                                      int reg, unsigned long val)
-{
-       if (!is_64_bit_mode(vcpu))
-               val = (u32)val;
-       return kvm_register_write_raw(vcpu, reg, val);
-}
-
 static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk)
 {
        return !(kvm->arch.disabled_quirks & quirk);
@@ -630,17 +559,6 @@ static inline bool kvm_pat_valid(u64 data)
        return (data | ((data & 0x0202020202020202ull) << 1)) == data;
 }
 
-static inline bool kvm_dr7_valid(u64 data)
-{
-       /* Bits [63:32] are reserved */
-       return !(data >> 32);
-}
-static inline bool kvm_dr6_valid(u64 data)
-{
-       /* Bits [63:32] are reserved */
-       return !(data >> 32);
-}
-
 /*
  * Trigger machine check on the host. We assume all the MSRs are already set up
  * by the CPU and that we still run on the same CPU as the MCE occurred on.
@@ -687,41 +605,6 @@ enum kvm_msr_access {
 #define  KVM_MSR_RET_UNSUPPORTED       2
 #define  KVM_MSR_RET_FILTERED          3
 
-static inline bool __kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
-{
-       return !(cr4 & vcpu->arch.cr4_guest_rsvd_bits);
-}
-
-#define __cr4_reserved_bits(__cpu_has, __c)             \
-({                                                      \
-       u64 __reserved_bits = CR4_RESERVED_BITS;        \
-                                                        \
-       if (!__cpu_has(__c, X86_FEATURE_XSAVE))         \
-               __reserved_bits |= X86_CR4_OSXSAVE;     \
-       if (!__cpu_has(__c, X86_FEATURE_SMEP))          \
-               __reserved_bits |= X86_CR4_SMEP;        \
-       if (!__cpu_has(__c, X86_FEATURE_SMAP))          \
-               __reserved_bits |= X86_CR4_SMAP;        \
-       if (!__cpu_has(__c, X86_FEATURE_FSGSBASE))      \
-               __reserved_bits |= X86_CR4_FSGSBASE;    \
-       if (!__cpu_has(__c, X86_FEATURE_PKU))           \
-               __reserved_bits |= X86_CR4_PKE;         \
-       if (!__cpu_has(__c, X86_FEATURE_LA57))          \
-               __reserved_bits |= X86_CR4_LA57;        \
-       if (!__cpu_has(__c, X86_FEATURE_UMIP))          \
-               __reserved_bits |= X86_CR4_UMIP;        \
-       if (!__cpu_has(__c, X86_FEATURE_VMX))           \
-               __reserved_bits |= X86_CR4_VMXE;        \
-       if (!__cpu_has(__c, X86_FEATURE_PCID))          \
-               __reserved_bits |= X86_CR4_PCIDE;       \
-       if (!__cpu_has(__c, X86_FEATURE_LAM))           \
-               __reserved_bits |= X86_CR4_LAM_SUP;     \
-       if (!__cpu_has(__c, X86_FEATURE_SHSTK) &&       \
-           !__cpu_has(__c, X86_FEATURE_IBT))           \
-               __reserved_bits |= X86_CR4_CET;         \
-       __reserved_bits;                                \
-})
-
 int kvm_sev_es_mmio(struct kvm_vcpu *vcpu, bool is_write, gpa_t gpa,
                    unsigned int bytes, void *data);
 int kvm_sev_es_string_io(struct kvm_vcpu *vcpu, unsigned int size,