From 82318e85af804c3466b6cfdd5a688901f0fa77f2 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Mon, 20 May 2024 10:22:48 -0700 Subject: [PATCH] arch-x86: Improve KVM set XCR (#1138) This adds two failsafes which may cause a panic on some machines. First, check the host machine has the KVM XCR capability before calling getXCRs or setXCRs. Second, ensure the x87 bit, which must always be one, will always return at least one by modifying the return value in readMiscReg. Change-Id: I5e778acc926a47443ef6cef29fabd84eb69bb9ba --- src/arch/x86/isa.cc | 4 ++++ src/arch/x86/kvm/x86_cpu.cc | 29 +++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index fd3e21273f..89b4328d66 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -244,6 +244,10 @@ ISA::readMiscReg(RegIndex idx) return base; } + if (idx == misc_reg::Xcr0) { + return regVal[idx] | 1; + } + return readMiscRegNoEffect(idx); } diff --git a/src/arch/x86/kvm/x86_cpu.cc b/src/arch/x86/kvm/x86_cpu.cc index 67df843000..a863ed79a2 100644 --- a/src/arch/x86/kvm/x86_cpu.cc +++ b/src/arch/x86/kvm/x86_cpu.cc @@ -1000,17 +1000,19 @@ X86KvmCPU::updateKvmStateMSRs() void X86KvmCPU::updateKvmStateXCRs() { - struct kvm_xcrs xcrs; + if (haveXCRs) { + struct kvm_xcrs xcrs; - xcrs.nr_xcrs = NumXCRegs; - xcrs.flags = 0; + xcrs.nr_xcrs = NumXCRegs; + xcrs.flags = 0; - for (int i = 0; i < xcrs.nr_xcrs; ++i) { - xcrs.xcrs[i].xcr = i; - xcrs.xcrs[i].value = tc->readMiscReg(misc_reg::xcr(i)); + for (int i = 0; i < xcrs.nr_xcrs; ++i) { + xcrs.xcrs[i].xcr = i; + xcrs.xcrs[i].value = tc->readMiscReg(misc_reg::xcr(i)); + } + + setXCRs(xcrs); } - - setXCRs(xcrs); } void @@ -1210,12 +1212,15 @@ X86KvmCPU::updateThreadContextMSRs() void X86KvmCPU::updateThreadContextXCRs() { - struct kvm_xcrs xcrs; + if (haveXCRs) { + struct kvm_xcrs xcrs; - getXCRs(xcrs); + getXCRs(xcrs); - for (int i = 0; i < xcrs.nr_xcrs; ++i) { - tc->setMiscReg(misc_reg::xcr(xcrs.xcrs[i].xcr), xcrs.xcrs[i].value); + for (int i = 0; i < xcrs.nr_xcrs; ++i) { + tc->setMiscReg(misc_reg::xcr(xcrs.xcrs[i].xcr), + xcrs.xcrs[i].value); + } } }