RE: [PATCH v11 2/2] Drivers: hv: Introduce mshv_vtl driver

Michael Kelley
2025-11-12T04:12:12Z

From: Peter Zijlstra <peterz@infradead.org> Sent: Tuesday, November 11, 2025 12:14 AM
>
> On Tue, Nov 11, 2025 at 12:25:54PM +0530, Naman Jain wrote:
>
> IBT isn't the problem, the thing is running objtool on vmlinux.o vs the
> individual translation units. vmlinux.o will have that symbol, while
> your .S file doesn't.
>
> > AS arch/x86/hyperv/mshv_vtl_asm.o
> > arch/x86/hyperv/mshv_vtl_asm.o: error: objtool: static_call: can't find
> > static_call_key symbol: __SCK____mshv_vtl_return_hypercall
>
> Right, and I said you had to do that ADDRESSABLE thing. So I added a
> DECLARE_STATIC_CALL() and a static_call() in hv.c, compiled it so .s and
> stole the bits.
>
> And then you get something like the below. See symbol 5, that's the
> entry we need.
>
> # readelf -sW defconfig-build/arch/x86/hyperv/mshv_vtl_asm.o
>
> Symbol table '.symtab' contains 8 entries:
> Num: Value Size Type Bind Vis Ndx Name
> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
> 1: 0000000000000000 8 OBJECT LOCAL DEFAULT 6
> __UNIQUE_ID_addressable___SCK____mshv_vtl_return_hypercall_662.0
> 2: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .noinstr.text
> 3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND
> __SCT____mshv_vtl_return_hypercall
> 4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __x86_return_thunk
> 5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND
> __SCK____mshv_vtl_return_hypercall
> 6: 0000000000000010 179 FUNC GLOBAL DEFAULT 4 __mshv_vtl_return_call
> 7: 0000000000000000 16 FUNC GLOBAL DEFAULT 4
> __pfx___mshv_vtl_return_call
>
>
> ---
> --- a/arch/x86/hyperv/hv_vtl.c
> +++ b/arch/x86/hyperv/hv_vtl.c
> @@ -256,20 +256,6 @@ int __init hv_vtl_early_init(void)
>
> DEFINE_STATIC_CALL_NULL(__mshv_vtl_return_hypercall, void (*)(void));
>
> -noinstr void mshv_vtl_return_hypercall(void)
> -{
> - asm volatile ("call " STATIC_CALL_TRAMP_STR(__mshv_vtl_return_hypercall));
> -}
> -
> -/*
> - * ASM_CALL_CONSTRAINT is intentionally not used in above asm block before making a call to
> - * __mshv_vtl_return_hypercall, to avoid rbp clobbering before actual VTL return happens.
> - * This however leads to objtool complain about "call without frame pointer save/setup".
> - * To ignore that warning, and inform objtool about this non-standard function,
> - * STACK_FRAME_NON_STANDARD_FP is used.
> - */
> -STACK_FRAME_NON_STANDARD_FP(mshv_vtl_return_hypercall);
> -
> void mshv_vtl_return_call_init(u64 vtl_return_offset)
> {
> static_call_update(__mshv_vtl_return_hypercall,
> --- a/arch/x86/hyperv/mshv_vtl_asm.S
> +++ b/arch/x86/hyperv/mshv_vtl_asm.S
> @@ -9,6 +9,7 @@
> */
>
> #include <linux/linkage.h>
> +#include <linux/static_call_types.h>
> #include <asm/asm.h>
> #include <asm/asm-offsets.h>
> #include <asm/frame.h>
> @@ -57,7 +58,7 @@ SYM_FUNC_START(__mshv_vtl_return_call)
> xor %ecx, %ecx
>
> /* make a hypercall to switch VTL */
> - call mshv_vtl_return_hypercall
> + call STATIC_CALL_TRAMP_STR(__mshv_vtl_return_hypercall)
>
> /* stash guest registers on stack, restore saved host copies */
> pushq %rax
> @@ -96,3 +97,10 @@ SYM_FUNC_START(__mshv_vtl_return_call)
> pop %rbp
> RET
> SYM_FUNC_END(__mshv_vtl_return_call)
> +
> + .section .discard.addressable,"aw"
> + .align 8
> + .type __UNIQUE_ID_addressable___SCK____mshv_vtl_return_hypercall_662.0, @object
> + .size __UNIQUE_ID_addressable___SCK____mshv_vtl_return_hypercall_662.0, 8
> +__UNIQUE_ID_addressable___SCK____mshv_vtl_return_hypercall_662.0:
> + .quad __SCK____mshv_vtl_return_hypercall

This is pretty yucky itself. Why is it better than calling out to a C function?
Is it because in spite of the annotations, there's no guarantee the C
compiler won't generate some code that messes up a register value? Or is
there some other reason?

Does the magic "_662.0" have any significance? Or is it just some
uniqueness salt on the symbol name?

Michael