1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 /* 4 * Linux-specific definitions for managing interactions with Microsoft's 5 * Hyper-V hypervisor. The definitions in this file are architecture 6 * independent. See arch/<arch>/include/asm/mshyperv.h for definitions 7 * that are specific to architecture <arch>. 8 * 9 * Definitions that are derived from Hyper-V code or headers should not go in 10 * this file, but should instead go in the relevant files in include/hyperv. 11 * 12 * Copyright (C) 2019, Microsoft, Inc. 13 * 14 * Author : Michael Kelley <mikelley@microsoft.com> 15 */ 16 17 #ifndef _ASM_GENERIC_MSHYPERV_H 18 #define _ASM_GENERIC_MSHYPERV_H 19 20 #include <linux/types.h> 21 #include <linux/atomic.h> 22 #include <linux/bitops.h> 23 #include <acpi/acpi_numa.h> 24 #include <linux/cpumask.h> 25 #include <linux/nmi.h> 26 #include <asm/ptrace.h> 27 #include <hyperv/hvhdk.h> 28 29 #define VTPM_BASE_ADDRESS 0xfed40000 30 31 enum hv_partition_type { 32 HV_PARTITION_TYPE_GUEST, 33 HV_PARTITION_TYPE_ROOT, 34 HV_PARTITION_TYPE_L1VH, 35 }; 36 37 struct ms_hyperv_info { 38 u32 features; 39 u32 priv_high; 40 u32 ext_features; 41 u32 misc_features; 42 u32 hints; 43 u32 nested_features; 44 u32 max_vp_index; 45 u32 max_lp_index; 46 u8 vtl; 47 union { 48 u32 isolation_config_a; 49 struct { 50 u32 paravisor_present : 1; 51 u32 reserved_a1 : 31; 52 }; 53 }; 54 union { 55 u32 isolation_config_b; 56 struct { 57 u32 cvm_type : 4; 58 u32 reserved_b1 : 1; 59 u32 shared_gpa_boundary_active : 1; 60 u32 shared_gpa_boundary_bits : 6; 61 u32 reserved_b2 : 20; 62 }; 63 }; 64 u64 shared_gpa_boundary; 65 }; 66 extern struct ms_hyperv_info ms_hyperv; 67 extern bool hv_nested; 68 extern u64 hv_current_partition_id; 69 extern enum hv_partition_type hv_curr_partition_type; 70 71 extern void * __percpu *hyperv_pcpu_input_arg; 72 extern void * __percpu *hyperv_pcpu_output_arg; 73 74 u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr); 75 u64 hv_do_fast_hypercall8(u16 control, u64 input8); 76 u64 hv_do_fast_hypercall16(u16 control, u64 input1, u64 input2); 77 78 bool hv_isolation_type_snp(void); 79 bool hv_isolation_type_tdx(void); 80 81 /* 82 * On architectures where Hyper-V doesn't support AEOI (e.g., ARM64), 83 * it doesn't provide a recommendation flag and AEOI must be disabled. 84 */ 85 static inline bool hv_recommend_using_aeoi(void) 86 { 87 #ifdef HV_DEPRECATING_AEOI_RECOMMENDED 88 return !(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED); 89 #else 90 return false; 91 #endif 92 } 93 94 static inline struct hv_proximity_domain_info hv_numa_node_to_pxm_info(int node) 95 { 96 struct hv_proximity_domain_info pxm_info = {}; 97 98 if (node != NUMA_NO_NODE) { 99 pxm_info.domain_id = node_to_pxm(node); 100 pxm_info.flags.proximity_info_valid = 1; 101 pxm_info.flags.proximity_preferred = 1; 102 } 103 104 return pxm_info; 105 } 106 107 /* Helper functions that provide a consistent pattern for checking Hyper-V hypercall status. */ 108 static inline int hv_result(u64 status) 109 { 110 return status & HV_HYPERCALL_RESULT_MASK; 111 } 112 113 static inline bool hv_result_success(u64 status) 114 { 115 return hv_result(status) == HV_STATUS_SUCCESS; 116 } 117 118 static inline unsigned int hv_repcomp(u64 status) 119 { 120 /* Bits [43:32] of status have 'Reps completed' data. */ 121 return (status & HV_HYPERCALL_REP_COMP_MASK) >> 122 HV_HYPERCALL_REP_COMP_OFFSET; 123 } 124 125 /* 126 * Rep hypercalls. Callers of this functions are supposed to ensure that 127 * rep_count, varhead_size, and rep_start comply with Hyper-V hypercall 128 * definition. 129 */ 130 static inline u64 hv_do_rep_hypercall_ex(u16 code, u16 rep_count, 131 u16 varhead_size, u16 rep_start, 132 void *input, void *output) 133 { 134 u64 control = code; 135 u64 status; 136 u16 rep_comp; 137 138 control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET; 139 control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET; 140 control |= (u64)rep_start << HV_HYPERCALL_REP_START_OFFSET; 141 142 do { 143 status = hv_do_hypercall(control, input, output); 144 if (!hv_result_success(status)) 145 return status; 146 147 rep_comp = hv_repcomp(status); 148 149 control &= ~HV_HYPERCALL_REP_START_MASK; 150 control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET; 151 152 touch_nmi_watchdog(); 153 } while (rep_comp < rep_count); 154 155 return status; 156 } 157 158 /* For the typical case where rep_start is 0 */ 159 static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, 160 void *input, void *output) 161 { 162 return hv_do_rep_hypercall_ex(code, rep_count, varhead_size, 0, 163 input, output); 164 } 165 166 /* Generate the guest OS identifier as described in the Hyper-V TLFS */ 167 static inline u64 hv_generate_guest_id(u64 kernel_version) 168 { 169 u64 guest_id; 170 171 guest_id = (((u64)HV_LINUX_VENDOR_ID) << 48); 172 guest_id |= (kernel_version << 16); 173 174 return guest_id; 175 } 176 177 #if IS_ENABLED(CONFIG_HYPERV_VMBUS) 178 /* Free the message slot and signal end-of-message if required */ 179 static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) 180 { 181 /* 182 * On crash we're reading some other CPU's message page and we need 183 * to be careful: this other CPU may already had cleared the header 184 * and the host may already had delivered some other message there. 185 * In case we blindly write msg->header.message_type we're going 186 * to lose it. We can still lose a message of the same type but 187 * we count on the fact that there can only be one 188 * CHANNELMSG_UNLOAD_RESPONSE and we don't care about other messages 189 * on crash. 190 */ 191 if (cmpxchg(&msg->header.message_type, old_msg_type, 192 HVMSG_NONE) != old_msg_type) 193 return; 194 195 /* 196 * The cmxchg() above does an implicit memory barrier to 197 * ensure the write to MessageType (ie set to 198 * HVMSG_NONE) happens before we read the 199 * MessagePending and EOMing. Otherwise, the EOMing 200 * will not deliver any more messages since there is 201 * no empty slot 202 */ 203 if (msg->header.message_flags.msg_pending) { 204 /* 205 * This will cause message queue rescan to 206 * possibly deliver another msg from the 207 * hypervisor 208 */ 209 hv_set_msr(HV_MSR_EOM, 0); 210 } 211 } 212 213 extern int vmbus_interrupt; 214 extern int vmbus_irq; 215 #endif /* CONFIG_HYPERV_VMBUS */ 216 217 int hv_get_hypervisor_version(union hv_hypervisor_version_info *info); 218 219 void hv_setup_vmbus_handler(void (*handler)(void)); 220 void hv_remove_vmbus_handler(void); 221 void hv_setup_stimer0_handler(void (*handler)(void)); 222 void hv_remove_stimer0_handler(void); 223 224 void hv_setup_kexec_handler(void (*handler)(void)); 225 void hv_remove_kexec_handler(void); 226 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)); 227 void hv_remove_crash_handler(void); 228 void hv_setup_mshv_handler(void (*handler)(void)); 229 230 #if IS_ENABLED(CONFIG_HYPERV) 231 /* 232 * Hypervisor's notion of virtual processor ID is different from 233 * Linux' notion of CPU ID. This information can only be retrieved 234 * in the context of the calling CPU. Setup a map for easy access 235 * to this information. 236 */ 237 extern u32 *hv_vp_index; 238 extern u32 hv_max_vp_index; 239 240 extern u64 (*hv_read_reference_counter)(void); 241 242 /* Sentinel value for an uninitialized entry in hv_vp_index array */ 243 #define VP_INVAL U32_MAX 244 245 int __init hv_common_init(void); 246 void __init hv_get_partition_id(void); 247 void __init hv_common_free(void); 248 void __init ms_hyperv_late_init(void); 249 int hv_common_cpu_init(unsigned int cpu); 250 int hv_common_cpu_die(unsigned int cpu); 251 void hv_identify_partition_type(void); 252 253 /** 254 * hv_cpu_number_to_vp_number() - Map CPU to VP. 255 * @cpu_number: CPU number in Linux terms 256 * 257 * This function returns the mapping between the Linux processor 258 * number and the hypervisor's virtual processor number, useful 259 * in making hypercalls and such that talk about specific 260 * processors. 261 * 262 * Return: Virtual processor number in Hyper-V terms 263 */ 264 static inline int hv_cpu_number_to_vp_number(int cpu_number) 265 { 266 return hv_vp_index[cpu_number]; 267 } 268 269 static inline int __cpumask_to_vpset(struct hv_vpset *vpset, 270 const struct cpumask *cpus, 271 bool (*func)(int cpu)) 272 { 273 int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1; 274 int max_vcpu_bank = hv_max_vp_index / HV_VCPUS_PER_SPARSE_BANK; 275 276 /* vpset.valid_bank_mask can represent up to HV_MAX_SPARSE_VCPU_BANKS banks */ 277 if (max_vcpu_bank >= HV_MAX_SPARSE_VCPU_BANKS) 278 return 0; 279 280 /* 281 * Clear all banks up to the maximum possible bank as hv_tlb_flush_ex 282 * structs are not cleared between calls, we risk flushing unneeded 283 * vCPUs otherwise. 284 */ 285 for (vcpu_bank = 0; vcpu_bank <= max_vcpu_bank; vcpu_bank++) 286 vpset->bank_contents[vcpu_bank] = 0; 287 288 /* 289 * Some banks may end up being empty but this is acceptable. 290 */ 291 for_each_cpu(cpu, cpus) { 292 if (func && func(cpu)) 293 continue; 294 vcpu = hv_cpu_number_to_vp_number(cpu); 295 if (vcpu == VP_INVAL) 296 return -1; 297 vcpu_bank = vcpu / HV_VCPUS_PER_SPARSE_BANK; 298 vcpu_offset = vcpu % HV_VCPUS_PER_SPARSE_BANK; 299 __set_bit(vcpu_offset, (unsigned long *) 300 &vpset->bank_contents[vcpu_bank]); 301 if (vcpu_bank >= nr_bank) 302 nr_bank = vcpu_bank + 1; 303 } 304 vpset->valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0); 305 return nr_bank; 306 } 307 308 /* 309 * Convert a Linux cpumask into a Hyper-V VPset. In the _skip variant, 310 * 'func' is called for each CPU present in cpumask. If 'func' returns 311 * true, that CPU is skipped -- i.e., that CPU from cpumask is *not* 312 * added to the Hyper-V VPset. If 'func' is NULL, no CPUs are 313 * skipped. 314 */ 315 static inline int cpumask_to_vpset(struct hv_vpset *vpset, 316 const struct cpumask *cpus) 317 { 318 return __cpumask_to_vpset(vpset, cpus, NULL); 319 } 320 321 static inline int cpumask_to_vpset_skip(struct hv_vpset *vpset, 322 const struct cpumask *cpus, 323 bool (*func)(int cpu)) 324 { 325 return __cpumask_to_vpset(vpset, cpus, func); 326 } 327 328 #define _hv_status_fmt(fmt) "%s: Hyper-V status: %#x = %s: " fmt 329 #define hv_status_printk(level, status, fmt, ...) \ 330 do { \ 331 u64 __status = (status); \ 332 pr_##level(_hv_status_fmt(fmt), __func__, hv_result(__status), \ 333 hv_result_to_string(__status), ##__VA_ARGS__); \ 334 } while (0) 335 #define hv_status_err(status, fmt, ...) \ 336 hv_status_printk(err, status, fmt, ##__VA_ARGS__) 337 #define hv_status_debug(status, fmt, ...) \ 338 hv_status_printk(debug, status, fmt, ##__VA_ARGS__) 339 340 const char *hv_result_to_string(u64 hv_status); 341 int hv_result_to_errno(u64 status); 342 void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die); 343 bool hv_is_hyperv_initialized(void); 344 bool hv_is_hibernation_supported(void); 345 enum hv_isolation_type hv_get_isolation_type(void); 346 bool hv_is_isolation_supported(void); 347 bool hv_isolation_type_snp(void); 348 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size); 349 u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2); 350 void hv_enable_coco_interrupt(unsigned int cpu, unsigned int vector, bool set); 351 void hyperv_cleanup(void); 352 bool hv_query_ext_cap(u64 cap_query); 353 void hv_setup_dma_ops(struct device *dev, bool coherent); 354 #else /* CONFIG_HYPERV */ 355 static inline void hv_identify_partition_type(void) {} 356 static inline bool hv_is_hyperv_initialized(void) { return false; } 357 static inline bool hv_is_hibernation_supported(void) { return false; } 358 static inline void hyperv_cleanup(void) {} 359 static inline void ms_hyperv_late_init(void) {} 360 static inline bool hv_is_isolation_supported(void) { return false; } 361 static inline enum hv_isolation_type hv_get_isolation_type(void) 362 { 363 return HV_ISOLATION_TYPE_NONE; 364 } 365 #endif /* CONFIG_HYPERV */ 366 367 #if IS_ENABLED(CONFIG_MSHV_ROOT) 368 static inline bool hv_root_partition(void) 369 { 370 return hv_curr_partition_type == HV_PARTITION_TYPE_ROOT; 371 } 372 static inline bool hv_l1vh_partition(void) 373 { 374 return hv_curr_partition_type == HV_PARTITION_TYPE_L1VH; 375 } 376 static inline bool hv_parent_partition(void) 377 { 378 return hv_root_partition() || hv_l1vh_partition(); 379 } 380 int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); 381 int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); 382 int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); 383 384 #else /* CONFIG_MSHV_ROOT */ 385 static inline bool hv_root_partition(void) { return false; } 386 static inline bool hv_l1vh_partition(void) { return false; } 387 static inline bool hv_parent_partition(void) { return false; } 388 static inline int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) 389 { 390 return -EOPNOTSUPP; 391 } 392 static inline int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id) 393 { 394 return -EOPNOTSUPP; 395 } 396 static inline int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags) 397 { 398 return -EOPNOTSUPP; 399 } 400 #endif /* CONFIG_MSHV_ROOT */ 401 402 #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE) 403 u8 __init get_vtl(void); 404 #else 405 static inline u8 get_vtl(void) { return 0; } 406 #endif 407 408 #endif 409