To set up and run the confidential VMBus, the guest needs the paravisor to intercept access to some synthetic MSRs. In the non-confidential case, the guest continues using the vendor-specific guest-host communication protocol.
Update the hv_set_non_nested_msr() function to trap access to 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 | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 83a85d94bcb3..db6f3e3db012 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/numa.h> @@ -77,14 +78,28 @@ EXPORT_SYMBOL_GPL(hv_get_non_nested_msr); void hv_set_non_nested_msr(unsigned int reg, u64 value) { + if (reg == HV_X64_MSR_EOM && vmbus_is_confidential()) { + /* Reach out to the paravisor. */ + native_wrmsrl(reg, value); + return; + } + 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)) - wrmsrl(reg, value | 1 << 20); + if (hv_is_sint_msr(reg)) { + /* + * Write proxy bit in the case of non-confidential VMBus. + * Using wrmsl instruction so the following goes to the paravisor. + */ + u32 proxy = vmbus_is_confidential() ? 0 : 1; + + value |= (proxy << 20); + native_wrmsrl(reg, value); + } } else { - wrmsrl(reg, value); + native_wrmsrl(reg, value); } } EXPORT_SYMBOL_GPL(hv_set_non_nested_msr); -- 2.43.0