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
This commit is contained in:
Matthew Poremba
2024-05-20 10:22:48 -07:00
committed by GitHub
parent 2b3beb92ff
commit 82318e85af
2 changed files with 21 additions and 12 deletions

View File

@@ -244,6 +244,10 @@ ISA::readMiscReg(RegIndex idx)
return base;
}
if (idx == misc_reg::Xcr0) {
return regVal[idx] | 1;
}
return readMiscRegNoEffect(idx);
}

View File

@@ -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);
}
}
}