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 'perf_urgent_for_v6.1_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Borislav Petkov:

- Fix an intel PT erratum where CPUs do not support single range output
for more than 4K

- Fix a NULL ptr dereference which can happen after an NMI interferes
with the event enabling dance in amd_pmu_enable_all()

- Free the events array too when freeing uncore contexts on CPU online,
thereby fixing a memory leak

- Improve the pending SIGTRAP check

* tag 'perf_urgent_for_v6.1_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel/pt: Fix sampling using single range output
perf/x86/amd: Fix crash due to race between amd_pmu_enable_all, perf NMI and throttling
perf/x86/amd/uncore: Fix memory leak for events array
perf: Improve missing SIGTRAP checking

+31 -9
+2 -3
arch/x86/events/amd/core.c
··· 861 861 pmu_enabled = cpuc->enabled; 862 862 cpuc->enabled = 0; 863 863 864 - /* stop everything (includes BRS) */ 865 - amd_pmu_disable_all(); 864 + amd_brs_disable_all(); 866 865 867 866 /* Drain BRS is in use (could be inactive) */ 868 867 if (cpuc->lbr_users) ··· 872 873 873 874 cpuc->enabled = pmu_enabled; 874 875 if (pmu_enabled) 875 - amd_pmu_enable_all(0); 876 + amd_brs_enable_all(); 876 877 877 878 return amd_pmu_adjust_nmi_window(handled); 878 879 }
+1
arch/x86/events/amd/uncore.c
··· 553 553 554 554 hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) { 555 555 hlist_del(&uncore->node); 556 + kfree(uncore->events); 556 557 kfree(uncore); 557 558 } 558 559 }
+9
arch/x86/events/intel/pt.c
··· 1263 1263 if (1 << order != nr_pages) 1264 1264 goto out; 1265 1265 1266 + /* 1267 + * Some processors cannot always support single range for more than 1268 + * 4KB - refer errata TGL052, ADL037 and RPL017. Future processors might 1269 + * also be affected, so for now rather than trying to keep track of 1270 + * which ones, just disable it for all. 1271 + */ 1272 + if (nr_pages > 1) 1273 + goto out; 1274 + 1266 1275 buf->single = true; 1267 1276 buf->nr_pages = nr_pages; 1268 1277 ret = 0;
+19 -6
kernel/events/core.c
··· 9306 9306 } 9307 9307 9308 9308 if (event->attr.sigtrap) { 9309 - /* 9310 - * Should not be able to return to user space without processing 9311 - * pending_sigtrap (kernel events can overflow multiple times). 9312 - */ 9313 - WARN_ON_ONCE(event->pending_sigtrap && event->attr.exclude_kernel); 9309 + unsigned int pending_id = 1; 9310 + 9311 + if (regs) 9312 + pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1; 9314 9313 if (!event->pending_sigtrap) { 9315 - event->pending_sigtrap = 1; 9314 + event->pending_sigtrap = pending_id; 9316 9315 local_inc(&event->ctx->nr_pending); 9316 + } else if (event->attr.exclude_kernel) { 9317 + /* 9318 + * Should not be able to return to user space without 9319 + * consuming pending_sigtrap; with exceptions: 9320 + * 9321 + * 1. Where !exclude_kernel, events can overflow again 9322 + * in the kernel without returning to user space. 9323 + * 9324 + * 2. Events that can overflow again before the IRQ- 9325 + * work without user space progress (e.g. hrtimer). 9326 + * To approximate progress (with false negatives), 9327 + * check 32-bit hash of the current IP. 9328 + */ 9329 + WARN_ON_ONCE(event->pending_sigtrap != pending_id); 9317 9330 } 9318 9331 event->pending_addr = data->addr; 9319 9332 irq_work_queue(&event->pending_irq);