mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
target/i386: Pass buffer and length to XSAVE helper
In preparation for removing assumptions about XSAVE area offsets, pass a buffer pointer and buffer length to the XSAVE helper functions. Signed-off-by: David Edmondson <david.edmondson@oracle.com> Message-Id: <20210705104632.2902400-5-david.edmondson@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
fde7482100
commit
c0198c5f87
5 changed files with 29 additions and 28 deletions
|
@ -1667,6 +1667,7 @@ typedef struct CPUX86State {
|
||||||
uint64_t apic_bus_freq;
|
uint64_t apic_bus_freq;
|
||||||
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
|
||||||
void *xsave_buf;
|
void *xsave_buf;
|
||||||
|
uint32_t xsave_buf_len;
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_KVM)
|
#if defined(CONFIG_KVM)
|
||||||
struct kvm_nested_state *nested_state;
|
struct kvm_nested_state *nested_state;
|
||||||
|
@ -2227,8 +2228,8 @@ void x86_cpu_dump_local_apic_state(CPUState *cs, int flags);
|
||||||
/* cpu.c */
|
/* cpu.c */
|
||||||
bool cpu_is_bsp(X86CPU *cpu);
|
bool cpu_is_bsp(X86CPU *cpu);
|
||||||
|
|
||||||
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf);
|
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen);
|
||||||
void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
|
void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen);
|
||||||
void x86_update_hflags(CPUX86State* env);
|
void x86_update_hflags(CPUX86State* env);
|
||||||
|
|
||||||
static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat)
|
static inline bool hyperv_feat_enabled(X86CPU *cpu, int feat)
|
||||||
|
|
|
@ -267,7 +267,8 @@ int hvf_arch_init_vcpu(CPUState *cpu)
|
||||||
wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
|
wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
|
||||||
|
|
||||||
x86cpu = X86_CPU(cpu);
|
x86cpu = X86_CPU(cpu);
|
||||||
x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
|
x86cpu->env.xsave_buf_len = 4096;
|
||||||
|
x86cpu->env.xsave_buf = qemu_memalign(4096, 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_STAR, 1);
|
||||||
hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1);
|
hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1);
|
||||||
|
|
|
@ -73,14 +73,12 @@ void hvf_get_segment(SegmentCache *qseg, struct vmx_segment *vmx_seg)
|
||||||
|
|
||||||
void hvf_put_xsave(CPUState *cpu_state)
|
void hvf_put_xsave(CPUState *cpu_state)
|
||||||
{
|
{
|
||||||
|
void *xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
||||||
|
uint32_t xsave_len = X86_CPU(cpu_state)->env.xsave_buf_len;
|
||||||
|
|
||||||
struct X86XSaveArea *xsave;
|
x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
|
||||||
|
|
||||||
xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, xsave, xsave_len)) {
|
||||||
|
|
||||||
x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave);
|
|
||||||
|
|
||||||
if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,15 +156,14 @@ void hvf_put_msrs(CPUState *cpu_state)
|
||||||
|
|
||||||
void hvf_get_xsave(CPUState *cpu_state)
|
void hvf_get_xsave(CPUState *cpu_state)
|
||||||
{
|
{
|
||||||
struct X86XSaveArea *xsave;
|
void *xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
||||||
|
uint32_t xsave_len = X86_CPU(cpu_state)->env.xsave_buf_len;
|
||||||
|
|
||||||
xsave = X86_CPU(cpu_state)->env.xsave_buf;
|
if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, xsave, xsave_len)) {
|
||||||
|
|
||||||
if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave);
|
x86_cpu_xrstor_all_areas(X86_CPU(cpu_state), xsave, xsave_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hvf_get_segments(CPUState *cpu_state)
|
void hvf_get_segments(CPUState *cpu_state)
|
||||||
|
|
|
@ -1888,8 +1888,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_xsave) {
|
if (has_xsave) {
|
||||||
env->xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
|
env->xsave_buf_len = sizeof(struct kvm_xsave);
|
||||||
memset(env->xsave_buf, 0, sizeof(struct kvm_xsave));
|
env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len);
|
||||||
|
memset(env->xsave_buf, 0, env->xsave_buf_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
max_nested_state_len = kvm_max_nested_state_length();
|
max_nested_state_len = kvm_max_nested_state_length();
|
||||||
|
@ -2469,12 +2470,12 @@ static int kvm_put_fpu(X86CPU *cpu)
|
||||||
static int kvm_put_xsave(X86CPU *cpu)
|
static int kvm_put_xsave(X86CPU *cpu)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
X86XSaveArea *xsave = env->xsave_buf;
|
void *xsave = env->xsave_buf;
|
||||||
|
|
||||||
if (!has_xsave) {
|
if (!has_xsave) {
|
||||||
return kvm_put_fpu(cpu);
|
return kvm_put_fpu(cpu);
|
||||||
}
|
}
|
||||||
x86_cpu_xsave_all_areas(cpu, xsave);
|
x86_cpu_xsave_all_areas(cpu, xsave, env->xsave_buf_len);
|
||||||
|
|
||||||
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
|
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
|
||||||
}
|
}
|
||||||
|
@ -3119,7 +3120,7 @@ static int kvm_get_fpu(X86CPU *cpu)
|
||||||
static int kvm_get_xsave(X86CPU *cpu)
|
static int kvm_get_xsave(X86CPU *cpu)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
X86XSaveArea *xsave = env->xsave_buf;
|
void *xsave = env->xsave_buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!has_xsave) {
|
if (!has_xsave) {
|
||||||
|
@ -3130,7 +3131,7 @@ static int kvm_get_xsave(X86CPU *cpu)
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
x86_cpu_xrstor_all_areas(cpu, xsave);
|
x86_cpu_xrstor_all_areas(cpu, xsave, env->xsave_buf_len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,16 @@
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
|
void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
X86XSaveArea *xsave = buf;
|
X86XSaveArea *xsave = buf;
|
||||||
|
|
||||||
uint16_t cwd, swd, twd;
|
uint16_t cwd, swd, twd;
|
||||||
int i;
|
int i;
|
||||||
memset(xsave, 0, sizeof(X86XSaveArea));
|
|
||||||
|
assert(buflen >= sizeof(*xsave));
|
||||||
|
|
||||||
|
memset(xsave, 0, buflen);
|
||||||
twd = 0;
|
twd = 0;
|
||||||
swd = env->fpus & ~(7 << 11);
|
swd = env->fpus & ~(7 << 11);
|
||||||
swd |= (env->fpstt & 7) << 11;
|
swd |= (env->fpstt & 7) << 11;
|
||||||
|
@ -56,17 +58,17 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf)
|
||||||
16 * sizeof env->xmm_regs[16]);
|
16 * sizeof env->xmm_regs[16]);
|
||||||
memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
|
memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf)
|
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen)
|
||||||
{
|
{
|
||||||
|
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
const X86XSaveArea *xsave = buf;
|
const X86XSaveArea *xsave = buf;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
uint16_t cwd, swd, twd;
|
uint16_t cwd, swd, twd;
|
||||||
|
|
||||||
|
assert(buflen >= sizeof(*xsave));
|
||||||
|
|
||||||
cwd = xsave->legacy.fcw;
|
cwd = xsave->legacy.fcw;
|
||||||
swd = xsave->legacy.fsw;
|
swd = xsave->legacy.fsw;
|
||||||
twd = xsave->legacy.ftw;
|
twd = xsave->legacy.ftw;
|
||||||
|
@ -108,5 +110,4 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf)
|
||||||
16 * sizeof env->xmm_regs[16]);
|
16 * sizeof env->xmm_regs[16]);
|
||||||
memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
|
memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue