|
|
e2f3ee |
From 8a8d1ef278933a3c3a11f8d8c2985e0af71741b4 Mon Sep 17 00:00:00 2001
|
|
|
e2f3ee |
From: David Edmondson <david.edmondson@oracle.com>
|
|
|
e2f3ee |
Date: Mon, 5 Jul 2021 11:46:28 +0100
|
|
|
e2f3ee |
Subject: [PATCH 4/7] target/i386: Pass buffer and length to XSAVE helper
|
|
|
e2f3ee |
|
|
|
e2f3ee |
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
e2f3ee |
RH-MergeRequest: 113: non-av 8.5z: Fix XSAVE on newer CPUs
|
|
|
e2f3ee |
RH-Commit: [4/7] 77e093a6ed3928b9191b37faad3cb50b4bdd65e3
|
|
|
e2f3ee |
RH-Bugzilla: 2065239
|
|
|
e2f3ee |
RH-Acked-by: Jon Maloy <jmaloy@redhat.com>
|
|
|
e2f3ee |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
e2f3ee |
RH-Acked-by: Bandan Das <None>
|
|
|
e2f3ee |
|
|
|
e2f3ee |
In preparation for removing assumptions about XSAVE area offsets, pass
|
|
|
e2f3ee |
a buffer pointer and buffer length to the XSAVE helper functions.
|
|
|
e2f3ee |
|
|
|
e2f3ee |
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
|
|
|
e2f3ee |
Message-Id: <20210705104632.2902400-5-david.edmondson@oracle.com>
|
|
|
e2f3ee |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
e2f3ee |
(cherry picked from commit c0198c5f87b6db25712672292e01ab710d6ef631)
|
|
|
e2f3ee |
dgilbert: Manual merge in target/i386/hvf/x86hvf.c
|
|
|
e2f3ee |
---
|
|
|
e2f3ee |
target/i386/cpu.h | 5 +++--
|
|
|
e2f3ee |
target/i386/hvf/hvf.c | 3 ++-
|
|
|
e2f3ee |
target/i386/hvf/x86hvf.c | 19 ++++++++-----------
|
|
|
e2f3ee |
target/i386/kvm.c | 13 +++++++------
|
|
|
e2f3ee |
target/i386/xsave_helper.c | 17 +++++++++--------
|
|
|
e2f3ee |
5 files changed, 29 insertions(+), 28 deletions(-)
|
|
|
e2f3ee |
|
|
|
e2f3ee |
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
|
|
|
e2f3ee |
index d586b5508d..8daa83a6a3 100644
|
|
|
e2f3ee |
--- a/target/i386/cpu.h
|
|
|
e2f3ee |
+++ b/target/i386/cpu.h
|
|
|
e2f3ee |
@@ -1626,6 +1626,7 @@ typedef struct CPUX86State {
|
|
|
e2f3ee |
int64_t user_tsc_khz; /* for sanity check only */
|
|
|
e2f3ee |
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
|
|
e2f3ee |
void *xsave_buf;
|
|
|
e2f3ee |
+ uint32_t xsave_buf_len;
|
|
|
e2f3ee |
#endif
|
|
|
e2f3ee |
#if defined(CONFIG_KVM)
|
|
|
e2f3ee |
struct kvm_nested_state *nested_state;
|
|
|
e2f3ee |
@@ -2254,8 +2255,8 @@ void x86_cpu_dump_local_apic_state(CPUState *cs, int flags);
|
|
|
e2f3ee |
/* cpu.c */
|
|
|
e2f3ee |
bool cpu_is_bsp(X86CPU *cpu);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
-void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf);
|
|
|
e2f3ee |
-void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
|
|
|
e2f3ee |
+void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen);
|
|
|
e2f3ee |
+void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen);
|
|
|
e2f3ee |
void x86_update_hflags(CPUX86State* env);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat)
|
|
|
e2f3ee |
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
|
|
|
e2f3ee |
index d72543dc31..bbede52fb7 100644
|
|
|
e2f3ee |
--- a/target/i386/hvf/hvf.c
|
|
|
e2f3ee |
+++ b/target/i386/hvf/hvf.c
|
|
|
e2f3ee |
@@ -609,7 +609,8 @@ int hvf_init_vcpu(CPUState *cpu)
|
|
|
e2f3ee |
wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
x86cpu = X86_CPU(cpu);
|
|
|
e2f3ee |
- x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
|
|
|
e2f3ee |
+ x86cpu->env.xsave_buf_len = 4096;
|
|
|
e2f3ee |
+ x86cpu->env.xsave_buf = qemu_memalign(4096, x86cpu->env.xsave_buf_len);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_STAR, 1);
|
|
|
e2f3ee |
hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_LSTAR, 1);
|
|
|
e2f3ee |
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
|
|
|
e2f3ee |
index edefe5319a..7be0582f28 100644
|
|
|
e2f3ee |
--- a/target/i386/hvf/x86hvf.c
|
|
|
e2f3ee |
+++ b/target/i386/hvf/x86hvf.c
|
|
|
e2f3ee |
@@ -72,14 +72,12 @@ void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg)
|
|
|
e2f3ee |
|
|
|
e2f3ee |
void hvf_put_xsave(CPUState *cpu_state)
|
|
|
e2f3ee |
{
|
|
|
e2f3ee |
+ void *xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
|
|
e2f3ee |
+ uint32_t xsave_len = X86_CPU(cpu_state)->env.xsave_buf_len;
|
|
|
e2f3ee |
|
|
|
e2f3ee |
- struct X86XSaveArea *xsave;
|
|
|
e2f3ee |
+ x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
- xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
- x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave);
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
- if (hv_vcpu_write_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
|
|
|
e2f3ee |
+ if (hv_vcpu_write_fpstate(cpu_state->hvf_fd, xsave, xsave_len)) {
|
|
|
e2f3ee |
abort();
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
@@ -157,15 +155,14 @@ void hvf_put_msrs(CPUState *cpu_state)
|
|
|
e2f3ee |
|
|
|
e2f3ee |
void hvf_get_xsave(CPUState *cpu_state)
|
|
|
e2f3ee |
{
|
|
|
e2f3ee |
- struct X86XSaveArea *xsave;
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
- xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
|
|
e2f3ee |
+ void *xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
|
|
e2f3ee |
+ uint32_t xsave_len = X86_CPU(cpu_state)->env.xsave_buf_len;
|
|
|
e2f3ee |
|
|
|
e2f3ee |
- if (hv_vcpu_read_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
|
|
|
e2f3ee |
+ if (hv_vcpu_read_fpstate(cpu_state->hvf_fd, xsave, xsave_len)) {
|
|
|
e2f3ee |
abort();
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
|
|
|
e2f3ee |
- x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave);
|
|
|
e2f3ee |
+ x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
|
|
|
e2f3ee |
void hvf_get_segments(CPUState *cpu_state)
|
|
|
e2f3ee |
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
|
|
|
e2f3ee |
index 215487b17d..8167587445 100644
|
|
|
e2f3ee |
--- a/target/i386/kvm.c
|
|
|
e2f3ee |
+++ b/target/i386/kvm.c
|
|
|
e2f3ee |
@@ -1826,8 +1826,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
|
|
|
e2f3ee |
if (has_xsave) {
|
|
|
e2f3ee |
- env->xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
|
|
|
e2f3ee |
- memset(env->xsave_buf, 0, sizeof(struct kvm_xsave));
|
|
|
e2f3ee |
+ env->xsave_buf_len = sizeof(struct kvm_xsave);
|
|
|
e2f3ee |
+ env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len);
|
|
|
e2f3ee |
+ memset(env->xsave_buf, 0, env->xsave_buf_len);
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
|
|
|
e2f3ee |
max_nested_state_len = kvm_max_nested_state_length();
|
|
|
e2f3ee |
@@ -2353,12 +2354,12 @@ static int kvm_put_fpu(X86CPU *cpu)
|
|
|
e2f3ee |
static int kvm_put_xsave(X86CPU *cpu)
|
|
|
e2f3ee |
{
|
|
|
e2f3ee |
CPUX86State *env = &cpu->env;
|
|
|
e2f3ee |
- X86XSaveArea *xsave = env->xsave_buf;
|
|
|
e2f3ee |
+ void *xsave = env->xsave_buf;
|
|
|
e2f3ee |
|
|
|
e2f3ee |
if (!has_xsave) {
|
|
|
e2f3ee |
return kvm_put_fpu(cpu);
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
- x86_cpu_xsave_all_areas(cpu, xsave);
|
|
|
e2f3ee |
+ x86_cpu_xsave_all_areas(cpu, xsave, env->xsave_buf_len);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
@@ -2977,7 +2978,7 @@ static int kvm_get_fpu(X86CPU *cpu)
|
|
|
e2f3ee |
static int kvm_get_xsave(X86CPU *cpu)
|
|
|
e2f3ee |
{
|
|
|
e2f3ee |
CPUX86State *env = &cpu->env;
|
|
|
e2f3ee |
- X86XSaveArea *xsave = env->xsave_buf;
|
|
|
e2f3ee |
+ void *xsave = env->xsave_buf;
|
|
|
e2f3ee |
int ret;
|
|
|
e2f3ee |
|
|
|
e2f3ee |
if (!has_xsave) {
|
|
|
e2f3ee |
@@ -2988,7 +2989,7 @@ static int kvm_get_xsave(X86CPU *cpu)
|
|
|
e2f3ee |
if (ret < 0) {
|
|
|
e2f3ee |
return ret;
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
- x86_cpu_xrstor_all_areas(cpu, xsave);
|
|
|
e2f3ee |
+ x86_cpu_xrstor_all_areas(cpu, xsave, env->xsave_buf_len);
|
|
|
e2f3ee |
|
|
|
e2f3ee |
return 0;
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c
|
|
|
e2f3ee |
index 818115e7d2..b16c6ac0fe 100644
|
|
|
e2f3ee |
--- a/target/i386/xsave_helper.c
|
|
|
e2f3ee |
+++ b/target/i386/xsave_helper.c
|
|
|
e2f3ee |
@@ -6,14 +6,16 @@
|
|
|
e2f3ee |
|
|
|
e2f3ee |
#include "cpu.h"
|
|
|
e2f3ee |
|
|
|
e2f3ee |
-void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
|
|
|
e2f3ee |
+void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen)
|
|
|
e2f3ee |
{
|
|
|
e2f3ee |
CPUX86State *env = &cpu->env;
|
|
|
e2f3ee |
X86XSaveArea *xsave = buf;
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
uint16_t cwd, swd, twd;
|
|
|
e2f3ee |
int i;
|
|
|
e2f3ee |
- memset(xsave, 0, sizeof(X86XSaveArea));
|
|
|
e2f3ee |
+
|
|
|
e2f3ee |
+ assert(buflen >= sizeof(*xsave));
|
|
|
e2f3ee |
+
|
|
|
e2f3ee |
+ memset(xsave, 0, buflen);
|
|
|
e2f3ee |
twd = 0;
|
|
|
e2f3ee |
swd = env->fpus & ~(7 << 11);
|
|
|
e2f3ee |
swd |= (env->fpstt & 7) << 11;
|
|
|
e2f3ee |
@@ -56,17 +58,17 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
|
|
|
e2f3ee |
16 * sizeof env->xmm_regs[16]);
|
|
|
e2f3ee |
memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
|
|
|
e2f3ee |
#endif
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
|
|
|
e2f3ee |
-void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf)
|
|
|
e2f3ee |
+void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen)
|
|
|
e2f3ee |
{
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
CPUX86State *env = &cpu->env;
|
|
|
e2f3ee |
const X86XSaveArea *xsave = buf;
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
int i;
|
|
|
e2f3ee |
uint16_t cwd, swd, twd;
|
|
|
e2f3ee |
+
|
|
|
e2f3ee |
+ assert(buflen >= sizeof(*xsave));
|
|
|
e2f3ee |
+
|
|
|
e2f3ee |
cwd = xsave->legacy.fcw;
|
|
|
e2f3ee |
swd = xsave->legacy.fsw;
|
|
|
e2f3ee |
twd = xsave->legacy.ftw;
|
|
|
e2f3ee |
@@ -108,5 +110,4 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf)
|
|
|
e2f3ee |
16 * sizeof env->xmm_regs[16]);
|
|
|
e2f3ee |
memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
|
|
|
e2f3ee |
#endif
|
|
|
e2f3ee |
-
|
|
|
e2f3ee |
}
|
|
|
e2f3ee |
--
|
|
|
e2f3ee |
2.27.0
|
|
|
e2f3ee |
|