From: Xin Li Add CR4.FRED to the emulator's CR4 write mask. Historically, CR4 was restricted to its lower 32 bits in the x86 architecture. With the introduction of FRED, CR4 is expanded to use its higher 32 bits to accommodate the FRED enablement bit at position 32. Update the mask to ensure the emulator correctly handles FRED initialization and prevents the inadvertent truncation of high-order bits. Signed-off-by: Xin Li Signed-off-by: Sohil Mehta --- v10: - New patch --- arch/x86/kvm/regs.h | 2 +- arch/x86/kvm/x86.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/regs.h b/arch/x86/kvm/regs.h index 4e641a6c20f9..ef46918daf43 100644 --- a/arch/x86/kvm/regs.h +++ b/arch/x86/kvm/regs.h @@ -8,7 +8,7 @@ #define KVM_POSSIBLE_CR4_GUEST_BITS \ (X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR \ | X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE \ - | X86_CR4_CET) + | X86_CR4_CET | X86_CR4_FRED) #define X86_CR0_PDPTR_BITS (X86_CR0_CD | X86_CR0_NW | X86_CR0_PG) #define X86_CR4_TLBFLUSH_BITS (X86_CR4_PGE | X86_CR4_PCIDE | X86_CR4_PAE | X86_CR4_SMEP) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e10ac6b280f6..f264bc9c35f9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5552,11 +5552,17 @@ static int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, return kvm_set_dr(emul_to_vcpu(ctxt), dr, value); } -static u64 mk_cr_64(u64 curr_cr, u32 new_val) +static u64 mk_cr0_64(u64 curr_cr, u32 new_val) { return (curr_cr & ~((1ULL << 32) - 1)) | new_val; } +static u64 mk_cr4_64(struct kvm_vcpu *vcpu, u64 curr_cr, u64 new_val) +{ + u32 shift = guest_cpu_cap_has(vcpu, X86_FEATURE_FRED) ? 33 : 32; + return (curr_cr & ~((1ULL << shift) - 1)) | new_val; +} + static unsigned long emulator_get_cr(struct x86_emulate_ctxt *ctxt, int cr) { struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); @@ -5593,7 +5599,7 @@ static int emulator_set_cr(struct x86_emulate_ctxt *ctxt, int cr, ulong val) switch (cr) { case 0: - res = kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); + res = kvm_set_cr0(vcpu, mk_cr0_64(kvm_read_cr0(vcpu), val)); break; case 2: vcpu->arch.cr2 = val; @@ -5602,7 +5608,7 @@ static int emulator_set_cr(struct x86_emulate_ctxt *ctxt, int cr, ulong val) res = kvm_set_cr3(vcpu, val); break; case 4: - res = kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); + res = kvm_set_cr4(vcpu, mk_cr4_64(vcpu, kvm_read_cr4(vcpu), val)); break; case 8: res = kvm_set_cr8(vcpu, val); -- 2.43.0