^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef _ASM_X86_MSHYPER_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define _ASM_X86_MSHYPER_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/nmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/msi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/hyperv-tlfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/nospec-branch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/paravirt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) typedef int (*hyperv_fill_flush_list_func)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct hv_guest_mapping_flush_list *flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define hv_init_timer(timer, tick) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) wrmsrl(HV_X64_MSR_STIMER0_COUNT + (2*timer), tick)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define hv_init_timer_config(timer, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) wrmsrl(HV_X64_MSR_STIMER0_CONFIG + (2*timer), val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define hv_get_simp(val) rdmsrl(HV_X64_MSR_SIMP, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define hv_set_simp(val) wrmsrl(HV_X64_MSR_SIMP, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define hv_get_siefp(val) rdmsrl(HV_X64_MSR_SIEFP, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define hv_set_siefp(val) wrmsrl(HV_X64_MSR_SIEFP, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define hv_get_synic_state(val) rdmsrl(HV_X64_MSR_SCONTROL, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define hv_set_synic_state(val) wrmsrl(HV_X64_MSR_SCONTROL, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define hv_get_vp_index(index) rdmsrl(HV_X64_MSR_VP_INDEX, index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define hv_signal_eom() wrmsrl(HV_X64_MSR_EOM, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define hv_get_synint_state(int_num, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) rdmsrl(HV_X64_MSR_SINT0 + int_num, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define hv_set_synint_state(int_num, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) wrmsrl(HV_X64_MSR_SINT0 + int_num, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define hv_recommend_using_aeoi() \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define hv_get_crash_ctl(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) rdmsrl(HV_X64_MSR_CRASH_CTL, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define hv_get_time_ref_count(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) rdmsrl(HV_X64_MSR_TIME_REF_COUNT, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define hv_get_reference_tsc(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) rdmsrl(HV_X64_MSR_REFERENCE_TSC, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define hv_set_reference_tsc(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) wrmsrl(HV_X64_MSR_REFERENCE_TSC, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define hv_set_clocksource_vdso(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ((val).vdso_clock_mode = VDSO_CLOCKMODE_HVCLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define hv_enable_vdso_clocksource() \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define hv_get_raw_timer() rdtsc_ordered()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define hv_get_vector() HYPERVISOR_CALLBACK_VECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Reference to pv_ops must be inline so objtool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * detection of noinstr violations can work correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static __always_inline void hv_setup_sched_clock(void *sched_clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #ifdef CONFIG_PARAVIRT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pv_ops.time.sched_clock = sched_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) void hyperv_vector_handler(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static inline void hv_enable_stimer0_percpu_irq(int irq) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline void hv_disable_stimer0_percpu_irq(int irq) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #if IS_ENABLED(CONFIG_HYPERV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) extern int hyperv_init_cpuhp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) extern void *hv_hypercall_pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) extern void __percpu **hyperv_pcpu_input_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u64 input_address = input ? virt_to_phys(input) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u64 output_address = output ? virt_to_phys(output) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u64 hv_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return U64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) __asm__ __volatile__("mov %4, %%r8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) CALL_NOSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) : "=a" (hv_status), ASM_CALL_CONSTRAINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) "+c" (control), "+d" (input_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) : "r" (output_address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) THUNK_TARGET(hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) : "cc", "memory", "r8", "r9", "r10", "r11");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 input_address_hi = upper_32_bits(input_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u32 input_address_lo = lower_32_bits(input_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u32 output_address_hi = upper_32_bits(output_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 output_address_lo = lower_32_bits(output_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return U64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) __asm__ __volatile__(CALL_NOSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) : "=A" (hv_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) "+c" (input_address_lo), ASM_CALL_CONSTRAINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) : "A" (control),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) "b" (input_address_hi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) "D"(output_address_hi), "S"(output_address_lo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) THUNK_TARGET(hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) : "cc", "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #endif /* !x86_64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return hv_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Fast hypercall with 8 bytes of input and no output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) __asm__ __volatile__(CALL_NOSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) : "=a" (hv_status), ASM_CALL_CONSTRAINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "+c" (control), "+d" (input1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) : THUNK_TARGET(hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) : "cc", "r8", "r9", "r10", "r11");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 input1_hi = upper_32_bits(input1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 input1_lo = lower_32_bits(input1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) __asm__ __volatile__ (CALL_NOSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) : "=A"(hv_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "+c"(input1_lo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ASM_CALL_CONSTRAINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) : "A" (control),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) "b" (input1_hi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) THUNK_TARGET(hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) : "cc", "edi", "esi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return hv_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Fast hypercall with 16 bytes of input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) __asm__ __volatile__("mov %4, %%r8\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) CALL_NOSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) : "=a" (hv_status), ASM_CALL_CONSTRAINT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "+c" (control), "+d" (input1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) : "r" (input2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) THUNK_TARGET(hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) : "cc", "r8", "r9", "r10", "r11");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u32 input1_hi = upper_32_bits(input1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u32 input1_lo = lower_32_bits(input1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u32 input2_hi = upper_32_bits(input2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) u32 input2_lo = lower_32_bits(input2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __asm__ __volatile__ (CALL_NOSPEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) : "=A"(hv_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) "+c"(input1_lo), ASM_CALL_CONSTRAINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) : "A" (control), "b" (input1_hi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) "D"(input2_hi), "S"(input2_lo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) THUNK_TARGET(hv_hypercall_pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) : "cc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return hv_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * Rep hypercalls. Callers of this functions are supposed to ensure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * rep_count and varhead_size comply with Hyper-V hypercall definition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void *input, void *output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u64 control = code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u64 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u16 rep_comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) status = hv_do_hypercall(control, input, output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Bits 32-43 of status have 'Reps completed' data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) HV_HYPERCALL_REP_COMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) control &= ~HV_HYPERCALL_REP_START_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) touch_nmi_watchdog();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) } while (rep_comp < rep_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) extern struct hv_vp_assist_page **hv_vp_assist_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!hv_vp_assist_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return hv_vp_assist_page[cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) void __init hyperv_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void hyperv_setup_mmu_ops(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) void *hv_alloc_hyperv_page(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) void *hv_alloc_hyperv_zeroed_page(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) void hv_free_hyperv_page(unsigned long addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) void set_hv_tscchange_cb(void (*cb)(void));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) void clear_hv_tscchange_cb(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void hyperv_stop_tsc_emulation(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int hyperv_flush_guest_mapping(u64 as);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int hyperv_flush_guest_mapping_range(u64 as,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) hyperv_fill_flush_list_func fill_func, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int hyperv_fill_flush_guest_mapping_list(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct hv_guest_mapping_flush_list *flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u64 start_gfn, u64 end_gfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) void hv_apic_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) void __init hv_init_spinlocks(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) bool hv_vcpu_is_preempted(int vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static inline void hv_apic_init(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static inline void hv_set_msi_entry_from_desc(union hv_msi_entry *msi_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct msi_desc *msi_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) msi_entry->address = msi_desc->msg.address_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) msi_entry->data = msi_desc->msg.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #else /* CONFIG_HYPERV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static inline void hyperv_init(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static inline void hyperv_setup_mmu_ops(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static inline void *hv_alloc_hyperv_page(void) { return NULL; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static inline void hv_free_hyperv_page(unsigned long addr) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static inline void set_hv_tscchange_cb(void (*cb)(void)) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static inline void clear_hv_tscchange_cb(void) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static inline void hyperv_stop_tsc_emulation(void) {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static inline int hyperv_flush_guest_mapping(u64 as) { return -1; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline int hyperv_flush_guest_mapping_range(u64 as,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) hyperv_fill_flush_list_func fill_func, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #endif /* CONFIG_HYPERV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #include <asm-generic/mshyperv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #endif