diff options
Diffstat (limited to 'arch/x86/include')
-rw-r--r-- | arch/x86/include/asm/mshyperv.h | 151 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/hyperv.h | 8 |
2 files changed, 159 insertions, 0 deletions
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index aaf59b7da98a..7c9c895432a9 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h | |||
@@ -3,8 +3,28 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
6 | #include <linux/clocksource.h> | ||
6 | #include <asm/hyperv.h> | 7 | #include <asm/hyperv.h> |
7 | 8 | ||
9 | /* | ||
10 | * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent | ||
11 | * is set by CPUID(HVCPUID_VERSION_FEATURES). | ||
12 | */ | ||
13 | enum hv_cpuid_function { | ||
14 | HVCPUID_VERSION_FEATURES = 0x00000001, | ||
15 | HVCPUID_VENDOR_MAXFUNCTION = 0x40000000, | ||
16 | HVCPUID_INTERFACE = 0x40000001, | ||
17 | |||
18 | /* | ||
19 | * The remaining functions depend on the value of | ||
20 | * HVCPUID_INTERFACE | ||
21 | */ | ||
22 | HVCPUID_VERSION = 0x40000002, | ||
23 | HVCPUID_FEATURES = 0x40000003, | ||
24 | HVCPUID_ENLIGHTENMENT_INFO = 0x40000004, | ||
25 | HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005, | ||
26 | }; | ||
27 | |||
8 | struct ms_hyperv_info { | 28 | struct ms_hyperv_info { |
9 | u32 features; | 29 | u32 features; |
10 | u32 misc_features; | 30 | u32 misc_features; |
@@ -13,6 +33,128 @@ struct ms_hyperv_info { | |||
13 | 33 | ||
14 | extern struct ms_hyperv_info ms_hyperv; | 34 | extern struct ms_hyperv_info ms_hyperv; |
15 | 35 | ||
36 | /* | ||
37 | * Declare the MSR used to setup pages used to communicate with the hypervisor. | ||
38 | */ | ||
39 | union hv_x64_msr_hypercall_contents { | ||
40 | u64 as_uint64; | ||
41 | struct { | ||
42 | u64 enable:1; | ||
43 | u64 reserved:11; | ||
44 | u64 guest_physical_address:52; | ||
45 | }; | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * TSC page layout. | ||
50 | */ | ||
51 | |||
52 | struct ms_hyperv_tsc_page { | ||
53 | volatile u32 tsc_sequence; | ||
54 | u32 reserved1; | ||
55 | volatile u64 tsc_scale; | ||
56 | volatile s64 tsc_offset; | ||
57 | u64 reserved2[509]; | ||
58 | }; | ||
59 | |||
60 | /* | ||
61 | * The guest OS needs to register the guest ID with the hypervisor. | ||
62 | * The guest ID is a 64 bit entity and the structure of this ID is | ||
63 | * specified in the Hyper-V specification: | ||
64 | * | ||
65 | * msdn.microsoft.com/en-us/library/windows/hardware/ff542653%28v=vs.85%29.aspx | ||
66 | * | ||
67 | * While the current guideline does not specify how Linux guest ID(s) | ||
68 | * need to be generated, our plan is to publish the guidelines for | ||
69 | * Linux and other guest operating systems that currently are hosted | ||
70 | * on Hyper-V. The implementation here conforms to this yet | ||
71 | * unpublished guidelines. | ||
72 | * | ||
73 | * | ||
74 | * Bit(s) | ||
75 | * 63 - Indicates if the OS is Open Source or not; 1 is Open Source | ||
76 | * 62:56 - Os Type; Linux is 0x100 | ||
77 | * 55:48 - Distro specific identification | ||
78 | * 47:16 - Linux kernel version number | ||
79 | * 15:0 - Distro specific identification | ||
80 | * | ||
81 | * | ||
82 | */ | ||
83 | |||
84 | #define HV_LINUX_VENDOR_ID 0x8100 | ||
85 | |||
86 | /* | ||
87 | * Generate the guest ID based on the guideline described above. | ||
88 | */ | ||
89 | |||
90 | static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version, | ||
91 | __u64 d_info2) | ||
92 | { | ||
93 | __u64 guest_id = 0; | ||
94 | |||
95 | guest_id = (((__u64)HV_LINUX_VENDOR_ID) << 48); | ||
96 | guest_id |= (d_info1 << 48); | ||
97 | guest_id |= (kernel_version << 16); | ||
98 | guest_id |= d_info2; | ||
99 | |||
100 | return guest_id; | ||
101 | } | ||
102 | |||
103 | |||
104 | /* Free the message slot and signal end-of-message if required */ | ||
105 | static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) | ||
106 | { | ||
107 | /* | ||
108 | * On crash we're reading some other CPU's message page and we need | ||
109 | * to be careful: this other CPU may already had cleared the header | ||
110 | * and the host may already had delivered some other message there. | ||
111 | * In case we blindly write msg->header.message_type we're going | ||
112 | * to lose it. We can still lose a message of the same type but | ||
113 | * we count on the fact that there can only be one | ||
114 | * CHANNELMSG_UNLOAD_RESPONSE and we don't care about other messages | ||
115 | * on crash. | ||
116 | */ | ||
117 | if (cmpxchg(&msg->header.message_type, old_msg_type, | ||
118 | HVMSG_NONE) != old_msg_type) | ||
119 | return; | ||
120 | |||
121 | /* | ||
122 | * Make sure the write to MessageType (ie set to | ||
123 | * HVMSG_NONE) happens before we read the | ||
124 | * MessagePending and EOMing. Otherwise, the EOMing | ||
125 | * will not deliver any more messages since there is | ||
126 | * no empty slot | ||
127 | */ | ||
128 | mb(); | ||
129 | |||
130 | if (msg->header.message_flags.msg_pending) { | ||
131 | /* | ||
132 | * This will cause message queue rescan to | ||
133 | * possibly deliver another msg from the | ||
134 | * hypervisor | ||
135 | */ | ||
136 | wrmsrl(HV_X64_MSR_EOM, 0); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | #define hv_get_current_tick(tick) rdmsrl(HV_X64_MSR_TIME_REF_COUNT, tick) | ||
141 | #define hv_init_timer(timer, tick) wrmsrl(timer, tick) | ||
142 | #define hv_init_timer_config(config, val) wrmsrl(config, val) | ||
143 | |||
144 | #define hv_get_simp(val) rdmsrl(HV_X64_MSR_SIMP, val) | ||
145 | #define hv_set_simp(val) wrmsrl(HV_X64_MSR_SIMP, val) | ||
146 | |||
147 | #define hv_get_siefp(val) rdmsrl(HV_X64_MSR_SIEFP, val) | ||
148 | #define hv_set_siefp(val) wrmsrl(HV_X64_MSR_SIEFP, val) | ||
149 | |||
150 | #define hv_get_synic_state(val) rdmsrl(HV_X64_MSR_SCONTROL, val) | ||
151 | #define hv_set_synic_state(val) wrmsrl(HV_X64_MSR_SCONTROL, val) | ||
152 | |||
153 | #define hv_get_vp_index(index) rdmsrl(HV_X64_MSR_VP_INDEX, index) | ||
154 | |||
155 | #define hv_get_synint_state(int_num, val) rdmsrl(int_num, val) | ||
156 | #define hv_set_synint_state(int_num, val) wrmsrl(int_num, val) | ||
157 | |||
16 | void hyperv_callback_vector(void); | 158 | void hyperv_callback_vector(void); |
17 | #ifdef CONFIG_TRACING | 159 | #ifdef CONFIG_TRACING |
18 | #define trace_hyperv_callback_vector hyperv_callback_vector | 160 | #define trace_hyperv_callback_vector hyperv_callback_vector |
@@ -25,4 +167,13 @@ void hv_setup_kexec_handler(void (*handler)(void)); | |||
25 | void hv_remove_kexec_handler(void); | 167 | void hv_remove_kexec_handler(void); |
26 | void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)); | 168 | void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)); |
27 | void hv_remove_crash_handler(void); | 169 | void hv_remove_crash_handler(void); |
170 | |||
171 | #if IS_ENABLED(CONFIG_HYPERV) | ||
172 | extern struct clocksource *hyperv_cs; | ||
173 | |||
174 | void hyperv_init(void); | ||
175 | void hyperv_report_panic(struct pt_regs *regs); | ||
176 | bool hv_is_hypercall_page_setup(void); | ||
177 | void hyperv_cleanup(void); | ||
178 | #endif | ||
28 | #endif | 179 | #endif |
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index 9b1a91834ac8..3a20ccf787b8 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h | |||
@@ -73,6 +73,9 @@ | |||
73 | */ | 73 | */ |
74 | #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) | 74 | #define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8) |
75 | 75 | ||
76 | /* Crash MSR available */ | ||
77 | #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10) | ||
78 | |||
76 | /* | 79 | /* |
77 | * Feature identification: EBX indicates which flags were specified at | 80 | * Feature identification: EBX indicates which flags were specified at |
78 | * partition creation. The format is the same as the partition creation | 81 | * partition creation. The format is the same as the partition creation |
@@ -144,6 +147,11 @@ | |||
144 | */ | 147 | */ |
145 | #define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5) | 148 | #define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5) |
146 | 149 | ||
150 | /* | ||
151 | * Crash notification flag. | ||
152 | */ | ||
153 | #define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63) | ||
154 | |||
147 | /* MSR used to identify the guest OS. */ | 155 | /* MSR used to identify the guest OS. */ |
148 | #define HV_X64_MSR_GUEST_OS_ID 0x40000000 | 156 | #define HV_X64_MSR_GUEST_OS_ID 0x40000000 |
149 | 157 | ||