static bool has_msr_hv_vapic;
static bool has_msr_hv_tsc;
static bool has_msr_mtrr;
+static bool has_msr_xss;
static bool has_msr_architectural_pmu;
static uint32_t num_architectural_pmu_counters;
int r, size;
size = sizeof(*cpuid) + max * sizeof(*cpuid->entries);
- cpuid = (struct kvm_cpuid2 *)g_malloc0(size);
+ cpuid = g_malloc0(size);
cpuid->nent = max;
r = kvm_ioctl(s, KVM_GET_SUPPORTED_CPUID, cpuid);
if (r == 0 && cpuid->nent >= max) {
return;
}
}
- page = g_malloc(sizeof(HWPoisonPage));
+ page = g_new(HWPoisonPage, 1);
page->ram_addr = ram_addr;
QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
}
has_msr_bndcfgs = true;
continue;
}
+ if (kvm_msr_list->indices[i] == MSR_IA32_XSS) {
+ has_msr_xss = true;
+ continue;
+ }
}
}
fpu.ftwx |= (!env->fptags[i]) << i;
}
memcpy(fpu.fpr, env->fpregs, sizeof env->fpregs);
- memcpy(fpu.xmm, env->xmm_regs, sizeof env->xmm_regs);
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ stq_p(&fpu.xmm[i][0], env->xmm_regs[i].XMM_Q(0));
+ stq_p(&fpu.xmm[i][8], env->xmm_regs[i].XMM_Q(1));
+ }
fpu.mxcsr = env->mxcsr;
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_FPU, &fpu);
CPUX86State *env = &cpu->env;
struct kvm_xsave* xsave = env->kvm_xsave_buf;
uint16_t cwd, swd, twd;
+ uint8_t *xmm, *ymmh, *zmmh;
int i, r;
if (!kvm_has_xsave()) {
memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp));
memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,
sizeof env->fpregs);
- memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs,
- sizeof env->xmm_regs);
xsave->region[XSAVE_MXCSR] = env->mxcsr;
*(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
- memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,
- sizeof env->ymmh_regs);
memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs,
sizeof env->bnd_regs);
memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs,
sizeof(env->bndcs_regs));
memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs,
sizeof env->opmask_regs);
- memcpy(&xsave->region[XSAVE_ZMM_Hi256], env->zmmh_regs,
- sizeof env->zmmh_regs);
+
+ xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
+ ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
+ zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
+ for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
+ stq_p(xmm, env->xmm_regs[i].XMM_Q(0));
+ stq_p(xmm+8, env->xmm_regs[i].XMM_Q(1));
+ stq_p(ymmh, env->xmm_regs[i].XMM_Q(2));
+ stq_p(ymmh+8, env->xmm_regs[i].XMM_Q(3));
+ stq_p(zmmh, env->xmm_regs[i].XMM_Q(4));
+ stq_p(zmmh+8, env->xmm_regs[i].XMM_Q(5));
+ stq_p(zmmh+16, env->xmm_regs[i].XMM_Q(6));
+ stq_p(zmmh+24, env->xmm_regs[i].XMM_Q(7));
+ }
+
#ifdef TARGET_X86_64
- memcpy(&xsave->region[XSAVE_Hi16_ZMM], env->hi16_zmm_regs,
- sizeof env->hi16_zmm_regs);
+ memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16],
+ 16 * sizeof env->xmm_regs[16]);
#endif
r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
return r;
static int kvm_put_xcrs(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
- struct kvm_xcrs xcrs;
+ struct kvm_xcrs xcrs = {};
if (!kvm_has_xcrs()) {
return 0;
uint32_t index, uint64_t value)
{
entry->index = index;
+ entry->reserved = 0;
entry->data = value;
}
kvm_msr_entry_set(&msrs[0], MSR_IA32_TSCDEADLINE, env->tsc_deadline);
- msr_data.info.nmsrs = 1;
+ msr_data.info = (struct kvm_msrs) {
+ .nmsrs = 1,
+ };
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
}
kvm_msr_entry_set(&msr_data.entry, MSR_IA32_FEATURE_CONTROL,
cpu->env.msr_ia32_feature_control);
- msr_data.info.nmsrs = 1;
+
+ msr_data.info = (struct kvm_msrs) {
+ .nmsrs = 1,
+ };
+
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
}
if (has_msr_bndcfgs) {
kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs);
}
+ if (has_msr_xss) {
+ kvm_msr_entry_set(&msrs[n++], MSR_IA32_XSS, env->xss);
+ }
#ifdef TARGET_X86_64
if (lm_capable_kernel) {
kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
}
}
- msr_data.info.nmsrs = n;
+ msr_data.info = (struct kvm_msrs) {
+ .nmsrs = n,
+ };
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
env->fptags[i] = !((fpu.ftwx >> i) & 1);
}
memcpy(env->fpregs, fpu.fpr, sizeof env->fpregs);
- memcpy(env->xmm_regs, fpu.xmm, sizeof env->xmm_regs);
+ for (i = 0; i < CPU_NB_REGS; i++) {
+ env->xmm_regs[i].XMM_Q(0) = ldq_p(&fpu.xmm[i][0]);
+ env->xmm_regs[i].XMM_Q(1) = ldq_p(&fpu.xmm[i][8]);
+ }
env->mxcsr = fpu.mxcsr;
return 0;
CPUX86State *env = &cpu->env;
struct kvm_xsave* xsave = env->kvm_xsave_buf;
int ret, i;
+ const uint8_t *xmm, *ymmh, *zmmh;
uint16_t cwd, swd, twd;
if (!kvm_has_xsave()) {
env->mxcsr = xsave->region[XSAVE_MXCSR];
memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
sizeof env->fpregs);
- memcpy(env->xmm_regs, &xsave->region[XSAVE_XMM_SPACE],
- sizeof env->xmm_regs);
env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
- memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],
- sizeof env->ymmh_regs);
memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS],
sizeof env->bnd_regs);
memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR],
sizeof(env->bndcs_regs));
memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK],
sizeof env->opmask_regs);
- memcpy(env->zmmh_regs, &xsave->region[XSAVE_ZMM_Hi256],
- sizeof env->zmmh_regs);
+
+ xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
+ ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
+ zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
+ for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
+ env->xmm_regs[i].XMM_Q(0) = ldq_p(xmm);
+ env->xmm_regs[i].XMM_Q(1) = ldq_p(xmm+8);
+ env->xmm_regs[i].XMM_Q(2) = ldq_p(ymmh);
+ env->xmm_regs[i].XMM_Q(3) = ldq_p(ymmh+8);
+ env->xmm_regs[i].XMM_Q(4) = ldq_p(zmmh);
+ env->xmm_regs[i].XMM_Q(5) = ldq_p(zmmh+8);
+ env->xmm_regs[i].XMM_Q(6) = ldq_p(zmmh+16);
+ env->xmm_regs[i].XMM_Q(7) = ldq_p(zmmh+24);
+ }
+
#ifdef TARGET_X86_64
- memcpy(env->hi16_zmm_regs, &xsave->region[XSAVE_Hi16_ZMM],
- sizeof env->hi16_zmm_regs);
+ memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM],
+ 16 * sizeof env->xmm_regs[16]);
#endif
return 0;
}
if (has_msr_bndcfgs) {
msrs[n++].index = MSR_IA32_BNDCFGS;
}
+ if (has_msr_xss) {
+ msrs[n++].index = MSR_IA32_XSS;
+ }
+
if (!env->tsc_valid) {
msrs[n++].index = MSR_IA32_TSC;
}
}
- msr_data.info.nmsrs = n;
+ msr_data.info = (struct kvm_msrs) {
+ .nmsrs = n,
+ };
+
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
if (ret < 0) {
return ret;
case MSR_IA32_BNDCFGS:
env->msr_bndcfgs = msrs[i].data;
break;
+ case MSR_IA32_XSS:
+ env->xss = msrs[i].data;
+ break;
default:
if (msrs[i].index >= MSR_MC0_CTL &&
msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
static int kvm_put_vcpu_events(X86CPU *cpu, int level)
{
CPUX86State *env = &cpu->env;
- struct kvm_vcpu_events events;
+ struct kvm_vcpu_events events = {};
if (!kvm_has_vcpu_events()) {
return 0;
* irqchip, so we can use irqfds, and on x86 we know
* we can use msi via irqfd and GSI routing.
*/
- kvm_irqfds_allowed = true;
kvm_msi_via_irqfd_allowed = true;
kvm_gsi_routing_allowed = true;
}
return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
KVM_DEV_IRQ_HOST_MSIX);
}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+ return 0;
+}