1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /****************************************************************************** 3 * asm-x86/guest/hyperv.h 4 * 5 * Copyright (c) 2019 Microsoft. 6 */ 7 8 #ifndef __X86_GUEST_HYPERV_H__ 9 #define __X86_GUEST_HYPERV_H__ 10 11 #include <xen/types.h> 12 13 /* Use top-most MFN for hypercall page */ 14 #define HV_HCALL_MFN (((1ull << paddr_bits) - 1) >> HV_HYP_PAGE_SHIFT) 15 16 /* 17 * The specification says: "The partition reference time is computed 18 * by the following formula: 19 * 20 * ReferenceTime = ((VirtualTsc * TscScale) >> 64) + TscOffset 21 * 22 * The multiplication is a 64 bit multiplication, which results in a 23 * 128 bit number which is then shifted 64 times to the right to obtain 24 * the high 64 bits." 25 */ hv_scale_tsc(uint64_t tsc,uint64_t scale,int64_t offset)26static inline uint64_t hv_scale_tsc(uint64_t tsc, uint64_t scale, 27 int64_t offset) 28 { 29 uint64_t result; 30 31 /* 32 * Quadword MUL takes an implicit operand in RAX, and puts the result 33 * in RDX:RAX. Because we only want the result of the multiplication 34 * after shifting right by 64 bits, we therefore only need the content 35 * of RDX. 36 */ 37 asm ( "mulq %[scale]" 38 : "+a" (tsc), "=d" (result) 39 : [scale] "rm" (scale) ); 40 41 return result + offset; 42 } 43 44 #ifdef CONFIG_HYPERV_GUEST 45 46 #include <asm/guest/hypervisor.h> 47 48 struct ms_hyperv_info { 49 uint32_t features; 50 uint32_t misc_features; 51 uint32_t hints; 52 uint32_t nested_features; 53 uint32_t max_vp_index; 54 uint32_t max_lp_index; 55 }; 56 extern struct ms_hyperv_info ms_hyperv; 57 58 const struct hypervisor_ops *hyperv_probe(void); 59 60 #else 61 hyperv_probe(void)62static inline const struct hypervisor_ops *hyperv_probe(void) { return NULL; } 63 64 #endif /* CONFIG_HYPERV_GUEST */ 65 #endif /* __X86_GUEST_HYPERV_H__ */ 66 67 /* 68 * Local variables: 69 * mode: C 70 * c-file-style: "BSD" 71 * c-basic-offset: 4 72 * tab-width: 4 73 * indent-tabs-mode: nil 74 * End: 75 */ 76