cpu-kvm: properly set x86 xsave header on gem5->KVM transition (#298)
If the XSAVE KVM capability is available (KVM_CAP_XSAVE), the X86KvmCPU will try to set the x87 FPU + SSE state using KVM_SET_XSAVE, which expects a buffer (struct kvm_xsave) in XSAVE area format (Vol. 1, Sec. 13.4 of Intel x86 SDM). The original implementation of `X86KvmCPU::updateKvmStateFPUXSave()`, however, improperly sets the xsave header, which contains a bitmap of state components present in the xsave area. This patch defines `XSaveHeader` structure to model the xsave header, which is expected directly following the legacy FPU region (defined in the `FXSave` structure) in the xsave area. It then sets two bist in the xsave header to indicate the presence of x86 FPU and SSE state components. GitHub issue: https://github.com/gem5/gem5/issues/296
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#include "arch/x86/regs/int.hh"
|
||||
#include "arch/x86/regs/msr.hh"
|
||||
#include "arch/x86/utility.hh"
|
||||
#include "base/bitunion.hh"
|
||||
#include "base/compiler.hh"
|
||||
#include "cpu/kvm/base.hh"
|
||||
#include "debug/Drain.hh"
|
||||
@@ -117,6 +118,32 @@ struct GEM5_PACKED FXSave
|
||||
|
||||
static_assert(sizeof(FXSave) == 512, "Unexpected size of FXSave");
|
||||
|
||||
BitUnion64(XStateBV)
|
||||
Bitfield<0> fpu;
|
||||
Bitfield<1> sse;
|
||||
Bitfield<2> avx;
|
||||
Bitfield<4, 3> mpx;
|
||||
Bitfield<7, 5> avx512;
|
||||
Bitfield<8> pt;
|
||||
Bitfield<9> pkru;
|
||||
Bitfield<10> pasid;
|
||||
Bitfield<12, 11> cet;
|
||||
Bitfield<13> hdc;
|
||||
Bitfield<14> uintr;
|
||||
Bitfield<15> lbr;
|
||||
Bitfield<16> hwp;
|
||||
Bitfield<18, 17> amx;
|
||||
Bitfield<63, 19> reserved;
|
||||
EndBitUnion(XStateBV)
|
||||
|
||||
struct XSaveHeader
|
||||
{
|
||||
XStateBV xstate_bv;
|
||||
uint64_t reserved[7];
|
||||
};
|
||||
|
||||
static_assert(sizeof(XSaveHeader) == 64, "Unexpected size of XSaveHeader");
|
||||
|
||||
#define FOREACH_IREG() \
|
||||
do { \
|
||||
APPLY_IREG(rax, int_reg::Rax); \
|
||||
@@ -912,6 +939,19 @@ X86KvmCPU::updateKvmStateFPUXSave()
|
||||
|
||||
updateKvmStateFPUCommon(tc, xsave);
|
||||
|
||||
/**
|
||||
* The xsave header (Vol. 1, Section 13.4.2 of the Intel Software
|
||||
* Development Manual) directly follows the legacy xsave region
|
||||
* (i.e., the FPU/SSE state). The first 8 bytes of the xsave header
|
||||
* hold a state-component bitmap called xstate_bv. We need to set
|
||||
* the state component bits corresponding to the FPU and SSE
|
||||
* states.
|
||||
*/
|
||||
XSaveHeader& xsave_hdr =
|
||||
* (XSaveHeader *) ((char *) &kxsave + sizeof(FXSave));
|
||||
xsave_hdr.xstate_bv.fpu = 1;
|
||||
xsave_hdr.xstate_bv.sse = 1;
|
||||
|
||||
if (tc->readMiscRegNoEffect(misc_reg::Fiseg))
|
||||
warn_once("misc_reg::Fiseg is non-zero.\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user