mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 23:24:11 +08:00
arm64 fixes:
- Support for nr_cpus= command line argument (maxcpus was previously changed to allow secondary CPUs to be hot-plugged) - ARM PMU interrupt handling fix - Fix potential TLB conflict in the hibernate code - Improved handling of EL1 instruction aborts (better error reporting) - Removal of useless jprobes code for stack saving/restoring - defconfig updates -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXr5vuAAoJEGvWsS0AyF7x2SMQAID5viyDMPAIA25v08SKWFSc aZnuLZfVFr60mw+NkFp2FycFJyrUiL8LByPjEpTKhsMx4BmkrJoOlUBs4lD9GZu+ 43N70tgSOFkKBwod0x1H7yyMURmVlMuy7/k3rJMRe71kFDL7qbH86bgxvPvx4nuX YdfhNdLIAQsyk3ngV4ym69tzfVWaFY2xLRoXh3rSKkDHPODsoEJk9+u72dnbrkoG gqr/ul0ChqOv7IPLRLCdyGLmVoyPqAv5P9VYDU/lOEXZ/qc+RgOxs7KHbS6nLQqQ +OkqEH0xFiJ80rtCuW3YBjUY6z8Gap3tHhZjI1waET/m7TyvqxesGCmp/40/EhB6 XfqXNXhFM2Yjmdze5MfY4qwNpS0ivovstMTsFG+AtnDV1rODVEXgXK2mpO3u6l2r MJ6uYL15Q0KmXdtSd+VZyQGfiBKQ854eRBkA9ueQRpVQeU9Fwe1koQilk2RmVa1p ezHEZ+jPOUKNr+89ZJKm2xUou1t3KUDljLQt9rja6zbnsro/YUPloEk6CJLeeMRj EFovXhxsD0j8eOktzHVXYlT631Rzzqz9Cx16jpJd5NlNqH+xUntmXMHeAkihbfD1 lCeihNY30gPkl4EGnu73wsNQqsZyOKNuwhQtqPpDsPtkUmW+uW3cb6XWKM/p+z8B raa2UN6bmIjBw3LiDN4V =XOhe -----END PGP SIGNATURE----- Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux Pull arm64 fixes from Catalin Marinas: - support for nr_cpus= command line argument (maxcpus was previously changed to allow secondary CPUs to be hot-plugged) - ARM PMU interrupt handling fix - fix potential TLB conflict in the hibernate code - improved handling of EL1 instruction aborts (better error reporting) - removal of useless jprobes code for stack saving/restoring - defconfig updates * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: defconfig: enable CONFIG_LOCALVERSION_AUTO arm64: defconfig: add options for virtualization and containers arm64: hibernate: handle allocation failures arm64: hibernate: avoid potential TLB conflict arm64: Handle el1 synchronous instruction aborts cleanly arm64: Remove stack duplicating code from jprobes drivers/perf: arm-pmu: Fix handling of SPI lacking "interrupt-affinity" property drivers/perf: arm-pmu: convert arm_pmu_mutex to spinlock arm64: Support hard limit of cpu count by nr_cpus
This commit is contained in:
commit
120c54751b
@ -1,4 +1,3 @@
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_AUDIT=y
|
||||
@ -15,10 +14,14 @@ CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_HUGETLB=y
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_IPC_NS is not set
|
||||
# CONFIG_NET_NS is not set
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
@ -71,6 +74,7 @@ CONFIG_PREEMPT=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_XEN=y
|
||||
CONFIG_KEXEC=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
@ -84,10 +88,37 @@ CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_IP_PNP_BOOTP=y
|
||||
# CONFIG_IPV6 is not set
|
||||
CONFIG_IPV6=m
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_NF_CONNTRACK_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_BRIDGE_VLAN_FILTERING=y
|
||||
CONFIG_VLAN_8021Q=m
|
||||
CONFIG_VLAN_8021Q_GVRP=y
|
||||
CONFIG_VLAN_8021Q_MVRP=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
@ -103,6 +134,7 @@ CONFIG_MTD=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_SRAM=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
@ -120,7 +152,10 @@ CONFIG_SATA_SIL24=y
|
||||
CONFIG_PATA_PLATFORM=y
|
||||
CONFIG_PATA_OF_PLATFORM=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_MACVLAN=m
|
||||
CONFIG_MACVTAP=m
|
||||
CONFIG_TUN=y
|
||||
CONFIG_VETH=m
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_AMD_XGBE=y
|
||||
CONFIG_NET_XGENE=y
|
||||
@ -350,12 +385,16 @@ CONFIG_EXYNOS_ADC=y
|
||||
CONFIG_PWM_SAMSUNG=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_BTRFS_FS=m
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=y
|
||||
CONFIG_FUSE_FS=m
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#define __ARCH_WANT_KPROBES_INSN_SLOT
|
||||
#define MAX_INSN_SIZE 1
|
||||
#define MAX_STACK_SIZE 128
|
||||
|
||||
#define flush_insn_slot(p) do { } while (0)
|
||||
#define kretprobe_blacklist_size 0
|
||||
@ -47,7 +46,6 @@ struct kprobe_ctlblk {
|
||||
struct prev_kprobe prev_kprobe;
|
||||
struct kprobe_step_ctx ss_ctx;
|
||||
struct pt_regs jprobe_saved_regs;
|
||||
char jprobes_stack[MAX_STACK_SIZE];
|
||||
};
|
||||
|
||||
void arch_remove_kprobe(struct kprobe *);
|
||||
|
@ -353,6 +353,8 @@ el1_sync:
|
||||
lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class
|
||||
cmp x24, #ESR_ELx_EC_DABT_CUR // data abort in EL1
|
||||
b.eq el1_da
|
||||
cmp x24, #ESR_ELx_EC_IABT_CUR // instruction abort in EL1
|
||||
b.eq el1_ia
|
||||
cmp x24, #ESR_ELx_EC_SYS64 // configurable trap
|
||||
b.eq el1_undef
|
||||
cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception
|
||||
@ -364,6 +366,11 @@ el1_sync:
|
||||
cmp x24, #ESR_ELx_EC_BREAKPT_CUR // debug exception in EL1
|
||||
b.ge el1_dbg
|
||||
b el1_inv
|
||||
|
||||
el1_ia:
|
||||
/*
|
||||
* Fall through to the Data abort case
|
||||
*/
|
||||
el1_da:
|
||||
/*
|
||||
* Data abort handling
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <asm/sections.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/sysreg.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
/*
|
||||
@ -217,12 +218,22 @@ static int create_safe_exec_page(void *src_start, size_t length,
|
||||
set_pte(pte, __pte(virt_to_phys((void *)dst) |
|
||||
pgprot_val(PAGE_KERNEL_EXEC)));
|
||||
|
||||
/* Load our new page tables */
|
||||
asm volatile("msr ttbr0_el1, %0;"
|
||||
"isb;"
|
||||
"tlbi vmalle1is;"
|
||||
"dsb ish;"
|
||||
"isb" : : "r"(virt_to_phys(pgd)));
|
||||
/*
|
||||
* Load our new page tables. A strict BBM approach requires that we
|
||||
* ensure that TLBs are free of any entries that may overlap with the
|
||||
* global mappings we are about to install.
|
||||
*
|
||||
* For a real hibernate/resume cycle TTBR0 currently points to a zero
|
||||
* page, but TLBs may contain stale ASID-tagged entries (e.g. for EFI
|
||||
* runtime services), while for a userspace-driven test_resume cycle it
|
||||
* points to userspace page tables (and we must point it at a zero page
|
||||
* ourselves). Elsewhere we only (un)install the idmap with preemption
|
||||
* disabled, so T0SZ should be as required regardless.
|
||||
*/
|
||||
cpu_set_reserved_ttbr0();
|
||||
local_flush_tlb_all();
|
||||
write_sysreg(virt_to_phys(pgd), ttbr0_el1);
|
||||
isb();
|
||||
|
||||
*phys_dst_addr = virt_to_phys((void *)dst);
|
||||
|
||||
@ -393,6 +404,38 @@ int swsusp_arch_resume(void)
|
||||
void __noreturn (*hibernate_exit)(phys_addr_t, phys_addr_t, void *,
|
||||
void *, phys_addr_t, phys_addr_t);
|
||||
|
||||
/*
|
||||
* Restoring the memory image will overwrite the ttbr1 page tables.
|
||||
* Create a second copy of just the linear map, and use this when
|
||||
* restoring.
|
||||
*/
|
||||
tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
|
||||
if (!tmp_pg_dir) {
|
||||
pr_err("Failed to allocate memory for temporary page tables.");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Since we only copied the linear map, we need to find restore_pblist's
|
||||
* linear map address.
|
||||
*/
|
||||
lm_restore_pblist = LMADDR(restore_pblist);
|
||||
|
||||
/*
|
||||
* We need a zero page that is zero before & after resume in order to
|
||||
* to break before make on the ttbr1 page tables.
|
||||
*/
|
||||
zero_page = (void *)get_safe_page(GFP_ATOMIC);
|
||||
if (!zero_page) {
|
||||
pr_err("Failed to allocate zero page.");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the exit code in the bottom-but-one page, so that *NULL
|
||||
* still has disastrous affects.
|
||||
@ -418,27 +461,6 @@ int swsusp_arch_resume(void)
|
||||
*/
|
||||
__flush_dcache_area(hibernate_exit, exit_size);
|
||||
|
||||
/*
|
||||
* Restoring the memory image will overwrite the ttbr1 page tables.
|
||||
* Create a second copy of just the linear map, and use this when
|
||||
* restoring.
|
||||
*/
|
||||
tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
|
||||
if (!tmp_pg_dir) {
|
||||
pr_err("Failed to allocate memory for temporary page tables.");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Since we only copied the linear map, we need to find restore_pblist's
|
||||
* linear map address.
|
||||
*/
|
||||
lm_restore_pblist = LMADDR(restore_pblist);
|
||||
|
||||
/*
|
||||
* KASLR will cause the el2 vectors to be in a different location in
|
||||
* the resumed kernel. Load hibernate's temporary copy into el2.
|
||||
@ -453,12 +475,6 @@ int swsusp_arch_resume(void)
|
||||
__hyp_set_vectors(el2_vectors);
|
||||
}
|
||||
|
||||
/*
|
||||
* We need a zero page that is zero before & after resume in order to
|
||||
* to break before make on the ttbr1 page tables.
|
||||
*/
|
||||
zero_page = (void *)get_safe_page(GFP_ATOMIC);
|
||||
|
||||
hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1,
|
||||
resume_hdr.reenter_kernel, lm_restore_pblist,
|
||||
resume_hdr.__hyp_stub_vectors, virt_to_phys(zero_page));
|
||||
|
@ -41,18 +41,6 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
||||
static void __kprobes
|
||||
post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
|
||||
|
||||
static inline unsigned long min_stack_size(unsigned long addr)
|
||||
{
|
||||
unsigned long size;
|
||||
|
||||
if (on_irq_stack(addr, raw_smp_processor_id()))
|
||||
size = IRQ_STACK_PTR(raw_smp_processor_id()) - addr;
|
||||
else
|
||||
size = (unsigned long)current_thread_info() + THREAD_START_SP - addr;
|
||||
|
||||
return min(size, FIELD_SIZEOF(struct kprobe_ctlblk, jprobes_stack));
|
||||
}
|
||||
|
||||
static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
|
||||
{
|
||||
/* prepare insn slot */
|
||||
@ -489,20 +477,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
long stack_ptr = kernel_stack_pointer(regs);
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
/*
|
||||
* As Linus pointed out, gcc assumes that the callee
|
||||
* owns the argument space and could overwrite it, e.g.
|
||||
* tailcall optimization. So, to be absolutely safe
|
||||
* we also save and restore enough stack bytes to cover
|
||||
* the argument area.
|
||||
* Since we can't be sure where in the stack frame "stacked"
|
||||
* pass-by-value arguments are stored we just don't try to
|
||||
* duplicate any of the stack. Do not use jprobes on functions that
|
||||
* use more than 64 bytes (after padding each to an 8 byte boundary)
|
||||
* of arguments, or pass individual arguments larger than 16 bytes.
|
||||
*/
|
||||
kasan_disable_current();
|
||||
memcpy(kcb->jprobes_stack, (void *)stack_ptr,
|
||||
min_stack_size(stack_ptr));
|
||||
kasan_enable_current();
|
||||
|
||||
instruction_pointer_set(regs, (unsigned long) jp->entry);
|
||||
preempt_disable();
|
||||
@ -554,10 +537,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
}
|
||||
unpause_graph_tracing();
|
||||
*regs = kcb->jprobe_saved_regs;
|
||||
kasan_disable_current();
|
||||
memcpy((void *)stack_addr, kcb->jprobes_stack,
|
||||
min_stack_size(stack_addr));
|
||||
kasan_enable_current();
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
@ -661,9 +661,9 @@ void __init smp_init_cpus(void)
|
||||
acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
|
||||
acpi_parse_gic_cpu_interface, 0);
|
||||
|
||||
if (cpu_count > NR_CPUS)
|
||||
pr_warn("no. of cores (%d) greater than configured maximum of %d - clipping\n",
|
||||
cpu_count, NR_CPUS);
|
||||
if (cpu_count > nr_cpu_ids)
|
||||
pr_warn("Number of cores (%d) exceeds configured maximum of %d - clipping\n",
|
||||
cpu_count, nr_cpu_ids);
|
||||
|
||||
if (!bootcpu_valid) {
|
||||
pr_err("missing boot CPU MPIDR, not enabling secondaries\n");
|
||||
@ -677,7 +677,7 @@ void __init smp_init_cpus(void)
|
||||
* with entries in cpu_logical_map while initializing the cpus.
|
||||
* If the cpu set-up fails, invalidate the cpu_logical_map entry.
|
||||
*/
|
||||
for (i = 1; i < NR_CPUS; i++) {
|
||||
for (i = 1; i < nr_cpu_ids; i++) {
|
||||
if (cpu_logical_map(i) != INVALID_HWID) {
|
||||
if (smp_cpu_setup(i))
|
||||
cpu_logical_map(i) = INVALID_HWID;
|
||||
|
@ -153,6 +153,11 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool is_el1_instruction_abort(unsigned int esr)
|
||||
{
|
||||
return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_CUR;
|
||||
}
|
||||
|
||||
/*
|
||||
* The kernel tried to access some page that wasn't present.
|
||||
*/
|
||||
@ -161,8 +166,9 @@ static void __do_kernel_fault(struct mm_struct *mm, unsigned long addr,
|
||||
{
|
||||
/*
|
||||
* Are we prepared to handle this kernel fault?
|
||||
* We are almost certainly not prepared to handle instruction faults.
|
||||
*/
|
||||
if (fixup_exception(regs))
|
||||
if (!is_el1_instruction_abort(esr) && fixup_exception(regs))
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -267,7 +273,8 @@ static inline bool is_permission_fault(unsigned int esr)
|
||||
unsigned int ec = ESR_ELx_EC(esr);
|
||||
unsigned int fsc_type = esr & ESR_ELx_FSC_TYPE;
|
||||
|
||||
return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM);
|
||||
return (ec == ESR_ELx_EC_DABT_CUR && fsc_type == ESR_ELx_FSC_PERM) ||
|
||||
(ec == ESR_ELx_EC_IABT_CUR && fsc_type == ESR_ELx_FSC_PERM);
|
||||
}
|
||||
|
||||
static bool is_el0_instruction_abort(unsigned int esr)
|
||||
@ -312,6 +319,9 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
|
||||
if (regs->orig_addr_limit == KERNEL_DS)
|
||||
die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
|
||||
|
||||
if (is_el1_instruction_abort(esr))
|
||||
die("Attempting to execute userspace memory", regs, esr);
|
||||
|
||||
if (!search_exception_tables(regs->pc))
|
||||
die("Accessing user space memory outside uaccess.h routines", regs, esr);
|
||||
}
|
||||
|
@ -688,7 +688,7 @@ static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(arm_pmu_mutex);
|
||||
static DEFINE_SPINLOCK(arm_pmu_lock);
|
||||
static LIST_HEAD(arm_pmu_list);
|
||||
|
||||
/*
|
||||
@ -701,7 +701,7 @@ static int arm_perf_starting_cpu(unsigned int cpu)
|
||||
{
|
||||
struct arm_pmu *pmu;
|
||||
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
spin_lock(&arm_pmu_lock);
|
||||
list_for_each_entry(pmu, &arm_pmu_list, entry) {
|
||||
|
||||
if (!cpumask_test_cpu(cpu, &pmu->supported_cpus))
|
||||
@ -709,7 +709,7 @@ static int arm_perf_starting_cpu(unsigned int cpu)
|
||||
if (pmu->reset)
|
||||
pmu->reset(pmu);
|
||||
}
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
spin_unlock(&arm_pmu_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -821,9 +821,9 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu)
|
||||
if (!cpu_hw_events)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
spin_lock(&arm_pmu_lock);
|
||||
list_add_tail(&cpu_pmu->entry, &arm_pmu_list);
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
spin_unlock(&arm_pmu_lock);
|
||||
|
||||
err = cpu_pm_pmu_register(cpu_pmu);
|
||||
if (err)
|
||||
@ -859,9 +859,9 @@ static int cpu_pmu_init(struct arm_pmu *cpu_pmu)
|
||||
return 0;
|
||||
|
||||
out_unregister:
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
spin_lock(&arm_pmu_lock);
|
||||
list_del(&cpu_pmu->entry);
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
spin_unlock(&arm_pmu_lock);
|
||||
free_percpu(cpu_hw_events);
|
||||
return err;
|
||||
}
|
||||
@ -869,9 +869,9 @@ out_unregister:
|
||||
static void cpu_pmu_destroy(struct arm_pmu *cpu_pmu)
|
||||
{
|
||||
cpu_pm_pmu_unregister(cpu_pmu);
|
||||
mutex_lock(&arm_pmu_mutex);
|
||||
spin_lock(&arm_pmu_lock);
|
||||
list_del(&cpu_pmu->entry);
|
||||
mutex_unlock(&arm_pmu_mutex);
|
||||
spin_unlock(&arm_pmu_lock);
|
||||
free_percpu(cpu_pmu->hw_events);
|
||||
}
|
||||
|
||||
@ -967,11 +967,12 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu)
|
||||
|
||||
/* If we didn't manage to parse anything, try the interrupt affinity */
|
||||
if (cpumask_weight(&pmu->supported_cpus) == 0) {
|
||||
if (!using_spi) {
|
||||
/* If using PPIs, check the affinity of the partition */
|
||||
int ret, irq;
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (irq_is_percpu(irq)) {
|
||||
/* If using PPIs, check the affinity of the partition */
|
||||
int ret;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
ret = irq_get_percpu_devid_partition(irq, &pmu->supported_cpus);
|
||||
if (ret) {
|
||||
kfree(irqs);
|
||||
|
Loading…
Reference in New Issue
Block a user