@samitouri / QOSamiQemu / commits / 65867d2ede

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 }