1717#include <asm/desc.h>
1818#include <asm/e820/api.h>
1919#include <asm/sev.h>
20- #include <asm/ibt.h>
2120#include <asm/hypervisor.h>
2221#include <hyperv/hvhdk.h>
2322#include <asm/mshyperv.h>
3938void * hv_hypercall_pg ;
4039
4140#ifdef CONFIG_X86_64
41+ static u64 __hv_hyperfail (u64 control , u64 param1 , u64 param2 )
42+ {
43+ return U64_MAX ;
44+ }
45+
46+ DEFINE_STATIC_CALL (__hv_hypercall , __hv_hyperfail );
47+
4248u64 hv_std_hypercall (u64 control , u64 param1 , u64 param2 )
4349{
4450 u64 hv_status ;
4551
46- if (!hv_hypercall_pg )
47- return U64_MAX ;
48-
4952 register u64 __r8 asm("r8" ) = param2 ;
50- asm volatile (CALL_NOSPEC
53+ asm volatile ("call " STATIC_CALL_TRAMP_STR ( __hv_hypercall )
5154 : "=a" (hv_status ), ASM_CALL_CONSTRAINT ,
5255 "+c" (control ), "+d" (param1 ), "+r" (__r8 )
53- : THUNK_TARGET (hv_hypercall_pg )
54- : "cc" , "memory" , "r9" , "r10" , "r11" );
56+ : : "cc" , "memory" , "r9" , "r10" , "r11" );
5557
5658 return hv_status ;
5759}
60+
61+ typedef u64 (* hv_hypercall_f )(u64 control , u64 param1 , u64 param2 );
62+
63+ static inline void hv_set_hypercall_pg (void * ptr )
64+ {
65+ hv_hypercall_pg = ptr ;
66+
67+ if (!ptr )
68+ ptr = & __hv_hyperfail ;
69+ static_call_update (__hv_hypercall , (hv_hypercall_f )ptr );
70+ }
5871#else
72+ static inline void hv_set_hypercall_pg (void * ptr )
73+ {
74+ hv_hypercall_pg = ptr ;
75+ }
5976EXPORT_SYMBOL_GPL (hv_hypercall_pg );
6077#endif
6178
@@ -350,7 +367,7 @@ static int hv_suspend(void)
350367 * pointer is restored on resume.
351368 */
352369 hv_hypercall_pg_saved = hv_hypercall_pg ;
353- hv_hypercall_pg = NULL ;
370+ hv_set_hypercall_pg ( NULL ) ;
354371
355372 /* Disable the hypercall page in the hypervisor */
356373 rdmsrq (HV_X64_MSR_HYPERCALL , hypercall_msr .as_uint64 );
@@ -376,7 +393,7 @@ static void hv_resume(void)
376393 vmalloc_to_pfn (hv_hypercall_pg_saved );
377394 wrmsrq (HV_X64_MSR_HYPERCALL , hypercall_msr .as_uint64 );
378395
379- hv_hypercall_pg = hv_hypercall_pg_saved ;
396+ hv_set_hypercall_pg ( hv_hypercall_pg_saved ) ;
380397 hv_hypercall_pg_saved = NULL ;
381398
382399 /*
@@ -496,8 +513,8 @@ void __init hyperv_init(void)
496513 if (hv_isolation_type_tdx () && !ms_hyperv .paravisor_present )
497514 goto skip_hypercall_pg_init ;
498515
499- hv_hypercall_pg = __vmalloc_node_range (PAGE_SIZE , 1 , VMALLOC_START ,
500- VMALLOC_END , GFP_KERNEL , PAGE_KERNEL_ROX ,
516+ hv_hypercall_pg = __vmalloc_node_range (PAGE_SIZE , 1 , MODULES_VADDR ,
517+ MODULES_END , GFP_KERNEL , PAGE_KERNEL_ROX ,
501518 VM_FLUSH_RESET_PERMS , NUMA_NO_NODE ,
502519 __builtin_return_address (0 ));
503520 if (hv_hypercall_pg == NULL )
@@ -535,27 +552,9 @@ void __init hyperv_init(void)
535552 wrmsrq (HV_X64_MSR_HYPERCALL , hypercall_msr .as_uint64 );
536553 }
537554
538- skip_hypercall_pg_init :
539- /*
540- * Some versions of Hyper-V that provide IBT in guest VMs have a bug
541- * in that there's no ENDBR64 instruction at the entry to the
542- * hypercall page. Because hypercalls are invoked via an indirect call
543- * to the hypercall page, all hypercall attempts fail when IBT is
544- * enabled, and Linux panics. For such buggy versions, disable IBT.
545- *
546- * Fixed versions of Hyper-V always provide ENDBR64 on the hypercall
547- * page, so if future Linux kernel versions enable IBT for 32-bit
548- * builds, additional hypercall page hackery will be required here
549- * to provide an ENDBR32.
550- */
551- #ifdef CONFIG_X86_KERNEL_IBT
552- if (cpu_feature_enabled (X86_FEATURE_IBT ) &&
553- * (u32 * )hv_hypercall_pg != gen_endbr ()) {
554- setup_clear_cpu_cap (X86_FEATURE_IBT );
555- pr_warn ("Disabling IBT because of Hyper-V bug\n" );
556- }
557- #endif
555+ hv_set_hypercall_pg (hv_hypercall_pg );
558556
557+ skip_hypercall_pg_init :
559558 /*
560559 * hyperv_init() is called before LAPIC is initialized: see
561560 * apic_intr_mode_init() -> x86_platform.apic_post_init() and
0 commit comments