Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'hyperv-next-signed-20240320' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv updates from Wei Liu:

- Use Hyper-V entropy to seed guest random number generator (Michael
Kelley)

- Convert to platform remove callback returning void for vmbus (Uwe
Kleine-König)

- Introduce hv_get_hypervisor_version function (Nuno Das Neves)

- Rename some HV_REGISTER_* defines for consistency (Nuno Das Neves)

- Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_* (Nuno Das
Neves)

- Cosmetic changes for hv_spinlock.c (Purna Pavan Chandra Aekkaladevi)

- Use per cpu initial stack for vtl context (Saurabh Sengar)

* tag 'hyperv-next-signed-20240320' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
x86/hyperv: Use Hyper-V entropy to seed guest random number generator
x86/hyperv: Cosmetic changes for hv_spinlock.c
hyperv-tlfs: Rename some HV_REGISTER_* defines for consistency
hv: vmbus: Convert to platform remove callback returning void
mshyperv: Introduce hv_get_hypervisor_version function
x86/hyperv: Use per cpu initial stack for vtl context
hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_*

+375 -236
+7 -7
arch/arm64/hyperv/hv_core.c
··· 160 160 return; 161 161 panic_reported = true; 162 162 163 - guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID); 163 + guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OS_ID); 164 164 165 165 /* 166 166 * Hyper-V provides the ability to store only 5 values. 167 167 * Pick the passed in error value, the guest_id, the PC, 168 168 * and the SP. 169 169 */ 170 - hv_set_vpreg(HV_REGISTER_CRASH_P0, err); 171 - hv_set_vpreg(HV_REGISTER_CRASH_P1, guest_id); 172 - hv_set_vpreg(HV_REGISTER_CRASH_P2, regs->pc); 173 - hv_set_vpreg(HV_REGISTER_CRASH_P3, regs->sp); 174 - hv_set_vpreg(HV_REGISTER_CRASH_P4, 0); 170 + hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P0, err); 171 + hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P1, guest_id); 172 + hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P2, regs->pc); 173 + hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P3, regs->sp); 174 + hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P4, 0); 175 175 176 176 /* 177 177 * Let Hyper-V know there is crash data available 178 178 */ 179 - hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY); 179 + hv_set_vpreg(HV_REGISTER_GUEST_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY); 180 180 } 181 181 EXPORT_SYMBOL_GPL(hyperv_report_panic);
+11 -11
arch/arm64/hyperv/mshyperv.c
··· 19 19 20 20 static bool hyperv_initialized; 21 21 22 + int hv_get_hypervisor_version(union hv_hypervisor_version_info *info) 23 + { 24 + hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, 25 + (struct hv_get_vp_registers_output *)info); 26 + 27 + return 0; 28 + } 29 + 22 30 static int __init hyperv_init(void) 23 31 { 24 32 struct hv_get_vp_registers_output result; 25 - u32 a, b, c, d; 26 33 u64 guest_id; 27 34 int ret; 28 35 ··· 46 39 47 40 /* Setup the guest ID */ 48 41 guest_id = hv_generate_guest_id(LINUX_VERSION_CODE); 49 - hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id); 42 + hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id); 50 43 51 44 /* Get the features and hints from Hyper-V */ 52 45 hv_get_vpreg_128(HV_REGISTER_FEATURES, &result); ··· 61 54 ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints, 62 55 ms_hyperv.misc_features); 63 56 64 - /* Get information about the Hyper-V host version */ 65 - hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result); 66 - a = result.as32.a; 67 - b = result.as32.b; 68 - c = result.as32.c; 69 - d = result.as32.d; 70 - pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n", 71 - b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24); 72 - 73 57 ret = hv_common_init(); 74 58 if (ret) 75 59 return ret; ··· 71 73 hv_common_free(); 72 74 return ret; 73 75 } 76 + 77 + ms_hyperv_late_init(); 74 78 75 79 hyperv_initialized = true; 76 80 return 0;
+19 -26
arch/arm64/include/asm/hyperv-tlfs.h
··· 22 22 */ 23 23 24 24 /* 25 - * These Hyper-V registers provide information equivalent to the CPUID 26 - * instruction on x86/x64. 27 - */ 28 - #define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */ 29 - #define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */ 30 - #define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */ 31 - 32 - /* 33 25 * Group C Features. See the asm-generic version of hyperv-tlfs.h 34 26 * for a description of Feature Groups. 35 27 */ ··· 33 41 #define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13) 34 42 35 43 /* 36 - * Synthetic register definitions equivalent to MSRs on x86/x64 44 + * To support arch-generic code calling hv_set/get_register: 45 + * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl 46 + * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall 37 47 */ 38 - #define HV_REGISTER_CRASH_P0 0x00000210 39 - #define HV_REGISTER_CRASH_P1 0x00000211 40 - #define HV_REGISTER_CRASH_P2 0x00000212 41 - #define HV_REGISTER_CRASH_P3 0x00000213 42 - #define HV_REGISTER_CRASH_P4 0x00000214 43 - #define HV_REGISTER_CRASH_CTL 0x00000215 48 + #define HV_MSR_CRASH_P0 (HV_REGISTER_GUEST_CRASH_P0) 49 + #define HV_MSR_CRASH_P1 (HV_REGISTER_GUEST_CRASH_P1) 50 + #define HV_MSR_CRASH_P2 (HV_REGISTER_GUEST_CRASH_P2) 51 + #define HV_MSR_CRASH_P3 (HV_REGISTER_GUEST_CRASH_P3) 52 + #define HV_MSR_CRASH_P4 (HV_REGISTER_GUEST_CRASH_P4) 53 + #define HV_MSR_CRASH_CTL (HV_REGISTER_GUEST_CRASH_CTL) 44 54 45 - #define HV_REGISTER_GUEST_OSID 0x00090002 46 - #define HV_REGISTER_VP_INDEX 0x00090003 47 - #define HV_REGISTER_TIME_REF_COUNT 0x00090004 48 - #define HV_REGISTER_REFERENCE_TSC 0x00090017 55 + #define HV_MSR_VP_INDEX (HV_REGISTER_VP_INDEX) 56 + #define HV_MSR_TIME_REF_COUNT (HV_REGISTER_TIME_REF_COUNT) 57 + #define HV_MSR_REFERENCE_TSC (HV_REGISTER_REFERENCE_TSC) 49 58 50 - #define HV_REGISTER_SINT0 0x000A0000 51 - #define HV_REGISTER_SCONTROL 0x000A0010 52 - #define HV_REGISTER_SIEFP 0x000A0012 53 - #define HV_REGISTER_SIMP 0x000A0013 54 - #define HV_REGISTER_EOM 0x000A0014 59 + #define HV_MSR_SINT0 (HV_REGISTER_SINT0) 60 + #define HV_MSR_SCONTROL (HV_REGISTER_SCONTROL) 61 + #define HV_MSR_SIEFP (HV_REGISTER_SIEFP) 62 + #define HV_MSR_SIMP (HV_REGISTER_SIMP) 63 + #define HV_MSR_EOM (HV_REGISTER_EOM) 55 64 56 - #define HV_REGISTER_STIMER0_CONFIG 0x000B0000 57 - #define HV_REGISTER_STIMER0_COUNT 0x000B0001 65 + #define HV_MSR_STIMER0_CONFIG (HV_REGISTER_STIMER0_CONFIG) 66 + #define HV_MSR_STIMER0_COUNT (HV_REGISTER_STIMER0_COUNT) 58 67 59 68 union hv_msi_entry { 60 69 u64 as_uint64[2];
+2 -2
arch/arm64/include/asm/mshyperv.h
··· 31 31 u64 hv_get_vpreg(u32 reg); 32 32 void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result); 33 33 34 - static inline void hv_set_register(unsigned int reg, u64 value) 34 + static inline void hv_set_msr(unsigned int reg, u64 value) 35 35 { 36 36 hv_set_vpreg(reg, value); 37 37 } 38 38 39 - static inline u64 hv_get_register(unsigned int reg) 39 + static inline u64 hv_get_msr(unsigned int reg) 40 40 { 41 41 return hv_get_vpreg(reg); 42 42 }
+4 -4
arch/x86/hyperv/hv_init.c
··· 667 667 hv_hypercall_pg = NULL; 668 668 669 669 /* Reset the hypercall page */ 670 - hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL); 670 + hypercall_msr.as_uint64 = hv_get_msr(HV_X64_MSR_HYPERCALL); 671 671 hypercall_msr.enable = 0; 672 - hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); 672 + hv_set_msr(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); 673 673 674 674 /* Reset the TSC page */ 675 - tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC); 675 + tsc_msr.as_uint64 = hv_get_msr(HV_X64_MSR_REFERENCE_TSC); 676 676 tsc_msr.enable = 0; 677 - hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); 677 + hv_set_msr(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); 678 678 } 679 679 680 680 void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
+2 -1
arch/x86/hyperv/hv_spinlock.c
··· 16 16 #include <asm/paravirt.h> 17 17 #include <asm/apic.h> 18 18 19 - static bool __initdata hv_pvspin = true; 19 + static bool hv_pvspin __initdata = true; 20 20 21 21 static void hv_qlock_kick(int cpu) 22 22 { ··· 64 64 { 65 65 return false; 66 66 } 67 + 67 68 PV_CALLEE_SAVE_REGS_THUNK(hv_vcpu_is_preempted); 68 69 69 70 void __init hv_init_spinlocks(void)
+15 -4
arch/x86/hyperv/hv_vtl.c
··· 12 12 #include <asm/i8259.h> 13 13 #include <asm/mshyperv.h> 14 14 #include <asm/realmode.h> 15 + #include <../kernel/smpboot.h> 15 16 16 17 extern struct boot_params boot_params; 17 18 static struct real_mode_header hv_vtl_real_mode_header; ··· 66 65 ((secondary_startup_64_fn)secondary_startup_64)(&boot_params, &boot_params); 67 66 } 68 67 69 - static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored) 68 + static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) 70 69 { 71 70 u64 status; 72 71 int ret = 0; ··· 80 79 struct ldttss_desc *ldt; 81 80 struct desc_struct *gdt; 82 81 83 - u64 rsp = current->thread.sp; 82 + struct task_struct *idle = idle_thread_get(cpu); 83 + u64 rsp = (unsigned long)idle->thread.sp; 84 + 84 85 u64 rip = (u64)&hv_vtl_ap_entry; 85 86 86 87 native_store_gdt(&gdt_ptr); ··· 209 206 210 207 static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip) 211 208 { 212 - int vp_id; 209 + int vp_id, cpu; 210 + 211 + /* Find the logical CPU for the APIC ID */ 212 + for_each_present_cpu(cpu) { 213 + if (arch_match_cpu_phys_id(cpu, apicid)) 214 + break; 215 + } 216 + if (cpu >= nr_cpu_ids) 217 + return -EINVAL; 213 218 214 219 pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid); 215 220 vp_id = hv_vtl_apicid_to_vp_id(apicid); ··· 231 220 return -EINVAL; 232 221 } 233 222 234 - return hv_vtl_bringup_vcpu(vp_id, start_eip); 223 + return hv_vtl_bringup_vcpu(vp_id, cpu, start_eip); 235 224 } 236 225 237 226 int __init hv_vtl_early_init(void)
+76 -69
arch/x86/include/asm/hyperv-tlfs.h
··· 182 182 #define HV_X64_MSR_HYPERCALL 0x40000001 183 183 184 184 /* MSR used to provide vcpu index */ 185 - #define HV_REGISTER_VP_INDEX 0x40000002 185 + #define HV_X64_MSR_VP_INDEX 0x40000002 186 186 187 187 /* MSR used to reset the guest OS. */ 188 188 #define HV_X64_MSR_RESET 0x40000003 ··· 191 191 #define HV_X64_MSR_VP_RUNTIME 0x40000010 192 192 193 193 /* MSR used to read the per-partition time reference counter */ 194 - #define HV_REGISTER_TIME_REF_COUNT 0x40000020 194 + #define HV_X64_MSR_TIME_REF_COUNT 0x40000020 195 195 196 196 /* A partition's reference time stamp counter (TSC) page */ 197 - #define HV_REGISTER_REFERENCE_TSC 0x40000021 197 + #define HV_X64_MSR_REFERENCE_TSC 0x40000021 198 198 199 199 /* MSR used to retrieve the TSC frequency */ 200 200 #define HV_X64_MSR_TSC_FREQUENCY 0x40000022 ··· 209 209 #define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073 210 210 211 211 /* Define synthetic interrupt controller model specific registers. */ 212 - #define HV_REGISTER_SCONTROL 0x40000080 213 - #define HV_REGISTER_SVERSION 0x40000081 214 - #define HV_REGISTER_SIEFP 0x40000082 215 - #define HV_REGISTER_SIMP 0x40000083 216 - #define HV_REGISTER_EOM 0x40000084 217 - #define HV_REGISTER_SINT0 0x40000090 218 - #define HV_REGISTER_SINT1 0x40000091 219 - #define HV_REGISTER_SINT2 0x40000092 220 - #define HV_REGISTER_SINT3 0x40000093 221 - #define HV_REGISTER_SINT4 0x40000094 222 - #define HV_REGISTER_SINT5 0x40000095 223 - #define HV_REGISTER_SINT6 0x40000096 224 - #define HV_REGISTER_SINT7 0x40000097 225 - #define HV_REGISTER_SINT8 0x40000098 226 - #define HV_REGISTER_SINT9 0x40000099 227 - #define HV_REGISTER_SINT10 0x4000009A 228 - #define HV_REGISTER_SINT11 0x4000009B 229 - #define HV_REGISTER_SINT12 0x4000009C 230 - #define HV_REGISTER_SINT13 0x4000009D 231 - #define HV_REGISTER_SINT14 0x4000009E 232 - #define HV_REGISTER_SINT15 0x4000009F 212 + #define HV_X64_MSR_SCONTROL 0x40000080 213 + #define HV_X64_MSR_SVERSION 0x40000081 214 + #define HV_X64_MSR_SIEFP 0x40000082 215 + #define HV_X64_MSR_SIMP 0x40000083 216 + #define HV_X64_MSR_EOM 0x40000084 217 + #define HV_X64_MSR_SINT0 0x40000090 218 + #define HV_X64_MSR_SINT1 0x40000091 219 + #define HV_X64_MSR_SINT2 0x40000092 220 + #define HV_X64_MSR_SINT3 0x40000093 221 + #define HV_X64_MSR_SINT4 0x40000094 222 + #define HV_X64_MSR_SINT5 0x40000095 223 + #define HV_X64_MSR_SINT6 0x40000096 224 + #define HV_X64_MSR_SINT7 0x40000097 225 + #define HV_X64_MSR_SINT8 0x40000098 226 + #define HV_X64_MSR_SINT9 0x40000099 227 + #define HV_X64_MSR_SINT10 0x4000009A 228 + #define HV_X64_MSR_SINT11 0x4000009B 229 + #define HV_X64_MSR_SINT12 0x4000009C 230 + #define HV_X64_MSR_SINT13 0x4000009D 231 + #define HV_X64_MSR_SINT14 0x4000009E 232 + #define HV_X64_MSR_SINT15 0x4000009F 233 233 234 234 /* 235 235 * Define synthetic interrupt controller model specific registers for 236 236 * nested hypervisor. 237 237 */ 238 - #define HV_REGISTER_NESTED_SCONTROL 0x40001080 239 - #define HV_REGISTER_NESTED_SVERSION 0x40001081 240 - #define HV_REGISTER_NESTED_SIEFP 0x40001082 241 - #define HV_REGISTER_NESTED_SIMP 0x40001083 242 - #define HV_REGISTER_NESTED_EOM 0x40001084 243 - #define HV_REGISTER_NESTED_SINT0 0x40001090 238 + #define HV_X64_MSR_NESTED_SCONTROL 0x40001080 239 + #define HV_X64_MSR_NESTED_SVERSION 0x40001081 240 + #define HV_X64_MSR_NESTED_SIEFP 0x40001082 241 + #define HV_X64_MSR_NESTED_SIMP 0x40001083 242 + #define HV_X64_MSR_NESTED_EOM 0x40001084 243 + #define HV_X64_MSR_NESTED_SINT0 0x40001090 244 244 245 245 /* 246 246 * Synthetic Timer MSRs. Four timers per vcpu. 247 247 */ 248 - #define HV_REGISTER_STIMER0_CONFIG 0x400000B0 249 - #define HV_REGISTER_STIMER0_COUNT 0x400000B1 250 - #define HV_REGISTER_STIMER1_CONFIG 0x400000B2 251 - #define HV_REGISTER_STIMER1_COUNT 0x400000B3 252 - #define HV_REGISTER_STIMER2_CONFIG 0x400000B4 253 - #define HV_REGISTER_STIMER2_COUNT 0x400000B5 254 - #define HV_REGISTER_STIMER3_CONFIG 0x400000B6 255 - #define HV_REGISTER_STIMER3_COUNT 0x400000B7 248 + #define HV_X64_MSR_STIMER0_CONFIG 0x400000B0 249 + #define HV_X64_MSR_STIMER0_COUNT 0x400000B1 250 + #define HV_X64_MSR_STIMER1_CONFIG 0x400000B2 251 + #define HV_X64_MSR_STIMER1_COUNT 0x400000B3 252 + #define HV_X64_MSR_STIMER2_CONFIG 0x400000B4 253 + #define HV_X64_MSR_STIMER2_COUNT 0x400000B5 254 + #define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 255 + #define HV_X64_MSR_STIMER3_COUNT 0x400000B7 256 256 257 257 /* Hyper-V guest idle MSR */ 258 258 #define HV_X64_MSR_GUEST_IDLE 0x400000F0 259 259 260 260 /* Hyper-V guest crash notification MSR's */ 261 - #define HV_REGISTER_CRASH_P0 0x40000100 262 - #define HV_REGISTER_CRASH_P1 0x40000101 263 - #define HV_REGISTER_CRASH_P2 0x40000102 264 - #define HV_REGISTER_CRASH_P3 0x40000103 265 - #define HV_REGISTER_CRASH_P4 0x40000104 266 - #define HV_REGISTER_CRASH_CTL 0x40000105 261 + #define HV_X64_MSR_CRASH_P0 0x40000100 262 + #define HV_X64_MSR_CRASH_P1 0x40000101 263 + #define HV_X64_MSR_CRASH_P2 0x40000102 264 + #define HV_X64_MSR_CRASH_P3 0x40000103 265 + #define HV_X64_MSR_CRASH_P4 0x40000104 266 + #define HV_X64_MSR_CRASH_CTL 0x40000105 267 267 268 268 /* TSC emulation after migration */ 269 269 #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 ··· 276 276 /* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */ 277 277 #define HV_EXPOSE_INVARIANT_TSC BIT_ULL(0) 278 278 279 - /* Register name aliases for temporary compatibility */ 280 - #define HV_X64_MSR_STIMER0_COUNT HV_REGISTER_STIMER0_COUNT 281 - #define HV_X64_MSR_STIMER0_CONFIG HV_REGISTER_STIMER0_CONFIG 282 - #define HV_X64_MSR_STIMER1_COUNT HV_REGISTER_STIMER1_COUNT 283 - #define HV_X64_MSR_STIMER1_CONFIG HV_REGISTER_STIMER1_CONFIG 284 - #define HV_X64_MSR_STIMER2_COUNT HV_REGISTER_STIMER2_COUNT 285 - #define HV_X64_MSR_STIMER2_CONFIG HV_REGISTER_STIMER2_CONFIG 286 - #define HV_X64_MSR_STIMER3_COUNT HV_REGISTER_STIMER3_COUNT 287 - #define HV_X64_MSR_STIMER3_CONFIG HV_REGISTER_STIMER3_CONFIG 288 - #define HV_X64_MSR_SCONTROL HV_REGISTER_SCONTROL 289 - #define HV_X64_MSR_SVERSION HV_REGISTER_SVERSION 290 - #define HV_X64_MSR_SIMP HV_REGISTER_SIMP 291 - #define HV_X64_MSR_SIEFP HV_REGISTER_SIEFP 292 - #define HV_X64_MSR_VP_INDEX HV_REGISTER_VP_INDEX 293 - #define HV_X64_MSR_EOM HV_REGISTER_EOM 294 - #define HV_X64_MSR_SINT0 HV_REGISTER_SINT0 295 - #define HV_X64_MSR_SINT15 HV_REGISTER_SINT15 296 - #define HV_X64_MSR_CRASH_P0 HV_REGISTER_CRASH_P0 297 - #define HV_X64_MSR_CRASH_P1 HV_REGISTER_CRASH_P1 298 - #define HV_X64_MSR_CRASH_P2 HV_REGISTER_CRASH_P2 299 - #define HV_X64_MSR_CRASH_P3 HV_REGISTER_CRASH_P3 300 - #define HV_X64_MSR_CRASH_P4 HV_REGISTER_CRASH_P4 301 - #define HV_X64_MSR_CRASH_CTL HV_REGISTER_CRASH_CTL 302 - #define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT 303 - #define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC 279 + /* 280 + * To support arch-generic code calling hv_set/get_register: 281 + * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl 282 + * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall 283 + */ 284 + #define HV_MSR_CRASH_P0 (HV_X64_MSR_CRASH_P0) 285 + #define HV_MSR_CRASH_P1 (HV_X64_MSR_CRASH_P1) 286 + #define HV_MSR_CRASH_P2 (HV_X64_MSR_CRASH_P2) 287 + #define HV_MSR_CRASH_P3 (HV_X64_MSR_CRASH_P3) 288 + #define HV_MSR_CRASH_P4 (HV_X64_MSR_CRASH_P4) 289 + #define HV_MSR_CRASH_CTL (HV_X64_MSR_CRASH_CTL) 290 + 291 + #define HV_MSR_VP_INDEX (HV_X64_MSR_VP_INDEX) 292 + #define HV_MSR_TIME_REF_COUNT (HV_X64_MSR_TIME_REF_COUNT) 293 + #define HV_MSR_REFERENCE_TSC (HV_X64_MSR_REFERENCE_TSC) 294 + 295 + #define HV_MSR_SINT0 (HV_X64_MSR_SINT0) 296 + #define HV_MSR_SVERSION (HV_X64_MSR_SVERSION) 297 + #define HV_MSR_SCONTROL (HV_X64_MSR_SCONTROL) 298 + #define HV_MSR_SIEFP (HV_X64_MSR_SIEFP) 299 + #define HV_MSR_SIMP (HV_X64_MSR_SIMP) 300 + #define HV_MSR_EOM (HV_X64_MSR_EOM) 301 + 302 + #define HV_MSR_NESTED_SCONTROL (HV_X64_MSR_NESTED_SCONTROL) 303 + #define HV_MSR_NESTED_SVERSION (HV_X64_MSR_NESTED_SVERSION) 304 + #define HV_MSR_NESTED_SIEFP (HV_X64_MSR_NESTED_SIEFP) 305 + #define HV_MSR_NESTED_SIMP (HV_X64_MSR_NESTED_SIMP) 306 + #define HV_MSR_NESTED_EOM (HV_X64_MSR_NESTED_EOM) 307 + #define HV_MSR_NESTED_SINT0 (HV_X64_MSR_NESTED_SINT0) 308 + 309 + #define HV_MSR_STIMER0_CONFIG (HV_X64_MSR_STIMER0_CONFIG) 310 + #define HV_MSR_STIMER0_COUNT (HV_X64_MSR_STIMER0_COUNT) 304 311 305 312 /* 306 313 * Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and
+15 -15
arch/x86/include/asm/mshyperv.h
··· 293 293 static inline void hv_ivm_msr_read(u64 msr, u64 *value) {} 294 294 #endif 295 295 296 - static inline bool hv_is_synic_reg(unsigned int reg) 296 + static inline bool hv_is_synic_msr(unsigned int reg) 297 297 { 298 - return (reg >= HV_REGISTER_SCONTROL) && 299 - (reg <= HV_REGISTER_SINT15); 298 + return (reg >= HV_X64_MSR_SCONTROL) && 299 + (reg <= HV_X64_MSR_SINT15); 300 300 } 301 301 302 - static inline bool hv_is_sint_reg(unsigned int reg) 302 + static inline bool hv_is_sint_msr(unsigned int reg) 303 303 { 304 - return (reg >= HV_REGISTER_SINT0) && 305 - (reg <= HV_REGISTER_SINT15); 304 + return (reg >= HV_X64_MSR_SINT0) && 305 + (reg <= HV_X64_MSR_SINT15); 306 306 } 307 307 308 - u64 hv_get_register(unsigned int reg); 309 - void hv_set_register(unsigned int reg, u64 value); 310 - u64 hv_get_non_nested_register(unsigned int reg); 311 - void hv_set_non_nested_register(unsigned int reg, u64 value); 308 + u64 hv_get_msr(unsigned int reg); 309 + void hv_set_msr(unsigned int reg, u64 value); 310 + u64 hv_get_non_nested_msr(unsigned int reg); 311 + void hv_set_non_nested_msr(unsigned int reg, u64 value); 312 312 313 - static __always_inline u64 hv_raw_get_register(unsigned int reg) 313 + static __always_inline u64 hv_raw_get_msr(unsigned int reg) 314 314 { 315 315 return __rdmsr(reg); 316 316 } ··· 331 331 { 332 332 return -1; 333 333 } 334 - static inline void hv_set_register(unsigned int reg, u64 value) { } 335 - static inline u64 hv_get_register(unsigned int reg) { return 0; } 336 - static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { } 337 - static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; } 334 + static inline void hv_set_msr(unsigned int reg, u64 value) { } 335 + static inline u64 hv_get_msr(unsigned int reg) { return 0; } 336 + static inline void hv_set_non_nested_msr(unsigned int reg, u64 value) { } 337 + static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; } 338 338 #endif /* CONFIG_HYPERV */ 339 339 340 340
+45 -48
arch/x86/kernel/cpu/mshyperv.c
··· 45 45 EXPORT_SYMBOL_GPL(hyperv_paravisor_present); 46 46 47 47 #if IS_ENABLED(CONFIG_HYPERV) 48 - static inline unsigned int hv_get_nested_reg(unsigned int reg) 48 + static inline unsigned int hv_get_nested_msr(unsigned int reg) 49 49 { 50 - if (hv_is_sint_reg(reg)) 51 - return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0; 50 + if (hv_is_sint_msr(reg)) 51 + return reg - HV_X64_MSR_SINT0 + HV_X64_MSR_NESTED_SINT0; 52 52 53 53 switch (reg) { 54 - case HV_REGISTER_SIMP: 55 - return HV_REGISTER_NESTED_SIMP; 56 - case HV_REGISTER_SIEFP: 57 - return HV_REGISTER_NESTED_SIEFP; 58 - case HV_REGISTER_SVERSION: 59 - return HV_REGISTER_NESTED_SVERSION; 60 - case HV_REGISTER_SCONTROL: 61 - return HV_REGISTER_NESTED_SCONTROL; 62 - case HV_REGISTER_EOM: 63 - return HV_REGISTER_NESTED_EOM; 54 + case HV_X64_MSR_SIMP: 55 + return HV_X64_MSR_NESTED_SIMP; 56 + case HV_X64_MSR_SIEFP: 57 + return HV_X64_MSR_NESTED_SIEFP; 58 + case HV_X64_MSR_SVERSION: 59 + return HV_X64_MSR_NESTED_SVERSION; 60 + case HV_X64_MSR_SCONTROL: 61 + return HV_X64_MSR_NESTED_SCONTROL; 62 + case HV_X64_MSR_EOM: 63 + return HV_X64_MSR_NESTED_EOM; 64 64 default: 65 65 return reg; 66 66 } 67 67 } 68 68 69 - u64 hv_get_non_nested_register(unsigned int reg) 69 + u64 hv_get_non_nested_msr(unsigned int reg) 70 70 { 71 71 u64 value; 72 72 73 - if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) 73 + if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) 74 74 hv_ivm_msr_read(reg, &value); 75 75 else 76 76 rdmsrl(reg, value); 77 77 return value; 78 78 } 79 - EXPORT_SYMBOL_GPL(hv_get_non_nested_register); 79 + EXPORT_SYMBOL_GPL(hv_get_non_nested_msr); 80 80 81 - void hv_set_non_nested_register(unsigned int reg, u64 value) 81 + void hv_set_non_nested_msr(unsigned int reg, u64 value) 82 82 { 83 - if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) { 83 + if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) { 84 84 hv_ivm_msr_write(reg, value); 85 85 86 86 /* Write proxy bit via wrmsl instruction */ 87 - if (hv_is_sint_reg(reg)) 87 + if (hv_is_sint_msr(reg)) 88 88 wrmsrl(reg, value | 1 << 20); 89 89 } else { 90 90 wrmsrl(reg, value); 91 91 } 92 92 } 93 - EXPORT_SYMBOL_GPL(hv_set_non_nested_register); 93 + EXPORT_SYMBOL_GPL(hv_set_non_nested_msr); 94 94 95 - u64 hv_get_register(unsigned int reg) 95 + u64 hv_get_msr(unsigned int reg) 96 96 { 97 97 if (hv_nested) 98 - reg = hv_get_nested_reg(reg); 98 + reg = hv_get_nested_msr(reg); 99 99 100 - return hv_get_non_nested_register(reg); 100 + return hv_get_non_nested_msr(reg); 101 101 } 102 - EXPORT_SYMBOL_GPL(hv_get_register); 102 + EXPORT_SYMBOL_GPL(hv_get_msr); 103 103 104 - void hv_set_register(unsigned int reg, u64 value) 104 + void hv_set_msr(unsigned int reg, u64 value) 105 105 { 106 106 if (hv_nested) 107 - reg = hv_get_nested_reg(reg); 107 + reg = hv_get_nested_msr(reg); 108 108 109 - hv_set_non_nested_register(reg, value); 109 + hv_set_non_nested_msr(reg, value); 110 110 } 111 - EXPORT_SYMBOL_GPL(hv_set_register); 111 + EXPORT_SYMBOL_GPL(hv_set_msr); 112 112 113 113 static void (*vmbus_handler)(void); 114 114 static void (*hv_stimer0_handler)(void); ··· 352 352 x86_init.irqs.pre_vector_init = x86_init_noop; 353 353 } 354 354 355 + int hv_get_hypervisor_version(union hv_hypervisor_version_info *info) 356 + { 357 + unsigned int hv_max_functions; 358 + 359 + hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS); 360 + if (hv_max_functions < HYPERV_CPUID_VERSION) { 361 + pr_err("%s: Could not detect Hyper-V version\n", __func__); 362 + return -ENODEV; 363 + } 364 + 365 + cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, &info->edx); 366 + 367 + return 0; 368 + } 369 + 355 370 static void __init ms_hyperv_init_platform(void) 356 371 { 357 372 int hv_max_functions_eax; 358 - int hv_host_info_eax; 359 - int hv_host_info_ebx; 360 - int hv_host_info_ecx; 361 - int hv_host_info_edx; 362 373 363 374 #ifdef CONFIG_PARAVIRT 364 375 pv_info.name = "Hyper-V"; ··· 420 409 pr_info("Hyper-V: running on a nested hypervisor\n"); 421 410 } 422 411 423 - /* 424 - * Extract host information. 425 - */ 426 - if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) { 427 - hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION); 428 - hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION); 429 - hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION); 430 - hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION); 431 - 432 - pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n", 433 - hv_host_info_ebx >> 16, hv_host_info_ebx & 0xFFFF, 434 - hv_host_info_eax, hv_host_info_edx & 0xFFFFFF, 435 - hv_host_info_ecx, hv_host_info_edx >> 24); 436 - } 437 - 438 412 if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && 439 413 ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { 440 414 x86_platform.calibrate_tsc = hv_get_tsc_khz; ··· 452 456 /* To be supported: more work is required. */ 453 457 ms_hyperv.features &= ~HV_MSR_REFERENCE_TSC_AVAILABLE; 454 458 455 - /* HV_REGISTER_CRASH_CTL is unsupported. */ 459 + /* HV_MSR_CRASH_CTL is unsupported. */ 456 460 ms_hyperv.misc_features &= ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE; 457 461 458 462 /* Don't trust Hyper-V's TLB-flushing hypercalls. */ ··· 644 648 .init.x2apic_available = ms_hyperv_x2apic_available, 645 649 .init.msi_ext_dest_id = ms_hyperv_msi_ext_dest_id, 646 650 .init.init_platform = ms_hyperv_init_platform, 651 + .init.guest_late_init = ms_hyperv_late_init, 647 652 #ifdef CONFIG_AMD_MEM_ENCRYPT 648 653 .runtime.sev_es_hcall_prepare = hv_sev_es_hcall_prepare, 649 654 .runtime.sev_es_hcall_finish = hv_sev_es_hcall_finish,
+13 -13
drivers/clocksource/hyperv_timer.c
··· 81 81 82 82 current_tick = hv_read_reference_counter(); 83 83 current_tick += delta; 84 - hv_set_register(HV_REGISTER_STIMER0_COUNT, current_tick); 84 + hv_set_msr(HV_MSR_STIMER0_COUNT, current_tick); 85 85 return 0; 86 86 } 87 87 88 88 static int hv_ce_shutdown(struct clock_event_device *evt) 89 89 { 90 - hv_set_register(HV_REGISTER_STIMER0_COUNT, 0); 91 - hv_set_register(HV_REGISTER_STIMER0_CONFIG, 0); 90 + hv_set_msr(HV_MSR_STIMER0_COUNT, 0); 91 + hv_set_msr(HV_MSR_STIMER0_CONFIG, 0); 92 92 if (direct_mode_enabled && stimer0_irq >= 0) 93 93 disable_percpu_irq(stimer0_irq); 94 94 ··· 119 119 timer_cfg.direct_mode = 0; 120 120 timer_cfg.sintx = stimer0_message_sint; 121 121 } 122 - hv_set_register(HV_REGISTER_STIMER0_CONFIG, timer_cfg.as_uint64); 122 + hv_set_msr(HV_MSR_STIMER0_CONFIG, timer_cfg.as_uint64); 123 123 return 0; 124 124 } 125 125 ··· 372 372 * is set to 0 when the partition is created and is incremented in 100 373 373 * nanosecond units. 374 374 * 375 - * Use hv_raw_get_register() because this function is used from 376 - * noinstr. Notable; while HV_REGISTER_TIME_REF_COUNT is a synthetic 375 + * Use hv_raw_get_msr() because this function is used from 376 + * noinstr. Notable; while HV_MSR_TIME_REF_COUNT is a synthetic 377 377 * register it doesn't need the GHCB path. 378 378 */ 379 - return hv_raw_get_register(HV_REGISTER_TIME_REF_COUNT); 379 + return hv_raw_get_msr(HV_MSR_TIME_REF_COUNT); 380 380 } 381 381 382 382 /* ··· 439 439 union hv_reference_tsc_msr tsc_msr; 440 440 441 441 /* Disable the TSC page */ 442 - tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); 442 + tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC); 443 443 tsc_msr.enable = 0; 444 - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); 444 + hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64); 445 445 } 446 446 447 447 ··· 450 450 union hv_reference_tsc_msr tsc_msr; 451 451 452 452 /* Re-enable the TSC page */ 453 - tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); 453 + tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC); 454 454 tsc_msr.enable = 1; 455 455 tsc_msr.pfn = tsc_pfn; 456 - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); 456 + hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64); 457 457 } 458 458 459 459 #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK ··· 555 555 * thus TSC clocksource will work even without the real TSC page 556 556 * mapped. 557 557 */ 558 - tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); 558 + tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC); 559 559 if (hv_root_partition) 560 560 tsc_pfn = tsc_msr.pfn; 561 561 else 562 562 tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page)); 563 563 tsc_msr.enable = 1; 564 564 tsc_msr.pfn = tsc_pfn; 565 - hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); 565 + hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64); 566 566 567 567 clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100); 568 568
+1
drivers/hv/Kconfig
··· 16 16 config HYPERV_VTL_MODE 17 17 bool "Enable Linux to boot in VTL context" 18 18 depends on X86_64 && HYPERV 19 + depends on SMP 19 20 default n 20 21 help 21 22 Virtual Secure Mode (VSM) is a set of hypervisor capabilities and
+16 -20
drivers/hv/hv.c
··· 270 270 union hv_synic_scontrol sctrl; 271 271 272 272 /* Setup the Synic's message page */ 273 - simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP); 273 + simp.as_uint64 = hv_get_msr(HV_MSR_SIMP); 274 274 simp.simp_enabled = 1; 275 275 276 276 if (ms_hyperv.paravisor_present || hv_root_partition) { ··· 286 286 >> HV_HYP_PAGE_SHIFT; 287 287 } 288 288 289 - hv_set_register(HV_REGISTER_SIMP, simp.as_uint64); 289 + hv_set_msr(HV_MSR_SIMP, simp.as_uint64); 290 290 291 291 /* Setup the Synic's event page */ 292 - siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP); 292 + siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP); 293 293 siefp.siefp_enabled = 1; 294 294 295 295 if (ms_hyperv.paravisor_present || hv_root_partition) { ··· 305 305 >> HV_HYP_PAGE_SHIFT; 306 306 } 307 307 308 - hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64); 308 + hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64); 309 309 310 310 /* Setup the shared SINT. */ 311 311 if (vmbus_irq != -1) 312 312 enable_percpu_irq(vmbus_irq, 0); 313 - shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 + 314 - VMBUS_MESSAGE_SINT); 313 + shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT); 315 314 316 315 shared_sint.vector = vmbus_interrupt; 317 316 shared_sint.masked = false; ··· 325 326 #else 326 327 shared_sint.auto_eoi = 0; 327 328 #endif 328 - hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT, 329 - shared_sint.as_uint64); 329 + hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); 330 330 331 331 /* Enable the global synic bit */ 332 - sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL); 332 + sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL); 333 333 sctrl.enable = 1; 334 334 335 - hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64); 335 + hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64); 336 336 } 337 337 338 338 int hv_synic_init(unsigned int cpu) ··· 355 357 union hv_synic_siefp siefp; 356 358 union hv_synic_scontrol sctrl; 357 359 358 - shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 + 359 - VMBUS_MESSAGE_SINT); 360 + shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT); 360 361 361 362 shared_sint.masked = 1; 362 363 363 364 /* Need to correctly cleanup in the case of SMP!!! */ 364 365 /* Disable the interrupt */ 365 - hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT, 366 - shared_sint.as_uint64); 366 + hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); 367 367 368 - simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP); 368 + simp.as_uint64 = hv_get_msr(HV_MSR_SIMP); 369 369 /* 370 370 * In Isolation VM, sim and sief pages are allocated by 371 371 * paravisor. These pages also will be used by kdump ··· 378 382 simp.base_simp_gpa = 0; 379 383 } 380 384 381 - hv_set_register(HV_REGISTER_SIMP, simp.as_uint64); 385 + hv_set_msr(HV_MSR_SIMP, simp.as_uint64); 382 386 383 - siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP); 387 + siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP); 384 388 siefp.siefp_enabled = 0; 385 389 386 390 if (ms_hyperv.paravisor_present || hv_root_partition) { ··· 390 394 siefp.base_siefp_gpa = 0; 391 395 } 392 396 393 - hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64); 397 + hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64); 394 398 395 399 /* Disable the global synic bit */ 396 - sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL); 400 + sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL); 397 401 sctrl.enable = 0; 398 - hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64); 402 + hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64); 399 403 400 404 if (vmbus_irq != -1) 401 405 disable_percpu_irq(vmbus_irq);
+88 -11
drivers/hv/hv_common.c
··· 20 20 #include <linux/sched/task_stack.h> 21 21 #include <linux/panic_notifier.h> 22 22 #include <linux/ptrace.h> 23 + #include <linux/random.h> 24 + #include <linux/efi.h> 23 25 #include <linux/kdebug.h> 24 26 #include <linux/kmsg_dump.h> 27 + #include <linux/sizes.h> 25 28 #include <linux/slab.h> 26 29 #include <linux/dma-map-ops.h> 27 30 #include <linux/set_memory.h> ··· 230 227 * contain the size of the panic data in that page. Rest of the 231 228 * registers are no-op when the NOTIFY_MSG flag is set. 232 229 */ 233 - hv_set_register(HV_REGISTER_CRASH_P0, 0); 234 - hv_set_register(HV_REGISTER_CRASH_P1, 0); 235 - hv_set_register(HV_REGISTER_CRASH_P2, 0); 236 - hv_set_register(HV_REGISTER_CRASH_P3, virt_to_phys(hv_panic_page)); 237 - hv_set_register(HV_REGISTER_CRASH_P4, bytes_written); 230 + hv_set_msr(HV_MSR_CRASH_P0, 0); 231 + hv_set_msr(HV_MSR_CRASH_P1, 0); 232 + hv_set_msr(HV_MSR_CRASH_P2, 0); 233 + hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page)); 234 + hv_set_msr(HV_MSR_CRASH_P4, bytes_written); 238 235 239 236 /* 240 237 * Let Hyper-V know there is crash data available along with 241 238 * the panic message. 242 239 */ 243 - hv_set_register(HV_REGISTER_CRASH_CTL, 244 - (HV_CRASH_CTL_CRASH_NOTIFY | 245 - HV_CRASH_CTL_CRASH_NOTIFY_MSG)); 240 + hv_set_msr(HV_MSR_CRASH_CTL, 241 + (HV_CRASH_CTL_CRASH_NOTIFY | 242 + HV_CRASH_CTL_CRASH_NOTIFY_MSG)); 246 243 } 247 244 248 245 static struct kmsg_dumper hv_kmsg_dumper = { ··· 281 278 int __init hv_common_init(void) 282 279 { 283 280 int i; 281 + union hv_hypervisor_version_info version; 282 + 283 + /* Get information about the Hyper-V host version */ 284 + if (!hv_get_hypervisor_version(&version)) 285 + pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n", 286 + version.major_version, version.minor_version, 287 + version.build_number, version.service_number, 288 + version.service_pack, version.service_branch); 284 289 285 290 if (hv_is_isolation_supported()) 286 291 sysctl_record_panic_msg = 0; ··· 321 310 * Register for panic kmsg callback only if the right 322 311 * capability is supported by the hypervisor. 323 312 */ 324 - hyperv_crash_ctl = hv_get_register(HV_REGISTER_CRASH_CTL); 313 + hyperv_crash_ctl = hv_get_msr(HV_MSR_CRASH_CTL); 325 314 if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG) 326 315 hv_kmsg_dump_register(); 327 316 ··· 356 345 hv_vp_index[i] = VP_INVAL; 357 346 358 347 return 0; 348 + } 349 + 350 + void __init ms_hyperv_late_init(void) 351 + { 352 + struct acpi_table_header *header; 353 + acpi_status status; 354 + u8 *randomdata; 355 + u32 length, i; 356 + 357 + /* 358 + * Seed the Linux random number generator with entropy provided by 359 + * the Hyper-V host in ACPI table OEM0. 360 + */ 361 + if (!IS_ENABLED(CONFIG_ACPI)) 362 + return; 363 + 364 + status = acpi_get_table("OEM0", 0, &header); 365 + if (ACPI_FAILURE(status) || !header) 366 + return; 367 + 368 + /* 369 + * Since the "OEM0" table name is for OEM specific usage, verify 370 + * that what we're seeing purports to be from Microsoft. 371 + */ 372 + if (strncmp(header->oem_table_id, "MICROSFT", 8)) 373 + goto error; 374 + 375 + /* 376 + * Ensure the length is reasonable. Requiring at least 8 bytes and 377 + * no more than 4K bytes is somewhat arbitrary and just protects 378 + * against a malformed table. Hyper-V currently provides 64 bytes, 379 + * but allow for a change in a later version. 380 + */ 381 + if (header->length < sizeof(*header) + 8 || 382 + header->length > sizeof(*header) + SZ_4K) 383 + goto error; 384 + 385 + length = header->length - sizeof(*header); 386 + randomdata = (u8 *)(header + 1); 387 + 388 + pr_debug("Hyper-V: Seeding rng with %d random bytes from ACPI table OEM0\n", 389 + length); 390 + 391 + add_bootloader_randomness(randomdata, length); 392 + 393 + /* 394 + * To prevent the seed data from being visible in /sys/firmware/acpi, 395 + * zero out the random data in the ACPI table and fixup the checksum. 396 + * The zero'ing is done out of an abundance of caution in avoiding 397 + * potential security risks to the rng. Similarly, reset the table 398 + * length to just the header size so that a subsequent kexec doesn't 399 + * try to use the zero'ed out random data. 400 + */ 401 + for (i = 0; i < length; i++) { 402 + header->checksum += randomdata[i]; 403 + randomdata[i] = 0; 404 + } 405 + 406 + for (i = 0; i < sizeof(header->length); i++) 407 + header->checksum += ((u8 *)&header->length)[i]; 408 + header->length = sizeof(*header); 409 + for (i = 0; i < sizeof(header->length); i++) 410 + header->checksum -= ((u8 *)&header->length)[i]; 411 + 412 + error: 413 + acpi_put_table(header); 359 414 } 360 415 361 416 /* ··· 486 409 *inputarg = mem; 487 410 } 488 411 489 - msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX); 412 + msr_vp_index = hv_get_msr(HV_MSR_VP_INDEX); 490 413 491 414 hv_vp_index[cpu] = msr_vp_index; 492 415 ··· 583 506 */ 584 507 static u64 __hv_read_ref_counter(void) 585 508 { 586 - return hv_get_register(HV_REGISTER_TIME_REF_COUNT); 509 + return hv_get_msr(HV_MSR_TIME_REF_COUNT); 587 510 } 588 511 589 512 u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter;
+2 -3
drivers/hv/vmbus_drv.c
··· 2359 2359 return vmbus_acpi_add(pdev); 2360 2360 } 2361 2361 2362 - static int vmbus_platform_driver_remove(struct platform_device *pdev) 2362 + static void vmbus_platform_driver_remove(struct platform_device *pdev) 2363 2363 { 2364 2364 vmbus_mmio_remove(); 2365 - return 0; 2366 2365 } 2367 2366 2368 2367 #ifdef CONFIG_PM_SLEEP ··· 2541 2542 2542 2543 static struct platform_driver vmbus_platform_driver = { 2543 2544 .probe = vmbus_platform_driver_probe, 2544 - .remove = vmbus_platform_driver_remove, 2545 + .remove_new = vmbus_platform_driver_remove, 2545 2546 .driver = { 2546 2547 .name = "vmbus", 2547 2548 .acpi_match_table = ACPI_PTR(vmbus_acpi_device_ids),
+54 -1
include/asm-generic/hyperv-tlfs.h
··· 625 625 struct hv_device_interrupt_target int_target; 626 626 } __packed __aligned(8); 627 627 628 + /* 629 + * These Hyper-V registers provide information equivalent to the CPUID 630 + * instruction on x86/x64. 631 + */ 632 + #define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */ 633 + #define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */ 634 + #define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */ 635 + 636 + /* 637 + * Synthetic register definitions equivalent to MSRs on x86/x64 638 + */ 639 + #define HV_REGISTER_GUEST_CRASH_P0 0x00000210 640 + #define HV_REGISTER_GUEST_CRASH_P1 0x00000211 641 + #define HV_REGISTER_GUEST_CRASH_P2 0x00000212 642 + #define HV_REGISTER_GUEST_CRASH_P3 0x00000213 643 + #define HV_REGISTER_GUEST_CRASH_P4 0x00000214 644 + #define HV_REGISTER_GUEST_CRASH_CTL 0x00000215 645 + 646 + #define HV_REGISTER_GUEST_OS_ID 0x00090002 647 + #define HV_REGISTER_VP_INDEX 0x00090003 648 + #define HV_REGISTER_TIME_REF_COUNT 0x00090004 649 + #define HV_REGISTER_REFERENCE_TSC 0x00090017 650 + 651 + #define HV_REGISTER_SINT0 0x000A0000 652 + #define HV_REGISTER_SCONTROL 0x000A0010 653 + #define HV_REGISTER_SIEFP 0x000A0012 654 + #define HV_REGISTER_SIMP 0x000A0013 655 + #define HV_REGISTER_EOM 0x000A0014 656 + 657 + #define HV_REGISTER_STIMER0_CONFIG 0x000B0000 658 + #define HV_REGISTER_STIMER0_COUNT 0x000B0001 628 659 629 660 /* HvGetVpRegisters hypercall input with variable size reg name list*/ 630 661 struct hv_get_vp_registers_input { ··· 670 639 u32 name1; 671 640 } element[]; 672 641 } __packed; 673 - 674 642 675 643 /* HvGetVpRegisters returns an array of these output elements */ 676 644 struct hv_get_vp_registers_output { ··· 816 786 817 787 #define HV_SOURCE_SHADOW_NONE 0x0 818 788 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE 0x1 789 + 790 + /* 791 + * Version info reported by hypervisor 792 + */ 793 + union hv_hypervisor_version_info { 794 + struct { 795 + u32 build_number; 796 + 797 + u32 minor_version : 16; 798 + u32 major_version : 16; 799 + 800 + u32 service_pack; 801 + 802 + u32 service_number : 24; 803 + u32 service_branch : 8; 804 + }; 805 + struct { 806 + u32 eax; 807 + u32 ebx; 808 + u32 ecx; 809 + u32 edx; 810 + }; 811 + }; 819 812 820 813 /* 821 814 * The whole argument should fit in a page to be able to pass to the hypervisor
+5 -1
include/asm-generic/mshyperv.h
··· 157 157 * possibly deliver another msg from the 158 158 * hypervisor 159 159 */ 160 - hv_set_register(HV_REGISTER_EOM, 0); 160 + hv_set_msr(HV_MSR_EOM, 0); 161 161 } 162 162 } 163 + 164 + int hv_get_hypervisor_version(union hv_hypervisor_version_info *info); 163 165 164 166 void hv_setup_vmbus_handler(void (*handler)(void)); 165 167 void hv_remove_vmbus_handler(void); ··· 195 193 196 194 int __init hv_common_init(void); 197 195 void __init hv_common_free(void); 196 + void __init ms_hyperv_late_init(void); 198 197 int hv_common_cpu_init(unsigned int cpu); 199 198 int hv_common_cpu_die(unsigned int cpu); 200 199 ··· 293 290 static inline bool hv_is_hyperv_initialized(void) { return false; } 294 291 static inline bool hv_is_hibernation_supported(void) { return false; } 295 292 static inline void hyperv_cleanup(void) {} 293 + static inline void ms_hyperv_late_init(void) {} 296 294 static inline bool hv_is_isolation_supported(void) { return false; } 297 295 static inline enum hv_isolation_type hv_get_isolation_type(void) 298 296 {