s390x: Vector Register IOCTLs
Handle the actual syncing of the vector registers with kernel space, via the get/put register IOCTLs. The vector registers that were introduced with the z13 overlay the existing floating point registers. FP registers 0-15 are the high-halves of vector registers 0-15. Thus, remove the freg fields and replace them with the equivalent vector field to avoid errors in duplication. Moreover, synchronize either the vector registers via kvm_sync_regs, or floating point registers via the GET/SET FPU IOCTLs. Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
c498d8e36e
commit
fcb79802e0
@ -81,7 +81,11 @@ typedef struct MchkQueue {
|
||||
|
||||
typedef struct CPUS390XState {
|
||||
uint64_t regs[16]; /* GP registers */
|
||||
CPU_DoubleU fregs[16]; /* FP registers */
|
||||
/*
|
||||
* The floating point registers are part of the vector registers.
|
||||
* vregs[0][0] -> vregs[15][0] are 16 floating point registers
|
||||
*/
|
||||
CPU_DoubleU vregs[32][2]; /* vector registers */
|
||||
uint32_t aregs[16]; /* access registers */
|
||||
|
||||
uint32_t fpc; /* floating-point control register */
|
||||
@ -164,7 +168,7 @@ typedef struct CPUS390XState {
|
||||
|
||||
static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr)
|
||||
{
|
||||
return &cs->fregs[nr];
|
||||
return &cs->vregs[nr][0];
|
||||
}
|
||||
|
||||
#include "cpu-qom.h"
|
||||
|
@ -337,6 +337,14 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
}
|
||||
}
|
||||
|
||||
if (can_sync_regs(cs, KVM_SYNC_VRS)) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
cs->kvm_run->s.regs.vrs[i][0] = env->vregs[i][0].ll;
|
||||
cs->kvm_run->s.regs.vrs[i][1] = env->vregs[i][1].ll;
|
||||
}
|
||||
cs->kvm_run->s.regs.fpc = env->fpc;
|
||||
cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_VRS;
|
||||
} else {
|
||||
/* Floating point */
|
||||
for (i = 0; i < 16; i++) {
|
||||
fpu.fprs[i] = get_freg(env, i)->ll;
|
||||
@ -347,6 +355,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we need to save more than that? */
|
||||
if (level == KVM_PUT_RUNTIME_STATE) {
|
||||
@ -468,7 +477,14 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
}
|
||||
}
|
||||
|
||||
/* Floating point */
|
||||
/* Floating point and vector registers */
|
||||
if (can_sync_regs(cs, KVM_SYNC_VRS)) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
env->vregs[i][0].ll = cs->kvm_run->s.regs.vrs[i][0];
|
||||
env->vregs[i][1].ll = cs->kvm_run->s.regs.vrs[i][1];
|
||||
}
|
||||
env->fpc = cs->kvm_run->s.regs.fpc;
|
||||
} else {
|
||||
r = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
@ -477,6 +493,7 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
get_freg(env, i)->ll = fpu.fprs[i];
|
||||
}
|
||||
env->fpc = fpu.fpc;
|
||||
}
|
||||
|
||||
/* The prefix */
|
||||
if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
|
||||
|
@ -47,22 +47,22 @@ const VMStateDescription vmstate_fpu = {
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT64(env.fregs[0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[1].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[2].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[3].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[4].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[5].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[6].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[7].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[8].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[9].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[10].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[11].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[12].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[13].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[14].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.fregs[15].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[0][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[1][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[2][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[3][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[4][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[5][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[6][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[7][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[8][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[9][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[10][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[11][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[12][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[13][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[14][0].ll, S390CPU),
|
||||
VMSTATE_UINT64(env.vregs[15][0].ll, S390CPU),
|
||||
VMSTATE_UINT32(env.fpc, S390CPU),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ void s390x_translate_init(void)
|
||||
for (i = 0; i < 16; i++) {
|
||||
snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
|
||||
fregs[i] = tcg_global_mem_new(TCG_AREG0,
|
||||
offsetof(CPUS390XState, fregs[i].d),
|
||||
offsetof(CPUS390XState, vregs[i][0].d),
|
||||
cpu_reg_names[i + 16]);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user