0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef _ASM_GENERIC_MSHYPERV_H
0019 #define _ASM_GENERIC_MSHYPERV_H
0020
0021 #include <linux/types.h>
0022 #include <linux/atomic.h>
0023 #include <linux/bitops.h>
0024 #include <linux/cpumask.h>
0025 #include <linux/nmi.h>
0026 #include <asm/ptrace.h>
0027 #include <asm/hyperv-tlfs.h>
0028
0029 struct ms_hyperv_info {
0030 u32 features;
0031 u32 priv_high;
0032 u32 misc_features;
0033 u32 hints;
0034 u32 nested_features;
0035 u32 max_vp_index;
0036 u32 max_lp_index;
0037 u32 isolation_config_a;
0038 union {
0039 u32 isolation_config_b;
0040 struct {
0041 u32 cvm_type : 4;
0042 u32 reserved1 : 1;
0043 u32 shared_gpa_boundary_active : 1;
0044 u32 shared_gpa_boundary_bits : 6;
0045 u32 reserved2 : 20;
0046 };
0047 };
0048 u64 shared_gpa_boundary;
0049 };
0050 extern struct ms_hyperv_info ms_hyperv;
0051
0052 extern void * __percpu *hyperv_pcpu_input_arg;
0053 extern void * __percpu *hyperv_pcpu_output_arg;
0054
0055 extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
0056 extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
0057 extern bool hv_isolation_type_snp(void);
0058
0059
0060 static inline int hv_result(u64 status)
0061 {
0062 return status & HV_HYPERCALL_RESULT_MASK;
0063 }
0064
0065 static inline bool hv_result_success(u64 status)
0066 {
0067 return hv_result(status) == HV_STATUS_SUCCESS;
0068 }
0069
0070 static inline unsigned int hv_repcomp(u64 status)
0071 {
0072
0073 return (status & HV_HYPERCALL_REP_COMP_MASK) >>
0074 HV_HYPERCALL_REP_COMP_OFFSET;
0075 }
0076
0077
0078
0079
0080
0081 static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size,
0082 void *input, void *output)
0083 {
0084 u64 control = code;
0085 u64 status;
0086 u16 rep_comp;
0087
0088 control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET;
0089 control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET;
0090
0091 do {
0092 status = hv_do_hypercall(control, input, output);
0093 if (!hv_result_success(status))
0094 return status;
0095
0096 rep_comp = hv_repcomp(status);
0097
0098 control &= ~HV_HYPERCALL_REP_START_MASK;
0099 control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET;
0100
0101 touch_nmi_watchdog();
0102 } while (rep_comp < rep_count);
0103
0104 return status;
0105 }
0106
0107
0108 static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version,
0109 __u64 d_info2)
0110 {
0111 __u64 guest_id = 0;
0112
0113 guest_id = (((__u64)HV_LINUX_VENDOR_ID) << 48);
0114 guest_id |= (d_info1 << 48);
0115 guest_id |= (kernel_version << 16);
0116 guest_id |= d_info2;
0117
0118 return guest_id;
0119 }
0120
0121
0122 static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
0123 {
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 if (cmpxchg(&msg->header.message_type, old_msg_type,
0135 HVMSG_NONE) != old_msg_type)
0136 return;
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 if (msg->header.message_flags.msg_pending) {
0147
0148
0149
0150
0151
0152 hv_set_register(HV_REGISTER_EOM, 0);
0153 }
0154 }
0155
0156 void hv_setup_vmbus_handler(void (*handler)(void));
0157 void hv_remove_vmbus_handler(void);
0158 void hv_setup_stimer0_handler(void (*handler)(void));
0159 void hv_remove_stimer0_handler(void);
0160
0161 void hv_setup_kexec_handler(void (*handler)(void));
0162 void hv_remove_kexec_handler(void);
0163 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
0164 void hv_remove_crash_handler(void);
0165
0166 extern int vmbus_interrupt;
0167 extern int vmbus_irq;
0168
0169 extern bool hv_root_partition;
0170
0171 #if IS_ENABLED(CONFIG_HYPERV)
0172
0173
0174
0175
0176
0177
0178 extern u32 *hv_vp_index;
0179 extern u32 hv_max_vp_index;
0180
0181 extern u64 (*hv_read_reference_counter)(void);
0182
0183
0184 #define VP_INVAL U32_MAX
0185
0186 int __init hv_common_init(void);
0187 void __init hv_common_free(void);
0188 int hv_common_cpu_init(unsigned int cpu);
0189 int hv_common_cpu_die(unsigned int cpu);
0190
0191 void *hv_alloc_hyperv_page(void);
0192 void *hv_alloc_hyperv_zeroed_page(void);
0193 void hv_free_hyperv_page(unsigned long addr);
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 static inline int hv_cpu_number_to_vp_number(int cpu_number)
0207 {
0208 return hv_vp_index[cpu_number];
0209 }
0210
0211 static inline int __cpumask_to_vpset(struct hv_vpset *vpset,
0212 const struct cpumask *cpus,
0213 bool exclude_self)
0214 {
0215 int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
0216 int this_cpu = smp_processor_id();
0217
0218
0219 if (hv_max_vp_index / 64 >= 64)
0220 return 0;
0221
0222
0223
0224
0225
0226
0227 for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
0228 vpset->bank_contents[vcpu_bank] = 0;
0229
0230
0231
0232
0233 for_each_cpu(cpu, cpus) {
0234 if (exclude_self && cpu == this_cpu)
0235 continue;
0236 vcpu = hv_cpu_number_to_vp_number(cpu);
0237 if (vcpu == VP_INVAL)
0238 return -1;
0239 vcpu_bank = vcpu / 64;
0240 vcpu_offset = vcpu % 64;
0241 __set_bit(vcpu_offset, (unsigned long *)
0242 &vpset->bank_contents[vcpu_bank]);
0243 if (vcpu_bank >= nr_bank)
0244 nr_bank = vcpu_bank + 1;
0245 }
0246 vpset->valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
0247 return nr_bank;
0248 }
0249
0250 static inline int cpumask_to_vpset(struct hv_vpset *vpset,
0251 const struct cpumask *cpus)
0252 {
0253 return __cpumask_to_vpset(vpset, cpus, false);
0254 }
0255
0256 static inline int cpumask_to_vpset_noself(struct hv_vpset *vpset,
0257 const struct cpumask *cpus)
0258 {
0259 WARN_ON_ONCE(preemptible());
0260 return __cpumask_to_vpset(vpset, cpus, true);
0261 }
0262
0263 void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die);
0264 bool hv_is_hyperv_initialized(void);
0265 bool hv_is_hibernation_supported(void);
0266 enum hv_isolation_type hv_get_isolation_type(void);
0267 bool hv_is_isolation_supported(void);
0268 bool hv_isolation_type_snp(void);
0269 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);
0270 void hyperv_cleanup(void);
0271 bool hv_query_ext_cap(u64 cap_query);
0272 void hv_setup_dma_ops(struct device *dev, bool coherent);
0273 void *hv_map_memory(void *addr, unsigned long size);
0274 void hv_unmap_memory(void *addr);
0275 #else
0276 static inline bool hv_is_hyperv_initialized(void) { return false; }
0277 static inline bool hv_is_hibernation_supported(void) { return false; }
0278 static inline void hyperv_cleanup(void) {}
0279 static inline bool hv_is_isolation_supported(void) { return false; }
0280 static inline enum hv_isolation_type hv_get_isolation_type(void)
0281 {
0282 return HV_ISOLATION_TYPE_NONE;
0283 }
0284 #endif
0285
0286 #endif