From: Naman Jain <[email protected]> Sent: Monday, April 13, 2026 4:46 AM > > On 4/1/2026 10:26 PM, Michael Kelley wrote: > > From: Naman Jain <[email protected]> Sent: Monday, March 16, 2026 > 5:13 AM > >> > >> Refactor MSHV_VTL driver to move some of the x86 specific code to arch > >> specific files, and add corresponding functions for arm64. > >> > >> Signed-off-by: Roman Kisel <[email protected]> > >> Signed-off-by: Naman Jain <[email protected]> > >> --- > >> arch/arm64/include/asm/mshyperv.h | 10 +++ > >> arch/x86/hyperv/hv_vtl.c | 98 ++++++++++++++++++++++++++++ > >> arch/x86/include/asm/mshyperv.h | 1 + > >> drivers/hv/mshv_vtl_main.c | 102 +----------------------------- > >> 4 files changed, 111 insertions(+), 100 deletions(-) > >> > >> diff --git a/arch/arm64/include/asm/mshyperv.h > >> b/arch/arm64/include/asm/mshyperv.h > >> index b721d3134ab6..804068e0941b 100644 > >> --- a/arch/arm64/include/asm/mshyperv.h > >> +++ b/arch/arm64/include/asm/mshyperv.h > >> @@ -60,6 +60,16 @@ static inline u64 hv_get_non_nested_msr(unsigned int > >> reg) > >> ARM_SMCCC_SMC_64, \ > >> ARM_SMCCC_OWNER_VENDOR_HYP, \ > >> HV_SMCCC_FUNC_NUMBER) > >> +#ifdef CONFIG_HYPERV_VTL_MODE > >> +/* > >> + * Get/Set the register. If the function returns `1`, that must be done > >> via > >> + * a hypercall. Returning `0` means success. > >> + */ > >> +static inline int hv_vtl_get_set_reg(struct hv_register_assoc *regs, bool > >> set, u64 shared) > >> +{ > >> + return 1; > >> +} > >> +#endif > >> > >> #include <asm-generic/mshyperv.h> > >> > >> diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c > >> index 9b6a9bc4ab76..72a0bb4ae0c7 100644 > >> --- a/arch/x86/hyperv/hv_vtl.c > >> +++ b/arch/x86/hyperv/hv_vtl.c > >> @@ -17,6 +17,8 @@ > >> #include <asm/realmode.h> > >> #include <asm/reboot.h> > >> #include <asm/smap.h> > >> +#include <uapi/asm/mtrr.h> > >> +#include <asm/debugreg.h> > >> #include <linux/export.h> > >> #include <../kernel/smpboot.h> > >> #include "../../kernel/fpu/legacy.h" > >> @@ -281,3 +283,99 @@ void mshv_vtl_return_call(struct mshv_vtl_cpu_context > >> *vtl0) > >> kernel_fpu_end(); > >> } > >> EXPORT_SYMBOL(mshv_vtl_return_call); > >> + > >> +/* Static table mapping register names to their corresponding actions */ > >> +static const struct { > >> + enum hv_register_name reg_name; > >> + int debug_reg_num; /* -1 if not a debug register */ > >> + u32 msr_addr; /* 0 if not an MSR */ > >> +} reg_table[] = { > >> + /* Debug registers */ > >> + {HV_X64_REGISTER_DR0, 0, 0}, > >> + {HV_X64_REGISTER_DR1, 1, 0}, > >> + {HV_X64_REGISTER_DR2, 2, 0}, > >> + {HV_X64_REGISTER_DR3, 3, 0}, > >> + {HV_X64_REGISTER_DR6, 6, 0}, > >> + /* MTRR MSRs */ > >> + {HV_X64_REGISTER_MSR_MTRR_CAP, -1, MSR_MTRRcap}, > >> + {HV_X64_REGISTER_MSR_MTRR_DEF_TYPE, -1, MSR_MTRRdefType}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0, -1, MTRRphysBase_MSR(0)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1, -1, MTRRphysBase_MSR(1)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2, -1, MTRRphysBase_MSR(2)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3, -1, MTRRphysBase_MSR(3)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4, -1, MTRRphysBase_MSR(4)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5, -1, MTRRphysBase_MSR(5)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6, -1, MTRRphysBase_MSR(6)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7, -1, MTRRphysBase_MSR(7)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE8, -1, MTRRphysBase_MSR(8)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASE9, -1, MTRRphysBase_MSR(9)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASEA, -1, MTRRphysBase_MSR(0xa)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASEB, -1, MTRRphysBase_MSR(0xb)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASEC, -1, MTRRphysBase_MSR(0xc)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASED, -1, MTRRphysBase_MSR(0xd)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASEE, -1, MTRRphysBase_MSR(0xe)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_BASEF, -1, MTRRphysBase_MSR(0xf)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0, -1, MTRRphysMask_MSR(0)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1, -1, MTRRphysMask_MSR(1)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2, -1, MTRRphysMask_MSR(2)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3, -1, MTRRphysMask_MSR(3)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4, -1, MTRRphysMask_MSR(4)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5, -1, MTRRphysMask_MSR(5)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6, -1, MTRRphysMask_MSR(6)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7, -1, MTRRphysMask_MSR(7)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK8, -1, MTRRphysMask_MSR(8)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASK9, -1, MTRRphysMask_MSR(9)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASKA, -1, MTRRphysMask_MSR(0xa)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASKB, -1, MTRRphysMask_MSR(0xb)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASKC, -1, MTRRphysMask_MSR(0xc)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASKD, -1, MTRRphysMask_MSR(0xd)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASKE, -1, MTRRphysMask_MSR(0xe)}, > >> + {HV_X64_REGISTER_MSR_MTRR_PHYS_MASKF, -1, MTRRphysMask_MSR(0xf)}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX64K00000, -1, MSR_MTRRfix64K_00000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX16K80000, -1, MSR_MTRRfix16K_80000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX16KA0000, -1, MSR_MTRRfix16K_A0000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KC0000, -1, MSR_MTRRfix4K_C0000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KC8000, -1, MSR_MTRRfix4K_C8000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KD0000, -1, MSR_MTRRfix4K_D0000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KD8000, -1, MSR_MTRRfix4K_D8000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KE0000, -1, MSR_MTRRfix4K_E0000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KE8000, -1, MSR_MTRRfix4K_E8000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KF0000, -1, MSR_MTRRfix4K_F0000}, > >> + {HV_X64_REGISTER_MSR_MTRR_FIX4KF8000, -1, MSR_MTRRfix4K_F8000}, > >> +}; > >> + > >> +int hv_vtl_get_set_reg(struct hv_register_assoc *regs, bool set, u64 > >> shared) > >> +{ > >> + u64 *reg64; > >> + enum hv_register_name gpr_name; > >> + int i; > >> + > >> + gpr_name = regs->name; > >> + reg64 = ®s->value.reg64; > >> + > >> + /* Search for the register in the table */ > >> + for (i = 0; i < ARRAY_SIZE(reg_table); i++) { > >> + if (reg_table[i].reg_name != gpr_name) > >> + continue; > >> + if (reg_table[i].debug_reg_num != -1) { > >> + /* Handle debug registers */ > >> + if (gpr_name == HV_X64_REGISTER_DR6 && !shared) > >> + goto hypercall; > >> + if (set) > >> + native_set_debugreg(reg_table[i].debug_reg_num, > >> *reg64); > >> + else > >> + *reg64 = > >> native_get_debugreg(reg_table[i].debug_reg_num); > >> + } else { > >> + /* Handle MSRs */ > >> + if (set) > >> + wrmsrl(reg_table[i].msr_addr, *reg64); > >> + else > >> + rdmsrl(reg_table[i].msr_addr, *reg64); > >> + } > >> + return 0; > >> + } > >> + > >> +hypercall: > >> + return 1; > >> +} > >> +EXPORT_SYMBOL(hv_vtl_get_set_reg); > >> diff --git a/arch/x86/include/asm/mshyperv.h > >> b/arch/x86/include/asm/mshyperv.h > >> index f64393e853ee..d5355a5b7517 100644 > >> --- a/arch/x86/include/asm/mshyperv.h > >> +++ b/arch/x86/include/asm/mshyperv.h > >> @@ -304,6 +304,7 @@ void mshv_vtl_return_call(struct mshv_vtl_cpu_context > *vtl0); > >> void mshv_vtl_return_call_init(u64 vtl_return_offset); > >> void mshv_vtl_return_hypercall(void); > >> void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0); > >> +int hv_vtl_get_set_reg(struct hv_register_assoc *regs, bool set, u64 > >> shared); > > > > Can this move to asm-generic/mshyperv.h? The function is no longer specific > > to x86/x64, so one would want to not declare it in the arch/x86 version > > of mshyperv.h. But maybe moving it to asm-generic/mshyperv.h breaks > > compilation on arm64 because there's also the static inline stub there. > > This is still arch specific (x86 to be precise). For ARM64, we always > want to return 1, which is to tell the client to use hypercall as a > fallback option. Moving this x86 specific implementation (X64 registers, > MTRR etc) to a common code, would not be right. One thing that could be > done here was to move the "return 1" stub code from arm64 to asm-generic > mshyperv.h, but that would not provide much benefit. > > I am currently not planning to make any changes here. If I misunderstood > your comment, please let me know. >
Yes, the implementation of hv_vtl_get_set_reg() is arch-specific. But the one-line declaration is not. If there was a full implementation on arm64 like with x86, then the declaration could move to asm-generic/mshyperv.h. But the arm64 side is a "static inline" function, and I'm pretty sure the above declaration would cause a compiler conflict. So not making any changes is appropriate. If the arm64 side should ever change to a full implementation that isn't static inline, then the one-line declaration should move to asm-generic/mshyperv.h. I probably should have omitted my comment entirely as it was just musing about a situation that doesn't actually exist at the moment. :-( Michael

