115
struct hv_register_assoc *assocs,
116
size_t n_regs);
117
118
+static void populate_fpu(const hv_register_assoc *assocs, X86CPU *x86cpu)
119
+{
120
+ union hv_register_value value;
121
+ const union hv_x64_fp_control_status_register *ctrl_status;
122
+ const union hv_x64_xmm_control_status_register *xmm_ctrl;
123
+ CPUX86State *env = &x86cpu->env;
124
+ size_t i, fp_i;
125
+ bool valid;
126
+
127
+ /* first 16 registers are xmm0-xmm15 */
128
+ for (i = 0; i < 16; i++) {
129
+ value = assocs[i].value;
130
+ env->xmm_regs[i].ZMM_Q(0) = value.reg128.low_part;
131
+ env->xmm_regs[i].ZMM_Q(1) = value.reg128.high_part;
132
+ }
133
+
134
+ /* next 8 registers are fp_mmx0-fp_mmx7 */
135
+ for (i = 16; i < 24; i++) {
136
+ fp_i = i - 16;
137
+ value = assocs[i].value;
138
+ env->fpregs[fp_i].d.low = value.fp.mantissa;
139
+ env->fpregs[fp_i].d.high = (value.fp.sign << 15)
140
+ | (value.fp.biased_exponent & 0x7FFF);
141
+ }
142
+
143
+ /* last two registers are fp_control_status and xmm_control_status */
144
+ ctrl_status = &assocs[24].value.fp_control_status;
145
+ env->fpuc = ctrl_status->fp_control;
146
+
147
+ env->fpus = ctrl_status->fp_status & ~0x3800;
148
+ /* bits 11,12,13 are the top of stack pointer */
149
+ env->fpstt = (ctrl_status->fp_status >> 11) & 0x7;
150
+
151
+ for (i = 0; i < 8; i++) {
152
+ valid = ctrl_status->fp_tag & (1 << i);
153
+ env->fptags[i] = valid ? 0 : 1;
154
+ }
155
+
156
+ env->fpop = ctrl_status->last_fp_op;
157
+ env->fpip = ctrl_status->last_fp_rip;
158
+
159
+ xmm_ctrl = &assocs[25].value.xmm_control_status;
160
+ env->mxcsr = xmm_ctrl->xmm_status_control;
161
+ env->fpdp = xmm_ctrl->last_fp_rdp;
162
+}
163
+
164
+static int get_fpu(CPUState *cpu)
165
+{
166
+ struct hv_register_assoc assocs[ARRAY_SIZE(FPU_REGISTER_NAMES)];
167
+ int ret;
168
+ X86CPU *x86cpu = X86_CPU(cpu);
169
+ size_t n_regs = ARRAY_SIZE(FPU_REGISTER_NAMES);
170
+
171
+ for (size_t i = 0; i < n_regs; i++) {
172
+ assocs[i].name = FPU_REGISTER_NAMES[i];
173
+ }
174
+ ret = get_generic_regs(cpu, assocs, n_regs);
175
+ if (ret < 0) {
176
+ error_report("failed to get special registers");
177
+ return -errno;
178
+ }
179
+
180
+ populate_fpu(assocs, x86cpu);
181
+
182
+ return 0;
183
+}
184
+
185
+static int get_xc_reg(CPUState *cpu)
186
+{
187
+ int ret;
188
+ X86CPU *x86cpu = X86_CPU(cpu);
189
+ CPUX86State *env = &x86cpu->env;
190
+ struct hv_register_assoc assocs[1];
191
+
192
+ assocs[0].name = HV_X64_REGISTER_XFEM;
193
+
194
+ ret = get_generic_regs(cpu, assocs, 1);
195
+ if (ret < 0) {
196
+ error_report("failed to get xcr0");
197
+ return -1;
198
+ }
199
+ env->xcr0 = assocs[0].value.reg64;
200
+
201
+ return 0;
202
+}
203
+
204
static int translate_gva(const CPUState *cpu, uint64_t gva, uint64_t *gpa,
205
uint64_t flags)
206
{
379
return 0;
380
}
381
296
-int mshv_arch_store_regs(CPUState *cpu)
382
+static int store_regs(CPUState *cpu)
383
{
384
int ret;
385
521
return 0;
522
}
523
438
-int mshv_arch_load_regs(CPUState *cpu)
524
+static int load_regs(CPUState *cpu)
525
{
526
int ret;
527
528
ret = get_standard_regs(cpu);
529
if (ret < 0) {
444
- error_report("Failed to load standard registers");
445
- return -1;
530
+ return ret;
531
}
532
533
ret = get_special_regs(cpu);
534
if (ret < 0) {
450
- error_report("Failed to load special registers");
451
- return -1;
535
+ return ret;
536
+ }
537
+
538
+ return 0;
539
+}
540
+
541
+int mshv_arch_load_vcpu_state(CPUState *cpu)
542
+{
543
+ int ret;
544
+
545
+ ret = get_standard_regs(cpu);
546
+ if (ret < 0) {
547
+ return ret;
548
+ }
549
+
550
+ ret = get_special_regs(cpu);
551
+ if (ret < 0) {
552
+ return ret;
553
+ }
554
+
555
+ ret = get_xc_reg(cpu);
556
+ if (ret < 0) {
557
+ return ret;
558
+ }
559
+
560
+ ret = get_fpu(cpu);
561
+ if (ret < 0) {
562
+ return ret;
563
}
564
565
return 0;
778
return ret;
779
}
780
670
-static int set_cpuid2(const CPUState *cpu)
781
+static int init_cpuid2(const CPUState *cpu)
782
{
783
int ret;
784
size_t n_entries, cpuid_size;
969
return 0;
970
}
971
861
-static int set_cpu_state(const CPUState *cpu)
862
-{
863
- int ret;
864
-
865
- ret = set_standard_regs(cpu);
866
- if (ret < 0) {
867
- return ret;
868
- }
869
- ret = set_special_regs(cpu);
870
- if (ret < 0) {
871
- return ret;
872
- }
873
- ret = set_fpu(cpu);
874
- if (ret < 0) {
875
- return ret;
876
- }
877
- ret = set_xc_reg(cpu);
878
- if (ret < 0) {
879
- return ret;
880
- }
881
- return 0;
882
-}
883
-
972
static int get_vp_state(int cpu_fd, struct mshv_get_set_vp_state *state)
973
{
974
int ret;
982
return 0;
983
}
984
897
-static int get_lapic(int cpu_fd,
985
+static int get_lapic(const CPUState *cpu,
986
struct hv_local_interrupt_controller_state *state)
987
{
988
int ret;
990
/* buffer aligned to 4k, as *state requires that */
991
void *buffer = qemu_memalign(size, size);
992
struct mshv_get_set_vp_state mshv_state = { 0 };
993
+ int cpu_fd = mshv_vcpufd(cpu);
994
995
mshv_state.buf_ptr = (uint64_t) buffer;
996
mshv_state.buf_sz = size;
1027
return 0;
1028
}
1029
941
-static int set_lapic(int cpu_fd,
1030
+static int set_lapic(const CPUState *cpu,
1031
const struct hv_local_interrupt_controller_state *state)
1032
{
1033
int ret;
1035
/* buffer aligned to 4k, as *state requires that */
1036
void *buffer = qemu_memalign(size, size);
1037
struct mshv_get_set_vp_state mshv_state = { 0 };
1038
+ int cpu_fd = mshv_vcpufd(cpu);
1039
1040
if (!state) {
1041
error_report("lapic state is NULL");
1057
return 0;
1058
}
1059
970
-static int set_lint(int cpu_fd)
1060
+static int init_lint(const CPUState *cpu)
1061
{
1062
int ret;
1063
uint32_t *lvt_lint0, *lvt_lint1;
1064
1065
struct hv_local_interrupt_controller_state lapic_state = { 0 };
976
- ret = get_lapic(cpu_fd, &lapic_state);
1066
+ ret = get_lapic(cpu, &lapic_state);
1067
if (ret < 0) {
1068
return ret;
1069
}
1076
1077
/* TODO: should we skip setting lapic if the values are the same? */
1078
989
- return set_lapic(cpu_fd, &lapic_state);
990
-}
991
-
992
-static int setup_msrs(const CPUState *cpu)
993
-{
994
- int ret;
995
- uint64_t default_type = MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB;
996
-
997
- /* boot msr entries */
998
- MshvMsrEntry msrs[9] = {
999
- { .index = IA32_MSR_SYSENTER_CS, .data = 0x0, },
1000
- { .index = IA32_MSR_SYSENTER_ESP, .data = 0x0, },
1001
- { .index = IA32_MSR_SYSENTER_EIP, .data = 0x0, },
1002
- { .index = IA32_MSR_STAR, .data = 0x0, },
1003
- { .index = IA32_MSR_CSTAR, .data = 0x0, },
1004
- { .index = IA32_MSR_LSTAR, .data = 0x0, },
1005
- { .index = IA32_MSR_KERNEL_GS_BASE, .data = 0x0, },
1006
- { .index = IA32_MSR_SFMASK, .data = 0x0, },
1007
- { .index = IA32_MSR_MTRR_DEF_TYPE, .data = default_type, },
1008
- };
1009
-
1010
- ret = mshv_configure_msr(cpu, msrs, 9);
1011
- if (ret < 0) {
1012
- error_report("failed to setup msrs");
1013
- return -1;
1014
- }
1015
-
1016
- return 0;
1079
+ return set_lapic(cpu, &lapic_state);
1080
}
1081
1019
-/*
1020
- * TODO: populate topology info:
1021
- *
1022
- * X86CPU *x86cpu = X86_CPU(cpu);
1023
- * CPUX86State *env = &x86cpu->env;
1024
- * X86CPUTopoInfo *topo_info = &env->topo_info;
1025
- */
1026
-int mshv_configure_vcpu(const CPUState *cpu)
1082
+int mshv_arch_store_vcpu_state(const CPUState *cpu)
1083
{
1084
int ret;
1029
- int cpu_fd = mshv_vcpufd(cpu);
1030
-
1031
- ret = set_cpuid2(cpu);
1032
- if (ret < 0) {
1033
- error_report("failed to set cpuid");
1034
- return -1;
1035
- }
1036
-
1037
- ret = setup_msrs(cpu);
1038
- if (ret < 0) {
1039
- error_report("failed to setup msrs");
1040
- return -1;
1041
- }
1042
-
1043
- ret = set_cpu_state(cpu);
1044
- if (ret < 0) {
1045
- error_report("failed to set cpu state");
1046
- return -1;
1047
- }
1085
1049
- ret = set_lint(cpu_fd);
1086
+ ret = set_standard_regs(cpu);
1087
if (ret < 0) {
1051
- error_report("failed to set lpic int");
1052
- return -1;
1088
+ return ret;
1089
}
1090
1055
- return 0;
1056
-}
1057
-
1058
-static int put_regs(const CPUState *cpu)
1059
-{
1060
- int ret;
1061
-
1062
- ret = mshv_configure_vcpu(cpu);
1091
+ ret = set_special_regs(cpu);
1092
if (ret < 0) {
1064
- error_report("failed to configure vcpu");
1093
return ret;
1094
}
1095
1068
- return 0;
1069
-}
1070
-
1071
-struct MsrPair {
1072
- uint32_t index;
1073
- uint64_t value;
1074
-};
1075
-
1076
-static int put_msrs(const CPUState *cpu)
1077
-{
1078
- int ret = 0;
1079
- X86CPU *x86cpu = X86_CPU(cpu);
1080
- CPUX86State *env = &x86cpu->env;
1081
- MshvMsrEntries *msrs = g_malloc0(sizeof(MshvMsrEntries));
1082
-
1083
- struct MsrPair pairs[] = {
1084
- { MSR_IA32_SYSENTER_CS, env->sysenter_cs },
1085
- { MSR_IA32_SYSENTER_ESP, env->sysenter_esp },
1086
- { MSR_IA32_SYSENTER_EIP, env->sysenter_eip },
1087
- { MSR_EFER, env->efer },
1088
- { MSR_PAT, env->pat },
1089
- { MSR_STAR, env->star },
1090
- { MSR_CSTAR, env->cstar },
1091
- { MSR_LSTAR, env->lstar },
1092
- { MSR_KERNELGSBASE, env->kernelgsbase },
1093
- { MSR_FMASK, env->fmask },
1094
- { MSR_MTRRdefType, env->mtrr_deftype },
1095
- { MSR_VM_HSAVE_PA, env->vm_hsave },
1096
- { MSR_SMI_COUNT, env->msr_smi_count },
1097
- { MSR_IA32_PKRS, env->pkrs },
1098
- { MSR_IA32_BNDCFGS, env->msr_bndcfgs },
1099
- { MSR_IA32_XSS, env->xss },
1100
- { MSR_IA32_UMWAIT_CONTROL, env->umwait },
1101
- { MSR_IA32_TSX_CTRL, env->tsx_ctrl },
1102
- { MSR_AMD64_TSC_RATIO, env->amd_tsc_scale_msr },
1103
- { MSR_TSC_AUX, env->tsc_aux },
1104
- { MSR_TSC_ADJUST, env->tsc_adjust },
1105
- { MSR_IA32_SMBASE, env->smbase },
1106
- { MSR_IA32_SPEC_CTRL, env->spec_ctrl },
1107
- { MSR_VIRT_SSBD, env->virt_ssbd },
1108
- };
1109
-
1110
- if (ARRAY_SIZE(pairs) > MSHV_MSR_ENTRIES_COUNT) {
1111
- error_report("MSR entries exceed maximum size");
1112
- g_free(msrs);
1113
- return -1;
1114
- }
1115
-
1116
- for (size_t i = 0; i < ARRAY_SIZE(pairs); i++) {
1117
- MshvMsrEntry *entry = &msrs->entries[i];
1118
- entry->index = pairs[i].index;
1119
- entry->reserved = 0;
1120
- entry->data = pairs[i].value;
1121
- msrs->nmsrs++;
1122
- }
1123
-
1124
- ret = mshv_configure_msr(cpu, &msrs->entries[0], msrs->nmsrs);
1125
- g_free(msrs);
1126
- return ret;
1127
-}
1128
-
1129
-
1130
-int mshv_arch_put_registers(const CPUState *cpu)
1131
-{
1132
- int ret;
1133
-
1134
- ret = put_regs(cpu);
1096
+ ret = set_xc_reg(cpu);
1097
if (ret < 0) {
1136
- error_report("Failed to put registers");
1137
- return -1;
1098
+ return ret;
1099
}
1100
1140
- ret = put_msrs(cpu);
1101
+ ret = set_fpu(cpu);
1102
if (ret < 0) {
1142
- error_report("Failed to put msrs");
1143
- return -1;
1103
+ return ret;
1104
}
1105
1106
return 0;
1142
int ret;
1143
x86_insn_stream stream = { .bytes = insn_bytes, .len = insn_len };
1144
1185
- ret = mshv_arch_load_regs(cpu);
1145
+ ret = load_regs(cpu);
1146
if (ret < 0) {
1147
error_report("Failed to load registers");
1148
return -1;
1151
decode_instruction_stream(env, &decode, &stream);
1152
exec_instruction(env, &decode);
1153
1194
- ret = mshv_arch_store_regs(cpu);
1154
+ ret = store_regs(cpu);
1155
if (ret < 0) {
1156
error_report("failed to store registers");
1157
return -1;
1449
X86CPU *x86_cpu = X86_CPU(cpu);
1450
CPUX86State *env = &x86_cpu->env;
1451
1492
- ret = mshv_arch_load_regs(cpu);
1452
+ ret = load_regs(cpu);
1453
if (ret < 0) {
1454
error_report("Failed to load registers");
1455
return -1;
1620
init_emu(&mshv_x86_emul_ops);
1621
}
1622
1623
+static int init_msrs(const CPUState *cpu)
1624
+{
1625
+ int ret;
1626
+ uint64_t d_t = MSR_MTRR_ENABLE | MSR_MTRR_MEM_TYPE_WB;
1627
+
1628
+ const struct hv_register_assoc assocs[] = {
1629
+ { .name = HV_X64_REGISTER_SYSENTER_CS, .value.reg64 = 0x0 },
1630
+ { .name = HV_X64_REGISTER_SYSENTER_ESP, .value.reg64 = 0x0 },
1631
+ { .name = HV_X64_REGISTER_SYSENTER_EIP, .value.reg64 = 0x0 },
1632
+ { .name = HV_X64_REGISTER_STAR, .value.reg64 = 0x0 },
1633
+ { .name = HV_X64_REGISTER_CSTAR, .value.reg64 = 0x0 },
1634
+ { .name = HV_X64_REGISTER_LSTAR, .value.reg64 = 0x0 },
1635
+ { .name = HV_X64_REGISTER_KERNEL_GS_BASE, .value.reg64 = 0x0 },
1636
+ { .name = HV_X64_REGISTER_SFMASK, .value.reg64 = 0x0 },
1637
+ { .name = HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, .value.reg64 = d_t },
1638
+ };
1639
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(assocs) > MSHV_MSR_ENTRIES_COUNT);
1640
+
1641
+ ret = mshv_set_generic_regs(cpu, assocs, ARRAY_SIZE(assocs));
1642
+ if (ret < 0) {
1643
+ error_report("failed to put msrs");
1644
+ return -1;
1645
+ }
1646
+
1647
+ return 0;
1648
+}
1649
+
1650
void mshv_arch_init_vcpu(CPUState *cpu)
1651
{
1652
X86CPU *x86_cpu = X86_CPU(cpu);
1654
AccelCPUState *state = cpu->accel;
1655
size_t page = HV_HYP_PAGE_SIZE;
1656
void *mem = qemu_memalign(page, 2 * page);
1657
+ int ret;
1658
1659
/* sanity check, to make sure we don't overflow the page */
1660
QEMU_BUILD_BUG_ON((MAX_REGISTER_COUNT
1667
state->hvcall_args.output_page = (uint8_t *)mem + page;
1668
1669
env->emu_mmio_buf = g_new(char, 4096);
1670
+
1671
+ /*
1672
+ * TODO: populate topology info:
1673
+ * X86CPUTopoInfo *topo_info = &env->topo_info;
1674
+ */
1675
+
1676
+ ret = init_cpuid2(cpu);
1677
+ assert(ret == 0);
1678
+
1679
+ ret = init_msrs(cpu);
1680
+ assert(ret == 0);
1681
+
1682
+ ret = init_lint(cpu);
1683
+ assert(ret == 0);
1684
}
1685
1686
void mshv_arch_destroy_vcpu(CPUState *cpu)