nova: enable FPU AVX support

Add extended FPU state detection and handling (via xsave and friends) to the
kernel, which has to store/load more FPU state (~512 -> 2k++) during context
switching of threads. Additional the referenced nova branch contains various
optimization during VM destruction and cross core IPC resource caching.

This FPU work is based upon upstream NOVA kernel and Hedron commits.

Issue #5314
Fixes #3914
This commit is contained in:
Alexander Boettcher 2024-07-22 10:20:44 +02:00 committed by Christian Helmuth
parent 79506e4494
commit 2e92b7ae32
6 changed files with 21 additions and 4 deletions

View File

@ -417,6 +417,7 @@ namespace Nova {
SYSCALL_SWAPGS = 1U << 23, /* SYSCALL and SWAPGS MSRs */ SYSCALL_SWAPGS = 1U << 23, /* SYSCALL and SWAPGS MSRs */
TPR = 1U << 24, /* TPR and TPR threshold */ TPR = 1U << 24, /* TPR and TPR threshold */
TSC_AUX = 1U << 25, /* IA32_TSC_AUX used by rdtscp */ TSC_AUX = 1U << 25, /* IA32_TSC_AUX used by rdtscp */
XSAVE = 1U << 26, /* XCR and XSS used with XSAVE */
FPU = 1U << 31, /* FPU state */ FPU = 1U << 31, /* FPU state */
IRQ = EFL | STA | INJ | TSC, IRQ = EFL | STA | INJ | TSC,
@ -660,8 +661,8 @@ namespace Nova {
#endif #endif
unsigned long long qual[2]; /* exit qualification */ unsigned long long qual[2]; /* exit qualification */
unsigned ctrl[2]; unsigned ctrl[2];
unsigned long long reserved;
mword_t cr0, cr2, cr3, cr4; mword_t cr0, cr2, cr3, cr4;
unsigned long long xcr0, xss;
mword_t pdpte[4]; mword_t pdpte[4];
#ifdef __x86_64__ #ifdef __x86_64__
mword_t cr8, efer; mword_t cr8, efer;

View File

@ -1 +1 @@
ff82f8cb5bb9b87bd8c05048863c564d05897b2c e8997fb0870b6f8bdcb6da34a9b333ed4a304305

View File

@ -4,7 +4,7 @@ DOWNLOADS := nova.git
# r10 branch # r10 branch
URL(nova) := https://github.com/alex-ab/NOVA.git URL(nova) := https://github.com/alex-ab/NOVA.git
REV(nova) := a19cd2a58d37f6f517e9928fe89a413a1eaa05d2 REV(nova) := bca1aa3553d8c5df4f4b6ed5a2ee72f69bdf7a7f
DIR(nova) := src/kernel/nova DIR(nova) := src/kernel/nova
PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch)) PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch))

View File

@ -725,7 +725,7 @@ Core::Platform::Platform()
/* show all warnings/errors after init_core_log setup core_log */ /* show all warnings/errors after init_core_log setup core_log */
if (warn_reorder) if (warn_reorder)
warning("re-ordering of CPU ids for SMT and P/E cores failed"); warning("re-ordering of CPU ids for SMT and P/E cores failed");
if (hip.api_version != 9) if (hip.api_version != 10)
error("running on a unsupported kernel API version ", hip.api_version); error("running on a unsupported kernel API version ", hip.api_version);
if (binaries_end != core_virt_end) if (binaries_end != core_virt_end)
error("mismatch in address layout of binaries with core"); error("mismatch in address layout of binaries with core");

View File

@ -134,6 +134,7 @@ struct Nova_vcpu : Rpc_client<Vm_session::Native_vcpu>, Noncopyable
mtd |= Nova::Mtd::SYSCALL_SWAPGS; mtd |= Nova::Mtd::SYSCALL_SWAPGS;
mtd |= Nova::Mtd::TPR; mtd |= Nova::Mtd::TPR;
mtd |= Nova::Mtd::QUAL; mtd |= Nova::Mtd::QUAL;
mtd |= Nova::Mtd::XSAVE;
mtd |= Nova::Mtd::FPU; mtd |= Nova::Mtd::FPU;
return Nova::Mtd(mtd); return Nova::Mtd(mtd);
@ -334,6 +335,11 @@ void Nova_vcpu::_read_nova_state(Nova::Utcb &utcb)
_vcpu_state.tpr.charge(utcb.read_tpr()); _vcpu_state.tpr.charge(utcb.read_tpr());
_vcpu_state.tpr_threshold.charge(utcb.read_tpr_threshold()); _vcpu_state.tpr_threshold.charge(utcb.read_tpr_threshold());
} }
if (utcb.mtd & Nova::Mtd::XSAVE) {
_vcpu_state.xcr0.charge(utcb.xcr0);
_vcpu_state.xss.charge(utcb.xss);
}
} }
@ -541,6 +547,13 @@ void Nova_vcpu::_write_nova_state(Nova::Utcb &utcb)
utcb.write_tpr_threshold(_vcpu_state.tpr_threshold.value()); utcb.write_tpr_threshold(_vcpu_state.tpr_threshold.value());
} }
if (_vcpu_state.xcr0.charged() || _vcpu_state.xss.charged()) {
utcb.xcr0 = _vcpu_state.xcr0.value();
utcb.xss = _vcpu_state.xss.value();
utcb.mtd |= Nova::Mtd::XSAVE;
}
if (_vcpu_state.fpu.charged()) { if (_vcpu_state.fpu.charged()) {
utcb.mtd |= Nova::Mtd::FPU; utcb.mtd |= Nova::Mtd::FPU;
_vcpu_state.fpu.with_state([&] (Vcpu_state::Fpu::State const &fpu) { _vcpu_state.fpu.with_state([&] (Vcpu_state::Fpu::State const &fpu) {

View File

@ -195,6 +195,9 @@ class Genode::Vcpu_state
Register<uint32_t> tpr { }; Register<uint32_t> tpr { };
Register<uint32_t> tpr_threshold { }; Register<uint32_t> tpr_threshold { };
Register<uint64_t> xcr0 { };
Register<uint64_t> xss { };
unsigned exit_reason { }; unsigned exit_reason { };
class Fpu : Noncopyable class Fpu : Noncopyable