hv_set_non_nested_msr() has special handling for SINT MSRs when a paravisor is present. In addition to updating the MSR on the host, the mirror MSR in the paravisor is updated, including with the proxy bit. But with Confidential VMBus, the proxy bit must not be used, so add a special case to skip it.
Update the hv_set_non_nested_msr() function as well as vmbus_signal_eom() to trap on access for some synthetic MSRs. Signed-off-by: Roman Kisel <rom...@linux.microsoft.com> Reviewed-by: Alok Tiwari <alok.a.tiw...@oracle.com> --- arch/x86/kernel/cpu/mshyperv.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 07c60231d0d8..6c5a0a779c02 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -28,6 +28,7 @@ #include <asm/apic.h> #include <asm/timer.h> #include <asm/reboot.h> +#include <asm/msr.h> #include <asm/nmi.h> #include <clocksource/hyperv_timer.h> #include <asm/msr.h> @@ -79,13 +80,21 @@ EXPORT_SYMBOL_GPL(hv_get_non_nested_msr); void hv_set_non_nested_msr(unsigned int reg, u64 value) { if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) { + /* The hypervisor will get the intercept. */ hv_ivm_msr_write(reg, value); - /* Write proxy bit via wrmsl instruction */ - if (hv_is_sint_msr(reg)) - wrmsrq(reg, value | 1 << 20); + if (hv_is_sint_msr(reg)) { + /* + * Write proxy bit in the case of non-confidential VMBus. + * Using wrmsrq instruction so the following goes to the paravisor. + */ + u32 proxy = vmbus_is_confidential() ? 0 : 1; + + value |= (proxy << 20); + native_wrmsrq(reg, value); + } } else { - wrmsrq(reg, value); + native_wrmsrq(reg, value); } } EXPORT_SYMBOL_GPL(hv_set_non_nested_msr); -- 2.43.0