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-fixes-signed-20230804' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv fixes from Wei Liu:

- Fix a bug in a python script for Hyper-V (Ani Sinha)

- Workaround a bug in Hyper-V when IBT is enabled (Michael Kelley)

- Fix an issue parsing MP table when Linux runs in VTL2 (Saurabh
Sengar)

- Several cleanup patches (Nischala Yelchuri, Kameron Carr, YueHaibing,
ZhiHu)

* tag 'hyperv-fixes-signed-20230804' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
Drivers: hv: vmbus: Remove unused extern declaration vmbus_ontimer()
x86/hyperv: add noop functions to x86_init mpparse functions
vmbus_testing: fix wrong python syntax for integer value comparison
x86/hyperv: fix a warning in mshyperv.h
x86/hyperv: Disable IBT when hypercall page lacks ENDBR instruction
x86/hyperv: Improve code for referencing hyperv_pcpu_input_arg
Drivers: hv: Change hv_free_hyperv_page() to take void * argument

+49 -46
+1 -3
arch/x86/hyperv/hv_apic.c
··· 107 107 static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector, 108 108 bool exclude_self) 109 109 { 110 - struct hv_send_ipi_ex **arg; 111 110 struct hv_send_ipi_ex *ipi_arg; 112 111 unsigned long flags; 113 112 int nr_bank = 0; ··· 116 117 return false; 117 118 118 119 local_irq_save(flags); 119 - arg = (struct hv_send_ipi_ex **)this_cpu_ptr(hyperv_pcpu_input_arg); 120 + ipi_arg = *this_cpu_ptr(hyperv_pcpu_input_arg); 120 121 121 - ipi_arg = *arg; 122 122 if (unlikely(!ipi_arg)) 123 123 goto ipi_mask_ex_done; 124 124
+21
arch/x86/hyperv/hv_init.c
··· 14 14 #include <asm/apic.h> 15 15 #include <asm/desc.h> 16 16 #include <asm/sev.h> 17 + #include <asm/ibt.h> 17 18 #include <asm/hypervisor.h> 18 19 #include <asm/hyperv-tlfs.h> 19 20 #include <asm/mshyperv.h> ··· 471 470 hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); 472 471 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); 473 472 } 473 + 474 + /* 475 + * Some versions of Hyper-V that provide IBT in guest VMs have a bug 476 + * in that there's no ENDBR64 instruction at the entry to the 477 + * hypercall page. Because hypercalls are invoked via an indirect call 478 + * to the hypercall page, all hypercall attempts fail when IBT is 479 + * enabled, and Linux panics. For such buggy versions, disable IBT. 480 + * 481 + * Fixed versions of Hyper-V always provide ENDBR64 on the hypercall 482 + * page, so if future Linux kernel versions enable IBT for 32-bit 483 + * builds, additional hypercall page hackery will be required here 484 + * to provide an ENDBR32. 485 + */ 486 + #ifdef CONFIG_X86_KERNEL_IBT 487 + if (cpu_feature_enabled(X86_FEATURE_IBT) && 488 + *(u32 *)hv_hypercall_pg != gen_endbr()) { 489 + setup_clear_cpu_cap(X86_FEATURE_IBT); 490 + pr_warn("Hyper-V: Disabling IBT because of Hyper-V bug\n"); 491 + } 492 + #endif 474 493 475 494 /* 476 495 * hyperv_init() is called before LAPIC is initialized: see
+4
arch/x86/hyperv/hv_vtl.c
··· 25 25 x86_init.irqs.pre_vector_init = x86_init_noop; 26 26 x86_init.timers.timer_init = x86_init_noop; 27 27 28 + /* Avoid searching for BIOS MP tables */ 29 + x86_init.mpparse.find_smp_config = x86_init_noop; 30 + x86_init.mpparse.get_smp_config = x86_init_uint_noop; 31 + 28 32 x86_platform.get_wallclock = get_rtc_noop; 29 33 x86_platform.set_wallclock = set_rtc_noop; 30 34 x86_platform.get_nmi_reason = hv_get_nmi_reason;
+3 -4
arch/x86/hyperv/ivm.c
··· 247 247 static int hv_mark_gpa_visibility(u16 count, const u64 pfn[], 248 248 enum hv_mem_host_visibility visibility) 249 249 { 250 - struct hv_gpa_range_for_visibility **input_pcpu, *input; 250 + struct hv_gpa_range_for_visibility *input; 251 251 u16 pages_processed; 252 252 u64 hv_status; 253 253 unsigned long flags; ··· 263 263 } 264 264 265 265 local_irq_save(flags); 266 - input_pcpu = (struct hv_gpa_range_for_visibility **) 267 - this_cpu_ptr(hyperv_pcpu_input_arg); 268 - input = *input_pcpu; 266 + input = *this_cpu_ptr(hyperv_pcpu_input_arg); 267 + 269 268 if (unlikely(!input)) { 270 269 local_irq_restore(flags); 271 270 return -EINVAL;
+2 -10
arch/x86/hyperv/mmu.c
··· 61 61 const struct flush_tlb_info *info) 62 62 { 63 63 int cpu, vcpu, gva_n, max_gvas; 64 - struct hv_tlb_flush **flush_pcpu; 65 64 struct hv_tlb_flush *flush; 66 65 u64 status; 67 66 unsigned long flags; ··· 73 74 74 75 local_irq_save(flags); 75 76 76 - flush_pcpu = (struct hv_tlb_flush **) 77 - this_cpu_ptr(hyperv_pcpu_input_arg); 78 - 79 - flush = *flush_pcpu; 77 + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); 80 78 81 79 if (unlikely(!flush)) { 82 80 local_irq_restore(flags); ··· 174 178 const struct flush_tlb_info *info) 175 179 { 176 180 int nr_bank = 0, max_gvas, gva_n; 177 - struct hv_tlb_flush_ex **flush_pcpu; 178 181 struct hv_tlb_flush_ex *flush; 179 182 u64 status; 180 183 181 184 if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) 182 185 return HV_STATUS_INVALID_PARAMETER; 183 186 184 - flush_pcpu = (struct hv_tlb_flush_ex **) 185 - this_cpu_ptr(hyperv_pcpu_input_arg); 186 - 187 - flush = *flush_pcpu; 187 + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); 188 188 189 189 if (info->mm) { 190 190 /*
+2 -9
arch/x86/hyperv/nested.c
··· 19 19 20 20 int hyperv_flush_guest_mapping(u64 as) 21 21 { 22 - struct hv_guest_mapping_flush **flush_pcpu; 23 22 struct hv_guest_mapping_flush *flush; 24 23 u64 status; 25 24 unsigned long flags; ··· 29 30 30 31 local_irq_save(flags); 31 32 32 - flush_pcpu = (struct hv_guest_mapping_flush **) 33 - this_cpu_ptr(hyperv_pcpu_input_arg); 34 - 35 - flush = *flush_pcpu; 33 + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); 36 34 37 35 if (unlikely(!flush)) { 38 36 local_irq_restore(flags); ··· 86 90 int hyperv_flush_guest_mapping_range(u64 as, 87 91 hyperv_fill_flush_list_func fill_flush_list_func, void *data) 88 92 { 89 - struct hv_guest_mapping_flush_list **flush_pcpu; 90 93 struct hv_guest_mapping_flush_list *flush; 91 94 u64 status; 92 95 unsigned long flags; ··· 97 102 98 103 local_irq_save(flags); 99 104 100 - flush_pcpu = (struct hv_guest_mapping_flush_list **) 101 - this_cpu_ptr(hyperv_pcpu_input_arg); 105 + flush = *this_cpu_ptr(hyperv_pcpu_input_arg); 102 106 103 - flush = *flush_pcpu; 104 107 if (unlikely(!flush)) { 105 108 local_irq_restore(flags); 106 109 goto fault;
+1 -1
arch/x86/include/asm/mshyperv.h
··· 5 5 #include <linux/types.h> 6 6 #include <linux/nmi.h> 7 7 #include <linux/msi.h> 8 - #include <asm/io.h> 8 + #include <linux/io.h> 9 9 #include <asm/hyperv-tlfs.h> 10 10 #include <asm/nospec-branch.h> 11 11 #include <asm/paravirt.h>
+6 -7
drivers/hv/connection.c
··· 209 209 * Setup the vmbus event connection for channel interrupt 210 210 * abstraction stuff 211 211 */ 212 - vmbus_connection.int_page = 213 - (void *)hv_alloc_hyperv_zeroed_page(); 212 + vmbus_connection.int_page = hv_alloc_hyperv_zeroed_page(); 214 213 if (vmbus_connection.int_page == NULL) { 215 214 ret = -ENOMEM; 216 215 goto cleanup; ··· 224 225 * Setup the monitor notification facility. The 1st page for 225 226 * parent->child and the 2nd page for child->parent 226 227 */ 227 - vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_page(); 228 - vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_page(); 228 + vmbus_connection.monitor_pages[0] = hv_alloc_hyperv_page(); 229 + vmbus_connection.monitor_pages[1] = hv_alloc_hyperv_page(); 229 230 if ((vmbus_connection.monitor_pages[0] == NULL) || 230 231 (vmbus_connection.monitor_pages[1] == NULL)) { 231 232 ret = -ENOMEM; ··· 332 333 destroy_workqueue(vmbus_connection.work_queue); 333 334 334 335 if (vmbus_connection.int_page) { 335 - hv_free_hyperv_page((unsigned long)vmbus_connection.int_page); 336 + hv_free_hyperv_page(vmbus_connection.int_page); 336 337 vmbus_connection.int_page = NULL; 337 338 } 338 339 339 340 set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1); 340 341 set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1); 341 342 342 - hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]); 343 - hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]); 343 + hv_free_hyperv_page(vmbus_connection.monitor_pages[0]); 344 + hv_free_hyperv_page(vmbus_connection.monitor_pages[1]); 344 345 vmbus_connection.monitor_pages[0] = NULL; 345 346 vmbus_connection.monitor_pages[1] = NULL; 346 347 }
+1 -1
drivers/hv/hv_balloon.c
··· 1628 1628 WARN_ON_ONCE(nents > HV_MEMORY_HINT_MAX_GPA_PAGE_RANGES); 1629 1629 WARN_ON_ONCE(sgl->length < (HV_HYP_PAGE_SIZE << page_reporting_order)); 1630 1630 local_irq_save(flags); 1631 - hint = *(struct hv_memory_hint **)this_cpu_ptr(hyperv_pcpu_input_arg); 1631 + hint = *this_cpu_ptr(hyperv_pcpu_input_arg); 1632 1632 if (!hint) { 1633 1633 local_irq_restore(flags); 1634 1634 return -ENOSPC;
+5 -5
drivers/hv/hv_common.c
··· 115 115 } 116 116 EXPORT_SYMBOL_GPL(hv_alloc_hyperv_zeroed_page); 117 117 118 - void hv_free_hyperv_page(unsigned long addr) 118 + void hv_free_hyperv_page(void *addr) 119 119 { 120 120 if (PAGE_SIZE == HV_HYP_PAGE_SIZE) 121 - free_page(addr); 121 + free_page((unsigned long)addr); 122 122 else 123 - kfree((void *)addr); 123 + kfree(addr); 124 124 } 125 125 EXPORT_SYMBOL_GPL(hv_free_hyperv_page); 126 126 ··· 253 253 atomic_notifier_chain_unregister(&panic_notifier_list, 254 254 &hyperv_panic_report_block); 255 255 256 - hv_free_hyperv_page((unsigned long)hv_panic_page); 256 + hv_free_hyperv_page(hv_panic_page); 257 257 hv_panic_page = NULL; 258 258 } 259 259 ··· 270 270 ret = kmsg_dump_register(&hv_kmsg_dumper); 271 271 if (ret) { 272 272 pr_err("Hyper-V: kmsg dump register error 0x%x\n", ret); 273 - hv_free_hyperv_page((unsigned long)hv_panic_page); 273 + hv_free_hyperv_page(hv_panic_page); 274 274 hv_panic_page = NULL; 275 275 } 276 276 }
+1 -1
include/asm-generic/mshyperv.h
··· 190 190 191 191 void *hv_alloc_hyperv_page(void); 192 192 void *hv_alloc_hyperv_zeroed_page(void); 193 - void hv_free_hyperv_page(unsigned long addr); 193 + void hv_free_hyperv_page(void *addr); 194 194 195 195 /** 196 196 * hv_cpu_number_to_vp_number() - Map CPU to VP.
-3
include/linux/hyperv.h
··· 1239 1239 u32 *buffer_actual_len, 1240 1240 u64 *requestid); 1241 1241 1242 - 1243 - extern void vmbus_ontimer(unsigned long data); 1244 - 1245 1242 /* Base driver object */ 1246 1243 struct hv_driver { 1247 1244 const char *name;
+2 -2
tools/hv/vmbus_testing
··· 164 164 def get_all_devices_test_status(file_map): 165 165 166 166 for device in file_map: 167 - if (get_test_state(locate_state(device, file_map)) is 1): 167 + if (get_test_state(locate_state(device, file_map)) == 1): 168 168 print("Testing = ON for: {}" 169 169 .format(device.split("/")[5])) 170 170 else: ··· 203 203 def set_test_state(state_path, state_value, quiet): 204 204 205 205 write_test_files(state_path, state_value) 206 - if (get_test_state(state_path) is 1): 206 + if (get_test_state(state_path) == 1): 207 207 if (not quiet): 208 208 print("Testing = ON for device: {}" 209 209 .format(state_path.split("/")[5]))