[RFC 6/9] arm64: add basic pointer authentication support
This patch adds basic support for pointer authentication, allowing userspace to make use of APIAKey. The kernel maintains an APIAKey value for each process (shared by all threads within), which is initialised to a random value at exec() time. Instructions using other keys (APIBKey, APDAKey, APDBKey) are disabled, and will behave as NOPs. These may be made use of in future patches. No support is added for the generic key (APGAKey), though this cannot be trapped or made to behave as a NOP. Its presence is not advertised with a hwcap. Signed-off-by: Mark RutlandCc: Catalin Marinas Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/Kconfig| 23 + arch/arm64/include/asm/mmu.h | 5 ++ arch/arm64/include/asm/mmu_context.h | 25 +- arch/arm64/include/asm/pointer_auth.h | 88 +++ arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/kernel/cpufeature.c| 11 + arch/arm64/kernel/cpuinfo.c | 1 + 7 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/include/asm/pointer_auth.h diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3741859..0923f70 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -931,6 +931,29 @@ config ARM64_UAO endmenu +menu "ARMv8.3 architectural features" + +config ARM64_POINTER_AUTHENTICATION + bool "Enable support for pointer authentication" + default y + help + Pointer authentication (part of the ARMv8.3 Extensions) provides + instructions for signing and authenticating pointers against secret + keys, which can be used to mitigate Return Oriented Programming (ROP) + and other attacks. + + This option enables these instructions at EL0 (i.e. for userspace). + + Choosing this option will cause the kernel to initialise secret keys + for each process at exec() time, with these keys being + context-switched along with the process. + + The feature is detected at runtime. If the feature is not present in + hardware it will not be advertised to userspace nor will it be + enabled. + +endmenu + config ARM64_MODULE_CMODEL_LARGE bool diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 5468c83..6a848f3 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -16,10 +16,15 @@ #ifndef __ASM_MMU_H #define __ASM_MMU_H +#include + typedef struct { atomic64_t id; void*vdso; unsigned long flags; +#ifdef CONFIG_ARM64_POINTER_AUTHENTICATION + struct ptrauth_keys ptrauth_keys; +#endif } mm_context_t; /* diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index 3257895a..06757a5 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -154,7 +153,14 @@ static inline void cpu_replace_ttbr1(pgd_t *pgd) #define destroy_context(mm)do { } while(0) void check_and_switch_context(struct mm_struct *mm, unsigned int cpu); -#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + atomic64_set(>context.id, 0); + mm_ctx_ptrauth_init(>context); + + return 0; +} /* * This is called when "tsk" is about to enter lazy TLB mode. @@ -200,6 +206,8 @@ static inline void __switch_mm(struct mm_struct *next) return; } + mm_ctx_ptrauth_switch(>context); + check_and_switch_context(next, cpu); } @@ -226,6 +234,19 @@ static inline void __switch_mm(struct mm_struct *next) void verify_cpu_asid_bits(void); +static inline void arch_dup_mmap(struct mm_struct *oldmm, +struct mm_struct *mm) +{ + mm_ctx_ptrauth_dup(>context, >context); +} +#define arch_dup_mmap arch_dup_mmap + +/* + * We need to override arch_dup_mmap before including the generic hooks, which + * are otherwise sufficient for us. + */ +#include + #endif /* !__ASSEMBLY__ */ #endif /* !__ASM_MMU_CONTEXT_H */ diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h new file mode 100644 index 000..345df24 --- /dev/null +++ b/arch/arm64/include/asm/pointer_auth.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + *
[RFC 6/9] arm64: add basic pointer authentication support
This patch adds basic support for pointer authentication, allowing userspace to make use of APIAKey. The kernel maintains an APIAKey value for each process (shared by all threads within), which is initialised to a random value at exec() time. Instructions using other keys (APIBKey, APDAKey, APDBKey) are disabled, and will behave as NOPs. These may be made use of in future patches. No support is added for the generic key (APGAKey), though this cannot be trapped or made to behave as a NOP. Its presence is not advertised with a hwcap. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/Kconfig| 23 + arch/arm64/include/asm/mmu.h | 5 ++ arch/arm64/include/asm/mmu_context.h | 25 +- arch/arm64/include/asm/pointer_auth.h | 88 +++ arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/kernel/cpufeature.c| 11 + arch/arm64/kernel/cpuinfo.c | 1 + 7 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/include/asm/pointer_auth.h diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3741859..0923f70 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -931,6 +931,29 @@ config ARM64_UAO endmenu +menu "ARMv8.3 architectural features" + +config ARM64_POINTER_AUTHENTICATION + bool "Enable support for pointer authentication" + default y + help + Pointer authentication (part of the ARMv8.3 Extensions) provides + instructions for signing and authenticating pointers against secret + keys, which can be used to mitigate Return Oriented Programming (ROP) + and other attacks. + + This option enables these instructions at EL0 (i.e. for userspace). + + Choosing this option will cause the kernel to initialise secret keys + for each process at exec() time, with these keys being + context-switched along with the process. + + The feature is detected at runtime. If the feature is not present in + hardware it will not be advertised to userspace nor will it be + enabled. + +endmenu + config ARM64_MODULE_CMODEL_LARGE bool diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 5468c83..6a848f3 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -16,10 +16,15 @@ #ifndef __ASM_MMU_H #define __ASM_MMU_H +#include + typedef struct { atomic64_t id; void*vdso; unsigned long flags; +#ifdef CONFIG_ARM64_POINTER_AUTHENTICATION + struct ptrauth_keys ptrauth_keys; +#endif } mm_context_t; /* diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index 3257895a..06757a5 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -154,7 +153,14 @@ static inline void cpu_replace_ttbr1(pgd_t *pgd) #define destroy_context(mm)do { } while(0) void check_and_switch_context(struct mm_struct *mm, unsigned int cpu); -#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + atomic64_set(>context.id, 0); + mm_ctx_ptrauth_init(>context); + + return 0; +} /* * This is called when "tsk" is about to enter lazy TLB mode. @@ -200,6 +206,8 @@ static inline void __switch_mm(struct mm_struct *next) return; } + mm_ctx_ptrauth_switch(>context); + check_and_switch_context(next, cpu); } @@ -226,6 +234,19 @@ static inline void __switch_mm(struct mm_struct *next) void verify_cpu_asid_bits(void); +static inline void arch_dup_mmap(struct mm_struct *oldmm, +struct mm_struct *mm) +{ + mm_ctx_ptrauth_dup(>context, >context); +} +#define arch_dup_mmap arch_dup_mmap + +/* + * We need to override arch_dup_mmap before including the generic hooks, which + * are otherwise sufficient for us. + */ +#include + #endif /* !__ASSEMBLY__ */ #endif /* !__ASM_MMU_CONTEXT_H */ diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h new file mode 100644 index 000..345df24 --- /dev/null +++ b/arch/arm64/include/asm/pointer_auth.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License
[RFC 8/9] arm64/kvm: context-switch PAC registers
If we have pointer authentication support, a guest may wish to use it. This patch adds the infrastructure to allow it to do so. This is sufficient for basic testing, but not for real-world usage. A guest will still see pointer authentication support advertised in the ID registers, and we will need to trap accesses to these to provide santized values. Signed-off-by: Mark RutlandCc: Christoffer Dall Cc: Marc Zyngier Cc: kvm...@lists.cs.columbia.edu --- arch/arm64/include/asm/kvm_emulate.h | 15 + arch/arm64/include/asm/kvm_host.h| 12 ++ arch/arm64/kvm/hyp/sysreg-sr.c | 43 3 files changed, 70 insertions(+) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index f5ea0ba..0c3cb43 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -49,6 +51,19 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 |= HCR_E2H; if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) vcpu->arch.hcr_el2 &= ~HCR_RW; + + /* +* Address auth and generic auth share the same enable bits, so we have +* to ensure both are uniform before we can enable support in a guest. +* Until we have the infrastructure to detect uniform absence of a +* feature, only permit the case when both are supported. +* +* Note that a guest will still see the feature in ID_AA64_ISAR1 until +* we introduce code to emulate the ID registers. +*/ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH) && + cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) + vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK); } static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e7705e7..b25f710 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -133,6 +133,18 @@ enum vcpu_sysreg { PMSWINC_EL0,/* Software Increment Register */ PMUSERENR_EL0, /* User Enable Register */ + /* Pointer Authentication Registers */ + APIAKEYLO_EL1, + APIAKEYHI_EL1, + APIBKEYLO_EL1, + APIBKEYHI_EL1, + APDAKEYLO_EL1, + APDAKEYHI_EL1, + APDBKEYLO_EL1, + APDBKEYHI_EL1, + APGAKEYLO_EL1, + APGAKEYHI_EL1, + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c index 9341376..3440b42 100644 --- a/arch/arm64/kvm/hyp/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/sysreg-sr.c @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include @@ -31,6 +33,24 @@ static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { } * pstate, and guest must save everything. */ +#define __save_ap_key(regs, key) \ + regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \ + regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_save_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __save_ap_key(ctxt->sys_regs, APIA); + __save_ap_key(ctxt->sys_regs, APIB); + __save_ap_key(ctxt->sys_regs, APDA); + __save_ap_key(ctxt->sys_regs, APDB); + } + + if (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) { + __save_ap_key(ctxt->sys_regs, APGA); + } +} + static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1); @@ -41,6 +61,8 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); + + __sysreg_save_ap_keys(ctxt); } static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) @@ -84,6 +106,25 @@ void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt) __sysreg_save_common_state(ctxt); } +#define __restore_ap_key(regs, key) \ + write_sysreg_s(regs[key ## KEYLO_EL1], SYS_ ## key ## KEYLO_EL1); \ + write_sysreg_s(regs[key ## KEYHI_EL1], SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_restore_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { +
[RFC 8/9] arm64/kvm: context-switch PAC registers
If we have pointer authentication support, a guest may wish to use it. This patch adds the infrastructure to allow it to do so. This is sufficient for basic testing, but not for real-world usage. A guest will still see pointer authentication support advertised in the ID registers, and we will need to trap accesses to these to provide santized values. Signed-off-by: Mark Rutland Cc: Christoffer Dall Cc: Marc Zyngier Cc: kvm...@lists.cs.columbia.edu --- arch/arm64/include/asm/kvm_emulate.h | 15 + arch/arm64/include/asm/kvm_host.h| 12 ++ arch/arm64/kvm/hyp/sysreg-sr.c | 43 3 files changed, 70 insertions(+) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index f5ea0ba..0c3cb43 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -49,6 +51,19 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 |= HCR_E2H; if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) vcpu->arch.hcr_el2 &= ~HCR_RW; + + /* +* Address auth and generic auth share the same enable bits, so we have +* to ensure both are uniform before we can enable support in a guest. +* Until we have the infrastructure to detect uniform absence of a +* feature, only permit the case when both are supported. +* +* Note that a guest will still see the feature in ID_AA64_ISAR1 until +* we introduce code to emulate the ID registers. +*/ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH) && + cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) + vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK); } static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e7705e7..b25f710 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -133,6 +133,18 @@ enum vcpu_sysreg { PMSWINC_EL0,/* Software Increment Register */ PMUSERENR_EL0, /* User Enable Register */ + /* Pointer Authentication Registers */ + APIAKEYLO_EL1, + APIAKEYHI_EL1, + APIBKEYLO_EL1, + APIBKEYHI_EL1, + APDAKEYLO_EL1, + APDAKEYHI_EL1, + APDBKEYLO_EL1, + APDBKEYHI_EL1, + APGAKEYLO_EL1, + APGAKEYHI_EL1, + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c index 9341376..3440b42 100644 --- a/arch/arm64/kvm/hyp/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/sysreg-sr.c @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include @@ -31,6 +33,24 @@ static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { } * pstate, and guest must save everything. */ +#define __save_ap_key(regs, key) \ + regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \ + regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_save_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __save_ap_key(ctxt->sys_regs, APIA); + __save_ap_key(ctxt->sys_regs, APIB); + __save_ap_key(ctxt->sys_regs, APDA); + __save_ap_key(ctxt->sys_regs, APDB); + } + + if (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) { + __save_ap_key(ctxt->sys_regs, APGA); + } +} + static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1); @@ -41,6 +61,8 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); + + __sysreg_save_ap_keys(ctxt); } static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) @@ -84,6 +106,25 @@ void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt) __sysreg_save_common_state(ctxt); } +#define __restore_ap_key(regs, key) \ + write_sysreg_s(regs[key ## KEYLO_EL1], SYS_ ## key ## KEYLO_EL1); \ + write_sysreg_s(regs[key ## KEYHI_EL1], SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_restore_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __restore_ap_key(ctxt->sys_regs, APIA); + __restore_ap_key(ctxt->sys_regs,
[RFC 9/9] arm64: docs: document pointer authentication
Now that we've added code to support pointer authentication, add some documentation so that people can figure out if/how to use it. Since there are new enable bits in SCR_EL3 (and HCR_EL2), I think we should document something in booting.txt w.r.t. functionality advertised via ID registers being available (e.g. as we expect for FP and other things today). I'm not sure quite what to say, and as it stands this isn't quite correct. Signed-off-by: Mark RutlandCc: Catalin Marinas Cc: Will Deacon --- Documentation/arm64/booting.txt| 8 +++ Documentation/arm64/pointer-authentication.txt | 78 ++ 2 files changed, 86 insertions(+) create mode 100644 Documentation/arm64/pointer-authentication.txt diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt index 8d0df62..8df9f46 100644 --- a/Documentation/arm64/booting.txt +++ b/Documentation/arm64/booting.txt @@ -205,6 +205,14 @@ Before jumping into the kernel, the following conditions must be met: ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b0. - The DT or ACPI tables must describe a GICv2 interrupt controller. + For CPUs with pointer authentication functionality: + - If EL3 is present: +SCR_EL3.APK (bit 16) must be initialised to 0b1 +SCR_EL3.API (bit 17) must be initialised to 0b1 + - If the kernel is entered at EL1: +HCR_EL2.APK (bit 40) must be initialised to 0b1 +HCR_EL2.API (bit 41) must be initialised to 0b1 + The requirements described above for CPU mode, caches, MMUs, architected timers, coherency and system registers apply to all CPUs. All CPUs must enter the kernel in the same exception level. diff --git a/Documentation/arm64/pointer-authentication.txt b/Documentation/arm64/pointer-authentication.txt new file mode 100644 index 000..fb07783 --- /dev/null +++ b/Documentation/arm64/pointer-authentication.txt @@ -0,0 +1,78 @@ +Pointer authentication in AArch64 Linux +=== + +Author: Mark Rutland +Date: 2017-02-21 + +This document briefly describes the provision of pointer authentication +functionality in AArch64 Linux. + + +Architecture overview +- + +The ARMv8.3 Pointer Authentication extension adds primitives that can be +used to mitigate certain classes of attack where an attacker can corrupt +the contents of some memory (e.g. the stack). + +The extension uses a Pointer Authentication Code (PAC) to determine +whether pointers have been modified unexpectedly. A PAC is derived from +a pointer, another value (such as the stack pointer), and a secret key +held in system registers. + +The extension adds instructions to insert a valid PAC into a pointer, +and to verify/remove the PAC from a pointer. The PAC occupies a number +of high-order bits of the pointer, which varies dependent on the +configured virtual address size and whether pointer tagging is in use. + +A subset of these instructions have been allocated from the HINT +encoding space. In the absence of the extension (or when disabled), +these instructions behave as NOPs. Applications and libraries using +these instructions operate correctly regardless of the presence of the +extension. + + +Basic support +- + +When CONFIG_ARM64_POINTER_AUTHENTICATION is selected, and relevant HW +support is present, the kernel will assign a random APIAKey value to +each process at exec*() time. This key is shared by all threads within +the process, and the key is preserved across fork(). Presence of +functionality using APIAKey is advertised via HWCAP_APIA. + +Recent versions of GCC can compile code with APIAKey-based return +address protection when passed the -msign-return-address option. This +uses instructions in the HINT space, and such code can run on systems +without the pointer authentication extension. + +The remaining instruction and data keys (APIBKey, APDAKey, APDBKey) are +reserved for future use, and instructions using these keys must not be +used by software until a purpose and scope for their use has been +decided. To enable future software using these keys to function on +contemporary kernels, where possible, instructions using these keys are +made to behave as NOPs. + +The generic key (APGAKey) is currently unsupported. Instructions using +the generic key must not be used by software. If/when supported in +future, its presence will be advertised via a new hwcap. + + +Virtualization +-- + +When CONFIG_ARM64_POINTER_AUTHENTICATION is selected, and uniform HW +support is present, KVM will context switch all keys used by vCPUs. +Otherwise, the feature is disabled. When disabled, accesses to keys, or +use of instructions enabled within the guest will trap to EL2, and an +UNDEFINED exception will be injected into the guest. + + +Debugging +- + +When CONFIG_ARM64_POINTER_AUTHENTICATION is selected, the kernel exposes +the
[RFC 9/9] arm64: docs: document pointer authentication
Now that we've added code to support pointer authentication, add some documentation so that people can figure out if/how to use it. Since there are new enable bits in SCR_EL3 (and HCR_EL2), I think we should document something in booting.txt w.r.t. functionality advertised via ID registers being available (e.g. as we expect for FP and other things today). I'm not sure quite what to say, and as it stands this isn't quite correct. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Will Deacon --- Documentation/arm64/booting.txt| 8 +++ Documentation/arm64/pointer-authentication.txt | 78 ++ 2 files changed, 86 insertions(+) create mode 100644 Documentation/arm64/pointer-authentication.txt diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt index 8d0df62..8df9f46 100644 --- a/Documentation/arm64/booting.txt +++ b/Documentation/arm64/booting.txt @@ -205,6 +205,14 @@ Before jumping into the kernel, the following conditions must be met: ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b0. - The DT or ACPI tables must describe a GICv2 interrupt controller. + For CPUs with pointer authentication functionality: + - If EL3 is present: +SCR_EL3.APK (bit 16) must be initialised to 0b1 +SCR_EL3.API (bit 17) must be initialised to 0b1 + - If the kernel is entered at EL1: +HCR_EL2.APK (bit 40) must be initialised to 0b1 +HCR_EL2.API (bit 41) must be initialised to 0b1 + The requirements described above for CPU mode, caches, MMUs, architected timers, coherency and system registers apply to all CPUs. All CPUs must enter the kernel in the same exception level. diff --git a/Documentation/arm64/pointer-authentication.txt b/Documentation/arm64/pointer-authentication.txt new file mode 100644 index 000..fb07783 --- /dev/null +++ b/Documentation/arm64/pointer-authentication.txt @@ -0,0 +1,78 @@ +Pointer authentication in AArch64 Linux +=== + +Author: Mark Rutland +Date: 2017-02-21 + +This document briefly describes the provision of pointer authentication +functionality in AArch64 Linux. + + +Architecture overview +- + +The ARMv8.3 Pointer Authentication extension adds primitives that can be +used to mitigate certain classes of attack where an attacker can corrupt +the contents of some memory (e.g. the stack). + +The extension uses a Pointer Authentication Code (PAC) to determine +whether pointers have been modified unexpectedly. A PAC is derived from +a pointer, another value (such as the stack pointer), and a secret key +held in system registers. + +The extension adds instructions to insert a valid PAC into a pointer, +and to verify/remove the PAC from a pointer. The PAC occupies a number +of high-order bits of the pointer, which varies dependent on the +configured virtual address size and whether pointer tagging is in use. + +A subset of these instructions have been allocated from the HINT +encoding space. In the absence of the extension (or when disabled), +these instructions behave as NOPs. Applications and libraries using +these instructions operate correctly regardless of the presence of the +extension. + + +Basic support +- + +When CONFIG_ARM64_POINTER_AUTHENTICATION is selected, and relevant HW +support is present, the kernel will assign a random APIAKey value to +each process at exec*() time. This key is shared by all threads within +the process, and the key is preserved across fork(). Presence of +functionality using APIAKey is advertised via HWCAP_APIA. + +Recent versions of GCC can compile code with APIAKey-based return +address protection when passed the -msign-return-address option. This +uses instructions in the HINT space, and such code can run on systems +without the pointer authentication extension. + +The remaining instruction and data keys (APIBKey, APDAKey, APDBKey) are +reserved for future use, and instructions using these keys must not be +used by software until a purpose and scope for their use has been +decided. To enable future software using these keys to function on +contemporary kernels, where possible, instructions using these keys are +made to behave as NOPs. + +The generic key (APGAKey) is currently unsupported. Instructions using +the generic key must not be used by software. If/when supported in +future, its presence will be advertised via a new hwcap. + + +Virtualization +-- + +When CONFIG_ARM64_POINTER_AUTHENTICATION is selected, and uniform HW +support is present, KVM will context switch all keys used by vCPUs. +Otherwise, the feature is disabled. When disabled, accesses to keys, or +use of instructions enabled within the guest will trap to EL2, and an +UNDEFINED exception will be injected into the guest. + + +Debugging +- + +When CONFIG_ARM64_POINTER_AUTHENTICATION is selected, the kernel exposes +the position of PAC bits in the form of masks that can be queried via +PTRACE_GETREGSET.
[RFC 4/9] arm64/cpufeature: detect pointer authentication
So that we can dynamically handle the presence of pointer authentication functionality, wire up probing code in cpufeature.c. Currently, this only detects the presence of an architected algorithm. Signed-off-by: Mark RutlandCc: Catalin Marinas Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/include/asm/cpucaps.h | 4 +++- arch/arm64/kernel/cpufeature.c | 22 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index fb78a5d..15dd6d6 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -37,7 +37,9 @@ #define ARM64_HAS_NO_FPSIMD16 #define ARM64_WORKAROUND_REPEAT_TLBI 17 #define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18 +#define ARM64_HAS_ADDRESS_AUTH 19 +#define ARM64_HAS_GENERIC_AUTH 20 -#define ARM64_NCAPS19 +#define ARM64_NCAPS21 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 30255b2..172c80e 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -871,6 +871,28 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus .min_field_value = 0, .matches = has_no_fpsimd, }, +#ifdef CONFIG_ARM64_POINTER_AUTHENTICATION + { + .desc = "Address authentication (architected algorithm)", + .capability = ARM64_HAS_ADDRESS_AUTH, + .def_scope = SCOPE_SYSTEM, + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .sign = FTR_UNSIGNED, + .field_pos = ID_AA64ISAR1_APA_SHIFT, + .min_field_value = ID_AA64ISAR1_APA_ARCHITECTED, + .matches = has_cpuid_feature, + }, + { + .desc = "Generic authentication (architected algorithm)", + .capability = ARM64_HAS_GENERIC_AUTH, + .def_scope = SCOPE_SYSTEM, + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .sign = FTR_UNSIGNED, + .field_pos = ID_AA64ISAR1_GPA_SHIFT, + .min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED, + .matches = has_cpuid_feature + }, +#endif /* CONFIG_ARM64_POINTER_AUTHENTICATION */ {}, }; -- 1.9.1
[RFC 4/9] arm64/cpufeature: detect pointer authentication
So that we can dynamically handle the presence of pointer authentication functionality, wire up probing code in cpufeature.c. Currently, this only detects the presence of an architected algorithm. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/include/asm/cpucaps.h | 4 +++- arch/arm64/kernel/cpufeature.c | 22 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index fb78a5d..15dd6d6 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -37,7 +37,9 @@ #define ARM64_HAS_NO_FPSIMD16 #define ARM64_WORKAROUND_REPEAT_TLBI 17 #define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18 +#define ARM64_HAS_ADDRESS_AUTH 19 +#define ARM64_HAS_GENERIC_AUTH 20 -#define ARM64_NCAPS19 +#define ARM64_NCAPS21 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 30255b2..172c80e 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -871,6 +871,28 @@ static bool has_no_fpsimd(const struct arm64_cpu_capabilities *entry, int __unus .min_field_value = 0, .matches = has_no_fpsimd, }, +#ifdef CONFIG_ARM64_POINTER_AUTHENTICATION + { + .desc = "Address authentication (architected algorithm)", + .capability = ARM64_HAS_ADDRESS_AUTH, + .def_scope = SCOPE_SYSTEM, + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .sign = FTR_UNSIGNED, + .field_pos = ID_AA64ISAR1_APA_SHIFT, + .min_field_value = ID_AA64ISAR1_APA_ARCHITECTED, + .matches = has_cpuid_feature, + }, + { + .desc = "Generic authentication (architected algorithm)", + .capability = ARM64_HAS_GENERIC_AUTH, + .def_scope = SCOPE_SYSTEM, + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .sign = FTR_UNSIGNED, + .field_pos = ID_AA64ISAR1_GPA_SHIFT, + .min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED, + .matches = has_cpuid_feature + }, +#endif /* CONFIG_ARM64_POINTER_AUTHENTICATION */ {}, }; -- 1.9.1
[RFC 5/9] arm64: Don't trap host pointer auth use to EL2
To allow EL0 (and/or EL1) to use pointer authentication functionality, we must ensure that pointer authentication instructions and accesses to pointer authentication keys are not trapped to EL2 (where we will not be able to handle them). This patch ensures that HCR_EL2 is configured appropriately when the kernel is booted at EL2. For non-VHE kernels we set HCR_EL2.{API,APK}, ensuring that EL1 can access keys and permit EL0 use of instructions. For VHE kernels, EL2 access is controlled by EL3, and we need not set anything. This does not enable support for KVM guests, since KVM manages HCR_EL2 itself. Signed-off-by: Mark RutlandCc: Catalin Marinas Cc: Christoffer Dall Cc: Marc Zyngier Cc: Will Deacon Cc: kvm...@lists.cs.columbia.edu --- arch/arm64/include/asm/kvm_arm.h | 2 ++ arch/arm64/kernel/head.S | 19 +-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 6e99978..d8a1271 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -23,6 +23,8 @@ #include /* Hyp Configuration Register (HCR) bits */ +#define HCR_API(UL(1) << 41) +#define HCR_APK(UL(1) << 40) #define HCR_E2H(UL(1) << 34) #define HCR_ID (UL(1) << 33) #define HCR_CD (UL(1) << 32) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 0b13748..9f3f49f 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -562,10 +562,25 @@ CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2 /* Hyp configuration. */ mov x0, #HCR_RW // 64-bit EL1 - cbz x2, set_hcr + cbz x2, 1f orr x0, x0, #HCR_TGE// Enable Host Extensions orr x0, x0, #HCR_E2H -set_hcr: +1: +#ifdef CONFIG_ARM64_POINTER_AUTHENTICATION + /* +* Disable pointer authentication traps to EL2. The HCR_EL2.{APK,API} +* bits exist iff at least one authentication mechanism is implemented. +*/ + mrs x1, id_aa64isar1_el1 + mov_q x3, ((0xf << ID_AA64ISAR1_GPI_SHIFT) | \ +(0xf << ID_AA64ISAR1_GPA_SHIFT) | \ +(0xf << ID_AA64ISAR1_API_SHIFT) | \ +(0xf << ID_AA64ISAR1_APA_SHIFT)) + and x1, x1, x3 + cbz x1, 1f + orr x0, x0, #(HCR_APK | HCR_API) +1: +#endif msr hcr_el2, x0 isb -- 1.9.1
[RFC 5/9] arm64: Don't trap host pointer auth use to EL2
To allow EL0 (and/or EL1) to use pointer authentication functionality, we must ensure that pointer authentication instructions and accesses to pointer authentication keys are not trapped to EL2 (where we will not be able to handle them). This patch ensures that HCR_EL2 is configured appropriately when the kernel is booted at EL2. For non-VHE kernels we set HCR_EL2.{API,APK}, ensuring that EL1 can access keys and permit EL0 use of instructions. For VHE kernels, EL2 access is controlled by EL3, and we need not set anything. This does not enable support for KVM guests, since KVM manages HCR_EL2 itself. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Christoffer Dall Cc: Marc Zyngier Cc: Will Deacon Cc: kvm...@lists.cs.columbia.edu --- arch/arm64/include/asm/kvm_arm.h | 2 ++ arch/arm64/kernel/head.S | 19 +-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 6e99978..d8a1271 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -23,6 +23,8 @@ #include /* Hyp Configuration Register (HCR) bits */ +#define HCR_API(UL(1) << 41) +#define HCR_APK(UL(1) << 40) #define HCR_E2H(UL(1) << 34) #define HCR_ID (UL(1) << 33) #define HCR_CD (UL(1) << 32) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 0b13748..9f3f49f 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -562,10 +562,25 @@ CPU_LE( bic x0, x0, #(1 << 25) ) // Clear the EE bit for EL2 /* Hyp configuration. */ mov x0, #HCR_RW // 64-bit EL1 - cbz x2, set_hcr + cbz x2, 1f orr x0, x0, #HCR_TGE// Enable Host Extensions orr x0, x0, #HCR_E2H -set_hcr: +1: +#ifdef CONFIG_ARM64_POINTER_AUTHENTICATION + /* +* Disable pointer authentication traps to EL2. The HCR_EL2.{APK,API} +* bits exist iff at least one authentication mechanism is implemented. +*/ + mrs x1, id_aa64isar1_el1 + mov_q x3, ((0xf << ID_AA64ISAR1_GPI_SHIFT) | \ +(0xf << ID_AA64ISAR1_GPA_SHIFT) | \ +(0xf << ID_AA64ISAR1_API_SHIFT) | \ +(0xf << ID_AA64ISAR1_APA_SHIFT)) + and x1, x1, x3 + cbz x1, 1f + orr x0, x0, #(HCR_APK | HCR_API) +1: +#endif msr hcr_el2, x0 isb -- 1.9.1
[RFC 3/9] arm64/cpufeature: add ARMv8.3 id_aa64isar1 bits
>From ARMv8.3 onwards, ID_AA64ISAR1 is no longer entirely RES0, and now has four fields describing the presence of pointer authentication functionality: * APA - address authentication present, using an architected algorithm * API - address authentication present, using an IMP DEF algorithm * GPA - generic authentication present, using an architected algorithm * GPI - generic authentication present, using an IMP DEF algoithm This patch adds the requisite definitions so that we can identify the presence of this functionality. For the timebeing, the features are hidden from userspace. Signed-off-by: Mark RutlandCc: Catalin Marinas Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/kernel/cpufeature.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 81a78d9..30255b2 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -101,7 +101,11 @@ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_LRCPC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_FCMA_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0), - ARM64_FTR_END, + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_GPI_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_GPA_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_API_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_APA_SHIFT, 4, 0), + ARM64_FTR_END }; static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { -- 1.9.1
Re: [RFC PATCH 1/4] fs: new infrastructure for writeback error handling and reporting
On Mon, 2017-04-03 at 07:47 -0700, Matthew Wilcox wrote: > On Fri, Mar 31, 2017 at 03:26:00PM -0400, Jeff Layton wrote: > > This set adds a wb_error field and a sequence counter to the > > address_space, and a corresponding sequence counter in the struct file. > > When errors are reported during writeback, we set the error field in the > > mapping and increment the sequence counter. > > +++ b/fs/open.c > > @@ -709,6 +709,9 @@ static int do_dentry_open(struct file *f, > > f->f_inode = inode; > > f->f_mapping = inode->i_mapping; > > > > + /* Don't need the i_lock since we're only interested in sequence */ > > + f->f_wb_err_seq = inode->i_mapping->wb_err_seq; > > + > > Do we need READ_ONCE() though, to ensure we get a consistent view of > wb_err_seq? In particular, you made it 64 bit, so 32-bit architectures > are going to have a problem if it's rolling over between 2^32-1 and 2^32. > Yeah, I thought about that, and wasn't sure so I left that off. If you think it's a good idea, then I'm fine with adding it. > > +++ b/include/linux/fs.h > > @@ -394,6 +394,8 @@ struct address_space { > > gfp_t gfp_mask; /* implicit gfp mask for > > allocations */ > > struct list_headprivate_list; /* ditto */ > > void*private_data; /* ditto */ > > + u64 wb_err_seq; > > + int wb_err; > > } __attribute__((aligned(sizeof(long; > > /* > > * On most architectures that alignment is already the case; but > > I thought we had you convinced to make wb_err_seq an s32 and do clock > arithmetic? > > > +int filemap_report_wb_error(struct file *file) > > +{ > > + int err = 0; > > + struct inode *inode = file_inode(file); > > + struct address_space *mapping = file->f_mapping; > > + > > + spin_lock(>i_lock); > > + if (file->f_wb_err_seq < mapping->wb_err_seq) { > > + err = mapping->wb_err; > > + file->f_wb_err_seq = mapping->wb_err_seq; > > + } > > + spin_unlock(>i_lock); > > + return err; > > +} > > Now that I think about this some more, I don't think you even need clock > arithmetic -- you just need !=. And that means there's only a 1 in 2^32 > chance that you miss an error. Good enough, I say! Particularly since > if errors are occurring that frequently that we wrapped the sequence > counter, the chance that we hit that magic point are really low. > > We could even combine the two (I know Dave Chinner has been really > against growing struct address_space in the past): > > int decode_wb_err(u32 wb_err) > { > if (wb_err & 1) > return -EIO; > if (wb_err & 2) > return -ENOSPC; > return 0; > } > > void set_wb_err(struct address_space *mapping, int err) > { > if (err == -EIO) > mapping->wb_err |= 1; > else if (err == -ENOSPC) > mapping->wb_err |= 2; > else > return; > mapping->wb_err += 4; > } > > ... > if (file->f_wb_err != mapping->wb_err) { > err = decode_wb_err(mapping->wb_err); > file->f_wb_err = mapping->wb_err; > } Agreed. I had the same thought about checking for equality just after I hit send last week. :) Yes, so just to be clear here if you bump a 32 bit counter every microsecond you'll end up wrapping in a little over an hour. How fast can DAX generate I/O errors? :) I'm fine with a 32 bit counter (and even with using the low order bits to store error flags) if we're ok with that limitation. The big question there is whether it's ok to continue reporting -EIO when there has actually been nothing but -ENOSPC errors since the last fsync. I think it's a corner case that's not of terribly great concern so I'm fine with that. We could try to mitigate it by zeroing out the value when i_writecount goes to zero though. Then if you close all of the fds on the file, the error is cleared. Or maybe we could add a new ioctl to explicitly zero it out? -- Jeff Layton
[RFC 3/9] arm64/cpufeature: add ARMv8.3 id_aa64isar1 bits
>From ARMv8.3 onwards, ID_AA64ISAR1 is no longer entirely RES0, and now has four fields describing the presence of pointer authentication functionality: * APA - address authentication present, using an architected algorithm * API - address authentication present, using an IMP DEF algorithm * GPA - generic authentication present, using an architected algorithm * GPI - generic authentication present, using an IMP DEF algoithm This patch adds the requisite definitions so that we can identify the presence of this functionality. For the timebeing, the features are hidden from userspace. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/kernel/cpufeature.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 81a78d9..30255b2 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -101,7 +101,11 @@ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_LRCPC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_FCMA_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0), - ARM64_FTR_END, + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_GPI_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_GPA_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_API_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_APA_SHIFT, 4, 0), + ARM64_FTR_END }; static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { -- 1.9.1
Re: [RFC PATCH 1/4] fs: new infrastructure for writeback error handling and reporting
On Mon, 2017-04-03 at 07:47 -0700, Matthew Wilcox wrote: > On Fri, Mar 31, 2017 at 03:26:00PM -0400, Jeff Layton wrote: > > This set adds a wb_error field and a sequence counter to the > > address_space, and a corresponding sequence counter in the struct file. > > When errors are reported during writeback, we set the error field in the > > mapping and increment the sequence counter. > > +++ b/fs/open.c > > @@ -709,6 +709,9 @@ static int do_dentry_open(struct file *f, > > f->f_inode = inode; > > f->f_mapping = inode->i_mapping; > > > > + /* Don't need the i_lock since we're only interested in sequence */ > > + f->f_wb_err_seq = inode->i_mapping->wb_err_seq; > > + > > Do we need READ_ONCE() though, to ensure we get a consistent view of > wb_err_seq? In particular, you made it 64 bit, so 32-bit architectures > are going to have a problem if it's rolling over between 2^32-1 and 2^32. > Yeah, I thought about that, and wasn't sure so I left that off. If you think it's a good idea, then I'm fine with adding it. > > +++ b/include/linux/fs.h > > @@ -394,6 +394,8 @@ struct address_space { > > gfp_t gfp_mask; /* implicit gfp mask for > > allocations */ > > struct list_headprivate_list; /* ditto */ > > void*private_data; /* ditto */ > > + u64 wb_err_seq; > > + int wb_err; > > } __attribute__((aligned(sizeof(long; > > /* > > * On most architectures that alignment is already the case; but > > I thought we had you convinced to make wb_err_seq an s32 and do clock > arithmetic? > > > +int filemap_report_wb_error(struct file *file) > > +{ > > + int err = 0; > > + struct inode *inode = file_inode(file); > > + struct address_space *mapping = file->f_mapping; > > + > > + spin_lock(>i_lock); > > + if (file->f_wb_err_seq < mapping->wb_err_seq) { > > + err = mapping->wb_err; > > + file->f_wb_err_seq = mapping->wb_err_seq; > > + } > > + spin_unlock(>i_lock); > > + return err; > > +} > > Now that I think about this some more, I don't think you even need clock > arithmetic -- you just need !=. And that means there's only a 1 in 2^32 > chance that you miss an error. Good enough, I say! Particularly since > if errors are occurring that frequently that we wrapped the sequence > counter, the chance that we hit that magic point are really low. > > We could even combine the two (I know Dave Chinner has been really > against growing struct address_space in the past): > > int decode_wb_err(u32 wb_err) > { > if (wb_err & 1) > return -EIO; > if (wb_err & 2) > return -ENOSPC; > return 0; > } > > void set_wb_err(struct address_space *mapping, int err) > { > if (err == -EIO) > mapping->wb_err |= 1; > else if (err == -ENOSPC) > mapping->wb_err |= 2; > else > return; > mapping->wb_err += 4; > } > > ... > if (file->f_wb_err != mapping->wb_err) { > err = decode_wb_err(mapping->wb_err); > file->f_wb_err = mapping->wb_err; > } Agreed. I had the same thought about checking for equality just after I hit send last week. :) Yes, so just to be clear here if you bump a 32 bit counter every microsecond you'll end up wrapping in a little over an hour. How fast can DAX generate I/O errors? :) I'm fine with a 32 bit counter (and even with using the low order bits to store error flags) if we're ok with that limitation. The big question there is whether it's ok to continue reporting -EIO when there has actually been nothing but -ENOSPC errors since the last fsync. I think it's a corner case that's not of terribly great concern so I'm fine with that. We could try to mitigate it by zeroing out the value when i_writecount goes to zero though. Then if you close all of the fds on the file, the error is cleared. Or maybe we could add a new ioctl to explicitly zero it out? -- Jeff Layton
Re: [PATCH 2/3] dt-bindings: Add bindings for nvidia,tegra186-ccplex-cluster
On 04/03/2017 05:24 PM, Jon Hunter wrote: On 03/04/17 13:42, Mikko Perttunen wrote: The Tegra186 CCPLEX_CLUSTER area contains memory-mapped registers that initiate CPU frequency/voltage transitions. Signed-off-by: Mikko Perttunen--- .../arm/tegra/nvidia,tegra186-ccplex-cluster.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt new file mode 100644 index ..50cd615219e9 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt @@ -0,0 +1,22 @@ +NVIDIA Tegra CCPLEX_CLUSTER area + +Required properties: +- compatible: Should contain one of the following: + - "nvidia,tegra186-ccplex-cluster": for Tegra186 Nit pick ... any reason why we append 'cluster' here? The TRM just says the "CPU Complex" consists of two CPU clusters. So "nvidia,tegra186-cpu-complex" or "nvidia,tegra186-ccplex" seems fine. BTW, I do see references in the TRM to CCPLEX_CLUSTER0/1, but never CCPLEX_CLUSTER in reference to both. I think it is just CCPLEX AFAICT. The reason was that the MMIO aperture is called "CCPLEX_CLUSTER" in the address map. But I agree it's not a very descriptive name. Cheers Jon
Re: [PATCH 2/3] dt-bindings: Add bindings for nvidia,tegra186-ccplex-cluster
On 04/03/2017 05:24 PM, Jon Hunter wrote: On 03/04/17 13:42, Mikko Perttunen wrote: The Tegra186 CCPLEX_CLUSTER area contains memory-mapped registers that initiate CPU frequency/voltage transitions. Signed-off-by: Mikko Perttunen --- .../arm/tegra/nvidia,tegra186-ccplex-cluster.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt new file mode 100644 index ..50cd615219e9 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt @@ -0,0 +1,22 @@ +NVIDIA Tegra CCPLEX_CLUSTER area + +Required properties: +- compatible: Should contain one of the following: + - "nvidia,tegra186-ccplex-cluster": for Tegra186 Nit pick ... any reason why we append 'cluster' here? The TRM just says the "CPU Complex" consists of two CPU clusters. So "nvidia,tegra186-cpu-complex" or "nvidia,tegra186-ccplex" seems fine. BTW, I do see references in the TRM to CCPLEX_CLUSTER0/1, but never CCPLEX_CLUSTER in reference to both. I think it is just CCPLEX AFAICT. The reason was that the MMIO aperture is called "CCPLEX_CLUSTER" in the address map. But I agree it's not a very descriptive name. Cheers Jon
[RFC 1/9] asm-generic: mm_hooks: allow hooks to be overridden individually
Currently, an architecture must either implement all of the mm hooks itself, or use all of those provided by the asm-generic implementation. When an architecture only needs to override a single hook, it must copy the stub implementations from the asm-generic version. To avoid this repetition, allow each hook to be overridden indiviually, by placing each under an #ifndef block. As architectures providing their own hooks can't include this file today, this shouldn't adversely affect any existing hooks. Signed-off-by: Mark RutlandCc: Arnd Bergmann Cc: linux-a...@vger.kernel.org --- include/asm-generic/mm_hooks.h | 12 1 file changed, 12 insertions(+) diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h index cc5d9a1..c5a4328 100644 --- a/include/asm-generic/mm_hooks.h +++ b/include/asm-generic/mm_hooks.h @@ -6,36 +6,48 @@ #ifndef _ASM_GENERIC_MM_HOOKS_H #define _ASM_GENERIC_MM_HOOKS_H +#ifndef arch_dup_mmap static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) { } +#endif +#ifndef arch_exit_mmap static inline void arch_exit_mmap(struct mm_struct *mm) { } +#endif +#ifndef arch_unmap static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end) { } +#endif +#ifndef arch_bprm_mm_init static inline void arch_bprm_mm_init(struct mm_struct *mm, struct vm_area_struct *vma) { } +#endif +#ifndef arch_vma_access_permitted static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { /* by default, allow everything */ return true; } +#endif +#ifndef arch_pte_access_permitted static inline bool arch_pte_access_permitted(pte_t pte, bool write) { /* by default, allow everything */ return true; } +#endif #endif /* _ASM_GENERIC_MM_HOOKS_H */ -- 1.9.1
[RFC 1/9] asm-generic: mm_hooks: allow hooks to be overridden individually
Currently, an architecture must either implement all of the mm hooks itself, or use all of those provided by the asm-generic implementation. When an architecture only needs to override a single hook, it must copy the stub implementations from the asm-generic version. To avoid this repetition, allow each hook to be overridden indiviually, by placing each under an #ifndef block. As architectures providing their own hooks can't include this file today, this shouldn't adversely affect any existing hooks. Signed-off-by: Mark Rutland Cc: Arnd Bergmann Cc: linux-a...@vger.kernel.org --- include/asm-generic/mm_hooks.h | 12 1 file changed, 12 insertions(+) diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h index cc5d9a1..c5a4328 100644 --- a/include/asm-generic/mm_hooks.h +++ b/include/asm-generic/mm_hooks.h @@ -6,36 +6,48 @@ #ifndef _ASM_GENERIC_MM_HOOKS_H #define _ASM_GENERIC_MM_HOOKS_H +#ifndef arch_dup_mmap static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) { } +#endif +#ifndef arch_exit_mmap static inline void arch_exit_mmap(struct mm_struct *mm) { } +#endif +#ifndef arch_unmap static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end) { } +#endif +#ifndef arch_bprm_mm_init static inline void arch_bprm_mm_init(struct mm_struct *mm, struct vm_area_struct *vma) { } +#endif +#ifndef arch_vma_access_permitted static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { /* by default, allow everything */ return true; } +#endif +#ifndef arch_pte_access_permitted static inline bool arch_pte_access_permitted(pte_t pte, bool write) { /* by default, allow everything */ return true; } +#endif #endif /* _ASM_GENERIC_MM_HOOKS_H */ -- 1.9.1
Re: [PATCH 2/3] dt-bindings: Add bindings for nvidia,tegra186-ccplex-cluster
On 04/03/2017 05:06 PM, Thierry Reding wrote: On Mon, Apr 03, 2017 at 03:42:24PM +0300, Mikko Perttunen wrote: The Tegra186 CCPLEX_CLUSTER area contains memory-mapped registers that initiate CPU frequency/voltage transitions. Signed-off-by: Mikko Perttunen--- .../arm/tegra/nvidia,tegra186-ccplex-cluster.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt new file mode 100644 index ..50cd615219e9 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt @@ -0,0 +1,22 @@ +NVIDIA Tegra CCPLEX_CLUSTER area + +Required properties: +- compatible: Should contain one of the following: + - "nvidia,tegra186-ccplex-cluster": for Tegra186 +- reg: Must contain an (offset, length) pair of the register set for each + entry in reg-names. +- reg-names: Must include the following entries: + - "a57": Public aperture for A57 CPU cluster + - "denver": Public aperture for Denver CPU cluster +- nvidia,bpmp: Phandle to BPMP device that can be queried for OPP tables "phandle" Will fix. +Example: + + ccplex@e00 { + compatible = "nvidia,tegra186-ccplex-cluster"; + reg = <0x0 0x0e06 0x0 0x1000>, + <0x0 0x0e07 0x0 0x1000>; + reg-names = "a57", "denver"; + + nvidia,bpmp = <>; + }; Where's the information about the register offsets coming from? The TRM says that CCPLEX_CLUSTER has a single aperture from 0x0e00 to 0x0e3f. Some internal document with a name related to Denver power management, IIRC. I'll link it to you tomorrow. Thierry
Re: [PATCH 2/3] dt-bindings: Add bindings for nvidia,tegra186-ccplex-cluster
On 04/03/2017 05:06 PM, Thierry Reding wrote: On Mon, Apr 03, 2017 at 03:42:24PM +0300, Mikko Perttunen wrote: The Tegra186 CCPLEX_CLUSTER area contains memory-mapped registers that initiate CPU frequency/voltage transitions. Signed-off-by: Mikko Perttunen --- .../arm/tegra/nvidia,tegra186-ccplex-cluster.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt new file mode 100644 index ..50cd615219e9 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-ccplex-cluster.txt @@ -0,0 +1,22 @@ +NVIDIA Tegra CCPLEX_CLUSTER area + +Required properties: +- compatible: Should contain one of the following: + - "nvidia,tegra186-ccplex-cluster": for Tegra186 +- reg: Must contain an (offset, length) pair of the register set for each + entry in reg-names. +- reg-names: Must include the following entries: + - "a57": Public aperture for A57 CPU cluster + - "denver": Public aperture for Denver CPU cluster +- nvidia,bpmp: Phandle to BPMP device that can be queried for OPP tables "phandle" Will fix. +Example: + + ccplex@e00 { + compatible = "nvidia,tegra186-ccplex-cluster"; + reg = <0x0 0x0e06 0x0 0x1000>, + <0x0 0x0e07 0x0 0x1000>; + reg-names = "a57", "denver"; + + nvidia,bpmp = <>; + }; Where's the information about the register offsets coming from? The TRM says that CCPLEX_CLUSTER has a single aperture from 0x0e00 to 0x0e3f. Some internal document with a name related to Denver power management, IIRC. I'll link it to you tomorrow. Thierry
Re: imx-drm: vblank wait timed out
2017-03-31 14:57 GMT+02:00 Philipp Zabel: > Hi Christian, > > On Fri, 2017-03-31 at 12:44 +0200, Christian Gmeiner wrote: >> Hi >> >> I get this from time to time on a 4.9.17 kernel: >> >> [3.353387] [ cut here ] >> [3.353408] WARNING: CPU: 0 PID: 1 at >> drivers/gpu/drm/drm_atomic_helper.c:1140 >> drm_atomic_helper_wait_for_vblanks+0x240/0x244 >> [3.353412] [CRTC:24] vblank wait timed out > [...] > > Do the four patches in > git://git.pengutronix.de/git/pza/linux.git tags/v4.9-ipu-dp-plane-fix > fix this? > Sadly no - this is what I get after a warm-reboot: [2.797368] imx-drm display-subsystem: bound imx-ipuv3-crtc.2 (ops ipu_crtc_ops) [2.804985] imx-drm display-subsystem: bound imx-ipuv3-crtc.3 (ops ipu_crtc_ops) [2.812574] imx-drm display-subsystem: bound imx-ipuv3-crtc.6 (ops ipu_crtc_ops) [2.820170] imx-drm display-subsystem: bound imx-ipuv3-crtc.7 (ops ipu_crtc_ops) [2.828119] imx-drm display-subsystem: bound 200.aips-bus:ldb@020e0008 (ops imx_ldb_ops) [ 13.933401] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 24.173399] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 24.175535] Console: switching to colour frame buffer device 80x30 [ 34.413391] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 34.460376] imx-drm display-subsystem: fb0: frame buffer device [ 34.504119] imx-ipuv3 280.ipu: IPUv3H probed ... [ 45.933472] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 56.173522] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 66.413519] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 76.653515] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 87.533556] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 99.053496] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 109.933532] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 120.813541] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 131.053513] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out greets -- Christian Gmeiner, MSc https://www.youtube.com/user/AloryOFFICIAL https://soundcloud.com/christian-gmeiner
Re: imx-drm: vblank wait timed out
2017-03-31 14:57 GMT+02:00 Philipp Zabel : > Hi Christian, > > On Fri, 2017-03-31 at 12:44 +0200, Christian Gmeiner wrote: >> Hi >> >> I get this from time to time on a 4.9.17 kernel: >> >> [3.353387] [ cut here ] >> [3.353408] WARNING: CPU: 0 PID: 1 at >> drivers/gpu/drm/drm_atomic_helper.c:1140 >> drm_atomic_helper_wait_for_vblanks+0x240/0x244 >> [3.353412] [CRTC:24] vblank wait timed out > [...] > > Do the four patches in > git://git.pengutronix.de/git/pza/linux.git tags/v4.9-ipu-dp-plane-fix > fix this? > Sadly no - this is what I get after a warm-reboot: [2.797368] imx-drm display-subsystem: bound imx-ipuv3-crtc.2 (ops ipu_crtc_ops) [2.804985] imx-drm display-subsystem: bound imx-ipuv3-crtc.3 (ops ipu_crtc_ops) [2.812574] imx-drm display-subsystem: bound imx-ipuv3-crtc.6 (ops ipu_crtc_ops) [2.820170] imx-drm display-subsystem: bound imx-ipuv3-crtc.7 (ops ipu_crtc_ops) [2.828119] imx-drm display-subsystem: bound 200.aips-bus:ldb@020e0008 (ops imx_ldb_ops) [ 13.933401] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 24.173399] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 24.175535] Console: switching to colour frame buffer device 80x30 [ 34.413391] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 34.460376] imx-drm display-subsystem: fb0: frame buffer device [ 34.504119] imx-ipuv3 280.ipu: IPUv3H probed ... [ 45.933472] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 56.173522] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 66.413519] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 76.653515] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 87.533556] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 99.053496] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 109.933532] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 120.813541] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out [ 131.053513] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR* [CRTC:24:crtc-0] flip_done timed out greets -- Christian Gmeiner, MSc https://www.youtube.com/user/AloryOFFICIAL https://soundcloud.com/christian-gmeiner
Re: [PATCH v6 02/39] [media] dt-bindings: Add bindings for i.MX media driver
On Mon, Apr 03, 2017 at 09:07:43AM -0500, Rob Herring wrote: > On Tue, Mar 28, 2017 at 05:35:52PM -0700, Steve Longerbeam wrote: > > I assume if there's another binding doc in progress, it means > > someone is working on another Synopsys DW CSI-2 subdevice driver. > > Yes. see http://patchwork.ozlabs.org/patch/736177/ > > > Unfortunately I don't have the time to contribute and switch to > > this other subdevice, and do test/debug. > > >From a DT perspective, I'm not asking that you share the subdevice > driver, only the binding. Simply put, there's 1 h/w block here, so there > should only be 1 binding. The binding is an ABI, so you can't just merge > it and change it later. I think it would be nice to have some kind of standard base binding for CSI2 interfaces, but beyond the standard compatible/reg/interrupts and graph properties, I'm not sure what it would look like. As far as those properties go, the iMX6 version does better than the DW version, because we specify the full graph, whereas the DW version only specifies the downstream link. Once that's done, there's some properties (like those specifying the output configuration) which probably ought to be moved to the graph links instead, once they exist. So, if anything, I think it's the DW version needs to be augmented with fuller information, and some of the properties moved. Also, as I've mentioned in my other reply, while they may both appear to be called "Synopsys DW CSI-2" devices, they appear to be quite different from the hardware perspective. The rest -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
Re: [PATCH v6 02/39] [media] dt-bindings: Add bindings for i.MX media driver
On Mon, Apr 03, 2017 at 09:07:43AM -0500, Rob Herring wrote: > On Tue, Mar 28, 2017 at 05:35:52PM -0700, Steve Longerbeam wrote: > > I assume if there's another binding doc in progress, it means > > someone is working on another Synopsys DW CSI-2 subdevice driver. > > Yes. see http://patchwork.ozlabs.org/patch/736177/ > > > Unfortunately I don't have the time to contribute and switch to > > this other subdevice, and do test/debug. > > >From a DT perspective, I'm not asking that you share the subdevice > driver, only the binding. Simply put, there's 1 h/w block here, so there > should only be 1 binding. The binding is an ABI, so you can't just merge > it and change it later. I think it would be nice to have some kind of standard base binding for CSI2 interfaces, but beyond the standard compatible/reg/interrupts and graph properties, I'm not sure what it would look like. As far as those properties go, the iMX6 version does better than the DW version, because we specify the full graph, whereas the DW version only specifies the downstream link. Once that's done, there's some properties (like those specifying the output configuration) which probably ought to be moved to the graph links instead, once they exist. So, if anything, I think it's the DW version needs to be augmented with fuller information, and some of the properties moved. Also, as I've mentioned in my other reply, while they may both appear to be called "Synopsys DW CSI-2" devices, they appear to be quite different from the hardware perspective. The rest -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
Re: [PATCH v4 1/2] power: supply: ltc2941-battery-gauge: Add vendor to compatibles in binding
On Wed, Mar 29, 2017 at 12:00:56PM -0400, Javier Martinez Canillas wrote: > The DT binding document for LTC2941 and LTC2943 battery gauges did not use > a vendor prefix in the listed compatible strings. The driver says that the > manufacturer is Linear Technology which is "lltc" in vendor-prefixes.txt. > > There isn't an upstream Device Tree source file that has nodes defined for > these devices, so there's no need to keep the old compatible strings. > > Signed-off-by: Javier Martinez Canillas> --- > > Changes in v4: None > Changes in v3: None > Changes in v2: None > > Documentation/devicetree/bindings/power/supply/ltc2941.txt | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) Acked-by: Rob Herring
Re: [PATCH v4 1/2] power: supply: ltc2941-battery-gauge: Add vendor to compatibles in binding
On Wed, Mar 29, 2017 at 12:00:56PM -0400, Javier Martinez Canillas wrote: > The DT binding document for LTC2941 and LTC2943 battery gauges did not use > a vendor prefix in the listed compatible strings. The driver says that the > manufacturer is Linear Technology which is "lltc" in vendor-prefixes.txt. > > There isn't an upstream Device Tree source file that has nodes defined for > these devices, so there's no need to keep the old compatible strings. > > Signed-off-by: Javier Martinez Canillas > --- > > Changes in v4: None > Changes in v3: None > Changes in v2: None > > Documentation/devicetree/bindings/power/supply/ltc2941.txt | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) Acked-by: Rob Herring
Re: linux-next: manual merge of the xen-tip tree with the tip tree
On 03/04/17 16:38, Ingo Molnar wrote: > > * Juergen Grosswrote: > >>> So my suggestion would be: could you delay 75cd32d6093e for a week, and >>> then >>> merge it on top of a pulled in tip:x86/mm? I'll send that tree to Linus on >>> the >>> first day of the merge window so there shouldn't be any ordering problems. >> >> Okay, that's rather easy to do. >> >> Boris, I renamed the current Xen for-linus-4.12 branch for easy development >> of >> other Xen patches to for-linus-4.12-pre. >> >> I'll create another branch for-linus-4.12 based on the tip tree next week >> which >> will be subject to the pull request for Linus. As soon as for-linus-4.12 is >> ready the for-linus-4.12-pre branch shouldn't be used any longer. > > I've created a tip:x86-mm-for-xen branch with the following head: > > 7f75540ff2ca ("Merge tag 'v4.11-rc5' into x86/mm, to refresh the branch") > > ... which should be a reasonable base that includes a working version of the > 5-level pagetable changes. Thanks, Juergen
Re: linux-next: manual merge of the xen-tip tree with the tip tree
On 03/04/17 16:38, Ingo Molnar wrote: > > * Juergen Gross wrote: > >>> So my suggestion would be: could you delay 75cd32d6093e for a week, and >>> then >>> merge it on top of a pulled in tip:x86/mm? I'll send that tree to Linus on >>> the >>> first day of the merge window so there shouldn't be any ordering problems. >> >> Okay, that's rather easy to do. >> >> Boris, I renamed the current Xen for-linus-4.12 branch for easy development >> of >> other Xen patches to for-linus-4.12-pre. >> >> I'll create another branch for-linus-4.12 based on the tip tree next week >> which >> will be subject to the pull request for Linus. As soon as for-linus-4.12 is >> ready the for-linus-4.12-pre branch shouldn't be used any longer. > > I've created a tip:x86-mm-for-xen branch with the following head: > > 7f75540ff2ca ("Merge tag 'v4.11-rc5' into x86/mm, to refresh the branch") > > ... which should be a reasonable base that includes a working version of the > 5-level pagetable changes. Thanks, Juergen
Re: [PATCH 1/7] mfd: cros-ec: Fix host command buffer size
On 03/04/17 16:30, Lee Jones wrote: > On Mon, 03 Apr 2017, Lee Jones wrote: > >> On Fri, 24 Mar 2017, Enric Balletbo i Serra wrote: >> >>> From: Vic Yang>>> >>> For SPI, we can get up to 32 additional bytes for response preamble. >>> The current overhead (2 bytes) may cause problems when we try to receive >>> a big response. Update it to 32 bytes. >>> >>> Without this fix we could see a kernel BUG when we receive a big response >>> from the Chrome EC when is connected via SPI. >>> >>> Signed-off-by: Vic Yang >>> Tested-by: Enric Balletbo i Serra >>> --- >>> >>> This patch is a FIX, and I think that would be interesting see it merged >>> in this release cycle. This should go through the MFD tree and can be picked >>> independently of the other patches. Lee Jones I think this is for you. >>> >>> include/linux/mfd/cros_ec.h | 3 ++- >>> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> Applied, thanks. > > Scrap that, I'll keep it with the set. > Ok, I'll send a v2 asap with this patch and the few modifications requested on patch 7/7. I'm wondering though if this specific patch could go with current release cycle as (explained above) is a fix and current kernel is affected. Thanks, Enric >>> diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h >>> index b3e812f..3b16c90 100644 >>> --- a/include/linux/mfd/cros_ec.h >>> +++ b/include/linux/mfd/cros_ec.h >>> @@ -35,10 +35,11 @@ >>> * Max bus-specific overhead incurred by request/responses. >>> * I2C requires 1 additional byte for requests. >>> * I2C requires 2 additional bytes for responses. >>> + * SPI requires up to 32 additional bytes for responses. >>> * */ >>> #define EC_PROTO_VERSION_UNKNOWN 0 >>> #define EC_MAX_REQUEST_OVERHEAD1 >>> -#define EC_MAX_RESPONSE_OVERHEAD 2 >>> +#define EC_MAX_RESPONSE_OVERHEAD 32 >>> >>> /* >>> * Command interface between EC and AP, for LPC, I2C and SPI interfaces. >> >
Re: [PATCH 1/7] mfd: cros-ec: Fix host command buffer size
On 03/04/17 16:30, Lee Jones wrote: > On Mon, 03 Apr 2017, Lee Jones wrote: > >> On Fri, 24 Mar 2017, Enric Balletbo i Serra wrote: >> >>> From: Vic Yang >>> >>> For SPI, we can get up to 32 additional bytes for response preamble. >>> The current overhead (2 bytes) may cause problems when we try to receive >>> a big response. Update it to 32 bytes. >>> >>> Without this fix we could see a kernel BUG when we receive a big response >>> from the Chrome EC when is connected via SPI. >>> >>> Signed-off-by: Vic Yang >>> Tested-by: Enric Balletbo i Serra >>> --- >>> >>> This patch is a FIX, and I think that would be interesting see it merged >>> in this release cycle. This should go through the MFD tree and can be picked >>> independently of the other patches. Lee Jones I think this is for you. >>> >>> include/linux/mfd/cros_ec.h | 3 ++- >>> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> Applied, thanks. > > Scrap that, I'll keep it with the set. > Ok, I'll send a v2 asap with this patch and the few modifications requested on patch 7/7. I'm wondering though if this specific patch could go with current release cycle as (explained above) is a fix and current kernel is affected. Thanks, Enric >>> diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h >>> index b3e812f..3b16c90 100644 >>> --- a/include/linux/mfd/cros_ec.h >>> +++ b/include/linux/mfd/cros_ec.h >>> @@ -35,10 +35,11 @@ >>> * Max bus-specific overhead incurred by request/responses. >>> * I2C requires 1 additional byte for requests. >>> * I2C requires 2 additional bytes for responses. >>> + * SPI requires up to 32 additional bytes for responses. >>> * */ >>> #define EC_PROTO_VERSION_UNKNOWN 0 >>> #define EC_MAX_REQUEST_OVERHEAD1 >>> -#define EC_MAX_RESPONSE_OVERHEAD 2 >>> +#define EC_MAX_RESPONSE_OVERHEAD 32 >>> >>> /* >>> * Command interface between EC and AP, for LPC, I2C and SPI interfaces. >> >
Re: 4.10.8 OOPS - BUG: unable to handle kernel NULL pointer dereference; IP: _raw_spin_lock+0x13/0x30
moving to https://bugzilla.kernel.org/show_bug.cgi?id=195229
Re: 4.10.8 OOPS - BUG: unable to handle kernel NULL pointer dereference; IP: _raw_spin_lock+0x13/0x30
moving to https://bugzilla.kernel.org/show_bug.cgi?id=195229
Re: [PATCH v1] reset: Make optional stuff optional for all users
On Mon, 2017-04-03 at 14:33 +, Shevchenko, Andriy wrote: > On Mon, 2017-04-03 at 17:31 +0300, Andy Shevchenko wrote: > > On Mon, 2017-04-03 at 16:27 +0200, Philipp Zabel wrote: > > > > > > > > int rstc_id; > > > > int ret; > > > > > > > > - if (!node) > > > > - return ERR_PTR(-EINVAL); > > > > - > > > > > > This should be > > > > > > if (!node) > > > return optional ? NULL : ERR_PTR(-EINVAL); > > > > > > instead. Can you confirm this works for Intel boards with DW UART? I > > > can > > > fix it up when applying if you agree. > > > > I don't think it worth to change. I specifically checked all of_* > > calls > > in that function and they cope pretty nice with node == NULL. __of_reset_control_get called with id != NULL calls of_property_match_string first, which then returns -EINVAL if node == NULL, which makes __of_reset_control_get return NULL if optional or -ENOENT otherwise, even though the correct return value would be -EINVAL in the DT case. __of_reset_control_get called with id == NULL calls of_parse_phandle_with_args first, which calls __of_parse_phandle_with_args, which returns an undefined value if np == NULL, as far as I can tell: of_for_each_phandle first calls of_phandle_iterator_init, which, when called with np == NULL clears the iterator structure returns -ENOENT. The return value is ignored in the of_for_each_phandle macro, and of_phandle_iterator_next is then called and returns -ENOENT because it->cur == NULL, ending the loop without ever assigning a value to rc. __of_parse_phandle_with_args then returns the uninitialized value. The point being, instead of having to regularly forage through a number of of_ API functions to make sure my expectations are still met, I'd prefer to keep the check in place. > > > > So, I rather to go with my initial change. > > > > Hit Enter before closing another thought. > > When you come with solution where this __of_reset_control_get() will be > called only for node != NULL case you will not need that check either. __of_reset_control_get is public API (via of_reset_control_get), so I can't guarantee node != NULL even in the DT case. > So, I would go my solution because of two benefits: > - it fixes bug True. > - if will not bring ping-ponging code Unfortunately not. regards Philipp
Re: [PATCH v1] reset: Make optional stuff optional for all users
On Mon, 2017-04-03 at 14:33 +, Shevchenko, Andriy wrote: > On Mon, 2017-04-03 at 17:31 +0300, Andy Shevchenko wrote: > > On Mon, 2017-04-03 at 16:27 +0200, Philipp Zabel wrote: > > > > > > > > int rstc_id; > > > > int ret; > > > > > > > > - if (!node) > > > > - return ERR_PTR(-EINVAL); > > > > - > > > > > > This should be > > > > > > if (!node) > > > return optional ? NULL : ERR_PTR(-EINVAL); > > > > > > instead. Can you confirm this works for Intel boards with DW UART? I > > > can > > > fix it up when applying if you agree. > > > > I don't think it worth to change. I specifically checked all of_* > > calls > > in that function and they cope pretty nice with node == NULL. __of_reset_control_get called with id != NULL calls of_property_match_string first, which then returns -EINVAL if node == NULL, which makes __of_reset_control_get return NULL if optional or -ENOENT otherwise, even though the correct return value would be -EINVAL in the DT case. __of_reset_control_get called with id == NULL calls of_parse_phandle_with_args first, which calls __of_parse_phandle_with_args, which returns an undefined value if np == NULL, as far as I can tell: of_for_each_phandle first calls of_phandle_iterator_init, which, when called with np == NULL clears the iterator structure returns -ENOENT. The return value is ignored in the of_for_each_phandle macro, and of_phandle_iterator_next is then called and returns -ENOENT because it->cur == NULL, ending the loop without ever assigning a value to rc. __of_parse_phandle_with_args then returns the uninitialized value. The point being, instead of having to regularly forage through a number of of_ API functions to make sure my expectations are still met, I'd prefer to keep the check in place. > > > > So, I rather to go with my initial change. > > > > Hit Enter before closing another thought. > > When you come with solution where this __of_reset_control_get() will be > called only for node != NULL case you will not need that check either. __of_reset_control_get is public API (via of_reset_control_get), so I can't guarantee node != NULL even in the DT case. > So, I would go my solution because of two benefits: > - it fixes bug True. > - if will not bring ping-ponging code Unfortunately not. regards Philipp
Re: [Intel-gfx] [BUG][REGRESSION] i915 gpu hangs under load
On Sun, 02 Apr 2017, Martin Kepplingerwrote: > Am 2. April 2017 13:50:26 MESZ schrieb Thorsten Leemhuis > : >>Lo! On 22.03.2017 11:36, Jani Nikula wrote: >>> On Wed, 22 Mar 2017, Martin Kepplinger wrote: I know something similar is here: https://bugs.freedesktop.org/show_bug.cgi?id=100110 too. But this is rc3 and my machine is totally *not usable*. Let me be annoying :) I hope I can help: >>> Please file a bug over at [1]. >>> […] >>> [1] >>https://bugs.freedesktop.org/enter_bug.cgi?product=DRI=DRM/Intel >> >>@Martin: did you file that bug? I could not find one :-/ > > I did. Got marked as duplicate of > https://bugs.freedesktop.org/show_bug.cgi?id=100181 and there's a fix out > there. I don't know if it's in rc5 though. Should be fixed in v4.11-rc5 by commit 0abfe7e2570d7c729a7662e82c09a23f00f29346 Author: Chris Wilson Date: Wed Mar 22 20:59:30 2017 + drm/i915: Restore marking context objects as dirty on pinning >>@Jani: In similar situations could you do me a favour and ask people to >>send one more reply to the public list which contains the link to the >>bug filed? Regression tracking is quite hard already; searching various >>bug tracker for follow up bug entries makes it even harder :-( I'll try, thanks for the feedback. BR, Jani. -- Jani Nikula, Intel Open Source Technology Center
Re: [Intel-gfx] [BUG][REGRESSION] i915 gpu hangs under load
On Sun, 02 Apr 2017, Martin Kepplinger wrote: > Am 2. April 2017 13:50:26 MESZ schrieb Thorsten Leemhuis > : >>Lo! On 22.03.2017 11:36, Jani Nikula wrote: >>> On Wed, 22 Mar 2017, Martin Kepplinger wrote: I know something similar is here: https://bugs.freedesktop.org/show_bug.cgi?id=100110 too. But this is rc3 and my machine is totally *not usable*. Let me be annoying :) I hope I can help: >>> Please file a bug over at [1]. >>> […] >>> [1] >>https://bugs.freedesktop.org/enter_bug.cgi?product=DRI=DRM/Intel >> >>@Martin: did you file that bug? I could not find one :-/ > > I did. Got marked as duplicate of > https://bugs.freedesktop.org/show_bug.cgi?id=100181 and there's a fix out > there. I don't know if it's in rc5 though. Should be fixed in v4.11-rc5 by commit 0abfe7e2570d7c729a7662e82c09a23f00f29346 Author: Chris Wilson Date: Wed Mar 22 20:59:30 2017 + drm/i915: Restore marking context objects as dirty on pinning >>@Jani: In similar situations could you do me a favour and ask people to >>send one more reply to the public list which contains the link to the >>bug filed? Regression tracking is quite hard already; searching various >>bug tracker for follow up bug entries makes it even harder :-( I'll try, thanks for the feedback. BR, Jani. -- Jani Nikula, Intel Open Source Technology Center
Re: [PATCH 7/7] mfd: cros_ec: add RTC as mfd subdevice
On 03/04/17 16:25, Lee Jones wrote: > On Fri, 24 Mar 2017, Enric Balletbo i Serra wrote: > >> From: Stephen Barber>> >> If the EC supports RTC host commands, expose an RTC device. >> >> Signed-off-by: Stephen Barber >> Signed-off-by: Enric Balletbo i Serra >> --- >> drivers/mfd/cros_ec.c | 18 ++ >> 1 file changed, 18 insertions(+) >> >> diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c >> index bbc17ab..1ff88b1 100644 >> --- a/drivers/mfd/cros_ec.c >> +++ b/drivers/mfd/cros_ec.c >> @@ -51,6 +51,11 @@ static const struct mfd_cell ec_pd_cell = { >> .pdata_size = sizeof(pd_p), >> }; >> >> +static const struct mfd_cell ec_rtc_cell = { >> +.name = "cros-ec-rtc", >> +.id = -1, > > Why -1? > >> +}; >> + >> static irqreturn_t ec_irq_thread(int irq, void *data) >> { >> struct cros_ec_device *ec_dev = data; >> @@ -238,6 +243,15 @@ static void cros_ec_sensors_register(struct >> cros_ec_device *ec_dev) >> kfree(msg); >> } >> >> +static void cros_ec_rtc_register(struct cros_ec_device *ec_dev) >> +{ >> +int ret; >> + >> +ret = mfd_add_devices(ec_dev->dev, 0, _rtc_cell, 1, NULL, 0, NULL); > > Why 0? > Right, just maintained the one in the original. I think I can use PLATFORM_DEVID_AUTO here? >> +if (ret) >> +dev_err(ec_dev->dev, "failed to add EC RTC\n"); >> +} >> + >> int cros_ec_register(struct cros_ec_device *ec_dev) >> { >> struct device *dev = ec_dev->dev; >> @@ -287,6 +301,10 @@ int cros_ec_register(struct cros_ec_device *ec_dev) >> if (cros_ec_check_features(ec_dev, EC_FEATURE_MOTION_SENSE)) >> cros_ec_sensors_register(ec_dev); >> >> +/* Check whether this EC has RTC support */ >> +if (cros_ec_check_features(ec_dev, EC_FEATURE_RTC)) >> +cros_ec_rtc_register(ec_dev); >> + >> if (ec_dev->max_passthru) { >> /* >> * Register a PD device as well on top of this device. >
Re: [PATCH 7/7] mfd: cros_ec: add RTC as mfd subdevice
On 03/04/17 16:25, Lee Jones wrote: > On Fri, 24 Mar 2017, Enric Balletbo i Serra wrote: > >> From: Stephen Barber >> >> If the EC supports RTC host commands, expose an RTC device. >> >> Signed-off-by: Stephen Barber >> Signed-off-by: Enric Balletbo i Serra >> --- >> drivers/mfd/cros_ec.c | 18 ++ >> 1 file changed, 18 insertions(+) >> >> diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c >> index bbc17ab..1ff88b1 100644 >> --- a/drivers/mfd/cros_ec.c >> +++ b/drivers/mfd/cros_ec.c >> @@ -51,6 +51,11 @@ static const struct mfd_cell ec_pd_cell = { >> .pdata_size = sizeof(pd_p), >> }; >> >> +static const struct mfd_cell ec_rtc_cell = { >> +.name = "cros-ec-rtc", >> +.id = -1, > > Why -1? > >> +}; >> + >> static irqreturn_t ec_irq_thread(int irq, void *data) >> { >> struct cros_ec_device *ec_dev = data; >> @@ -238,6 +243,15 @@ static void cros_ec_sensors_register(struct >> cros_ec_device *ec_dev) >> kfree(msg); >> } >> >> +static void cros_ec_rtc_register(struct cros_ec_device *ec_dev) >> +{ >> +int ret; >> + >> +ret = mfd_add_devices(ec_dev->dev, 0, _rtc_cell, 1, NULL, 0, NULL); > > Why 0? > Right, just maintained the one in the original. I think I can use PLATFORM_DEVID_AUTO here? >> +if (ret) >> +dev_err(ec_dev->dev, "failed to add EC RTC\n"); >> +} >> + >> int cros_ec_register(struct cros_ec_device *ec_dev) >> { >> struct device *dev = ec_dev->dev; >> @@ -287,6 +301,10 @@ int cros_ec_register(struct cros_ec_device *ec_dev) >> if (cros_ec_check_features(ec_dev, EC_FEATURE_MOTION_SENSE)) >> cros_ec_sensors_register(ec_dev); >> >> +/* Check whether this EC has RTC support */ >> +if (cros_ec_check_features(ec_dev, EC_FEATURE_RTC)) >> +cros_ec_rtc_register(ec_dev); >> + >> if (ec_dev->max_passthru) { >> /* >> * Register a PD device as well on top of this device. >
Re: [PATCH v6 02/39] [media] dt-bindings: Add bindings for i.MX media driver
On Mon, Apr 03, 2017 at 09:11:35AM -0500, Rob Herring wrote: > On Wed, Mar 29, 2017 at 09:39:05AM +0100, Russell King - ARM Linux wrote: > > On Tue, Mar 28, 2017 at 07:21:34PM -0500, Rob Herring wrote: > > > On Mon, Mar 27, 2017 at 7:40 PM, Steve Longerbeam> > > wrote: > > > > Add bindings documentation for the i.MX media driver. > > > > > > > > Signed-off-by: Steve Longerbeam > > > > --- > > > > Documentation/devicetree/bindings/media/imx.txt | 74 > > > > + > > > > 1 file changed, 74 insertions(+) > > > > create mode 100644 Documentation/devicetree/bindings/media/imx.txt > > > > > > > > diff --git a/Documentation/devicetree/bindings/media/imx.txt > > > > b/Documentation/devicetree/bindings/media/imx.txt > > > > new file mode 100644 > > > > index 000..3059c06 > > > > --- /dev/null > > > > +++ b/Documentation/devicetree/bindings/media/imx.txt > > > > @@ -0,0 +1,74 @@ > > > > +Freescale i.MX Media Video Device > > > > += > > > > + > > > > +Video Media Controller node > > > > +--- > > > > + > > > > +This is the media controller node for video capture support. It is a > > > > +virtual device that lists the camera serial interface nodes that the > > > > +media device will control. > > > > + > > > > +Required properties: > > > > +- compatible : "fsl,imx-capture-subsystem"; > > > > +- ports : Should contain a list of phandles pointing to camera > > > > + sensor interface ports of IPU devices > > > > + > > > > +example: > > > > + > > > > +capture-subsystem { > > > > + compatible = "fsl,imx-capture-subsystem"; > > > > + ports = <_csi0>, <_csi1>; > > > > +}; > > > > + > > > > +fim child node > > > > +-- > > > > + > > > > +This is an optional child node of the ipu_csi port nodes. If present > > > > and > > > > +available, it enables the Frame Interval Monitor. Its properties can be > > > > +used to modify the method in which the FIM measures frame intervals. > > > > +Refer to Documentation/media/v4l-drivers/imx.rst for more info on the > > > > +Frame Interval Monitor. > > > > + > > > > +Optional properties: > > > > +- fsl,input-capture-channel: an input capture channel and channel > > > > flags, > > > > +specified as . The channel > > > > number > > > > +must be 0 or 1. The flags can be > > > > +IRQ_TYPE_EDGE_RISING, > > > > IRQ_TYPE_EDGE_FALLING, or > > > > +IRQ_TYPE_EDGE_BOTH, and specify which input > > > > +capture signal edge will trigger the input > > > > +capture event. If an input capture channel > > > > is > > > > +specified, the FIM will use this method to > > > > +measure frame intervals instead of via the > > > > EOF > > > > +interrupt. The input capture method is much > > > > +preferred over EOF as it is not subject to > > > > +interrupt latency errors. However it > > > > requires > > > > +routing the VSYNC or FIELD output signals > > > > of > > > > +the camera sensor to one of the i.MX input > > > > +capture pads (SD1_DAT0, SD1_DAT1), which > > > > also > > > > +gives up support for SD1. > > > > + > > > > + > > > > +mipi_csi2 node > > > > +-- > > > > + > > > > +This is the device node for the MIPI CSI-2 Receiver, required for MIPI > > > > +CSI-2 sensors. > > > > + > > > > +Required properties: > > > > +- compatible : "fsl,imx6-mipi-csi2", "snps,dw-mipi-csi2"; > > > > > > As I mentioned in v5, there's a DW CSI2 binding in progress. This > > > needs to be based on that. > > > > Maybe someone can provide some kind of reference to it, and it's > > associated driver? > > Let me Google that for you (TM). The reference is in my comments on v5. > Here's a reference to it [1]. Looking at the actual driver, it seems to at least have a different register layout: registerimx6dw version 0x000 0x000 n_lanes 0x004 0x004 phy_shutdownz 0x008 - dphy_resetz 0x00c - resetn 0x010 0x008 phy_state 0x014 - data_ids_1 0x018 0x010 data_ids_2 0x01c 0x014 err10x020 - err20x024 - msk10x028 - msk20x02c - phy_tst_ctrl0 0x030 - phy_tst_ctrl1 0x034 - sft_reset 0xf00 - (not part of CSI2, but a IMX6 specific CSI2 to IPU gasket layer, but lives in CSI2's register region) The DW version has many more registers than are documented by the iMX6 version. Only the first two registers appear to be common
[PATCH] x86/tsc: fix multiple checkpatch warnings
Fixed style issues: * block comments * replaced ACCESS_ONCE with WRITE_ONCE * "EXPORT_SYMBOL should immediately follow its function" Plus fixed typo in comment. Signed-off-by: Abhishek Rose--- arch/x86/kernel/tsc.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 714dfba..9bb89dc 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -26,7 +26,7 @@ #include #include -unsigned int __read_mostly cpu_khz;/* TSC clocks / usec, not used here */ +unsigned int __read_mostly cpu_khz;/* TSC clocks / msec, not used here */ EXPORT_SYMBOL(cpu_khz); unsigned int __read_mostly tsc_khz; @@ -37,9 +37,11 @@ EXPORT_SYMBOL(tsc_khz); */ static int __read_mostly tsc_unstable; -/* native_sched_clock() is called before tsc_init(), so - we must start with the TSC soft disabled to prevent - erroneous rdtsc usage on !boot_cpu_has(X86_FEATURE_TSC) processors */ +/* + * native_sched_clock() is called before tsc_init(), so + * we must start with the TSC soft disabled to prevent + * erroneous rdtsc usage on !boot_cpu_has(X86_FEATURE_TSC) processors + */ static int __read_mostly tsc_disabled = -1; static DEFINE_STATIC_KEY_FALSE(__use_tsc); @@ -159,7 +161,7 @@ static void cyc2ns_write_end(int cpu, struct cyc2ns_data *data) */ smp_wmb(); - ACCESS_ONCE(c2n->head) = data; + WRITE_ONCE(c2n->head, data); } /* @@ -320,8 +322,10 @@ u64 native_sched_clock_from_tsc(u64 tsc) return cycles_2_ns(tsc); } -/* We need to define a real function for sched_clock, to override the - weak default version */ +/* + * We need to define a real function for sched_clock, to override the + * weak default version + */ #ifdef CONFIG_PARAVIRT unsigned long long sched_clock(void) { @@ -831,7 +835,7 @@ unsigned long native_calibrate_cpu(void) else tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2); - tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); + tsc_ref_min = min_t(unsigned long, tsc_ref_min, tsc2); /* Check the reference deviation */ delta = ((u64) tsc_pit_min) * 100; @@ -933,7 +937,6 @@ int recalibrate_cpu_khz(void) return -ENODEV; #endif } - EXPORT_SYMBOL(recalibrate_cpu_khz); @@ -1160,7 +1163,6 @@ void mark_tsc_unstable(char *reason) clocksource_tsc.rating = 0; } } - EXPORT_SYMBOL_GPL(mark_tsc_unstable); static void __init check_system_tsc_reliable(void) -- 2.9.3
[PATCH V7 4/7] mfd: da9061: MFD core support
From: Steve TwissMFD support for DA9061 is provided as part of the DA9062 device driver. The registers header file adds two new chip variant IDs defined in DA9061 and DA9062 hardware. The core header file adds new software enumerations for listing the valid DA9061 IRQs and a da9062_compatible_types enumeration for distinguishing between DA9061/62 devices in software. The core source code adds a new .compatible of_device_id entry. This is extended from DA9062 to support both "dlg,da9061" and "dlg,da9062". The .data entry now holds a reference to the enumerated device type. A new regmap_irq_chip model is added for DA9061 and this supports the new list of regmap_irq entries. A new mfd_cell da9061_devs[] array lists the new sub system components for DA9061. Support is added for a new DA9061 regmap_config which lists the correct readable, writable and volatile ranges for this chip. The probe function uses the device tree compatible string to switch on the da9062_compatible_types and configure the correct mfd cells, irq chip and regmap config. Kconfig is updated to reflect support for DA9061 and DA9062 PMICs. Signed-off-by: Steve Twiss --- Acked-for-mfd-by: Lee Jones Hi Lee, that Ack was from your earlier posting: https://lkml.org/lkml/2017/1/4/328 this was Regards, Steve. This patch applies against linux-next and v4.11-rc3 v6 -> v7 + update - Removed brackets surrounding case statements for case COMPAT_TYPE_DA9061: case COMPAT_TYPE_DA9062: v6 -> v7 - Remove compilation warning when casting a void * to an integer on ARCH=x86_64 using -Wpointer-to-int-cast. - Recommendation uintptr_t cast: https://lkml.org/lkml/2017/3/28/292 - Compile tested ARCH=x86_64 v5 -> v6 - Rebased from v4.9 to v4.11-rc3 - Modify Copyright to match Dialog latest legal statement - Fixed "braces {} should be used on all arms" checkpatch warning v4 -> v5 - NO CODE CHANGE - Rebased from v4.8 to v4.9 v3 -> v4 - Patch renamed from [PATCH V3 5/9] to [PATCH V4 4/8] - Removed DEFINE_RES_NAMED() macros for DA9061 resources and replaced them with DEFINE_RES_IRQ_NAMED(). - Removed whitespace - Reverted change for badly defined mfd_cell da9062_devs of_compatible string from "dlg,da9062-watchdog" back to "dlg,da9062-wdt" v2 -> v3 - NO CODE CHANGE - Patch renamed from [PATCH V2 05/10] to [PATCH V3 5/9] v1 -> v2 - Patch renamed from [PATCH V1 01/10] to [PATCH V2 05/10] -- these changes were made to fix checkpatch warnings caused by the patch set dependency order - Fixed typo in the commit message "readble" to "readable" - Removed the explicit cross-check to decide if there is a conflict between the device tree compatible string and the hardware definition. This patch assumes the device tree is correctly written and therefore removes the need for a hardware/DT sanity check. - Removed extra semicolon in drivers/mfd/da9062-core.c:877 - Re-write compatible entries into numerical order Lee, Changes as described in the version history above. As previously: This patch adds support for the DA9061 PMIC. This is done as part of the existing DA9062 device driver by extending the of_device_id match table. This in turn allows new MFD cells, irq chip and regmap definitions to support DA9061. Regards, Steve Twiss, Dialog Semiconductor drivers/mfd/Kconfig | 5 +- drivers/mfd/da9062-core.c| 427 +-- include/linux/mfd/da9062/core.h | 29 ++- include/linux/mfd/da9062/registers.h | 5 +- 4 files changed, 443 insertions(+), 23 deletions(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 55ecdfb..29cc11a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -263,13 +263,14 @@ config MFD_DA9055 called "da9055" config MFD_DA9062 - tristate "Dialog Semiconductor DA9062 PMIC Support" + tristate "Dialog Semiconductor DA9062/61 PMIC Support" select MFD_CORE select REGMAP_I2C select REGMAP_IRQ depends on I2C help - Say yes here for support for the Dialog Semiconductor DA9062 PMIC. + Say yes here for support for the Dialog Semiconductor DA9061 and + DA9062 PMICs. This includes the I2C driver and core APIs. Additional drivers must be enabled in order to use the functionality of the device. diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index 8f873866..1803f58 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -1,6 +1,6 @@ /* - * Core, IRQ and I2C device driver for DA9062 PMIC - * Copyright (C) 2015 Dialog Semiconductor Ltd. + * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs + * Copyright (C) 2015-2017 Dialog Semiconductor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@
Re: [PATCH v6 02/39] [media] dt-bindings: Add bindings for i.MX media driver
On Mon, Apr 03, 2017 at 09:11:35AM -0500, Rob Herring wrote: > On Wed, Mar 29, 2017 at 09:39:05AM +0100, Russell King - ARM Linux wrote: > > On Tue, Mar 28, 2017 at 07:21:34PM -0500, Rob Herring wrote: > > > On Mon, Mar 27, 2017 at 7:40 PM, Steve Longerbeam > > > wrote: > > > > Add bindings documentation for the i.MX media driver. > > > > > > > > Signed-off-by: Steve Longerbeam > > > > --- > > > > Documentation/devicetree/bindings/media/imx.txt | 74 > > > > + > > > > 1 file changed, 74 insertions(+) > > > > create mode 100644 Documentation/devicetree/bindings/media/imx.txt > > > > > > > > diff --git a/Documentation/devicetree/bindings/media/imx.txt > > > > b/Documentation/devicetree/bindings/media/imx.txt > > > > new file mode 100644 > > > > index 000..3059c06 > > > > --- /dev/null > > > > +++ b/Documentation/devicetree/bindings/media/imx.txt > > > > @@ -0,0 +1,74 @@ > > > > +Freescale i.MX Media Video Device > > > > += > > > > + > > > > +Video Media Controller node > > > > +--- > > > > + > > > > +This is the media controller node for video capture support. It is a > > > > +virtual device that lists the camera serial interface nodes that the > > > > +media device will control. > > > > + > > > > +Required properties: > > > > +- compatible : "fsl,imx-capture-subsystem"; > > > > +- ports : Should contain a list of phandles pointing to camera > > > > + sensor interface ports of IPU devices > > > > + > > > > +example: > > > > + > > > > +capture-subsystem { > > > > + compatible = "fsl,imx-capture-subsystem"; > > > > + ports = <_csi0>, <_csi1>; > > > > +}; > > > > + > > > > +fim child node > > > > +-- > > > > + > > > > +This is an optional child node of the ipu_csi port nodes. If present > > > > and > > > > +available, it enables the Frame Interval Monitor. Its properties can be > > > > +used to modify the method in which the FIM measures frame intervals. > > > > +Refer to Documentation/media/v4l-drivers/imx.rst for more info on the > > > > +Frame Interval Monitor. > > > > + > > > > +Optional properties: > > > > +- fsl,input-capture-channel: an input capture channel and channel > > > > flags, > > > > +specified as . The channel > > > > number > > > > +must be 0 or 1. The flags can be > > > > +IRQ_TYPE_EDGE_RISING, > > > > IRQ_TYPE_EDGE_FALLING, or > > > > +IRQ_TYPE_EDGE_BOTH, and specify which input > > > > +capture signal edge will trigger the input > > > > +capture event. If an input capture channel > > > > is > > > > +specified, the FIM will use this method to > > > > +measure frame intervals instead of via the > > > > EOF > > > > +interrupt. The input capture method is much > > > > +preferred over EOF as it is not subject to > > > > +interrupt latency errors. However it > > > > requires > > > > +routing the VSYNC or FIELD output signals > > > > of > > > > +the camera sensor to one of the i.MX input > > > > +capture pads (SD1_DAT0, SD1_DAT1), which > > > > also > > > > +gives up support for SD1. > > > > + > > > > + > > > > +mipi_csi2 node > > > > +-- > > > > + > > > > +This is the device node for the MIPI CSI-2 Receiver, required for MIPI > > > > +CSI-2 sensors. > > > > + > > > > +Required properties: > > > > +- compatible : "fsl,imx6-mipi-csi2", "snps,dw-mipi-csi2"; > > > > > > As I mentioned in v5, there's a DW CSI2 binding in progress. This > > > needs to be based on that. > > > > Maybe someone can provide some kind of reference to it, and it's > > associated driver? > > Let me Google that for you (TM). The reference is in my comments on v5. > Here's a reference to it [1]. Looking at the actual driver, it seems to at least have a different register layout: registerimx6dw version 0x000 0x000 n_lanes 0x004 0x004 phy_shutdownz 0x008 - dphy_resetz 0x00c - resetn 0x010 0x008 phy_state 0x014 - data_ids_1 0x018 0x010 data_ids_2 0x01c 0x014 err10x020 - err20x024 - msk10x028 - msk20x02c - phy_tst_ctrl0 0x030 - phy_tst_ctrl1 0x034 - sft_reset 0xf00 - (not part of CSI2, but a IMX6 specific CSI2 to IPU gasket layer, but lives in CSI2's register region) The DW version has many more registers than are documented by the iMX6 version. Only the first two registers appear to be common between these two devices, and maybe five registers
[PATCH] x86/tsc: fix multiple checkpatch warnings
Fixed style issues: * block comments * replaced ACCESS_ONCE with WRITE_ONCE * "EXPORT_SYMBOL should immediately follow its function" Plus fixed typo in comment. Signed-off-by: Abhishek Rose --- arch/x86/kernel/tsc.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 714dfba..9bb89dc 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -26,7 +26,7 @@ #include #include -unsigned int __read_mostly cpu_khz;/* TSC clocks / usec, not used here */ +unsigned int __read_mostly cpu_khz;/* TSC clocks / msec, not used here */ EXPORT_SYMBOL(cpu_khz); unsigned int __read_mostly tsc_khz; @@ -37,9 +37,11 @@ EXPORT_SYMBOL(tsc_khz); */ static int __read_mostly tsc_unstable; -/* native_sched_clock() is called before tsc_init(), so - we must start with the TSC soft disabled to prevent - erroneous rdtsc usage on !boot_cpu_has(X86_FEATURE_TSC) processors */ +/* + * native_sched_clock() is called before tsc_init(), so + * we must start with the TSC soft disabled to prevent + * erroneous rdtsc usage on !boot_cpu_has(X86_FEATURE_TSC) processors + */ static int __read_mostly tsc_disabled = -1; static DEFINE_STATIC_KEY_FALSE(__use_tsc); @@ -159,7 +161,7 @@ static void cyc2ns_write_end(int cpu, struct cyc2ns_data *data) */ smp_wmb(); - ACCESS_ONCE(c2n->head) = data; + WRITE_ONCE(c2n->head, data); } /* @@ -320,8 +322,10 @@ u64 native_sched_clock_from_tsc(u64 tsc) return cycles_2_ns(tsc); } -/* We need to define a real function for sched_clock, to override the - weak default version */ +/* + * We need to define a real function for sched_clock, to override the + * weak default version + */ #ifdef CONFIG_PARAVIRT unsigned long long sched_clock(void) { @@ -831,7 +835,7 @@ unsigned long native_calibrate_cpu(void) else tsc2 = calc_pmtimer_ref(tsc2, ref1, ref2); - tsc_ref_min = min(tsc_ref_min, (unsigned long) tsc2); + tsc_ref_min = min_t(unsigned long, tsc_ref_min, tsc2); /* Check the reference deviation */ delta = ((u64) tsc_pit_min) * 100; @@ -933,7 +937,6 @@ int recalibrate_cpu_khz(void) return -ENODEV; #endif } - EXPORT_SYMBOL(recalibrate_cpu_khz); @@ -1160,7 +1163,6 @@ void mark_tsc_unstable(char *reason) clocksource_tsc.rating = 0; } } - EXPORT_SYMBOL_GPL(mark_tsc_unstable); static void __init check_system_tsc_reliable(void) -- 2.9.3
[PATCH V7 4/7] mfd: da9061: MFD core support
From: Steve Twiss MFD support for DA9061 is provided as part of the DA9062 device driver. The registers header file adds two new chip variant IDs defined in DA9061 and DA9062 hardware. The core header file adds new software enumerations for listing the valid DA9061 IRQs and a da9062_compatible_types enumeration for distinguishing between DA9061/62 devices in software. The core source code adds a new .compatible of_device_id entry. This is extended from DA9062 to support both "dlg,da9061" and "dlg,da9062". The .data entry now holds a reference to the enumerated device type. A new regmap_irq_chip model is added for DA9061 and this supports the new list of regmap_irq entries. A new mfd_cell da9061_devs[] array lists the new sub system components for DA9061. Support is added for a new DA9061 regmap_config which lists the correct readable, writable and volatile ranges for this chip. The probe function uses the device tree compatible string to switch on the da9062_compatible_types and configure the correct mfd cells, irq chip and regmap config. Kconfig is updated to reflect support for DA9061 and DA9062 PMICs. Signed-off-by: Steve Twiss --- Acked-for-mfd-by: Lee Jones Hi Lee, that Ack was from your earlier posting: https://lkml.org/lkml/2017/1/4/328 this was Regards, Steve. This patch applies against linux-next and v4.11-rc3 v6 -> v7 + update - Removed brackets surrounding case statements for case COMPAT_TYPE_DA9061: case COMPAT_TYPE_DA9062: v6 -> v7 - Remove compilation warning when casting a void * to an integer on ARCH=x86_64 using -Wpointer-to-int-cast. - Recommendation uintptr_t cast: https://lkml.org/lkml/2017/3/28/292 - Compile tested ARCH=x86_64 v5 -> v6 - Rebased from v4.9 to v4.11-rc3 - Modify Copyright to match Dialog latest legal statement - Fixed "braces {} should be used on all arms" checkpatch warning v4 -> v5 - NO CODE CHANGE - Rebased from v4.8 to v4.9 v3 -> v4 - Patch renamed from [PATCH V3 5/9] to [PATCH V4 4/8] - Removed DEFINE_RES_NAMED() macros for DA9061 resources and replaced them with DEFINE_RES_IRQ_NAMED(). - Removed whitespace - Reverted change for badly defined mfd_cell da9062_devs of_compatible string from "dlg,da9062-watchdog" back to "dlg,da9062-wdt" v2 -> v3 - NO CODE CHANGE - Patch renamed from [PATCH V2 05/10] to [PATCH V3 5/9] v1 -> v2 - Patch renamed from [PATCH V1 01/10] to [PATCH V2 05/10] -- these changes were made to fix checkpatch warnings caused by the patch set dependency order - Fixed typo in the commit message "readble" to "readable" - Removed the explicit cross-check to decide if there is a conflict between the device tree compatible string and the hardware definition. This patch assumes the device tree is correctly written and therefore removes the need for a hardware/DT sanity check. - Removed extra semicolon in drivers/mfd/da9062-core.c:877 - Re-write compatible entries into numerical order Lee, Changes as described in the version history above. As previously: This patch adds support for the DA9061 PMIC. This is done as part of the existing DA9062 device driver by extending the of_device_id match table. This in turn allows new MFD cells, irq chip and regmap definitions to support DA9061. Regards, Steve Twiss, Dialog Semiconductor drivers/mfd/Kconfig | 5 +- drivers/mfd/da9062-core.c| 427 +-- include/linux/mfd/da9062/core.h | 29 ++- include/linux/mfd/da9062/registers.h | 5 +- 4 files changed, 443 insertions(+), 23 deletions(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 55ecdfb..29cc11a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -263,13 +263,14 @@ config MFD_DA9055 called "da9055" config MFD_DA9062 - tristate "Dialog Semiconductor DA9062 PMIC Support" + tristate "Dialog Semiconductor DA9062/61 PMIC Support" select MFD_CORE select REGMAP_I2C select REGMAP_IRQ depends on I2C help - Say yes here for support for the Dialog Semiconductor DA9062 PMIC. + Say yes here for support for the Dialog Semiconductor DA9061 and + DA9062 PMICs. This includes the I2C driver and core APIs. Additional drivers must be enabled in order to use the functionality of the device. diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index 8f873866..1803f58 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -1,6 +1,6 @@ /* - * Core, IRQ and I2C device driver for DA9062 PMIC - * Copyright (C) 2015 Dialog Semiconductor Ltd. + * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs + * Copyright (C) 2015-2017 Dialog Semiconductor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,6 +30,70 @@ #defineDA9062_REG_EVENT_B_OFFSET 1 #define
[PATCH v3 4/4] ARM: dts: sun7i: Add can0_pins_a pinctrl settings
The A20 SoC has an on-board CAN controller. This patch adds the pinctrl settings for pins PH20 and PH21. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel--- arch/arm/boot/dts/sun7i-a20.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index c637e10..8536caf 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -1096,6 +1096,11 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + can0_pins_a: can0@0 { + pins = "PH20","PH21"; + function = "can"; + }; + clk_out_a_pins_a: clk_out_a@0 { pins = "PI12"; function = "clk_out_a"; -- 1.9.1
[PATCH v3 4/4] ARM: dts: sun7i: Add can0_pins_a pinctrl settings
The A20 SoC has an on-board CAN controller. This patch adds the pinctrl settings for pins PH20 and PH21. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel --- arch/arm/boot/dts/sun7i-a20.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index c637e10..8536caf 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -1096,6 +1096,11 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + can0_pins_a: can0@0 { + pins = "PH20","PH21"; + function = "can"; + }; + clk_out_a_pins_a: clk_out_a@0 { pins = "PI12"; function = "clk_out_a"; -- 1.9.1
[PATCH v3 0/4] ARM: dts: sunxi: Add CAN node and can0_pins_a pinctrl settings
The Allwinner A10/A20 SoCs have an on-board CAN (Controller Area Network) controller. This patch adds the CAN core to the SoC's include files, sun4i-a10.dtsi and sun7i-a20.dtsi. On linux-can mailing list was a discussion about updating the device tree bindings https://lkml.org/lkml/2015/9/17/220 but it did not progress past writing the documentation file. Documentation/devicetree/bindings/net/can/sun4i_can.txt The CAN controller can be enabled in a board specific dts file as described in the documentation file or by using a device tree overlay. I have tested the patch on a Banana Pi (A20 SoC) with mainline kernel 4.10.5. History: v3: added "allwinner,sun7i-a20-can" compatible to can0 device node contents, make separate patches for device nodes and pinctrl settings v2: changed can0_pins_a node contents to new generic binding method, changed can0_pins_a node position by alphabetical order, changed can0 device node position by rising physical address order v1: initial Patrick Menschel (4): ARM: dts: sun4i: Add CAN node ARM: dts: sun4i: Add can0_pins_a pinctrl settings ARM: dts: sun7i: Add CAN node ARM: dts: sun7i: Add can0_pins_a pinctrl settings arch/arm/boot/dts/sun4i-a10.dtsi | 13 + arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++ 2 files changed, 27 insertions(+) -- 1.9.1
[PATCH v3 0/4] ARM: dts: sunxi: Add CAN node and can0_pins_a pinctrl settings
The Allwinner A10/A20 SoCs have an on-board CAN (Controller Area Network) controller. This patch adds the CAN core to the SoC's include files, sun4i-a10.dtsi and sun7i-a20.dtsi. On linux-can mailing list was a discussion about updating the device tree bindings https://lkml.org/lkml/2015/9/17/220 but it did not progress past writing the documentation file. Documentation/devicetree/bindings/net/can/sun4i_can.txt The CAN controller can be enabled in a board specific dts file as described in the documentation file or by using a device tree overlay. I have tested the patch on a Banana Pi (A20 SoC) with mainline kernel 4.10.5. History: v3: added "allwinner,sun7i-a20-can" compatible to can0 device node contents, make separate patches for device nodes and pinctrl settings v2: changed can0_pins_a node contents to new generic binding method, changed can0_pins_a node position by alphabetical order, changed can0 device node position by rising physical address order v1: initial Patrick Menschel (4): ARM: dts: sun4i: Add CAN node ARM: dts: sun4i: Add can0_pins_a pinctrl settings ARM: dts: sun7i: Add CAN node ARM: dts: sun7i: Add can0_pins_a pinctrl settings arch/arm/boot/dts/sun4i-a10.dtsi | 13 + arch/arm/boot/dts/sun7i-a20.dtsi | 14 ++ 2 files changed, 27 insertions(+) -- 1.9.1
[PATCH v3 3/4] ARM: dts: sun7i: Add CAN node
The A20 SoC has an on-board CAN controller. This patch adds the device node. The CAN controller is inherited from the A10 SoC and uses the same driver. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel--- arch/arm/boot/dts/sun7i-a20.dtsi | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 2db97fc..c637e10 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -1582,6 +1582,15 @@ #size-cells = <0>; }; + can0: can@01c2bc00 { + compatible = "allwinner,sun7i-a20-can", +"allwinner,sun4i-a10-can"; + reg = <0x01c2bc00 0x400>; + interrupts = ; + clocks = <_gates 4>; + status = "disabled"; + }; + i2c4: i2c@01c2c000 { compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c"; -- 1.9.1
[PATCH v3 3/4] ARM: dts: sun7i: Add CAN node
The A20 SoC has an on-board CAN controller. This patch adds the device node. The CAN controller is inherited from the A10 SoC and uses the same driver. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel --- arch/arm/boot/dts/sun7i-a20.dtsi | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 2db97fc..c637e10 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -1582,6 +1582,15 @@ #size-cells = <0>; }; + can0: can@01c2bc00 { + compatible = "allwinner,sun7i-a20-can", +"allwinner,sun4i-a10-can"; + reg = <0x01c2bc00 0x400>; + interrupts = ; + clocks = <_gates 4>; + status = "disabled"; + }; + i2c4: i2c@01c2c000 { compatible = "allwinner,sun7i-a20-i2c", "allwinner,sun4i-a10-i2c"; -- 1.9.1
[PATCH v3 1/4] ARM: dts: sun4i: Add CAN node
The A10 SoC has an on-board CAN controller. This patch adds the device node. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel--- arch/arm/boot/dts/sun4i-a10.dtsi | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index ba20b48..7c559e7 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -1313,6 +1313,14 @@ #size-cells = <0>; }; + can0: can@01c2bc00 { + compatible = "allwinner,sun4i-a10-can"; + reg = <0x01c2bc00 0x400>; + interrupts = <26>; + clocks = <_gates 4>; + status = "disabled"; + }; + ps20: ps2@01c2a000 { compatible = "allwinner,sun4i-a10-ps2"; reg = <0x01c2a000 0x400>; -- 1.9.1
[PATCH v3 1/4] ARM: dts: sun4i: Add CAN node
The A10 SoC has an on-board CAN controller. This patch adds the device node. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel --- arch/arm/boot/dts/sun4i-a10.dtsi | 8 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index ba20b48..7c559e7 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -1313,6 +1313,14 @@ #size-cells = <0>; }; + can0: can@01c2bc00 { + compatible = "allwinner,sun4i-a10-can"; + reg = <0x01c2bc00 0x400>; + interrupts = <26>; + clocks = <_gates 4>; + status = "disabled"; + }; + ps20: ps2@01c2a000 { compatible = "allwinner,sun4i-a10-ps2"; reg = <0x01c2a000 0x400>; -- 1.9.1
[PATCH v6 01/11] powerpc/powernv: Data structure and macros definitions
From: Hemant KumarCreate new header file "imc-pmu.h" to add the data structures and macros needed for IMC pmu support. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h | 68 ++ 1 file changed, 68 insertions(+) create mode 100644 arch/powerpc/include/asm/imc-pmu.h diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h new file mode 100644 index ..a3d4f1bf9492 --- /dev/null +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -0,0 +1,68 @@ +#ifndef PPC_POWERNV_IMC_PMU_DEF_H +#define PPC_POWERNV_IMC_PMU_DEF_H + +/* + * IMC Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define IMC_MAX_CHIPS 32 +#define IMC_MAX_PMUS 32 +#define IMC_MAX_PMU_NAME_LEN 256 + +#define IMC_NEST_MAX_PAGES 16 + +#define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" +#define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" + +/* + * Structure to hold per chip specific memory address + * information for nest pmus. Nest Counter data are exported + * in per-chip reserved memory region by the PORE Engine. + */ +struct perchip_nest_info { + u32 chip_id; + u64 pbase; + u64 vbase[IMC_NEST_MAX_PAGES]; + u64 size; +}; + +/* + * Place holder for nest pmu events and values. + */ +struct imc_events { + char *ev_name; + char *ev_value; +}; + +/* + * Device tree parser code detects IMC pmu support and + * registers new IMC pmus. This structure will + * hold the pmu functions and attrs for each imc pmu and + * will be referenced at the time of pmu registration. + */ +struct imc_pmu { + struct pmu pmu; + int domain; + const struct attribute_group *attr_groups[4]; +}; + +/* + * Domains for IMC PMUs + */ +#define IMC_DOMAIN_NEST1 +#define IMC_DOMAIN_UNKNOWN -1 + +#endif /* PPC_POWERNV_IMC_PMU_DEF_H */ -- 2.7.4
[PATCH v6 02/11] powerpc/powernv: Autoload IMC device driver module
From: Hemant KumarThis patch does three things : - Enables "opal.c" to create a platform device for the IMC interface according to the appropriate compatibility string. - Find the reserved-memory region details from the system device tree and get the base address of HOMER (Reserved memory) region address for each chip. - We also get the Nest PMU counter data offsets (in the HOMER region) and their sizes. The offsets for the counters' data are fixed and won't change from chip to chip. The device tree parsing logic is separated from the PMU creation functions (which is done in subsequent patches). Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/opal-imc.c | 126 ++ arch/powerpc/platforms/powernv/opal.c | 14 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/powernv/opal-imc.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb3f482..44909fec1121 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-imc.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c new file mode 100644 index ..c476d596c6a8 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -0,0 +1,126 @@ +/* + * OPAL IMC interface detection driver + * Supported on POWERNV platform + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; + +static int opal_imc_counters_probe(struct platform_device *pdev) +{ + struct device_node *child, *imc_dev, *rm_node = NULL; + struct perchip_nest_info *pcni; + u32 pages, nest_offset, nest_size, idx; + int i = 0; + const char *node_name; + const __be32 *addrp; + u64 reg_addr, reg_size; + + if (!pdev || !pdev->dev.of_node) + return -ENODEV; + + /* +* Check whether this kdump kernel. If yes, just return. +*/ + if (is_kdump_kernel()) + return -ENODEV; + + imc_dev = pdev->dev.of_node; + + /* +* nest_offset : where the nest-counters' data start. +* size : size of the entire nest-counters region +*/ + if (of_property_read_u32(imc_dev, "imc-nest-offset", _offset)) + goto err; + + if (of_property_read_u32(imc_dev, "imc-nest-size", _size)) + goto err; + + /* Find the "homer region" for each chip */ + rm_node = of_find_node_by_path("/reserved-memory"); + if (!rm_node) + goto err; + + for_each_child_of_node(rm_node, child) { + if (of_property_read_string_index(child, "name", 0, + _name)) + continue; + if (strncmp("ibm,homer-image", node_name, + strlen("ibm,homer-image"))) + continue; + + /* Get the chip id to which the above homer region belongs to */ + if (of_property_read_u32(child, "ibm,chip-id", )) + goto err; + + pcni = _perchip_info[idx]; + addrp = of_get_address(child, 0, _size, NULL); + if (!addrp) + goto err; + + /* Fetch the homer region base address */ + reg_addr = of_read_number(addrp, 2); + pcni->pbase = reg_addr;
[PATCH v6 01/11] powerpc/powernv: Data structure and macros definitions
From: Hemant Kumar Create new header file "imc-pmu.h" to add the data structures and macros needed for IMC pmu support. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h | 68 ++ 1 file changed, 68 insertions(+) create mode 100644 arch/powerpc/include/asm/imc-pmu.h diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h new file mode 100644 index ..a3d4f1bf9492 --- /dev/null +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -0,0 +1,68 @@ +#ifndef PPC_POWERNV_IMC_PMU_DEF_H +#define PPC_POWERNV_IMC_PMU_DEF_H + +/* + * IMC Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define IMC_MAX_CHIPS 32 +#define IMC_MAX_PMUS 32 +#define IMC_MAX_PMU_NAME_LEN 256 + +#define IMC_NEST_MAX_PAGES 16 + +#define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" +#define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" + +/* + * Structure to hold per chip specific memory address + * information for nest pmus. Nest Counter data are exported + * in per-chip reserved memory region by the PORE Engine. + */ +struct perchip_nest_info { + u32 chip_id; + u64 pbase; + u64 vbase[IMC_NEST_MAX_PAGES]; + u64 size; +}; + +/* + * Place holder for nest pmu events and values. + */ +struct imc_events { + char *ev_name; + char *ev_value; +}; + +/* + * Device tree parser code detects IMC pmu support and + * registers new IMC pmus. This structure will + * hold the pmu functions and attrs for each imc pmu and + * will be referenced at the time of pmu registration. + */ +struct imc_pmu { + struct pmu pmu; + int domain; + const struct attribute_group *attr_groups[4]; +}; + +/* + * Domains for IMC PMUs + */ +#define IMC_DOMAIN_NEST1 +#define IMC_DOMAIN_UNKNOWN -1 + +#endif /* PPC_POWERNV_IMC_PMU_DEF_H */ -- 2.7.4
[PATCH v6 02/11] powerpc/powernv: Autoload IMC device driver module
From: Hemant Kumar This patch does three things : - Enables "opal.c" to create a platform device for the IMC interface according to the appropriate compatibility string. - Find the reserved-memory region details from the system device tree and get the base address of HOMER (Reserved memory) region address for each chip. - We also get the Nest PMU counter data offsets (in the HOMER region) and their sizes. The offsets for the counters' data are fixed and won't change from chip to chip. The device tree parsing logic is separated from the PMU creation functions (which is done in subsequent patches). Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/opal-imc.c | 126 ++ arch/powerpc/platforms/powernv/opal.c | 14 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/powernv/opal-imc.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb3f482..44909fec1121 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -2,7 +2,7 @@ obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-imc.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c new file mode 100644 index ..c476d596c6a8 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -0,0 +1,126 @@ +/* + * OPAL IMC interface detection driver + * Supported on POWERNV platform + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; + +static int opal_imc_counters_probe(struct platform_device *pdev) +{ + struct device_node *child, *imc_dev, *rm_node = NULL; + struct perchip_nest_info *pcni; + u32 pages, nest_offset, nest_size, idx; + int i = 0; + const char *node_name; + const __be32 *addrp; + u64 reg_addr, reg_size; + + if (!pdev || !pdev->dev.of_node) + return -ENODEV; + + /* +* Check whether this kdump kernel. If yes, just return. +*/ + if (is_kdump_kernel()) + return -ENODEV; + + imc_dev = pdev->dev.of_node; + + /* +* nest_offset : where the nest-counters' data start. +* size : size of the entire nest-counters region +*/ + if (of_property_read_u32(imc_dev, "imc-nest-offset", _offset)) + goto err; + + if (of_property_read_u32(imc_dev, "imc-nest-size", _size)) + goto err; + + /* Find the "homer region" for each chip */ + rm_node = of_find_node_by_path("/reserved-memory"); + if (!rm_node) + goto err; + + for_each_child_of_node(rm_node, child) { + if (of_property_read_string_index(child, "name", 0, + _name)) + continue; + if (strncmp("ibm,homer-image", node_name, + strlen("ibm,homer-image"))) + continue; + + /* Get the chip id to which the above homer region belongs to */ + if (of_property_read_u32(child, "ibm,chip-id", )) + goto err; + + pcni = _perchip_info[idx]; + addrp = of_get_address(child, 0, _size, NULL); + if (!addrp) + goto err; + + /* Fetch the homer region base address */ + reg_addr = of_read_number(addrp, 2); + pcni->pbase = reg_addr; + /* Add the nest IMC Base offset */ + pcni->pbase = pcni->pbase +
[PATCH v3 2/4] ARM: dts: sun4i: Add can0_pins_a pinctrl settings
The A10 SoC has an on-board CAN controller. This patch adds the pinctrl settings for pins PH20 and PH21. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel--- arch/arm/boot/dts/sun4i-a10.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 7c559e7..f7dced4 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -974,6 +974,11 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + can0_pins_a: can0@0 { + pins = "PH20","PH21"; + function = "can"; + }; + emac_pins_a: emac0@0 { pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", -- 1.9.1
[PATCH v3 2/4] ARM: dts: sun4i: Add can0_pins_a pinctrl settings
The A10 SoC has an on-board CAN controller. This patch adds the pinctrl settings for pins PH20 and PH21. This patch is adapted from the description in Documentation/devicetree/bindings/net/can/sun4i_can.txt Signed-off-by: Patrick Menschel --- arch/arm/boot/dts/sun4i-a10.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 7c559e7..f7dced4 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -974,6 +974,11 @@ #interrupt-cells = <3>; #gpio-cells = <3>; + can0_pins_a: can0@0 { + pins = "PH20","PH21"; + function = "can"; + }; + emac_pins_a: emac0@0 { pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", -- 1.9.1
[PATCH v6 00/11] IMC Instrumentation Support
Power9 has In-Memory-Collection (IMC) infrastructure which contains various Performance Monitoring Units (PMUs) at Nest level (these are on-chip but off-core), Core level and Thread level. The Nest PMU counters are handled by a Nest IMC microcode which runs in the OCC (On-Chip Controller) complex. The microcode collects the counter data and moves the nest IMC counter data to memory. The Core and Thread IMC PMU counters are handled in the core. Core level PMU counters give us the IMC counters' data per core and thread level PMU counters give us the IMC counters' data per CPU thread. This patchset enables the nest IMC, core IMC and thread IMC PMUs and is based on the initial work done by Madhavan Srinivasan. "Nest Instrumentation Support" : https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-August/132078.html v1 for this patchset can be found here : https://lwn.net/Articles/705475/ Nest events: Per-chip nest instrumentation provides various per-chip metrics such as memory, powerbus, Xlink and Alink bandwidth. Core events: Per-core IMC instrumentation provides various per-core metrics such as non-idle cycles, non-idle instructions, various cache and memory related metrics etc. Thread events: All the events for thread level are same as core level with the difference being in the domain. These are per-cpu metrics. PMU Events' Information: OPAL obtains the IMC PMU and event information from the IMC Catalog and passes on to the kernel via the device tree. The events' information contains : - Event name - Event Offset - Event description and, maybe : - Event scale - Event unit Some PMUs may have a common scale and unit values for all their supported events. For those cases, the scale and unit properties for those events must be inherited from the PMU. The event offset in the memory is where the counter data gets accumulated. The OPAL-side patches are posted upstream : https://lists.ozlabs.org/pipermail/skiboot/2017-March/006531.html The kernel discovers the IMC counters information in the device tree at the "imc-counters" device node which has a compatible field "ibm,opal-in-memory-counters". Parsing of the Events' information: To parse the IMC PMUs and events information, the kernel has to discover the "imc-counters" node and walk through the pmu and event nodes. Here is an excerpt of the dt showing the imc-counters with mcs0 (nest), core and thread node: https://github.com/open-power/ima-catalog/blob/master/81E00612.4E0100.dts /dts-v1/; [...] /dts-v1/; / { name = ""; compatible = "ibm,opal-in-memory-counters"; #address-cells = <0x1>; #size-cells = <0x1>; imc-nest-offset = <0x32>; imc-nest-size = <0x3>; version-id = ""; NEST_MCS: nest-mcs-events { #address-cells = <0x1>; #size-cells = <0x1>; event@0 { event-name = "RRTO_QFULL_NO_DISP" ; reg = <0x0 0x8>; desc = "RRTO not dispatched in MCS0 due to capacity - pulses once for each time a valid RRTO op is not dispatched due to a command list full condition" ; }; event@8 { event-name = "WRTO_QFULL_NO_DISP" ; reg = <0x8 0x8>; desc = "WRTO not dispatched in MCS0 due to capacity - pulses once for each time a valid WRTO op is not dispatched due to a command list full condition" ; }; [...] mcs0 { compatible = "ibm,imc-counters-nest"; events-prefix = "PM_MCS0_"; unit = ""; scale = ""; reg = <0x118 0x8>; events = < _MCS >; }; mcs1 { compatible = "ibm,imc-counters-nest"; events-prefix = "PM_MCS1_"; unit = ""; scale = ""; reg = <0x198 0x8>; events = < _MCS >; }; [...] CORE_EVENTS: core-events { #address-cells = <0x1>; #size-cells = <0x1>; event@e0 { event-name = "0THRD_NON_IDLE_PCYC" ; reg = <0xe0 0x8>; desc = "The number of processor cycles when all threads are idle" ; }; event@120 { event-name = "1THRD_NON_IDLE_PCYC" ; reg = <0x120 0x8>; desc = "The number of processor cycles when exactly one SMT thread is executing non-idle code" ; }; [...] core { compatible = "ibm,imc-counters-core"; events-prefix = "CPM_"; unit = ""; scale = ""; reg = <0x0 0x8>; events = < _EVENTS >; }; thread { compatible =
[PATCH v6 00/11] IMC Instrumentation Support
Power9 has In-Memory-Collection (IMC) infrastructure which contains various Performance Monitoring Units (PMUs) at Nest level (these are on-chip but off-core), Core level and Thread level. The Nest PMU counters are handled by a Nest IMC microcode which runs in the OCC (On-Chip Controller) complex. The microcode collects the counter data and moves the nest IMC counter data to memory. The Core and Thread IMC PMU counters are handled in the core. Core level PMU counters give us the IMC counters' data per core and thread level PMU counters give us the IMC counters' data per CPU thread. This patchset enables the nest IMC, core IMC and thread IMC PMUs and is based on the initial work done by Madhavan Srinivasan. "Nest Instrumentation Support" : https://lists.ozlabs.org/pipermail/linuxppc-dev/2015-August/132078.html v1 for this patchset can be found here : https://lwn.net/Articles/705475/ Nest events: Per-chip nest instrumentation provides various per-chip metrics such as memory, powerbus, Xlink and Alink bandwidth. Core events: Per-core IMC instrumentation provides various per-core metrics such as non-idle cycles, non-idle instructions, various cache and memory related metrics etc. Thread events: All the events for thread level are same as core level with the difference being in the domain. These are per-cpu metrics. PMU Events' Information: OPAL obtains the IMC PMU and event information from the IMC Catalog and passes on to the kernel via the device tree. The events' information contains : - Event name - Event Offset - Event description and, maybe : - Event scale - Event unit Some PMUs may have a common scale and unit values for all their supported events. For those cases, the scale and unit properties for those events must be inherited from the PMU. The event offset in the memory is where the counter data gets accumulated. The OPAL-side patches are posted upstream : https://lists.ozlabs.org/pipermail/skiboot/2017-March/006531.html The kernel discovers the IMC counters information in the device tree at the "imc-counters" device node which has a compatible field "ibm,opal-in-memory-counters". Parsing of the Events' information: To parse the IMC PMUs and events information, the kernel has to discover the "imc-counters" node and walk through the pmu and event nodes. Here is an excerpt of the dt showing the imc-counters with mcs0 (nest), core and thread node: https://github.com/open-power/ima-catalog/blob/master/81E00612.4E0100.dts /dts-v1/; [...] /dts-v1/; / { name = ""; compatible = "ibm,opal-in-memory-counters"; #address-cells = <0x1>; #size-cells = <0x1>; imc-nest-offset = <0x32>; imc-nest-size = <0x3>; version-id = ""; NEST_MCS: nest-mcs-events { #address-cells = <0x1>; #size-cells = <0x1>; event@0 { event-name = "RRTO_QFULL_NO_DISP" ; reg = <0x0 0x8>; desc = "RRTO not dispatched in MCS0 due to capacity - pulses once for each time a valid RRTO op is not dispatched due to a command list full condition" ; }; event@8 { event-name = "WRTO_QFULL_NO_DISP" ; reg = <0x8 0x8>; desc = "WRTO not dispatched in MCS0 due to capacity - pulses once for each time a valid WRTO op is not dispatched due to a command list full condition" ; }; [...] mcs0 { compatible = "ibm,imc-counters-nest"; events-prefix = "PM_MCS0_"; unit = ""; scale = ""; reg = <0x118 0x8>; events = < _MCS >; }; mcs1 { compatible = "ibm,imc-counters-nest"; events-prefix = "PM_MCS1_"; unit = ""; scale = ""; reg = <0x198 0x8>; events = < _MCS >; }; [...] CORE_EVENTS: core-events { #address-cells = <0x1>; #size-cells = <0x1>; event@e0 { event-name = "0THRD_NON_IDLE_PCYC" ; reg = <0xe0 0x8>; desc = "The number of processor cycles when all threads are idle" ; }; event@120 { event-name = "1THRD_NON_IDLE_PCYC" ; reg = <0x120 0x8>; desc = "The number of processor cycles when exactly one SMT thread is executing non-idle code" ; }; [...] core { compatible = "ibm,imc-counters-core"; events-prefix = "CPM_"; unit = ""; scale = ""; reg = <0x0 0x8>; events = < _EVENTS >; }; thread { compatible =
[PATCH v6 10/11] powerpc/perf: Thread IMC PMU functions
From: Hemant KumarThis patch adds the PMU functions required for event initialization, read, update, add, del etc. for thread IMC PMU. Thread IMC PMUs are used for per-task monitoring. These PMUs don't need any hotplugging support. For each CPU, a page of memory is allocated and is kept static i.e., these pages will exist till the machine shuts down. The base address of this page is assigned to the ldbar of that cpu. As soon as we do that, the thread IMC counters start running for that cpu and the data of these counters are assigned to the page allocated. But we use this for per-task monitoring. Whenever we start monitoring a task, the event is added is onto the task. At that point, we read the initial value of the event. Whenever, we stop monitoring the task, the final value is taken and the difference is the event data. Now, a task can move to a different cpu. Suppose a task X is moving from cpu A to cpu B. When the task is scheduled out of A, we get an event_del for A, and hence, the event data is updated. And, we stop updating the X's event data. As soon as X moves on to B, event_add is called for B, and we again update the event_data. And this is how it keeps on updating the event data even when the task is scheduled on to different cpus. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 5 + arch/powerpc/perf/imc-pmu.c | 173 +- arch/powerpc/platforms/powernv/opal-imc.c | 3 + 3 files changed, 180 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index c63bc78fd6f6..42f0149886b4 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -25,12 +25,16 @@ #define IMC_NEST_MAX_PAGES 16 #define IMC_CORE_COUNTER_MEM 8192 +#define IMC_THREAD_COUNTER_MEM 8192 #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" #define IMC_DTB_CORE_COMPAT"ibm,imc-counters-core" #define IMC_DTB_THREAD_COMPAT "ibm,imc-counters-thread" +#define THREAD_IMC_LDBAR_MASK 0x0003e000 +#define THREAD_IMC_ENABLE 0x8000 + /* * Structure to hold per chip specific memory address * information for nest pmus. Nest Counter data are exported @@ -73,4 +77,5 @@ struct imc_pmu { int imc_get_domain(struct device_node *pmu_dev); void core_imc_disable(void); +void thread_imc_disable(void); #endif /* PPC_POWERNV_IMC_PMU_DEF_H */ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 35b3564747e2..3db637c6d3f4 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -30,6 +30,9 @@ static u64 per_core_pdbar_add[IMC_MAX_CHIPS][IMC_MAX_CORES]; static cpumask_t core_imc_cpumask; struct imc_pmu *core_imc_pmu; +/* Maintains base address for all the cpus */ +static u64 per_cpu_add[NR_CPUS]; + /* Needed for sanity check */ extern u64 nest_max_offset; extern u64 core_max_offset; @@ -461,6 +464,56 @@ static int core_imc_event_init(struct perf_event *event) return 0; } +static int thread_imc_event_init(struct perf_event *event) +{ + struct task_struct *target; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + event->hw.idx = -1; + + /* Sanity check for config (event offset) */ + if (event->attr.config > thread_max_offset) + return -EINVAL; + + target = event->hw.target; + + if (!target) + return -EINVAL; + + event->pmu->task_ctx_nr = perf_sw_context; + return 0; +} + +static void thread_imc_read_counter(struct perf_event *event) +{ + u64 *addr, data; + int cpu_id = smp_processor_id(); + + addr = (u64 *)(per_cpu_add[cpu_id] + event->attr.config); + data = __be64_to_cpu(READ_ONCE(*addr)); + local64_set(>hw.prev_count, data); +} + +static void thread_imc_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count, *addr; + int cpu_id = smp_processor_id(); + + addr = (u64 *)(per_cpu_add[cpu_id] + event->attr.config); + counter_prev = local64_read(>hw.prev_count); + counter_new = __be64_to_cpu(READ_ONCE(*addr)); + final_count = counter_new - counter_prev; + + local64_set(>hw.prev_count, counter_new); + local64_add(final_count, >count); +} + static void imc_read_counter(struct perf_event *event) { u64 *addr, data; @@ -511,6 +564,53 @@ static int imc_event_add(struct perf_event *event, int flags) return 0; } +static void
[PATCH v6 10/11] powerpc/perf: Thread IMC PMU functions
From: Hemant Kumar This patch adds the PMU functions required for event initialization, read, update, add, del etc. for thread IMC PMU. Thread IMC PMUs are used for per-task monitoring. These PMUs don't need any hotplugging support. For each CPU, a page of memory is allocated and is kept static i.e., these pages will exist till the machine shuts down. The base address of this page is assigned to the ldbar of that cpu. As soon as we do that, the thread IMC counters start running for that cpu and the data of these counters are assigned to the page allocated. But we use this for per-task monitoring. Whenever we start monitoring a task, the event is added is onto the task. At that point, we read the initial value of the event. Whenever, we stop monitoring the task, the final value is taken and the difference is the event data. Now, a task can move to a different cpu. Suppose a task X is moving from cpu A to cpu B. When the task is scheduled out of A, we get an event_del for A, and hence, the event data is updated. And, we stop updating the X's event data. As soon as X moves on to B, event_add is called for B, and we again update the event_data. And this is how it keeps on updating the event data even when the task is scheduled on to different cpus. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 5 + arch/powerpc/perf/imc-pmu.c | 173 +- arch/powerpc/platforms/powernv/opal-imc.c | 3 + 3 files changed, 180 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index c63bc78fd6f6..42f0149886b4 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -25,12 +25,16 @@ #define IMC_NEST_MAX_PAGES 16 #define IMC_CORE_COUNTER_MEM 8192 +#define IMC_THREAD_COUNTER_MEM 8192 #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" #define IMC_DTB_CORE_COMPAT"ibm,imc-counters-core" #define IMC_DTB_THREAD_COMPAT "ibm,imc-counters-thread" +#define THREAD_IMC_LDBAR_MASK 0x0003e000 +#define THREAD_IMC_ENABLE 0x8000 + /* * Structure to hold per chip specific memory address * information for nest pmus. Nest Counter data are exported @@ -73,4 +77,5 @@ struct imc_pmu { int imc_get_domain(struct device_node *pmu_dev); void core_imc_disable(void); +void thread_imc_disable(void); #endif /* PPC_POWERNV_IMC_PMU_DEF_H */ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 35b3564747e2..3db637c6d3f4 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -30,6 +30,9 @@ static u64 per_core_pdbar_add[IMC_MAX_CHIPS][IMC_MAX_CORES]; static cpumask_t core_imc_cpumask; struct imc_pmu *core_imc_pmu; +/* Maintains base address for all the cpus */ +static u64 per_cpu_add[NR_CPUS]; + /* Needed for sanity check */ extern u64 nest_max_offset; extern u64 core_max_offset; @@ -461,6 +464,56 @@ static int core_imc_event_init(struct perf_event *event) return 0; } +static int thread_imc_event_init(struct perf_event *event) +{ + struct task_struct *target; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + event->hw.idx = -1; + + /* Sanity check for config (event offset) */ + if (event->attr.config > thread_max_offset) + return -EINVAL; + + target = event->hw.target; + + if (!target) + return -EINVAL; + + event->pmu->task_ctx_nr = perf_sw_context; + return 0; +} + +static void thread_imc_read_counter(struct perf_event *event) +{ + u64 *addr, data; + int cpu_id = smp_processor_id(); + + addr = (u64 *)(per_cpu_add[cpu_id] + event->attr.config); + data = __be64_to_cpu(READ_ONCE(*addr)); + local64_set(>hw.prev_count, data); +} + +static void thread_imc_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count, *addr; + int cpu_id = smp_processor_id(); + + addr = (u64 *)(per_cpu_add[cpu_id] + event->attr.config); + counter_prev = local64_read(>hw.prev_count); + counter_new = __be64_to_cpu(READ_ONCE(*addr)); + final_count = counter_new - counter_prev; + + local64_set(>hw.prev_count, counter_new); + local64_add(final_count, >count); +} + static void imc_read_counter(struct perf_event *event) { u64 *addr, data; @@ -511,6 +564,53 @@ static int imc_event_add(struct perf_event *event, int flags) return 0; } +static void thread_imc_event_start(struct perf_event *event, int flags) +{ + thread_imc_read_counter(event); +}
[PATCH v6 08/11] powerpc/perf: PMU functions for Core IMC and hotplugging
From: Hemant KumarThis patch adds the PMU function to initialize a core IMC event. It also adds cpumask initialization function for core IMC PMU. For initialization, a 8KB of memory is allocated per core where the data for core IMC counters will be accumulated. The base address for this page is sent to OPAL via an OPAL call which initializes various SCOMs related to Core IMC initialization. Upon any errors, the pages are free'ed and core IMC counters are disabled using the same OPAL call. For CPU hotplugging, a cpumask is initialized which contains an online CPU from each core. If a cpu goes offline, we check whether that cpu belongs to the core imc cpumask, if yes, then, we migrate the PMU context to any other online cpu (if available) in that core. If a cpu comes back online, then this cpu will be added to the core imc cpumask only if there was no other cpu from that core in the previous cpumask. To register the hotplug functions for core_imc, a new state CPUHP_AP_PERF_POWERPC_COREIMC_ONLINE is added to the list of existing states. Patch also adds OPAL device shutdown callback. Needed to disable the IMC core engine to handle kexec. Signed-off-by: Hemant Kumar [Anju: Changed the condition for setting cpumask for core in imc_pmu_cpumask_get_attr() ] Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h | 3 + arch/powerpc/include/asm/opal-api.h| 10 +- arch/powerpc/include/asm/opal.h| 2 + arch/powerpc/perf/imc-pmu.c| 267 - arch/powerpc/platforms/powernv/opal-imc.c | 13 +- arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + include/linux/cpuhotplug.h | 1 + 7 files changed, 287 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index 2c39603ff3e7..4aa63191456a 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -21,8 +21,10 @@ #define IMC_MAX_CHIPS 32 #define IMC_MAX_PMUS 32 #define IMC_MAX_PMU_NAME_LEN 256 +#define IMC_MAX_CORES 32 #define IMC_NEST_MAX_PAGES 16 +#define IMC_CORE_COUNTER_MEM 8192 #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" @@ -68,4 +70,5 @@ struct imc_pmu { #define IMC_DOMAIN_UNKNOWN -1 int imc_get_domain(struct device_node *pmu_dev); +void core_imc_disable(void); #endif /* PPC_POWERNV_IMC_PMU_DEF_H */ diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 23fc51e9d71d..971918deb793 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -169,7 +169,8 @@ #define OPAL_PCI_TCE_KILL 126 #define OPAL_NMMU_SET_PTCR 127 #define OPAL_NEST_IMC_COUNTERS_CONTROL 149 -#define OPAL_LAST 149 +#define OPAL_CORE_IMC_COUNTERS_CONTROL 150 +#define OPAL_LAST 150 /* Device tree flags */ @@ -939,6 +940,13 @@ enum { OPAL_NEST_IMC_START, }; +/* Operation argument to Core IMC */ +enum { + OPAL_CORE_IMC_DISABLE, + OPAL_CORE_IMC_ENABLE, + OPAL_CORE_IMC_INIT, +}; + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index d93d08204243..c4baa6d32037 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -229,6 +229,8 @@ int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr); int64_t opal_nest_imc_counters_control(uint64_t mode, uint64_t value1, uint64_t value2, uint64_t value3); +int64_t opal_core_imc_counters_control(uint64_t operation, uint64_t addr, + uint64_t value2, uint64_t value3); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 728c67e139e0..45f9b35142a7 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -1,5 +1,5 @@ /* - * Nest Performance Monitor counter support. + * IMC Performance Monitor counter support. * * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. * (C) 2016 Hemant K Shaw, IBM Corporation. @@ -19,6 +19,15 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; static cpumask_t nest_imc_cpumask; +/* + * Maintains base addresses for all the cores. + * MAX chip and core are defined as 32. So we + * statically allocate 8K for this structure. + * + * TODO -- Could be made dynamic
[PATCH v6 09/11] powerpc/powernv: Thread IMC events detection
From: Hemant KumarPatch adds support for detection of thread IMC events. It adds a new domain IMC_DOMAIN_THREAD and it is determined with the help of the compatibility string "ibm,imc-counters-thread" based on the IMC device tree. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 2 ++ arch/powerpc/perf/imc-pmu.c | 1 + arch/powerpc/platforms/powernv/opal-imc.c | 9 - 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index 4aa63191456a..c63bc78fd6f6 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -29,6 +29,7 @@ #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" #define IMC_DTB_CORE_COMPAT"ibm,imc-counters-core" +#define IMC_DTB_THREAD_COMPAT "ibm,imc-counters-thread" /* * Structure to hold per chip specific memory address @@ -67,6 +68,7 @@ struct imc_pmu { */ #define IMC_DOMAIN_NEST1 #define IMC_DOMAIN_CORE2 +#define IMC_DOMAIN_THREAD 3 #define IMC_DOMAIN_UNKNOWN -1 int imc_get_domain(struct device_node *pmu_dev); diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 45f9b35142a7..35b3564747e2 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -33,6 +33,7 @@ struct imc_pmu *core_imc_pmu; /* Needed for sanity check */ extern u64 nest_max_offset; extern u64 core_max_offset; +extern u64 thread_max_offset; PMU_FORMAT_ATTR(event, "config:0-20"); static struct attribute *imc_format_attrs[] = { diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index f261fc933959..ac625cf13875 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -40,6 +40,7 @@ extern int init_imc_pmu(struct imc_events *events, int idx, struct imc_pmu *pmu_ptr); u64 nest_max_offset; u64 core_max_offset; +u64 thread_max_offset; static int imc_event_info(char *name, struct imc_events *events) { @@ -87,6 +88,10 @@ static void update_max_value(u32 value, int pmu_domain) if (core_max_offset < value) core_max_offset = value; break; + case IMC_DOMAIN_THREAD: + if (thread_max_offset < value) + thread_max_offset = value; + break; default: /* Unknown domain, return */ return; @@ -240,6 +245,8 @@ int imc_get_domain(struct device_node *pmu_dev) return IMC_DOMAIN_NEST; if (of_device_is_compatible(pmu_dev, IMC_DTB_CORE_COMPAT)) return IMC_DOMAIN_CORE; + if (of_device_is_compatible(pmu_dev, IMC_DTB_THREAD_COMPAT)) + return IMC_DOMAIN_THREAD; else return IMC_DOMAIN_UNKNOWN; } @@ -278,7 +285,7 @@ static void imc_free_events(struct imc_events *events, int nr_entries) /* * imc_pmu_create : Takes the parent device which is the pmu unit and a * pmu_index as the inputs. - * Allocates memory for the pmu, sets up its domain (NEST or CORE), and + * Allocates memory for the pmu, sets up its domain (NEST/CORE/THREAD), and * allocates memory for the events supported by this pmu. Assigns a name for * the pmu. Calls imc_events_node_parser() to setup the individual events. * If everything goes fine, it calls, init_imc_pmu() to setup the pmu device -- 2.7.4
[PATCH v6 08/11] powerpc/perf: PMU functions for Core IMC and hotplugging
From: Hemant Kumar This patch adds the PMU function to initialize a core IMC event. It also adds cpumask initialization function for core IMC PMU. For initialization, a 8KB of memory is allocated per core where the data for core IMC counters will be accumulated. The base address for this page is sent to OPAL via an OPAL call which initializes various SCOMs related to Core IMC initialization. Upon any errors, the pages are free'ed and core IMC counters are disabled using the same OPAL call. For CPU hotplugging, a cpumask is initialized which contains an online CPU from each core. If a cpu goes offline, we check whether that cpu belongs to the core imc cpumask, if yes, then, we migrate the PMU context to any other online cpu (if available) in that core. If a cpu comes back online, then this cpu will be added to the core imc cpumask only if there was no other cpu from that core in the previous cpumask. To register the hotplug functions for core_imc, a new state CPUHP_AP_PERF_POWERPC_COREIMC_ONLINE is added to the list of existing states. Patch also adds OPAL device shutdown callback. Needed to disable the IMC core engine to handle kexec. Signed-off-by: Hemant Kumar [Anju: Changed the condition for setting cpumask for core in imc_pmu_cpumask_get_attr() ] Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h | 3 + arch/powerpc/include/asm/opal-api.h| 10 +- arch/powerpc/include/asm/opal.h| 2 + arch/powerpc/perf/imc-pmu.c| 267 - arch/powerpc/platforms/powernv/opal-imc.c | 13 +- arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + include/linux/cpuhotplug.h | 1 + 7 files changed, 287 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index 2c39603ff3e7..4aa63191456a 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -21,8 +21,10 @@ #define IMC_MAX_CHIPS 32 #define IMC_MAX_PMUS 32 #define IMC_MAX_PMU_NAME_LEN 256 +#define IMC_MAX_CORES 32 #define IMC_NEST_MAX_PAGES 16 +#define IMC_CORE_COUNTER_MEM 8192 #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" @@ -68,4 +70,5 @@ struct imc_pmu { #define IMC_DOMAIN_UNKNOWN -1 int imc_get_domain(struct device_node *pmu_dev); +void core_imc_disable(void); #endif /* PPC_POWERNV_IMC_PMU_DEF_H */ diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 23fc51e9d71d..971918deb793 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -169,7 +169,8 @@ #define OPAL_PCI_TCE_KILL 126 #define OPAL_NMMU_SET_PTCR 127 #define OPAL_NEST_IMC_COUNTERS_CONTROL 149 -#define OPAL_LAST 149 +#define OPAL_CORE_IMC_COUNTERS_CONTROL 150 +#define OPAL_LAST 150 /* Device tree flags */ @@ -939,6 +940,13 @@ enum { OPAL_NEST_IMC_START, }; +/* Operation argument to Core IMC */ +enum { + OPAL_CORE_IMC_DISABLE, + OPAL_CORE_IMC_ENABLE, + OPAL_CORE_IMC_INIT, +}; + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index d93d08204243..c4baa6d32037 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -229,6 +229,8 @@ int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr); int64_t opal_nest_imc_counters_control(uint64_t mode, uint64_t value1, uint64_t value2, uint64_t value3); +int64_t opal_core_imc_counters_control(uint64_t operation, uint64_t addr, + uint64_t value2, uint64_t value3); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 728c67e139e0..45f9b35142a7 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -1,5 +1,5 @@ /* - * Nest Performance Monitor counter support. + * IMC Performance Monitor counter support. * * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. * (C) 2016 Hemant K Shaw, IBM Corporation. @@ -19,6 +19,15 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; static cpumask_t nest_imc_cpumask; +/* + * Maintains base addresses for all the cores. + * MAX chip and core are defined as 32. So we + * statically allocate 8K for this structure. + * + * TODO -- Could be made dynamic + */ +static u64 per_core_pdbar_add[IMC_MAX_CHIPS][IMC_MAX_CORES]; +static cpumask_t core_imc_cpumask;
[PATCH v6 09/11] powerpc/powernv: Thread IMC events detection
From: Hemant Kumar Patch adds support for detection of thread IMC events. It adds a new domain IMC_DOMAIN_THREAD and it is determined with the help of the compatibility string "ibm,imc-counters-thread" based on the IMC device tree. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 2 ++ arch/powerpc/perf/imc-pmu.c | 1 + arch/powerpc/platforms/powernv/opal-imc.c | 9 - 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index 4aa63191456a..c63bc78fd6f6 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -29,6 +29,7 @@ #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" #define IMC_DTB_CORE_COMPAT"ibm,imc-counters-core" +#define IMC_DTB_THREAD_COMPAT "ibm,imc-counters-thread" /* * Structure to hold per chip specific memory address @@ -67,6 +68,7 @@ struct imc_pmu { */ #define IMC_DOMAIN_NEST1 #define IMC_DOMAIN_CORE2 +#define IMC_DOMAIN_THREAD 3 #define IMC_DOMAIN_UNKNOWN -1 int imc_get_domain(struct device_node *pmu_dev); diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 45f9b35142a7..35b3564747e2 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -33,6 +33,7 @@ struct imc_pmu *core_imc_pmu; /* Needed for sanity check */ extern u64 nest_max_offset; extern u64 core_max_offset; +extern u64 thread_max_offset; PMU_FORMAT_ATTR(event, "config:0-20"); static struct attribute *imc_format_attrs[] = { diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index f261fc933959..ac625cf13875 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -40,6 +40,7 @@ extern int init_imc_pmu(struct imc_events *events, int idx, struct imc_pmu *pmu_ptr); u64 nest_max_offset; u64 core_max_offset; +u64 thread_max_offset; static int imc_event_info(char *name, struct imc_events *events) { @@ -87,6 +88,10 @@ static void update_max_value(u32 value, int pmu_domain) if (core_max_offset < value) core_max_offset = value; break; + case IMC_DOMAIN_THREAD: + if (thread_max_offset < value) + thread_max_offset = value; + break; default: /* Unknown domain, return */ return; @@ -240,6 +245,8 @@ int imc_get_domain(struct device_node *pmu_dev) return IMC_DOMAIN_NEST; if (of_device_is_compatible(pmu_dev, IMC_DTB_CORE_COMPAT)) return IMC_DOMAIN_CORE; + if (of_device_is_compatible(pmu_dev, IMC_DTB_THREAD_COMPAT)) + return IMC_DOMAIN_THREAD; else return IMC_DOMAIN_UNKNOWN; } @@ -278,7 +285,7 @@ static void imc_free_events(struct imc_events *events, int nr_entries) /* * imc_pmu_create : Takes the parent device which is the pmu unit and a * pmu_index as the inputs. - * Allocates memory for the pmu, sets up its domain (NEST or CORE), and + * Allocates memory for the pmu, sets up its domain (NEST/CORE/THREAD), and * allocates memory for the events supported by this pmu. Assigns a name for * the pmu. Calls imc_events_node_parser() to setup the individual events. * If everything goes fine, it calls, init_imc_pmu() to setup the pmu device -- 2.7.4
[PATCH v6 06/11] powerpc/perf: IMC pmu cpumask and cpu hotplug support
From: Hemant KumarAdds cpumask attribute to be used by each IMC pmu. Only one cpu (any online CPU) from each chip for nest PMUs is designated to read counters. On CPU hotplug, dying CPU is checked to see whether it is one of the designated cpus, if yes, next online cpu from the same chip (for nest units) is designated as new cpu to read counters. For this purpose, we introduce a new state : CPUHP_AP_PERF_POWERPC_NEST_ONLINE. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/opal-api.h| 13 ++- arch/powerpc/include/asm/opal.h| 3 + arch/powerpc/perf/imc-pmu.c| 155 - arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + include/linux/cpuhotplug.h | 1 + 5 files changed, 171 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index a0aa285869b5..23fc51e9d71d 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -168,7 +168,8 @@ #define OPAL_INT_SET_MFRR 125 #define OPAL_PCI_TCE_KILL 126 #define OPAL_NMMU_SET_PTCR 127 -#define OPAL_LAST 127 +#define OPAL_NEST_IMC_COUNTERS_CONTROL 149 +#define OPAL_LAST 149 /* Device tree flags */ @@ -928,6 +929,16 @@ enum { OPAL_PCI_TCE_KILL_ALL, }; +/* Operation argument to OPAL_NEST_IMC_COUNTERS_CONTROL */ +enum { + OPAL_NEST_IMC_PRODUCTION_MODE = 1, +}; + +enum { + OPAL_NEST_IMC_STOP, + OPAL_NEST_IMC_START, +}; + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 1ff03a6da76e..d93d08204243 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -227,6 +227,9 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, uint64_t dma_addr, uint32_t npages); int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr); +int64_t opal_nest_imc_counters_control(uint64_t mode, uint64_t value1, + uint64_t value2, uint64_t value3); + /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index bd5bf66bd920..b28835b861b3 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -17,6 +17,7 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +static cpumask_t nest_imc_cpumask; /* Needed for sanity check */ extern u64 nest_max_offset; @@ -32,6 +33,152 @@ static struct attribute_group imc_format_group = { .attrs = imc_format_attrs, }; +/* Get the cpumask printed to a buffer "buf" */ +static ssize_t imc_pmu_cpumask_get_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + cpumask_t *active_mask; + + active_mask = _imc_cpumask; + return cpumap_print_to_pagebuf(true, buf, active_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL); + +static struct attribute *imc_pmu_cpumask_attrs[] = { + _attr_cpumask.attr, + NULL, +}; + +static struct attribute_group imc_pmu_cpumask_attr_group = { + .attrs = imc_pmu_cpumask_attrs, +}; + +/* + * nest_init : Initializes the nest imc engine for the current chip. + */ +static void nest_init(int *loc) +{ + int rc; + + rc = opal_nest_imc_counters_control(OPAL_NEST_IMC_PRODUCTION_MODE, + OPAL_NEST_IMC_START, 0, 0); + if (rc) + loc[smp_processor_id()] = 1; +} + +static void nest_change_cpu_context(int old_cpu, int new_cpu) +{ + int i; + + for (i = 0; +(per_nest_pmu_arr[i] != NULL) && (i < IMC_MAX_PMUS); i++) + perf_pmu_migrate_context(_nest_pmu_arr[i]->pmu, + old_cpu, new_cpu); +} + +static int ppc_nest_imc_cpu_online(unsigned int cpu) +{ + int nid; + const struct cpumask *l_cpumask; + struct cpumask tmp_mask; + + /* Find the cpumask of this node */ + nid = cpu_to_node(cpu); + l_cpumask = cpumask_of_node(nid); + + /* +* If any of the cpu from this node is already present in the mask, +* just return, if not, then set this cpu in the mask. +*/ + if (!cpumask_and(_mask, l_cpumask, _imc_cpumask)) { + cpumask_set_cpu(cpu, _imc_cpumask); + return 0; + } + + return 0; +} + +static int
[PATCH v6 07/11] powerpc/powernv: Core IMC events detection
From: Hemant KumarThis patch adds support for detection of core IMC events along with the Nest IMC events. It adds a new domain IMC_DOMAIN_CORE and its determined with the help of the compatibility string "ibm,imc-counters-core" based on the IMC device tree. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 2 ++ arch/powerpc/perf/imc-pmu.c | 3 +++ arch/powerpc/platforms/powernv/opal-imc.c | 18 -- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index e13f51047522..2c39603ff3e7 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -26,6 +26,7 @@ #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" +#define IMC_DTB_CORE_COMPAT"ibm,imc-counters-core" /* * Structure to hold per chip specific memory address @@ -63,6 +64,7 @@ struct imc_pmu { * Domains for IMC PMUs */ #define IMC_DOMAIN_NEST1 +#define IMC_DOMAIN_CORE2 #define IMC_DOMAIN_UNKNOWN -1 int imc_get_domain(struct device_node *pmu_dev); diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index b28835b861b3..728c67e139e0 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -19,8 +19,11 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; static cpumask_t nest_imc_cpumask; +struct imc_pmu *core_imc_pmu; + /* Needed for sanity check */ extern u64 nest_max_offset; +extern u64 core_max_offset; PMU_FORMAT_ATTR(event, "config:0-20"); static struct attribute *imc_format_attrs[] = { diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index a98678266b0d..f6f63399ab06 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -34,10 +34,12 @@ extern struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +extern struct imc_pmu *core_imc_pmu; extern int init_imc_pmu(struct imc_events *events, int idx, struct imc_pmu *pmu_ptr); u64 nest_max_offset; +u64 core_max_offset; static int imc_event_info(char *name, struct imc_events *events) { @@ -81,6 +83,10 @@ static void update_max_value(u32 value, int pmu_domain) if (nest_max_offset < value) nest_max_offset = value; break; + case IMC_DOMAIN_CORE: + if (core_max_offset < value) + core_max_offset = value; + break; default: /* Unknown domain, return */ return; @@ -232,6 +238,8 @@ int imc_get_domain(struct device_node *pmu_dev) { if (of_device_is_compatible(pmu_dev, IMC_DTB_NEST_COMPAT)) return IMC_DOMAIN_NEST; + if (of_device_is_compatible(pmu_dev, IMC_DTB_CORE_COMPAT)) + return IMC_DOMAIN_CORE; else return IMC_DOMAIN_UNKNOWN; } @@ -299,7 +307,10 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index) goto free_pmu; /* Needed for hotplug/migration */ - per_nest_pmu_arr[pmu_index] = pmu_ptr; + if (pmu_ptr->domain == IMC_DOMAIN_CORE) + core_imc_pmu = pmu_ptr; + else if (pmu_ptr->domain == IMC_DOMAIN_NEST) + per_nest_pmu_arr[pmu_index] = pmu_ptr; /* * "events" property inside a PMU node contains the phandle value @@ -355,7 +366,10 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index) } /* Save the name to register it later */ - sprintf(buf, "nest_%s", (char *)pp->value); + if (pmu_ptr->domain == IMC_DOMAIN_NEST) + sprintf(buf, "nest_%s", (char *)pp->value); + else + sprintf(buf, "%s_imc", (char *)pp->value); pmu_ptr->pmu.name = (char *)buf; /* -- 2.7.4
[PATCH v6 06/11] powerpc/perf: IMC pmu cpumask and cpu hotplug support
From: Hemant Kumar Adds cpumask attribute to be used by each IMC pmu. Only one cpu (any online CPU) from each chip for nest PMUs is designated to read counters. On CPU hotplug, dying CPU is checked to see whether it is one of the designated cpus, if yes, next online cpu from the same chip (for nest units) is designated as new cpu to read counters. For this purpose, we introduce a new state : CPUHP_AP_PERF_POWERPC_NEST_ONLINE. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/opal-api.h| 13 ++- arch/powerpc/include/asm/opal.h| 3 + arch/powerpc/perf/imc-pmu.c| 155 - arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + include/linux/cpuhotplug.h | 1 + 5 files changed, 171 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index a0aa285869b5..23fc51e9d71d 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -168,7 +168,8 @@ #define OPAL_INT_SET_MFRR 125 #define OPAL_PCI_TCE_KILL 126 #define OPAL_NMMU_SET_PTCR 127 -#define OPAL_LAST 127 +#define OPAL_NEST_IMC_COUNTERS_CONTROL 149 +#define OPAL_LAST 149 /* Device tree flags */ @@ -928,6 +929,16 @@ enum { OPAL_PCI_TCE_KILL_ALL, }; +/* Operation argument to OPAL_NEST_IMC_COUNTERS_CONTROL */ +enum { + OPAL_NEST_IMC_PRODUCTION_MODE = 1, +}; + +enum { + OPAL_NEST_IMC_STOP, + OPAL_NEST_IMC_START, +}; + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 1ff03a6da76e..d93d08204243 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -227,6 +227,9 @@ int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, uint64_t dma_addr, uint32_t npages); int64_t opal_nmmu_set_ptcr(uint64_t chip_id, uint64_t ptcr); +int64_t opal_nest_imc_counters_control(uint64_t mode, uint64_t value1, + uint64_t value2, uint64_t value3); + /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index bd5bf66bd920..b28835b861b3 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -17,6 +17,7 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +static cpumask_t nest_imc_cpumask; /* Needed for sanity check */ extern u64 nest_max_offset; @@ -32,6 +33,152 @@ static struct attribute_group imc_format_group = { .attrs = imc_format_attrs, }; +/* Get the cpumask printed to a buffer "buf" */ +static ssize_t imc_pmu_cpumask_get_attr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + cpumask_t *active_mask; + + active_mask = _imc_cpumask; + return cpumap_print_to_pagebuf(true, buf, active_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL); + +static struct attribute *imc_pmu_cpumask_attrs[] = { + _attr_cpumask.attr, + NULL, +}; + +static struct attribute_group imc_pmu_cpumask_attr_group = { + .attrs = imc_pmu_cpumask_attrs, +}; + +/* + * nest_init : Initializes the nest imc engine for the current chip. + */ +static void nest_init(int *loc) +{ + int rc; + + rc = opal_nest_imc_counters_control(OPAL_NEST_IMC_PRODUCTION_MODE, + OPAL_NEST_IMC_START, 0, 0); + if (rc) + loc[smp_processor_id()] = 1; +} + +static void nest_change_cpu_context(int old_cpu, int new_cpu) +{ + int i; + + for (i = 0; +(per_nest_pmu_arr[i] != NULL) && (i < IMC_MAX_PMUS); i++) + perf_pmu_migrate_context(_nest_pmu_arr[i]->pmu, + old_cpu, new_cpu); +} + +static int ppc_nest_imc_cpu_online(unsigned int cpu) +{ + int nid; + const struct cpumask *l_cpumask; + struct cpumask tmp_mask; + + /* Find the cpumask of this node */ + nid = cpu_to_node(cpu); + l_cpumask = cpumask_of_node(nid); + + /* +* If any of the cpu from this node is already present in the mask, +* just return, if not, then set this cpu in the mask. +*/ + if (!cpumask_and(_mask, l_cpumask, _imc_cpumask)) { + cpumask_set_cpu(cpu, _imc_cpumask); + return 0; + } + + return 0; +} + +static int ppc_nest_imc_cpu_offline(unsigned int cpu) +{ + int nid, target = -1; + const struct cpumask
[PATCH v6 07/11] powerpc/powernv: Core IMC events detection
From: Hemant Kumar This patch adds support for detection of core IMC events along with the Nest IMC events. It adds a new domain IMC_DOMAIN_CORE and its determined with the help of the compatibility string "ibm,imc-counters-core" based on the IMC device tree. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 2 ++ arch/powerpc/perf/imc-pmu.c | 3 +++ arch/powerpc/platforms/powernv/opal-imc.c | 18 -- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index e13f51047522..2c39603ff3e7 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -26,6 +26,7 @@ #define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" #define IMC_DTB_NEST_COMPAT"ibm,imc-counters-nest" +#define IMC_DTB_CORE_COMPAT"ibm,imc-counters-core" /* * Structure to hold per chip specific memory address @@ -63,6 +64,7 @@ struct imc_pmu { * Domains for IMC PMUs */ #define IMC_DOMAIN_NEST1 +#define IMC_DOMAIN_CORE2 #define IMC_DOMAIN_UNKNOWN -1 int imc_get_domain(struct device_node *pmu_dev); diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index b28835b861b3..728c67e139e0 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -19,8 +19,11 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; static cpumask_t nest_imc_cpumask; +struct imc_pmu *core_imc_pmu; + /* Needed for sanity check */ extern u64 nest_max_offset; +extern u64 core_max_offset; PMU_FORMAT_ATTR(event, "config:0-20"); static struct attribute *imc_format_attrs[] = { diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index a98678266b0d..f6f63399ab06 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -34,10 +34,12 @@ extern struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +extern struct imc_pmu *core_imc_pmu; extern int init_imc_pmu(struct imc_events *events, int idx, struct imc_pmu *pmu_ptr); u64 nest_max_offset; +u64 core_max_offset; static int imc_event_info(char *name, struct imc_events *events) { @@ -81,6 +83,10 @@ static void update_max_value(u32 value, int pmu_domain) if (nest_max_offset < value) nest_max_offset = value; break; + case IMC_DOMAIN_CORE: + if (core_max_offset < value) + core_max_offset = value; + break; default: /* Unknown domain, return */ return; @@ -232,6 +238,8 @@ int imc_get_domain(struct device_node *pmu_dev) { if (of_device_is_compatible(pmu_dev, IMC_DTB_NEST_COMPAT)) return IMC_DOMAIN_NEST; + if (of_device_is_compatible(pmu_dev, IMC_DTB_CORE_COMPAT)) + return IMC_DOMAIN_CORE; else return IMC_DOMAIN_UNKNOWN; } @@ -299,7 +307,10 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index) goto free_pmu; /* Needed for hotplug/migration */ - per_nest_pmu_arr[pmu_index] = pmu_ptr; + if (pmu_ptr->domain == IMC_DOMAIN_CORE) + core_imc_pmu = pmu_ptr; + else if (pmu_ptr->domain == IMC_DOMAIN_NEST) + per_nest_pmu_arr[pmu_index] = pmu_ptr; /* * "events" property inside a PMU node contains the phandle value @@ -355,7 +366,10 @@ static int imc_pmu_create(struct device_node *parent, int pmu_index) } /* Save the name to register it later */ - sprintf(buf, "nest_%s", (char *)pp->value); + if (pmu_ptr->domain == IMC_DOMAIN_NEST) + sprintf(buf, "nest_%s", (char *)pp->value); + else + sprintf(buf, "%s_imc", (char *)pp->value); pmu_ptr->pmu.name = (char *)buf; /* -- 2.7.4
[PATCH v6 05/11] powerpc/perf: Generic imc pmu event functions
From: Hemant KumarSince, the IMC counters' data are periodically fed to a memory location, the functions to read/update, start/stop, add/del can be generic and can be used by all IMC PMU units. This patch adds a set of generic imc pmu related event functions to be used by each imc pmu unit. Add code to setup format attribute and to register imc pmus. Add a event_init function for nest_imc events. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 1 + arch/powerpc/perf/imc-pmu.c | 137 ++ arch/powerpc/platforms/powernv/opal-imc.c | 30 ++- 3 files changed, 164 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index a3d4f1bf9492..e13f51047522 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -65,4 +65,5 @@ struct imc_pmu { #define IMC_DOMAIN_NEST1 #define IMC_DOMAIN_UNKNOWN -1 +int imc_get_domain(struct device_node *pmu_dev); #endif /* PPC_POWERNV_IMC_PMU_DEF_H */ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index ec464c76b749..bd5bf66bd920 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -18,6 +18,132 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +/* Needed for sanity check */ +extern u64 nest_max_offset; + +PMU_FORMAT_ATTR(event, "config:0-20"); +static struct attribute *imc_format_attrs[] = { + _attr_event.attr, + NULL, +}; + +static struct attribute_group imc_format_group = { + .name = "format", + .attrs = imc_format_attrs, +}; + +static int nest_imc_event_init(struct perf_event *event) +{ + int chip_id; + u32 config = event->attr.config; + struct perchip_nest_info *pcni; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + /* Sanity check for config (event offset) */ + if (config > nest_max_offset) + return -EINVAL; + + chip_id = topology_physical_package_id(event->cpu); + pcni = _perchip_info[chip_id]; + + /* +* Memory for Nest HW counter data could be in multiple pages. +* Hence check and pick the right base page from the event offset, +* and then add to it. +*/ + event->hw.event_base = pcni->vbase[config/PAGE_SIZE] + + (config & ~PAGE_MASK); + + return 0; +} + +static void imc_read_counter(struct perf_event *event) +{ + u64 *addr, data; + + addr = (u64 *)event->hw.event_base; + data = __be64_to_cpu(READ_ONCE(*addr)); + local64_set(>hw.prev_count, data); +} + +static void imc_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count, *addr; + + addr = (u64 *)event->hw.event_base; + counter_prev = local64_read(>hw.prev_count); + counter_new = __be64_to_cpu(READ_ONCE(*addr)); + final_count = counter_new - counter_prev; + + local64_set(>hw.prev_count, counter_new); + local64_add(final_count, >count); +} + +static void imc_event_start(struct perf_event *event, int flags) +{ + /* +* In Memory Counters are free flowing counters. HW or the microcode +* keeps adding to the counter offset in memory. To get event +* counter value, we snapshot the value here and we calculate +* delta at later point. +*/ + imc_read_counter(event); +} + +static void imc_event_stop(struct perf_event *event, int flags) +{ + /* +* Take a snapshot and calculate the delta and update +* the event counter values. +*/ + imc_perf_event_update(event); +} + +static int imc_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + imc_event_start(event, flags); + + return 0; +} + +/* update_pmu_ops : Populate the appropriate operations for "pmu" */ +static int update_pmu_ops(struct imc_pmu *pmu) +{ + if (!pmu) + return -EINVAL; + + pmu->pmu.task_ctx_nr = perf_invalid_context; + pmu->pmu.event_init = nest_imc_event_init; + pmu->pmu.add = imc_event_add; +
[PATCH v6 04/11] powerpc/perf: Add event attribute and group to IMC pmus
From: Hemant KumarDevice tree IMC driver code parses the IMC units and their events. It passes the information to IMC pmu code which is placed in powerpc/perf as "imc-pmu.c". This patch creates only event attributes and attribute groups for the IMC pmus. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/perf/Makefile| 6 +- arch/powerpc/perf/imc-pmu.c | 97 +++ arch/powerpc/platforms/powernv/opal-imc.c | 12 +++- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/perf/imc-pmu.c diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index 4d606b99a5cb..d0d1f04203c7 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -2,10 +2,14 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o +imc-$(CONFIG_PPC_POWERNV) += imc-pmu.o + obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ power5+-pmu.o power6-pmu.o power7-pmu.o \ - isa207-common.o power8-pmu.o power9-pmu.o + isa207-common.o power8-pmu.o power9-pmu.o \ + $(imc-y) + obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c new file mode 100644 index ..ec464c76b749 --- /dev/null +++ b/arch/powerpc/perf/imc-pmu.c @@ -0,0 +1,97 @@ +/* + * Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; +struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; + +/* dev_str_attr : Populate event "name" and string "str" in attribute */ +static struct attribute *dev_str_attr(const char *name, const char *str) +{ + struct perf_pmu_events_attr *attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + + sysfs_attr_init(>attr.attr); + + attr->event_str = str; + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = perf_event_sysfs_show; + + return >attr.attr; +} + +/* + * update_events_in_group: Update the "events" information in an attr_group + * and assign the attr_group to the pmu "pmu". + */ +static int update_events_in_group(struct imc_events *events, + int idx, struct imc_pmu *pmu) +{ + struct attribute_group *attr_group; + struct attribute **attrs; + int i; + + /* Allocate memory for attribute group */ + attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + if (!attr_group) + return -ENOMEM; + + /* Allocate memory for attributes */ + attrs = kzalloc((sizeof(struct attribute *) * (idx + 1)), GFP_KERNEL); + if (!attrs) { + kfree(attr_group); + return -ENOMEM; + } + + attr_group->name = "events"; + attr_group->attrs = attrs; + for (i = 0; i < idx; i++, events++) { + attrs[i] = dev_str_attr((char *)events->ev_name, + (char *)events->ev_value); + } + + pmu->attr_groups[0] = attr_group; + return 0; +} + +/* + * init_imc_pmu : Setup the IMC pmu device in "pmu_ptr" and its events + *"events". + * Setup the cpu mask information for these pmus and setup the state machine + * hotplug notifiers as well. + */ +int init_imc_pmu(struct imc_events *events, int idx, +struct imc_pmu *pmu_ptr) +{ + int ret = -ENODEV; + + ret = update_events_in_group(events, idx, pmu_ptr); + if (ret) + goto err_free; + + return 0; + +err_free: + /* Only free the attr_groups which are dynamically allocated */ + if (pmu_ptr->attr_groups[0]) { + kfree(pmu_ptr->attr_groups[0]->attrs); + kfree(pmu_ptr->attr_groups[0]); + } + + return ret; +} diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index ba0203e669c0..73c46703c2af 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -32,8 +32,11 @@ #include #include -struct perchip_nest_info
[PATCH v6 05/11] powerpc/perf: Generic imc pmu event functions
From: Hemant Kumar Since, the IMC counters' data are periodically fed to a memory location, the functions to read/update, start/stop, add/del can be generic and can be used by all IMC PMU units. This patch adds a set of generic imc pmu related event functions to be used by each imc pmu unit. Add code to setup format attribute and to register imc pmus. Add a event_init function for nest_imc events. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/include/asm/imc-pmu.h| 1 + arch/powerpc/perf/imc-pmu.c | 137 ++ arch/powerpc/platforms/powernv/opal-imc.c | 30 ++- 3 files changed, 164 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h index a3d4f1bf9492..e13f51047522 100644 --- a/arch/powerpc/include/asm/imc-pmu.h +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -65,4 +65,5 @@ struct imc_pmu { #define IMC_DOMAIN_NEST1 #define IMC_DOMAIN_UNKNOWN -1 +int imc_get_domain(struct device_node *pmu_dev); #endif /* PPC_POWERNV_IMC_PMU_DEF_H */ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index ec464c76b749..bd5bf66bd920 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -18,6 +18,132 @@ struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +/* Needed for sanity check */ +extern u64 nest_max_offset; + +PMU_FORMAT_ATTR(event, "config:0-20"); +static struct attribute *imc_format_attrs[] = { + _attr_event.attr, + NULL, +}; + +static struct attribute_group imc_format_group = { + .name = "format", + .attrs = imc_format_attrs, +}; + +static int nest_imc_event_init(struct perf_event *event) +{ + int chip_id; + u32 config = event->attr.config; + struct perchip_nest_info *pcni; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + /* Sanity check for config (event offset) */ + if (config > nest_max_offset) + return -EINVAL; + + chip_id = topology_physical_package_id(event->cpu); + pcni = _perchip_info[chip_id]; + + /* +* Memory for Nest HW counter data could be in multiple pages. +* Hence check and pick the right base page from the event offset, +* and then add to it. +*/ + event->hw.event_base = pcni->vbase[config/PAGE_SIZE] + + (config & ~PAGE_MASK); + + return 0; +} + +static void imc_read_counter(struct perf_event *event) +{ + u64 *addr, data; + + addr = (u64 *)event->hw.event_base; + data = __be64_to_cpu(READ_ONCE(*addr)); + local64_set(>hw.prev_count, data); +} + +static void imc_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count, *addr; + + addr = (u64 *)event->hw.event_base; + counter_prev = local64_read(>hw.prev_count); + counter_new = __be64_to_cpu(READ_ONCE(*addr)); + final_count = counter_new - counter_prev; + + local64_set(>hw.prev_count, counter_new); + local64_add(final_count, >count); +} + +static void imc_event_start(struct perf_event *event, int flags) +{ + /* +* In Memory Counters are free flowing counters. HW or the microcode +* keeps adding to the counter offset in memory. To get event +* counter value, we snapshot the value here and we calculate +* delta at later point. +*/ + imc_read_counter(event); +} + +static void imc_event_stop(struct perf_event *event, int flags) +{ + /* +* Take a snapshot and calculate the delta and update +* the event counter values. +*/ + imc_perf_event_update(event); +} + +static int imc_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + imc_event_start(event, flags); + + return 0; +} + +/* update_pmu_ops : Populate the appropriate operations for "pmu" */ +static int update_pmu_ops(struct imc_pmu *pmu) +{ + if (!pmu) + return -EINVAL; + + pmu->pmu.task_ctx_nr = perf_invalid_context; + pmu->pmu.event_init = nest_imc_event_init; + pmu->pmu.add = imc_event_add; + pmu->pmu.del = imc_event_stop; + pmu->pmu.start = imc_event_start; + pmu->pmu.stop = imc_event_stop;
[PATCH v6 04/11] powerpc/perf: Add event attribute and group to IMC pmus
From: Hemant Kumar Device tree IMC driver code parses the IMC units and their events. It passes the information to IMC pmu code which is placed in powerpc/perf as "imc-pmu.c". This patch creates only event attributes and attribute groups for the IMC pmus. Signed-off-by: Anju T Sudhakar Signed-off-by: Hemant Kumar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/perf/Makefile| 6 +- arch/powerpc/perf/imc-pmu.c | 97 +++ arch/powerpc/platforms/powernv/opal-imc.c | 12 +++- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/perf/imc-pmu.c diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index 4d606b99a5cb..d0d1f04203c7 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -2,10 +2,14 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o +imc-$(CONFIG_PPC_POWERNV) += imc-pmu.o + obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ power5+-pmu.o power6-pmu.o power7-pmu.o \ - isa207-common.o power8-pmu.o power9-pmu.o + isa207-common.o power8-pmu.o power9-pmu.o \ + $(imc-y) + obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c new file mode 100644 index ..ec464c76b749 --- /dev/null +++ b/arch/powerpc/perf/imc-pmu.c @@ -0,0 +1,97 @@ +/* + * Nest Performance Monitor counter support. + * + * Copyright (C) 2016 Madhavan Srinivasan, IBM Corporation. + * (C) 2016 Hemant K Shaw, IBM Corporation. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; +struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; + +/* dev_str_attr : Populate event "name" and string "str" in attribute */ +static struct attribute *dev_str_attr(const char *name, const char *str) +{ + struct perf_pmu_events_attr *attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + + sysfs_attr_init(>attr.attr); + + attr->event_str = str; + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = perf_event_sysfs_show; + + return >attr.attr; +} + +/* + * update_events_in_group: Update the "events" information in an attr_group + * and assign the attr_group to the pmu "pmu". + */ +static int update_events_in_group(struct imc_events *events, + int idx, struct imc_pmu *pmu) +{ + struct attribute_group *attr_group; + struct attribute **attrs; + int i; + + /* Allocate memory for attribute group */ + attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + if (!attr_group) + return -ENOMEM; + + /* Allocate memory for attributes */ + attrs = kzalloc((sizeof(struct attribute *) * (idx + 1)), GFP_KERNEL); + if (!attrs) { + kfree(attr_group); + return -ENOMEM; + } + + attr_group->name = "events"; + attr_group->attrs = attrs; + for (i = 0; i < idx; i++, events++) { + attrs[i] = dev_str_attr((char *)events->ev_name, + (char *)events->ev_value); + } + + pmu->attr_groups[0] = attr_group; + return 0; +} + +/* + * init_imc_pmu : Setup the IMC pmu device in "pmu_ptr" and its events + *"events". + * Setup the cpu mask information for these pmus and setup the state machine + * hotplug notifiers as well. + */ +int init_imc_pmu(struct imc_events *events, int idx, +struct imc_pmu *pmu_ptr) +{ + int ret = -ENODEV; + + ret = update_events_in_group(events, idx, pmu_ptr); + if (ret) + goto err_free; + + return 0; + +err_free: + /* Only free the attr_groups which are dynamically allocated */ + if (pmu_ptr->attr_groups[0]) { + kfree(pmu_ptr->attr_groups[0]->attrs); + kfree(pmu_ptr->attr_groups[0]); + } + + return ret; +} diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index ba0203e669c0..73c46703c2af 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -32,8 +32,11 @@ #include #include -struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; -struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +extern struct perchip_nest_info
Re: [PATCH v3 3/4] tty/serial: meson_uart: add the core clock handling to the driver
On Fri, 2017-03-31 at 18:54 +0200, Helmut Klein wrote: > This patch gets the core clock as provided by the DT and enables it. > The code was taken from Amlogic's serial driver, and was tested on my > board. > > Signed-off-by: Helmut Klein> --- > drivers/tty/serial/meson_uart.c | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c > index 60f16795d16b..cb99112288eb 100644 > --- a/drivers/tty/serial/meson_uart.c > +++ b/drivers/tty/serial/meson_uart.c > @@ -600,6 +600,7 @@ static int meson_uart_probe(struct platform_device *pdev) > struct resource *res_mem, *res_irq; > struct uart_port *port; > struct clk *clk; > + struct clk *core_clk; > int ret = 0; > > if (pdev->dev.of_node) > @@ -625,6 +626,15 @@ static int meson_uart_probe(struct platform_device *pdev) > if (!port) > return -ENOMEM; > > + core_clk = devm_clk_get(>dev, "core"); > + if (!IS_ERR(core_clk)) { > + ret = clk_prepare_enable(core_clk); This needs to be balanced with a clk_disable_unprepare() in remove. You could try play with devm_add_action_or_reset, maybe like this: devm_add_action_or_reset(dev, (void(*)(void *))clk_disable_unprepare, core_clk); Sorry I did not notice it on the v2. > + if (ret) { > + dev_err(>dev, "couldn't enable clkc\n"); > + return ret; > + } > + } > + > clk = clk_get(>dev, NULL); I still think you should name this one. Otherwise, what the non AO UART will get here will depends on the order it was declared in DT. To answer your question from the v2, yes I think it is ok to add clock-names to the AO-UART. You are doing it for non AO ones so, why not ? > if (IS_ERR(clk)) > return PTR_ERR(clk); > -- > 2.11.0 >
Re: [PATCH v3 3/4] tty/serial: meson_uart: add the core clock handling to the driver
On Fri, 2017-03-31 at 18:54 +0200, Helmut Klein wrote: > This patch gets the core clock as provided by the DT and enables it. > The code was taken from Amlogic's serial driver, and was tested on my > board. > > Signed-off-by: Helmut Klein > --- > drivers/tty/serial/meson_uart.c | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c > index 60f16795d16b..cb99112288eb 100644 > --- a/drivers/tty/serial/meson_uart.c > +++ b/drivers/tty/serial/meson_uart.c > @@ -600,6 +600,7 @@ static int meson_uart_probe(struct platform_device *pdev) > struct resource *res_mem, *res_irq; > struct uart_port *port; > struct clk *clk; > + struct clk *core_clk; > int ret = 0; > > if (pdev->dev.of_node) > @@ -625,6 +626,15 @@ static int meson_uart_probe(struct platform_device *pdev) > if (!port) > return -ENOMEM; > > + core_clk = devm_clk_get(>dev, "core"); > + if (!IS_ERR(core_clk)) { > + ret = clk_prepare_enable(core_clk); This needs to be balanced with a clk_disable_unprepare() in remove. You could try play with devm_add_action_or_reset, maybe like this: devm_add_action_or_reset(dev, (void(*)(void *))clk_disable_unprepare, core_clk); Sorry I did not notice it on the v2. > + if (ret) { > + dev_err(>dev, "couldn't enable clkc\n"); > + return ret; > + } > + } > + > clk = clk_get(>dev, NULL); I still think you should name this one. Otherwise, what the non AO UART will get here will depends on the order it was declared in DT. To answer your question from the v2, yes I think it is ok to add clock-names to the AO-UART. You are doing it for non AO ones so, why not ? > if (IS_ERR(clk)) > return PTR_ERR(clk); > -- > 2.11.0 >
[PATCH v6 11/11] powerpc/perf: Thread imc cpuhotplug support
From: Anju T SudhakarThis patch adds support for thread IMC on cpuhotplug. When a cpu goes offline, the LDBAR for that cpu is disabled, and when it comes back online the previous ldbar value is written back to the LDBAR for that cpu. To register the hotplug functions for thread_imc, a new state CPUHP_AP_PERF_POWERPC_THREADIMC_ONLINE is added to the list of existing states. Reviewed-by: Gautham R. Shenoy Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/perf/imc-pmu.c | 32 +++- include/linux/cpuhotplug.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 3db637c6d3f4..944e568b52ff 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -726,6 +726,16 @@ static void cleanup_all_thread_imc_memory(void) on_each_cpu(cleanup_thread_imc_memory, NULL, 1); } +static void thread_imc_update_ldbar(unsigned int cpu_id) +{ + u64 ldbar_addr, ldbar_value; + + ldbar_addr = (u64)virt_to_phys((void *)per_cpu_add[cpu_id]); + ldbar_value = (ldbar_addr & (u64)THREAD_IMC_LDBAR_MASK) | + (u64)THREAD_IMC_ENABLE; + mtspr(SPRN_LDBAR, ldbar_value); +} + /* * Allocates a page of memory for each of the online cpus, and, writes the * physical base address of that page to the LDBAR for that cpu. This starts @@ -733,21 +743,33 @@ static void cleanup_all_thread_imc_memory(void) */ static void thread_imc_mem_alloc(void *dummy) { - u64 ldbar_addr, ldbar_value; int cpu_id = smp_processor_id(); int phys_id = topology_physical_package_id(smp_processor_id()); per_cpu_add[cpu_id] = (u64)alloc_pages_exact_nid(phys_id, (size_t)IMC_THREAD_COUNTER_MEM, GFP_KERNEL | __GFP_ZERO); - ldbar_addr = (u64)virt_to_phys((void *)per_cpu_add[cpu_id]); - ldbar_value = (ldbar_addr & (u64)THREAD_IMC_LDBAR_MASK) | - (u64)THREAD_IMC_ENABLE; - mtspr(SPRN_LDBAR, ldbar_value); + thread_imc_update_ldbar(cpu_id); +} + +static int ppc_thread_imc_cpu_online(unsigned int cpu) +{ + thread_imc_update_ldbar(cpu); + return 0; } +static int ppc_thread_imc_cpu_offline(unsigned int cpu) +{ + mtspr(SPRN_LDBAR, 0); + return 0; + } + void thread_imc_cpu_init(void) { on_each_cpu(thread_imc_mem_alloc, NULL, 1); + cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_THREADIMC_ONLINE, + "POWER_THREAD_IMC_ONLINE", + ppc_thread_imc_cpu_online, + ppc_thread_imc_cpu_offline); } /* diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index abde85d9511a..724df46b2c3c 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -138,6 +138,7 @@ enum cpuhp_state { CPUHP_AP_PERF_ARM_L2X0_ONLINE, CPUHP_AP_PERF_POWERPC_NEST_ONLINE, CPUHP_AP_PERF_POWERPC_COREIMC_ONLINE, + CPUHP_AP_PERF_POWERPC_THREADIMC_ONLINE, CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE, CPUHP_AP_WORKQUEUE_ONLINE, CPUHP_AP_RCUTREE_ONLINE, -- 2.7.4
[PATCH v6 11/11] powerpc/perf: Thread imc cpuhotplug support
From: Anju T Sudhakar This patch adds support for thread IMC on cpuhotplug. When a cpu goes offline, the LDBAR for that cpu is disabled, and when it comes back online the previous ldbar value is written back to the LDBAR for that cpu. To register the hotplug functions for thread_imc, a new state CPUHP_AP_PERF_POWERPC_THREADIMC_ONLINE is added to the list of existing states. Reviewed-by: Gautham R. Shenoy Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/perf/imc-pmu.c | 32 +++- include/linux/cpuhotplug.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 3db637c6d3f4..944e568b52ff 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -726,6 +726,16 @@ static void cleanup_all_thread_imc_memory(void) on_each_cpu(cleanup_thread_imc_memory, NULL, 1); } +static void thread_imc_update_ldbar(unsigned int cpu_id) +{ + u64 ldbar_addr, ldbar_value; + + ldbar_addr = (u64)virt_to_phys((void *)per_cpu_add[cpu_id]); + ldbar_value = (ldbar_addr & (u64)THREAD_IMC_LDBAR_MASK) | + (u64)THREAD_IMC_ENABLE; + mtspr(SPRN_LDBAR, ldbar_value); +} + /* * Allocates a page of memory for each of the online cpus, and, writes the * physical base address of that page to the LDBAR for that cpu. This starts @@ -733,21 +743,33 @@ static void cleanup_all_thread_imc_memory(void) */ static void thread_imc_mem_alloc(void *dummy) { - u64 ldbar_addr, ldbar_value; int cpu_id = smp_processor_id(); int phys_id = topology_physical_package_id(smp_processor_id()); per_cpu_add[cpu_id] = (u64)alloc_pages_exact_nid(phys_id, (size_t)IMC_THREAD_COUNTER_MEM, GFP_KERNEL | __GFP_ZERO); - ldbar_addr = (u64)virt_to_phys((void *)per_cpu_add[cpu_id]); - ldbar_value = (ldbar_addr & (u64)THREAD_IMC_LDBAR_MASK) | - (u64)THREAD_IMC_ENABLE; - mtspr(SPRN_LDBAR, ldbar_value); + thread_imc_update_ldbar(cpu_id); +} + +static int ppc_thread_imc_cpu_online(unsigned int cpu) +{ + thread_imc_update_ldbar(cpu); + return 0; } +static int ppc_thread_imc_cpu_offline(unsigned int cpu) +{ + mtspr(SPRN_LDBAR, 0); + return 0; + } + void thread_imc_cpu_init(void) { on_each_cpu(thread_imc_mem_alloc, NULL, 1); + cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_THREADIMC_ONLINE, + "POWER_THREAD_IMC_ONLINE", + ppc_thread_imc_cpu_online, + ppc_thread_imc_cpu_offline); } /* diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index abde85d9511a..724df46b2c3c 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -138,6 +138,7 @@ enum cpuhp_state { CPUHP_AP_PERF_ARM_L2X0_ONLINE, CPUHP_AP_PERF_POWERPC_NEST_ONLINE, CPUHP_AP_PERF_POWERPC_COREIMC_ONLINE, + CPUHP_AP_PERF_POWERPC_THREADIMC_ONLINE, CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE, CPUHP_AP_WORKQUEUE_ONLINE, CPUHP_AP_RCUTREE_ONLINE, -- 2.7.4
[PATCH v6 03/11] powerpc/powernv: Detect supported IMC units and its events
From: Hemant KumarParse device tree to detect IMC units. Traverse through each IMC unit node to find supported events and corresponding unit/scale files (if any). Here is the DTS file for reference: https://github.com/open-power/ima-catalog/blob/master/81E00612.4E0100.dts The device tree for IMC counters starts at the node "imc-counters". This node contains all the IMC PMU nodes and event nodes for these IMC PMUs. The PMU nodes have an "events" property which has a phandle value for the actual events node. The events are separated from the PMU nodes to abstract out the common events. For example, PMU node "mcs0", "mcs1" etc. will contain a pointer to "nest-mcs-events" since, the events are common between these PMUs. These events have a different prefix based on their relation to different PMUs, and hence, the PMU nodes themselves contain an "events-prefix" property. The value for this property concatenated to the event name, forms the actual event name. Also, the PMU have a "reg" field as the base offset for the events which belong to this PMU. This "reg" field is added to an event in the "events" node, which gives us the location of the counter data. Kernel code uses this offset as event configuration value. Device tree parser code also looks for scale/unit property in the event node and passes on the value as an event attr for perf interface to use in the post processing by the perf tool. Some PMUs may have common scale and unit properties which implies that all events supported by this PMU inherit the scale and unit properties of the PMU itself. For those events, we need to set the common unit and scale values. For failure to initialize any unit or any event, disable that unit and continue setting up the rest of them. Signed-off-by: Hemant Kumar Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/platforms/powernv/opal-imc.c | 386 ++ 1 file changed, 386 insertions(+) diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index c476d596c6a8..ba0203e669c0 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -33,6 +33,388 @@ #include struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; +struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; + +static int imc_event_info(char *name, struct imc_events *events) +{ + char *buf; + + /* memory for content */ + buf = kzalloc(IMC_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + events->ev_name = name; + events->ev_value = buf; + return 0; +} + +static int imc_event_info_str(struct property *pp, char *name, + struct imc_events *events) +{ + int ret; + + ret = imc_event_info(name, events); + if (ret) + return ret; + + if (!pp->value || (strnlen(pp->value, pp->length) == pp->length) || + (pp->length > IMC_MAX_PMU_NAME_LEN)) + return -EINVAL; + strncpy(events->ev_value, (const char *)pp->value, pp->length); + + return 0; +} + +static int imc_event_info_val(char *name, u32 val, + struct imc_events *events) +{ + int ret; + + ret = imc_event_info(name, events); + if (ret) + return ret; + sprintf(events->ev_value, "event=0x%x", val); + + return 0; +} + +static int set_event_property(struct property *pp, char *event_prop, + struct imc_events *events, char *ev_name) +{ + char *buf; + int ret; + + buf = kzalloc(IMC_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + sprintf(buf, "%s.%s", ev_name, event_prop); + ret = imc_event_info_str(pp, buf, events); + if (ret) { + kfree(events->ev_name); + kfree(events->ev_value); + } + + return ret; +} + +/* + * imc_events_node_parser: Parse the event node "dev" and assign the parsed + * information to event "events". + * + * Parses the "reg" property of this event. "reg" gives us the event offset. + * Also, parse the "scale" and "unit" properties, if any. + */ +static int imc_events_node_parser(struct device_node *dev, + struct imc_events *events, + struct property *event_scale, + struct property *event_unit, + struct property *name_prefix, + u32 reg) +{ + struct property *name, *pp; + char *ev_name; + u32 val; + int idx = 0, ret; + + if (!dev) + return -EINVAL; + + /* +* Loop through each property of an event node +*/ +
[PATCH v6 03/11] powerpc/powernv: Detect supported IMC units and its events
From: Hemant Kumar Parse device tree to detect IMC units. Traverse through each IMC unit node to find supported events and corresponding unit/scale files (if any). Here is the DTS file for reference: https://github.com/open-power/ima-catalog/blob/master/81E00612.4E0100.dts The device tree for IMC counters starts at the node "imc-counters". This node contains all the IMC PMU nodes and event nodes for these IMC PMUs. The PMU nodes have an "events" property which has a phandle value for the actual events node. The events are separated from the PMU nodes to abstract out the common events. For example, PMU node "mcs0", "mcs1" etc. will contain a pointer to "nest-mcs-events" since, the events are common between these PMUs. These events have a different prefix based on their relation to different PMUs, and hence, the PMU nodes themselves contain an "events-prefix" property. The value for this property concatenated to the event name, forms the actual event name. Also, the PMU have a "reg" field as the base offset for the events which belong to this PMU. This "reg" field is added to an event in the "events" node, which gives us the location of the counter data. Kernel code uses this offset as event configuration value. Device tree parser code also looks for scale/unit property in the event node and passes on the value as an event attr for perf interface to use in the post processing by the perf tool. Some PMUs may have common scale and unit properties which implies that all events supported by this PMU inherit the scale and unit properties of the PMU itself. For those events, we need to set the common unit and scale values. For failure to initialize any unit or any event, disable that unit and continue setting up the rest of them. Signed-off-by: Hemant Kumar Signed-off-by: Anju T Sudhakar Signed-off-by: Madhavan Srinivasan --- arch/powerpc/platforms/powernv/opal-imc.c | 386 ++ 1 file changed, 386 insertions(+) diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index c476d596c6a8..ba0203e669c0 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -33,6 +33,388 @@ #include struct perchip_nest_info nest_perchip_info[IMC_MAX_CHIPS]; +struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; + +static int imc_event_info(char *name, struct imc_events *events) +{ + char *buf; + + /* memory for content */ + buf = kzalloc(IMC_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + events->ev_name = name; + events->ev_value = buf; + return 0; +} + +static int imc_event_info_str(struct property *pp, char *name, + struct imc_events *events) +{ + int ret; + + ret = imc_event_info(name, events); + if (ret) + return ret; + + if (!pp->value || (strnlen(pp->value, pp->length) == pp->length) || + (pp->length > IMC_MAX_PMU_NAME_LEN)) + return -EINVAL; + strncpy(events->ev_value, (const char *)pp->value, pp->length); + + return 0; +} + +static int imc_event_info_val(char *name, u32 val, + struct imc_events *events) +{ + int ret; + + ret = imc_event_info(name, events); + if (ret) + return ret; + sprintf(events->ev_value, "event=0x%x", val); + + return 0; +} + +static int set_event_property(struct property *pp, char *event_prop, + struct imc_events *events, char *ev_name) +{ + char *buf; + int ret; + + buf = kzalloc(IMC_MAX_PMU_NAME_LEN, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + sprintf(buf, "%s.%s", ev_name, event_prop); + ret = imc_event_info_str(pp, buf, events); + if (ret) { + kfree(events->ev_name); + kfree(events->ev_value); + } + + return ret; +} + +/* + * imc_events_node_parser: Parse the event node "dev" and assign the parsed + * information to event "events". + * + * Parses the "reg" property of this event. "reg" gives us the event offset. + * Also, parse the "scale" and "unit" properties, if any. + */ +static int imc_events_node_parser(struct device_node *dev, + struct imc_events *events, + struct property *event_scale, + struct property *event_unit, + struct property *name_prefix, + u32 reg) +{ + struct property *name, *pp; + char *ev_name; + u32 val; + int idx = 0, ret; + + if (!dev) + return -EINVAL; + + /* +* Loop through each property of an event node +*/ + name = of_find_property(dev, "event-name", NULL); + if (!name) + return -ENODEV; + +
Re: [PATCH 0/3] Add RTC support on STM32F746
Hi On 01/19/2017 02:45 PM, Amelie Delaunay wrote: This patchset enables STM32 RTC on STM32F746 MCU. Amelie Delaunay (3): ARM: dts: stm32: set HSE_RTC clock frequency to 1 MHz on stm32f746 ARM: dts: stm32: Add RTC support for STM32F746 MCU ARM: dts: stm32: enable RTC on stm32746g-eval arch/arm/boot/dts/stm32746g-eval.dts | 4 arch/arm/boot/dts/stm32f746.dtsi | 16 2 files changed, 20 insertions(+) Series applied on stm32-dt-for-v4.12 regards Alex
Re: [PATCH 0/3] Add RTC support on STM32F746
Hi On 01/19/2017 02:45 PM, Amelie Delaunay wrote: This patchset enables STM32 RTC on STM32F746 MCU. Amelie Delaunay (3): ARM: dts: stm32: set HSE_RTC clock frequency to 1 MHz on stm32f746 ARM: dts: stm32: Add RTC support for STM32F746 MCU ARM: dts: stm32: enable RTC on stm32746g-eval arch/arm/boot/dts/stm32746g-eval.dts | 4 arch/arm/boot/dts/stm32f746.dtsi | 16 2 files changed, 20 insertions(+) Series applied on stm32-dt-for-v4.12 regards Alex
Re: [PATCH] i2c: add sc18is600 driver
On Wed, Mar 29, 2017 at 04:03:39PM +0200, Sebastian Reichel wrote: > This adds an I²C master driver for SPI -> I²C bus bridge chips. > It currently supports NXP's SC18IS600 and SC18IS601, as well as > Silicon Labs' CP2120. The driver was only tested on SC18IS600. > > Signed-off-By: Sebastian Reichel> --- > .../devicetree/bindings/i2c/i2c-cp2120.txt | 1 + > .../devicetree/bindings/i2c/i2c-sc18is600.txt | 62 +++ Acked-by: Rob Herring > drivers/i2c/busses/Kconfig | 10 + > drivers/i2c/busses/Makefile| 1 + > drivers/i2c/busses/i2c-sc18is600.c | 572 > + > 5 files changed, 646 insertions(+) > create mode 100644 Documentation/devicetree/bindings/i2c/i2c-cp2120.txt > create mode 100644 Documentation/devicetree/bindings/i2c/i2c-sc18is600.txt > create mode 100644 drivers/i2c/busses/i2c-sc18is600.c
Re: [PATCH] i2c: add sc18is600 driver
On Wed, Mar 29, 2017 at 04:03:39PM +0200, Sebastian Reichel wrote: > This adds an I²C master driver for SPI -> I²C bus bridge chips. > It currently supports NXP's SC18IS600 and SC18IS601, as well as > Silicon Labs' CP2120. The driver was only tested on SC18IS600. > > Signed-off-By: Sebastian Reichel > --- > .../devicetree/bindings/i2c/i2c-cp2120.txt | 1 + > .../devicetree/bindings/i2c/i2c-sc18is600.txt | 62 +++ Acked-by: Rob Herring > drivers/i2c/busses/Kconfig | 10 + > drivers/i2c/busses/Makefile| 1 + > drivers/i2c/busses/i2c-sc18is600.c | 572 > + > 5 files changed, 646 insertions(+) > create mode 100644 Documentation/devicetree/bindings/i2c/i2c-cp2120.txt > create mode 100644 Documentation/devicetree/bindings/i2c/i2c-sc18is600.txt > create mode 100644 drivers/i2c/busses/i2c-sc18is600.c
Re: [PATCH] mm: Add additional consistency check
On Mon, Apr 03, 2017 at 09:03:50AM -0500, Christoph Lameter wrote: > On Mon, 3 Apr 2017, Michael Ellerman wrote: > > > At least in slab.c it seems that would allow you to "free" an object > > from one kmem_cache onto the array_cache of another kmem_cache, which > > seems fishy. But maybe there's a check somewhere I'm missing? > > kfree can be used to free any object from any slab cache. Is that a guarantee? There's some wording in the RCU free code that seems to indicate we can't rely on that being true.
Re: [PATCH] mm: Add additional consistency check
On Mon, Apr 03, 2017 at 09:03:50AM -0500, Christoph Lameter wrote: > On Mon, 3 Apr 2017, Michael Ellerman wrote: > > > At least in slab.c it seems that would allow you to "free" an object > > from one kmem_cache onto the array_cache of another kmem_cache, which > > seems fishy. But maybe there's a check somewhere I'm missing? > > kfree can be used to free any object from any slab cache. Is that a guarantee? There's some wording in the RCU free code that seems to indicate we can't rely on that being true.
Re: [PATCH v2 0/7] Add support for triggered buffer mode to STM32 ADC
Hi On 01/26/2017 03:28 PM, Fabrice Gasnier wrote: The following patches add support for triggered buffer mode. These are based on top of "Add PWM and IIO timer drivers for STM32" series. Reference: https://lkml.org/lkml/2017/1/20/116 STM32 ADC, can use either interrupts or DMA to collect data. Either timer trigger output (TRGO) or PWM can be used as trigger source. This patchset has been tested on STM32F429 eval board. ... Fabrice Gasnier (7): iio: adc: stm32: add support for triggered buffer mode iio: adc: stm32: Enable use of stm32 timer triggers iio: adc: stm32: add trigger polarity extended attribute Documentation: dt: iio: stm32-adc: optional dma support iio: adc: stm32: add optional dma support ARM: dts: stm32: Enable dma by default on stm32f4 adc ARM: dts: stm32: Enable pwm1 and pwm3 on stm32f429i-eval Patches 6 & 7 (DT) applied on stm32-dt-for-v4.12 Regards Alex Documentation/ABI/testing/sysfs-bus-iio-adc-stm32 | 18 + .../devicetree/bindings/iio/adc/st,stm32-adc.txt | 7 + arch/arm/boot/dts/stm32429i-eval.dts | 28 + arch/arm/boot/dts/stm32f429.dtsi | 6 + drivers/iio/adc/Kconfig| 5 + drivers/iio/adc/stm32-adc-core.c | 1 + drivers/iio/adc/stm32-adc-core.h | 2 + drivers/iio/adc/stm32-adc.c| 633 - 8 files changed, 676 insertions(+), 24 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-stm32
Re: [PATCH v2 0/7] Add support for triggered buffer mode to STM32 ADC
Hi On 01/26/2017 03:28 PM, Fabrice Gasnier wrote: The following patches add support for triggered buffer mode. These are based on top of "Add PWM and IIO timer drivers for STM32" series. Reference: https://lkml.org/lkml/2017/1/20/116 STM32 ADC, can use either interrupts or DMA to collect data. Either timer trigger output (TRGO) or PWM can be used as trigger source. This patchset has been tested on STM32F429 eval board. ... Fabrice Gasnier (7): iio: adc: stm32: add support for triggered buffer mode iio: adc: stm32: Enable use of stm32 timer triggers iio: adc: stm32: add trigger polarity extended attribute Documentation: dt: iio: stm32-adc: optional dma support iio: adc: stm32: add optional dma support ARM: dts: stm32: Enable dma by default on stm32f4 adc ARM: dts: stm32: Enable pwm1 and pwm3 on stm32f429i-eval Patches 6 & 7 (DT) applied on stm32-dt-for-v4.12 Regards Alex Documentation/ABI/testing/sysfs-bus-iio-adc-stm32 | 18 + .../devicetree/bindings/iio/adc/st,stm32-adc.txt | 7 + arch/arm/boot/dts/stm32429i-eval.dts | 28 + arch/arm/boot/dts/stm32f429.dtsi | 6 + drivers/iio/adc/Kconfig| 5 + drivers/iio/adc/stm32-adc-core.c | 1 + drivers/iio/adc/stm32-adc-core.h | 2 + drivers/iio/adc/stm32-adc.c| 633 - 8 files changed, 676 insertions(+), 24 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-stm32
Re: [PATCH v3 1/5] dt-bindings: update device tree binding for Allwinner PRCM CCUs
On Wed, Mar 29, 2017 at 06:42:42PM +0800, Icenowy Zheng wrote: > From: Icenowy Zheng> > Many Allwinner SoCs after A31 have a CCU in PRCM block. > > Give the ones on H3 and A64 compatible strings. > > Signed-off-by: Icenowy Zheng > --- > Changes in v3: > - Removed frequency info of iosc in this device tree binding document. > Changes in v2: > - Add iosc for R_CCU's on H3/A64. > > Documentation/devicetree/bindings/clock/sunxi-ccu.txt | 17 - > 1 file changed, 16 insertions(+), 1 deletion(-) Acked-by: Rob Herring
Re: [PATCH v3 1/5] dt-bindings: update device tree binding for Allwinner PRCM CCUs
On Wed, Mar 29, 2017 at 06:42:42PM +0800, Icenowy Zheng wrote: > From: Icenowy Zheng > > Many Allwinner SoCs after A31 have a CCU in PRCM block. > > Give the ones on H3 and A64 compatible strings. > > Signed-off-by: Icenowy Zheng > --- > Changes in v3: > - Removed frequency info of iosc in this device tree binding document. > Changes in v2: > - Add iosc for R_CCU's on H3/A64. > > Documentation/devicetree/bindings/clock/sunxi-ccu.txt | 17 - > 1 file changed, 16 insertions(+), 1 deletion(-) Acked-by: Rob Herring
Re: [RFC PATCH 0/4] fs: introduce new writeback error tracking infrastructure and convert ext4 to use it
On Mon, Apr 03, 2017 at 02:25:11PM +1000, NeilBrown wrote: > I don't like that you need to add a 'flush' handler to every filesystem, > most of which just call > +return filemap_report_wb_error(file); > > Could we just have > if (filp->f_op->flush) > retval = filp->f_op->flush(filp, id); > + else > + retval = filemap_report_wb_error(filp); > in flip_close() ?? Maybe this is badly named as ext4_flush_file(). Maybe this should be generic_flush_file(), and then there's no per-filesystem overhead to this?
Re: [RFC PATCH 0/4] fs: introduce new writeback error tracking infrastructure and convert ext4 to use it
On Mon, Apr 03, 2017 at 02:25:11PM +1000, NeilBrown wrote: > I don't like that you need to add a 'flush' handler to every filesystem, > most of which just call > +return filemap_report_wb_error(file); > > Could we just have > if (filp->f_op->flush) > retval = filp->f_op->flush(filp, id); > + else > + retval = filemap_report_wb_error(filp); > in flip_close() ?? Maybe this is badly named as ext4_flush_file(). Maybe this should be generic_flush_file(), and then there's no per-filesystem overhead to this?
Re: [PATCH v3 2/2] PCI: Add tango PCIe host bridge support
On Wed, Mar 29, 2017 at 01:34:45PM +0200, Marc Gonzalez wrote: > This driver is used to work around HW bugs in the controller. > > Note: the controller does NOT support the following features. > > Legacy PCI interrupts > IO space > > Signed-off-by: Marc Gonzalez> --- > Documentation/devicetree/bindings/pci/tango-pcie.txt | 33 + Acked-by: Rob Herring > drivers/pci/host/Kconfig | 7 ++ > drivers/pci/host/Makefile| 1 + > drivers/pci/host/pcie-tango.c| 150 > +++ > 4 files changed, 191 insertions(+)
Re: [PATCH v3 2/2] PCI: Add tango PCIe host bridge support
On Wed, Mar 29, 2017 at 01:34:45PM +0200, Marc Gonzalez wrote: > This driver is used to work around HW bugs in the controller. > > Note: the controller does NOT support the following features. > > Legacy PCI interrupts > IO space > > Signed-off-by: Marc Gonzalez > --- > Documentation/devicetree/bindings/pci/tango-pcie.txt | 33 + Acked-by: Rob Herring > drivers/pci/host/Kconfig | 7 ++ > drivers/pci/host/Makefile| 1 + > drivers/pci/host/pcie-tango.c| 150 > +++ > 4 files changed, 191 insertions(+)
Re: [RFC PATCH 1/4] fs: new infrastructure for writeback error handling and reporting
On Fri, Mar 31, 2017 at 03:26:00PM -0400, Jeff Layton wrote: > This set adds a wb_error field and a sequence counter to the > address_space, and a corresponding sequence counter in the struct file. > When errors are reported during writeback, we set the error field in the > mapping and increment the sequence counter. > +++ b/fs/open.c > @@ -709,6 +709,9 @@ static int do_dentry_open(struct file *f, > f->f_inode = inode; > f->f_mapping = inode->i_mapping; > > + /* Don't need the i_lock since we're only interested in sequence */ > + f->f_wb_err_seq = inode->i_mapping->wb_err_seq; > + Do we need READ_ONCE() though, to ensure we get a consistent view of wb_err_seq? In particular, you made it 64 bit, so 32-bit architectures are going to have a problem if it's rolling over between 2^32-1 and 2^32. > +++ b/include/linux/fs.h > @@ -394,6 +394,8 @@ struct address_space { > gfp_t gfp_mask; /* implicit gfp mask for > allocations */ > struct list_headprivate_list; /* ditto */ > void*private_data; /* ditto */ > + u64 wb_err_seq; > + int wb_err; > } __attribute__((aligned(sizeof(long; > /* >* On most architectures that alignment is already the case; but I thought we had you convinced to make wb_err_seq an s32 and do clock arithmetic? > +int filemap_report_wb_error(struct file *file) > +{ > + int err = 0; > + struct inode *inode = file_inode(file); > + struct address_space *mapping = file->f_mapping; > + > + spin_lock(>i_lock); > + if (file->f_wb_err_seq < mapping->wb_err_seq) { > + err = mapping->wb_err; > + file->f_wb_err_seq = mapping->wb_err_seq; > + } > + spin_unlock(>i_lock); > + return err; > +} Now that I think about this some more, I don't think you even need clock arithmetic -- you just need !=. And that means there's only a 1 in 2^32 chance that you miss an error. Good enough, I say! Particularly since if errors are occurring that frequently that we wrapped the sequence counter, the chance that we hit that magic point are really low. We could even combine the two (I know Dave Chinner has been really against growing struct address_space in the past): int decode_wb_err(u32 wb_err) { if (wb_err & 1) return -EIO; if (wb_err & 2) return -ENOSPC; return 0; } void set_wb_err(struct address_space *mapping, int err) { if (err == -EIO) mapping->wb_err |= 1; else if (err == -ENOSPC) mapping->wb_err |= 2; else return; mapping->wb_err += 4; } ... if (file->f_wb_err != mapping->wb_err) { err = decode_wb_err(mapping->wb_err); file->f_wb_err = mapping->wb_err; }
Re: [RFC PATCH 1/4] fs: new infrastructure for writeback error handling and reporting
On Fri, Mar 31, 2017 at 03:26:00PM -0400, Jeff Layton wrote: > This set adds a wb_error field and a sequence counter to the > address_space, and a corresponding sequence counter in the struct file. > When errors are reported during writeback, we set the error field in the > mapping and increment the sequence counter. > +++ b/fs/open.c > @@ -709,6 +709,9 @@ static int do_dentry_open(struct file *f, > f->f_inode = inode; > f->f_mapping = inode->i_mapping; > > + /* Don't need the i_lock since we're only interested in sequence */ > + f->f_wb_err_seq = inode->i_mapping->wb_err_seq; > + Do we need READ_ONCE() though, to ensure we get a consistent view of wb_err_seq? In particular, you made it 64 bit, so 32-bit architectures are going to have a problem if it's rolling over between 2^32-1 and 2^32. > +++ b/include/linux/fs.h > @@ -394,6 +394,8 @@ struct address_space { > gfp_t gfp_mask; /* implicit gfp mask for > allocations */ > struct list_headprivate_list; /* ditto */ > void*private_data; /* ditto */ > + u64 wb_err_seq; > + int wb_err; > } __attribute__((aligned(sizeof(long; > /* >* On most architectures that alignment is already the case; but I thought we had you convinced to make wb_err_seq an s32 and do clock arithmetic? > +int filemap_report_wb_error(struct file *file) > +{ > + int err = 0; > + struct inode *inode = file_inode(file); > + struct address_space *mapping = file->f_mapping; > + > + spin_lock(>i_lock); > + if (file->f_wb_err_seq < mapping->wb_err_seq) { > + err = mapping->wb_err; > + file->f_wb_err_seq = mapping->wb_err_seq; > + } > + spin_unlock(>i_lock); > + return err; > +} Now that I think about this some more, I don't think you even need clock arithmetic -- you just need !=. And that means there's only a 1 in 2^32 chance that you miss an error. Good enough, I say! Particularly since if errors are occurring that frequently that we wrapped the sequence counter, the chance that we hit that magic point are really low. We could even combine the two (I know Dave Chinner has been really against growing struct address_space in the past): int decode_wb_err(u32 wb_err) { if (wb_err & 1) return -EIO; if (wb_err & 2) return -ENOSPC; return 0; } void set_wb_err(struct address_space *mapping, int err) { if (err == -EIO) mapping->wb_err |= 1; else if (err == -ENOSPC) mapping->wb_err |= 2; else return; mapping->wb_err += 4; } ... if (file->f_wb_err != mapping->wb_err) { err = decode_wb_err(mapping->wb_err); file->f_wb_err = mapping->wb_err; }
Re: [PATCH 1/3] cpufreq: Add Tegra186 cpufreq driver
On Mon, Apr 03, 2017 at 03:42:23PM +0300, Mikko Perttunen wrote: > Add a new cpufreq driver for Tegra186 (and likely later). > The CPUs are organized into two clusters, Denver and A57, > with two and four cores respectively. CPU frequency can be > adjusted by writing the desired rate divisor and a voltage > hint to a special per-core register. > > The frequency of each core can be set individually; however, > this is just a hint as all CPUs in a cluster will run at > the maximum rate of non-idle CPUs in the cluster. > > Signed-off-by: Mikko Perttunen> --- > drivers/cpufreq/Kconfig.arm| 7 + > drivers/cpufreq/Makefile | 1 + > drivers/cpufreq/tegra186-cpufreq.c | 277 > + > 3 files changed, 285 insertions(+) > create mode 100644 drivers/cpufreq/tegra186-cpufreq.c > > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm > index 74fa5c5904d3..168d36fa4a58 100644 > --- a/drivers/cpufreq/Kconfig.arm > +++ b/drivers/cpufreq/Kconfig.arm > @@ -247,6 +247,13 @@ config ARM_TEGRA124_CPUFREQ > help > This adds the CPUFreq driver support for Tegra124 SOCs. > > +config ARM_TEGRA186_CPUFREQ > + tristate "Tegra186 CPUFreq support" > + depends on ARCH_TEGRA && TEGRA_BPMP > + default y I'd rather not default this to "y". We can use the defconfig to enable this. > + help > + This adds the CPUFreq driver support for Tegra186 SOCs. > + > config ARM_TI_CPUFREQ > bool "Texas Instruments CPUFreq support" > depends on ARCH_OMAP2PLUS > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile > index 9f5a8045f36d..b7e78f063c4f 100644 > --- a/drivers/cpufreq/Makefile > +++ b/drivers/cpufreq/Makefile > @@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += > spear-cpufreq.o > obj-$(CONFIG_ARM_STI_CPUFREQ)+= sti-cpufreq.o > obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)+= tegra20-cpufreq.o > obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o > +obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o > obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o > obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o > obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o > diff --git a/drivers/cpufreq/tegra186-cpufreq.c > b/drivers/cpufreq/tegra186-cpufreq.c > new file mode 100644 > index ..794c1f2d8231 > --- /dev/null > +++ b/drivers/cpufreq/tegra186-cpufreq.c > @@ -0,0 +1,277 @@ > +/* > + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#define EDVD_CORE_VOLT_FREQ(core)(0x20 + (core) * 0x4) > +#define EDVD_CORE_VOLT_FREQ_F_SHIFT 0 > +#define EDVD_CORE_VOLT_FREQ_F_MASK 0xff > +#define EDVD_CORE_VOLT_FREQ_V_SHIFT 16 > +#define EDVD_CORE_VOLT_FREQ_V_MASK 0xff > + > +#define CLUSTER_DENVER 0 > +#define CLUSTER_A57 1 > +#define NUM_CLUSTERS 2 > + > +struct tegra186_cpufreq_cluster { > + const char *name; > + unsigned int num_cores; > +}; > + > +static const struct tegra186_cpufreq_cluster CLUSTERS[] = { We don't usually use uppercase letters for variable names. > + { > + .name = "denver", > + .num_cores = 2, > + }, > + { > + .name = "a57", > + .num_cores = 4, > + } > +}; > + > +struct tegra186_cpufreq_data { > + void __iomem *regs[NUM_CLUSTERS]; > + struct cpufreq_frequency_table *tables[NUM_CLUSTERS]; > +}; Given my comments regarding the aperture, perhaps it would be useful to only have a single range of memory-mapped registers and add an offset to struct tegra186_cpufreq_cluster that points into that region? Also, you're somewhat mixing arrays of NUM_CLUSTERS elements and dynamically sized ones (CLUSTERS[]). Probably best to just stick to one of them. Might be worth considering to dynamically allocate based on the cluster table, but that could be done in a separate patch if we ever get a configuration where NUM_CLUSTERS != 2. > +static void get_cluster_core(int cpu, int *cluster, int *core) These can all be unsigned int. > +{ > + switch (cpu) { > + case 0: > + *cluster = CLUSTER_A57; *core = 0; break; > + case 3: > + *cluster = CLUSTER_A57; *core = 1; break; > + case 4: > +
Re: [PATCH v3] Allow user probes on versioned symbols
Em Fri, Mar 31, 2017 at 02:38:11PM -0500, Paul Clarke escreveu: > On 03/31/2017 12:31 PM, Arnaldo Carvalho de Melo wrote: > > Em Fri, Mar 31, 2017 at 11:06:16AM -0500, Paul Clarke escreveu: > > > Symbol versioning, as in glibc, results in symbols being defined as: > > > @[@] > > > (Note that "@@" identifies a default symbol, if the symbol name > > > is repeated.) > > > > > > perf is currently unable to deal with this, and is unable to create > > > user probes at such symbols: > > > > On top of what tree/branch should I try to apply this? > > I worked from torvalds/linux. > > > Trying on acme/perf/core: > > Pardon my ignorance, but where can I find that tree? see below, but I think you got it already :-) > > [acme@jouet linux]$ patch -p1 < /wb/1.patch > > patching file tools/perf/util/auxtrace.c > > Hunk #1 FAILED at 1875. > [...] > > > Apart from that, you are not checking the return of strndup, that > > however unlikely, can fail, so must be checked. > It's in the middle of strcmp-type function, so all return values are > valid. Shall I emit a message and call exit()? See below for an alternative on how to implement this > > On the style front you sometimes add a space after commas, sometimes > > not, please make sure you add one. > Ack. > > But apart from those problems, I think that one should be able to ask > > for a versioned symbol, to probe just apps using that specific version, > I agree, but wasn't trying to tackle that at the moment. I can look into it, > though. > > for instance, we should consider the whole name as two functions, which > > in fact, they are, no? > I'm not sure I understand what you mean here. Do you mean we should set a > probe at every version of a given symbol name? For example, if there are > symbols: > a@@V2 > a@V1.1 > a@V1 > ...for a request to set a probe at "a", we'd actually set a probe at all 3? I think that we should just probe the default for that symbol and have a way to probe all of them, perhaps using the wildcard, i.e.: [root@jouet linux]# nm /lib64/libpthread-2.24.so | grep ' pthread_cond_timedwait' dd90 T pthread_cond_timedwait@GLIBC_2.2.5 d6e0 T pthread_cond_timedwait@@GLIBC_2.3.2 [root@jouet linux]# # perf probe -x /lib64/libpthread-2.24.so pthread_cond_timedwait should be equivalent to: # perf probe -x /lib64/libpthread-2.24.so pthread_cond_timedwait@@GLIBC_2.3.2 Which matches how these versioned symbols are resolved by the linker, no? I.e. when 'pthread_cond_timedwait' is specified and the symbol table lookup fails, I think we should re-lookup for 'pthread_cond_timedwait@@*', i.e. we should have a symbol__find_default_by_name(), which will take the "pthread_cond_timedwait" and use a symbol comparison using strncmp(strlen(key)), matching, should then look at right after the common part looking for the double @@. Perhaps we should somehow mark a struct dso as being versioned, i.e. having symbols using @@, so that we speed up the search and don't try to look for such symbols where there are none. And if we mark the DSO as versioned, perhaps we can just one search using both strcmp and, not matching, doing the strncmp + strcmp(strlen(key) + 1, "@@") thing, no? > > Additionaly, I can't reproduce your problem here, on x86_64: > > I just cloned from acme/linux, and will rebase to there, if that's the best > tree. It is, to be precise: git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git Right now it is the same as the next best thing to do perf development, the tip tree: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git You should try, on both, to use the perf/urgent branch if you think this is a bug fix that should go upstream ASAP, or perf/core, if it is a new feature or a fix for something introduced during the current development cycle, i.e. poised to be merged in the next Linus Torvalds merge window. - Arnaldo
Re: [PATCH 1/3] cpufreq: Add Tegra186 cpufreq driver
On Mon, Apr 03, 2017 at 03:42:23PM +0300, Mikko Perttunen wrote: > Add a new cpufreq driver for Tegra186 (and likely later). > The CPUs are organized into two clusters, Denver and A57, > with two and four cores respectively. CPU frequency can be > adjusted by writing the desired rate divisor and a voltage > hint to a special per-core register. > > The frequency of each core can be set individually; however, > this is just a hint as all CPUs in a cluster will run at > the maximum rate of non-idle CPUs in the cluster. > > Signed-off-by: Mikko Perttunen > --- > drivers/cpufreq/Kconfig.arm| 7 + > drivers/cpufreq/Makefile | 1 + > drivers/cpufreq/tegra186-cpufreq.c | 277 > + > 3 files changed, 285 insertions(+) > create mode 100644 drivers/cpufreq/tegra186-cpufreq.c > > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm > index 74fa5c5904d3..168d36fa4a58 100644 > --- a/drivers/cpufreq/Kconfig.arm > +++ b/drivers/cpufreq/Kconfig.arm > @@ -247,6 +247,13 @@ config ARM_TEGRA124_CPUFREQ > help > This adds the CPUFreq driver support for Tegra124 SOCs. > > +config ARM_TEGRA186_CPUFREQ > + tristate "Tegra186 CPUFreq support" > + depends on ARCH_TEGRA && TEGRA_BPMP > + default y I'd rather not default this to "y". We can use the defconfig to enable this. > + help > + This adds the CPUFreq driver support for Tegra186 SOCs. > + > config ARM_TI_CPUFREQ > bool "Texas Instruments CPUFreq support" > depends on ARCH_OMAP2PLUS > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile > index 9f5a8045f36d..b7e78f063c4f 100644 > --- a/drivers/cpufreq/Makefile > +++ b/drivers/cpufreq/Makefile > @@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += > spear-cpufreq.o > obj-$(CONFIG_ARM_STI_CPUFREQ)+= sti-cpufreq.o > obj-$(CONFIG_ARM_TEGRA20_CPUFREQ)+= tegra20-cpufreq.o > obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o > +obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o > obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o > obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o > obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o > diff --git a/drivers/cpufreq/tegra186-cpufreq.c > b/drivers/cpufreq/tegra186-cpufreq.c > new file mode 100644 > index ..794c1f2d8231 > --- /dev/null > +++ b/drivers/cpufreq/tegra186-cpufreq.c > @@ -0,0 +1,277 @@ > +/* > + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#define EDVD_CORE_VOLT_FREQ(core)(0x20 + (core) * 0x4) > +#define EDVD_CORE_VOLT_FREQ_F_SHIFT 0 > +#define EDVD_CORE_VOLT_FREQ_F_MASK 0xff > +#define EDVD_CORE_VOLT_FREQ_V_SHIFT 16 > +#define EDVD_CORE_VOLT_FREQ_V_MASK 0xff > + > +#define CLUSTER_DENVER 0 > +#define CLUSTER_A57 1 > +#define NUM_CLUSTERS 2 > + > +struct tegra186_cpufreq_cluster { > + const char *name; > + unsigned int num_cores; > +}; > + > +static const struct tegra186_cpufreq_cluster CLUSTERS[] = { We don't usually use uppercase letters for variable names. > + { > + .name = "denver", > + .num_cores = 2, > + }, > + { > + .name = "a57", > + .num_cores = 4, > + } > +}; > + > +struct tegra186_cpufreq_data { > + void __iomem *regs[NUM_CLUSTERS]; > + struct cpufreq_frequency_table *tables[NUM_CLUSTERS]; > +}; Given my comments regarding the aperture, perhaps it would be useful to only have a single range of memory-mapped registers and add an offset to struct tegra186_cpufreq_cluster that points into that region? Also, you're somewhat mixing arrays of NUM_CLUSTERS elements and dynamically sized ones (CLUSTERS[]). Probably best to just stick to one of them. Might be worth considering to dynamically allocate based on the cluster table, but that could be done in a separate patch if we ever get a configuration where NUM_CLUSTERS != 2. > +static void get_cluster_core(int cpu, int *cluster, int *core) These can all be unsigned int. > +{ > + switch (cpu) { > + case 0: > + *cluster = CLUSTER_A57; *core = 0; break; > + case 3: > + *cluster = CLUSTER_A57; *core = 1; break; > + case 4: > + *cluster =
Re: [PATCH v3] Allow user probes on versioned symbols
Em Fri, Mar 31, 2017 at 02:38:11PM -0500, Paul Clarke escreveu: > On 03/31/2017 12:31 PM, Arnaldo Carvalho de Melo wrote: > > Em Fri, Mar 31, 2017 at 11:06:16AM -0500, Paul Clarke escreveu: > > > Symbol versioning, as in glibc, results in symbols being defined as: > > > @[@] > > > (Note that "@@" identifies a default symbol, if the symbol name > > > is repeated.) > > > > > > perf is currently unable to deal with this, and is unable to create > > > user probes at such symbols: > > > > On top of what tree/branch should I try to apply this? > > I worked from torvalds/linux. > > > Trying on acme/perf/core: > > Pardon my ignorance, but where can I find that tree? see below, but I think you got it already :-) > > [acme@jouet linux]$ patch -p1 < /wb/1.patch > > patching file tools/perf/util/auxtrace.c > > Hunk #1 FAILED at 1875. > [...] > > > Apart from that, you are not checking the return of strndup, that > > however unlikely, can fail, so must be checked. > It's in the middle of strcmp-type function, so all return values are > valid. Shall I emit a message and call exit()? See below for an alternative on how to implement this > > On the style front you sometimes add a space after commas, sometimes > > not, please make sure you add one. > Ack. > > But apart from those problems, I think that one should be able to ask > > for a versioned symbol, to probe just apps using that specific version, > I agree, but wasn't trying to tackle that at the moment. I can look into it, > though. > > for instance, we should consider the whole name as two functions, which > > in fact, they are, no? > I'm not sure I understand what you mean here. Do you mean we should set a > probe at every version of a given symbol name? For example, if there are > symbols: > a@@V2 > a@V1.1 > a@V1 > ...for a request to set a probe at "a", we'd actually set a probe at all 3? I think that we should just probe the default for that symbol and have a way to probe all of them, perhaps using the wildcard, i.e.: [root@jouet linux]# nm /lib64/libpthread-2.24.so | grep ' pthread_cond_timedwait' dd90 T pthread_cond_timedwait@GLIBC_2.2.5 d6e0 T pthread_cond_timedwait@@GLIBC_2.3.2 [root@jouet linux]# # perf probe -x /lib64/libpthread-2.24.so pthread_cond_timedwait should be equivalent to: # perf probe -x /lib64/libpthread-2.24.so pthread_cond_timedwait@@GLIBC_2.3.2 Which matches how these versioned symbols are resolved by the linker, no? I.e. when 'pthread_cond_timedwait' is specified and the symbol table lookup fails, I think we should re-lookup for 'pthread_cond_timedwait@@*', i.e. we should have a symbol__find_default_by_name(), which will take the "pthread_cond_timedwait" and use a symbol comparison using strncmp(strlen(key)), matching, should then look at right after the common part looking for the double @@. Perhaps we should somehow mark a struct dso as being versioned, i.e. having symbols using @@, so that we speed up the search and don't try to look for such symbols where there are none. And if we mark the DSO as versioned, perhaps we can just one search using both strcmp and, not matching, doing the strncmp + strcmp(strlen(key) + 1, "@@") thing, no? > > Additionaly, I can't reproduce your problem here, on x86_64: > > I just cloned from acme/linux, and will rebase to there, if that's the best > tree. It is, to be precise: git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git Right now it is the same as the next best thing to do perf development, the tip tree: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git You should try, on both, to use the perf/urgent branch if you think this is a bug fix that should go upstream ASAP, or perf/core, if it is a new feature or a fix for something introduced during the current development cycle, i.e. poised to be merged in the next Linus Torvalds merge window. - Arnaldo