target/i386/mshv: migrate Synic SINT MSRs
Migrate HyperV SynIC SINT MSRs. We can only read/write those if SCONTROL is enabled in the guest, hence we have to split the SINT MSR out and make reading/writing them dependent on that MSR. Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com> Reviewed-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com> Link: https://lore.kernel.org/r/20260710101534.664604-7-magnuskulke@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Magnus Kulke committed
Jul 10, 2026 at 12:15 UTC
65867d2edea0ec2cb1e7de338a998e0d7d5ee1aa
1 file changed
+41
target/i386/mshv/msr.c
+41
@@ -331,6 +331,8 @@ int mshv_get_msrs(CPUState *cpu)
331
struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT];
332
size_t i, j;
333
uint32_t name;
334
+ X86CPU *x86cpu = X86_CPU(cpu);
335
+ bool synic_enabled;
336
337
set_hv_name_in_assocs(assocs, n_assocs);
338
@@ -357,6 +359,27 @@ int mshv_get_msrs(CPUState *cpu)
359
360
store_in_env(cpu, assocs, n_assocs);
361
362
+ /* Read SINT MSRs only if SynIC is enabled */
363
+ synic_enabled = x86cpu->env.msr_hv_synic_control & 1;
364
+ if (synic_enabled) {
365
+ QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT);
366
+
367
+ for (i = 0; i < HV_SINT_COUNT; i++) {
368
+ assocs[i].name = HV_REGISTER_SINT0 + i;
369
+ }
370
+
371
+ ret = mshv_get_generic_regs(cpu, assocs, HV_SINT_COUNT);
372
+ if (ret < 0) {
373
+ error_report("Failed to get SynIC SINT MSRs");
374
+ return -errno;
375
+ }
376
+
377
+ for (i = 0; i < HV_SINT_COUNT; i++) {
378
+ uint64_t hv_sint_value = assocs[i].value.reg64;
379
+ x86cpu->env.msr_hv_synic_sint[i] = hv_sint_value;
380
+ }
381
+ }
382
+
383
return 0;
384
}
385
@@ -391,6 +414,8 @@ int mshv_set_msrs(const CPUState *cpu)
414
struct hv_register_assoc assocs[MSHV_MSR_TOTAL_COUNT];
415
int ret;
416
size_t i, j;
417
+ X86CPU *x86cpu = X86_CPU(cpu);
418
+ bool synic_enabled = x86cpu->env.msr_hv_synic_control & 1;
419
420
load_from_env(cpu, assocs, n_assocs);
421
@@ -423,5 +448,21 @@ int mshv_set_msrs(const CPUState *cpu)
448
return -errno;
449
}
450
451
+ /* SINT MSRs can only be written if SCONTROL has been set, so we split */
452
+ if (synic_enabled) {
453
+ QEMU_BUILD_BUG_ON(MSHV_MSR_TOTAL_COUNT < HV_SINT_COUNT);
454
+
455
+ for (i = 0; i < HV_SINT_COUNT; i++) {
456
+ assocs[i].name = HV_REGISTER_SINT0 + i;
457
+ assocs[i].value.reg64 = x86cpu->env.msr_hv_synic_sint[i];
458
+ }
459
+
460
+ ret = mshv_set_generic_regs(cpu, assocs, HV_SINT_COUNT);
461
+ if (ret < 0) {
462
+ error_report("Failed to set SynIC SINT MSRs");
463
+ return -errno;
464
+ }
465
+ }
466
+
467
return 0;
468
}