diff options
author | David Edmondson <david.edmondson@oracle.com> | 2021-07-05 11:46:31 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-07-06 08:33:48 +0200 |
commit | fea4500841024195ec701713e05b92ebf667f192 (patch) | |
tree | 7901cb3679ee3b1177ff80493f874bade24d63ea /target/i386/hvf | |
parent | 3568987f78faff90829ea6c885bbdd5b083dc86c (diff) |
target/i386: Populate x86_ext_save_areas offsets using cpuid where possible
Rather than relying on the X86XSaveArea structure definition,
determine the offset of XSAVE state areas using CPUID leaf 0xd where
possible (KVM and HVF).
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
Message-Id: <20210705104632.2902400-8-david.edmondson@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386/hvf')
-rw-r--r-- | target/i386/hvf/hvf-cpu.c | 29 | ||||
-rw-r--r-- | target/i386/hvf/hvf.c | 6 |
2 files changed, 35 insertions, 0 deletions
diff --git a/target/i386/hvf/hvf-cpu.c b/target/i386/hvf/hvf-cpu.c index 8fbc423888..333db59898 100644 --- a/target/i386/hvf/hvf-cpu.c +++ b/target/i386/hvf/hvf-cpu.c @@ -30,6 +30,33 @@ static void hvf_cpu_max_instance_init(X86CPU *cpu) hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); } +static void hvf_cpu_xsave_init(void) +{ + static bool first = true; + int i; + + if (!first) { + return; + } + first = false; + + /* x87 and SSE states are in the legacy region of the XSAVE area. */ + x86_ext_save_areas[XSTATE_FP_BIT].offset = 0; + x86_ext_save_areas[XSTATE_SSE_BIT].offset = 0; + + for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { + ExtSaveArea *esa = &x86_ext_save_areas[i]; + + if (esa->size) { + int sz = hvf_get_supported_cpuid(0xd, i, R_EAX); + if (sz != 0) { + assert(esa->size == sz); + esa->offset = hvf_get_supported_cpuid(0xd, i, R_EBX); + } + } + } +} + static void hvf_cpu_instance_init(CPUState *cs) { X86CPU *cpu = X86_CPU(cs); @@ -42,6 +69,8 @@ static void hvf_cpu_instance_init(CPUState *cs) if (cpu->max_features) { hvf_cpu_max_instance_init(cpu); } + + hvf_cpu_xsave_init(); } static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data) diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index e62e8df028..79ba4ed93a 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -270,6 +270,12 @@ int hvf_arch_init_vcpu(CPUState *cpu) x86cpu->env.xsave_buf_len = 4096; x86cpu->env.xsave_buf = qemu_memalign(4096, x86cpu->env.xsave_buf_len); + /* + * The allocated storage must be large enough for all of the + * possible XSAVE state components. + */ + assert(hvf_get_supported_cpuid(0xd, 0, R_ECX) <= x86cpu->env.xsave_buf_len); + hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_STAR, 1); hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1); hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_CSTAR, 1); |