* [PATCH v9 3/4] arm/syscalls: Optimize address limit check
From: Thomas Garnier @ 2017-04-28 15:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428153213.137279-1-thgarnie@google.com>
Disable the generic address limit check in favor of an architecture
specific optimized implementation.
The address limit is checked on each syscall return path to user-mode
path as well as the irq user-mode return function. If the address limit
was changed, a generic handler is called to stop the kernel on an
explicit check.
Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170426
---
arch/arm/Kconfig | 1 +
arch/arm/kernel/entry-common.S | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4c1a35f15838..c7322f2bb818 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,6 +1,7 @@
config ARM
bool
default y
+ select ADDR_LIMIT_CHECK
select ARCH_CLOCKSOURCE_DATA
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index eb5cd77bf1d8..c83927498f40 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -12,6 +12,7 @@
#include <asm/unistd.h>
#include <asm/ftrace.h>
#include <asm/unwind.h>
+#include <asm/memory.h>
#ifdef CONFIG_AEABI
#include <asm/unistd-oabi.h>
#endif
@@ -27,7 +28,6 @@
#include "entry-header.S"
-
.align 5
#if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING))
/*
@@ -40,9 +40,12 @@ ret_fast_syscall:
UNWIND(.fnstart )
UNWIND(.cantunwind )
disable_irq_notrace @ disable interrupts
+ ldr r2, [tsk, #TI_ADDR_LIMIT]
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
bne fast_work_pending
+ cmp r2, #TASK_SIZE
+ blne addr_limit_check_failed
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr
@@ -66,6 +69,7 @@ ret_fast_syscall:
UNWIND(.cantunwind )
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
disable_irq_notrace @ disable interrupts
+ ldr r2, [tsk, #TI_ADDR_LIMIT]
ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
beq no_work_pending
@@ -82,6 +86,7 @@ slow_work_pending:
mov r2, why @ 'syscall'
bl do_work_pending
cmp r0, #0
+ ldreq r2, [tsk, #TI_ADDR_LIMIT]
beq no_work_pending
movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
ldmia sp, {r0 - r6} @ have to reload r0 - r6
@@ -99,9 +104,12 @@ ret_slow_syscall:
disable_irq_notrace @ disable interrupts
ENTRY(ret_to_user_from_irq)
ldr r1, [tsk, #TI_FLAGS]
+ ldr r2, [tsk, #TI_ADDR_LIMIT]
tst r1, #_TIF_WORK_MASK
bne slow_work_pending
no_work_pending:
+ cmp r2, #TASK_SIZE
+ blne addr_limit_check_failed
asm_trace_hardirqs_on save = 0
/* perform architecture specific actions before user return */
--
2.13.0.rc0.306.g87b477812d-goog
^ permalink raw reply related
* [PATCH v9 2/4] x86/syscalls: Optimize address limit check
From: Thomas Garnier @ 2017-04-28 15:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428153213.137279-1-thgarnie@google.com>
Disable the generic address limit check in favor of an architecture
specific optimized implementation.
The user-mode state check is added to the prepare_exit_to_usermode
function. This function is called before any user-mode return on 32-bit
and on the 64-bit syscall slowpath. For the 64-bit syscall fast path, an
assembly address limit check redirects to the slow path if the address
limit is different.
The TASK_SIZE_MAX definition is moved to the pgtable_64_types header so
it can be used in assembly code.
Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170426
---
arch/x86/Kconfig | 1 +
arch/x86/entry/common.c | 3 +++
arch/x86/entry/entry_64.S | 8 ++++++++
arch/x86/include/asm/pgtable_64_types.h | 11 +++++++++++
arch/x86/include/asm/processor.h | 11 -----------
5 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index cd18994a9555..34c04696068b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -42,6 +42,7 @@ config X86
#
select ACPI_LEGACY_TABLES_LOOKUP if ACPI
select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
+ select ADDR_LIMIT_CHECK
select ANON_INODES
select ARCH_CLOCKSOURCE_DATA
select ARCH_DISCARD_MEMBLOCK
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index cdefcfdd9e63..057d133d7b78 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -23,6 +23,7 @@
#include <linux/user-return-notifier.h>
#include <linux/uprobes.h>
#include <linux/livepatch.h>
+#include <linux/syscalls.h>
#include <asm/desc.h>
#include <asm/traps.h>
@@ -183,6 +184,8 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
struct thread_info *ti = current_thread_info();
u32 cached_flags;
+ addr_limit_check_syscall();
+
if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled()))
local_irq_disable();
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 607d72c4a485..62aca6dcdaf4 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -218,6 +218,14 @@ entry_SYSCALL_64_fastpath:
testl $_TIF_ALLWORK_MASK, TASK_TI_flags(%r11)
jnz 1f
+ /*
+ * If address limit is not based on user-mode, jump to slow path for
+ * additional security checks.
+ */
+ movq $TASK_SIZE_MAX, %rcx
+ cmp %rcx, TASK_addr_limit(%r11)
+ jne 1f
+
LOCKDEP_SYS_EXIT
TRACE_IRQS_ON /* user mode is traced as IRQs on */
movq RIP(%rsp), %rcx
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 06470da156ba..78af4d43a7ce 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -104,4 +104,15 @@ typedef struct { pteval_t pte; } pte_t;
#define EARLY_DYNAMIC_PAGE_TABLES 64
+/*
+ * User space process size. 47bits minus one guard page. The guard
+ * page is necessary on Intel CPUs: if a SYSCALL instruction is at
+ * the highest possible canonical userspace address, then that
+ * syscall will enter the kernel with a non-canonical return
+ * address, and SYSRET will explode dangerously. We avoid this
+ * particular problem by preventing anything from being mapped
+ * at the maximum canonical address.
+ */
+#define TASK_SIZE_MAX ((_AC(1, UL) << 47) - PAGE_SIZE)
+
#endif /* _ASM_X86_PGTABLE_64_DEFS_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 3cada998a402..e80822582d3e 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -825,17 +825,6 @@ static inline void spin_lock_prefetch(const void *x)
#define KSTK_ESP(task) (task_pt_regs(task)->sp)
#else
-/*
- * User space process size. 47bits minus one guard page. The guard
- * page is necessary on Intel CPUs: if a SYSCALL instruction is at
- * the highest possible canonical userspace address, then that
- * syscall will enter the kernel with a non-canonical return
- * address, and SYSRET will explode dangerously. We avoid this
- * particular problem by preventing anything from being mapped
- * at the maximum canonical address.
- */
-#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)
-
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
--
2.13.0.rc0.306.g87b477812d-goog
^ permalink raw reply related
* [PATCH v9 1/4] syscalls: Verify address limit before returning to user-mode
From: Thomas Garnier @ 2017-04-28 15:32 UTC (permalink / raw)
To: linux-arm-kernel
Ensure that a syscall does not return to user-mode with a kernel address
limit. If that happens, a process can corrupt kernel-mode memory and
elevate privileges [1].
The CONFIG_ADDR_LIMIT_CHECK option disables the generic check so each
architecture can create optimized versions. This option is enabled by
default on s390 because a similar feature already exists.
[1] https://bugs.chromium.org/p/project-zero/issues/detail?id=990
Signed-off-by: Thomas Garnier <thgarnie@google.com>
Tested-by: Kees Cook <keescook@chromium.org>
---
Based on next-20170426
---
arch/s390/Kconfig | 1 +
include/linux/syscalls.h | 27 ++++++++++++++++++++++++++-
init/Kconfig | 6 ++++++
kernel/sys.c | 13 +++++++++++++
4 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index d25435d94b6e..3d2ec084d5fc 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -64,6 +64,7 @@ config ARCH_SUPPORTS_UPROBES
config S390
def_bool y
+ select ADDR_LIMIT_CHECK
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 980c3c9b06f8..e534b93ce43a 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -191,6 +191,28 @@ extern struct trace_event_functions exit_syscall_print_funcs;
SYSCALL_METADATA(sname, x, __VA_ARGS__) \
__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+
+/*
+ * Called before coming back to user-mode. Returning to user-mode with an
+ * address limit different than USER_DS can allow to overwrite kernel memory.
+ */
+static inline void addr_limit_check_syscall(void)
+{
+ BUG_ON(!segment_eq(get_fs(), USER_DS));
+}
+
+#ifndef CONFIG_ADDR_LIMIT_CHECK
+#define ADDR_LIMIT_CHECK_PRE() \
+ bool user_caller = segment_eq(get_fs(), USER_DS)
+#define ADDR_LIMIT_CHECK_POST() \
+ if (user_caller) addr_limit_check_syscall()
+#else
+#define ADDR_LIMIT_CHECK_PRE()
+#define ADDR_LIMIT_CHECK_POST()
+asmlinkage void addr_limit_check_failed(void) __noreturn;
+#endif
+
+
#define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
@@ -199,7 +221,10 @@ extern struct trace_event_functions exit_syscall_print_funcs;
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
- long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
+ long ret; \
+ ADDR_LIMIT_CHECK_PRE(); \
+ ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
+ ADDR_LIMIT_CHECK_POST(); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
diff --git a/init/Kconfig b/init/Kconfig
index 42a346b0df43..599d9fe30703 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1961,6 +1961,12 @@ config PROFILING
config TRACEPOINTS
bool
+config ADDR_LIMIT_CHECK
+ bool
+ help
+ Disable the generic address limit check. Allow each architecture to
+ optimize how and when the verification is done.
+
source "arch/Kconfig"
endmenu # General setup
diff --git a/kernel/sys.c b/kernel/sys.c
index 8a94b4eabcaa..a1cbcd715d62 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2458,3 +2458,16 @@ COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
return 0;
}
#endif /* CONFIG_COMPAT */
+
+#ifdef CONFIG_ADDR_LIMIT_CHECK
+/*
+ * Used when an architecture specific implementation detects an invalid address
+ * limit. This function does not return.
+ */
+asmlinkage void addr_limit_check_failed(void)
+{
+ /* Try to fail on the generic address limit check */
+ addr_limit_check_syscall();
+ panic("Invalid address limit before returning to user-mode");
+}
+#endif
--
2.13.0.rc0.306.g87b477812d-goog
^ permalink raw reply related
* arm64: next-20170428 hangs on boot
From: Yury Norov @ 2017-04-28 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428145233.GB5292@leverpostej>
On Fri, Apr 28, 2017 at 03:52:34PM +0100, Mark Rutland wrote:
> On Fri, Apr 28, 2017 at 04:24:29PM +0300, Yury Norov wrote:
> > Hi all,
>
> Hi,
>
> [adding Dave Miller, netdev, lkml]
thanks
> > On QEMU the next-20170428 hangs on boot for me due to kernel panic in
> > rtnetlink_init():
> >
> > void __init rtnetlink_init(void)
> > {
> > if (register_pernet_subsys(&rtnetlink_net_ops))
> > panic("rtnetlink_init: cannot initialize rtnetlink\n");
> >
> > ...
> > }
>
> I see the same thing with a next-20170428 arm64 defconfig, on a Juno R1
> system:
>
> [ 0.531949] Kernel panic - not syncing: rtnetlink_init: cannot initialize rtnetlink
> [ 0.531949]
> [ 0.541271] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.11.0-rc8-next-20170428-00002-g6ee3799 #10
> [ 0.550307] Hardware name: ARM Juno development board (r1) (DT)
> [ 0.556332] Call trace:
> [ 0.558833] [<ffff000008088538>] dump_backtrace+0x0/0x238
> [ 0.564332] [<ffff000008088834>] show_stack+0x14/0x20
> [ 0.569477] [<ffff00000839dd54>] dump_stack+0x9c/0xc0
> [ 0.574622] [<ffff000008175344>] panic+0x11c/0x28c
> [ 0.579505] [<ffff000008d80034>] rtnetlink_init+0x2c/0x1d0
> [ 0.585092] [<ffff000008d8047c>] netlink_proto_init+0x14c/0x17c
> [ 0.591119] [<ffff000008083150>] do_one_initcall+0x38/0x120
> [ 0.596796] [<ffff000008d30d00>] kernel_init_freeable+0x1a0/0x240
> [ 0.603003] [<ffff00000892a790>] kernel_init+0x10/0x100
> [ 0.608324] [<ffff000008082ec0>] ret_from_fork+0x10/0x50
> [ 0.613736] SMP: stopping secondary CPUs
> [ 0.617738] ---[ end Kernel panic - not syncing: rtnetlink_init: cannot initialize rtnetlink
>
> If this isn't a known issue, it would be worth trying to bisect this.
The exact function that fails is:
include/linux/rhashtable.h
static inline void *__rhashtable_insert_fast(
struct rhashtable *ht, const void *key, struct rhash_head *obj,
const struct rhashtable_params params, bool rhlist)
{
...
data = ERR_PTR(-E2BIG);
if (unlikely(rht_grow_above_max(ht, tbl)))
goto out;
...
out:
spin_unlock_bh(lock);
rcu_read_unlock();
return data;
}
And the backtrace:
#0 __rhashtable_insert_fast (rhlist=<optimized out>, params=..., obj=<optimized out>,
key=<optimized out>, ht=<optimized out>) at ./include/linux/rhashtable.h:803
#1 rhashtable_lookup_insert_key (params=..., obj=<optimized out>, key=<optimized out>,
ht=<optimized out>) at ./include/linux/rhashtable.h:980
#2 __netlink_insert (sk=<optimized out>, table=<optimized out>) at net/netlink/af_netlink.c:484
#3 netlink_insert (sk=0xffff80003da85000, portid=0) at net/netlink/af_netlink.c:548
#4 0xffff00000876c5a0 in __netlink_kernel_create (net=<optimized out>, unit=0, module=0x0,
cfg=0xffff80003d84fc60) at net/netlink/af_netlink.c:1996
#5 0xffff000008756704 in netlink_kernel_create (cfg=<optimized out>, unit=<optimized out>,
net=<optimized out>) at ./include/linux/netlink.h:62
#6 rtnetlink_net_init (net=0xffff000008c7c100 <init_net>) at net/core/rtnetlink.c:4175
#7 0xffff000008737a2c in ops_init (ops=0xffff000008c7e268 <rtnetlink_net_ops>,
net=0xffff000008c7c100 <init_net>) at net/core/net_namespace.c:117
#8 0xffff000008738704 in __register_pernet_operations (ops=<optimized out>,
list=<optimized out>) at net/core/net_namespace.c:818
#9 register_pernet_operations (list=<optimized out>, ops=0xffff000008c7e268
<rtnetlink_net_ops>) at net/core/net_namespace.c:892
#10 0xffff0000087387fc in register_pernet_subsys (ops=0xffff000008c7e268
<rtnetlink_net_ops>) at net/core/net_namespace.c:934
#11 0xffff000008b5b9b8 in rtnetlink_init () at net/core/rtnetlink.c:4195
#12 0xffff000008b5be08 in netlink_proto_init () at net/netlink/af_netlink.c:2730
#13 0xffff000008083158 in do_one_initcall (fn=0xffff000008b5bcc4 <netlink_proto_init>) at init/main.c:795
#14 0xffff000008b20d04 in do_initcall_level (level=<optimized out>) at init/main.c:861
#15 do_initcalls () at init/main.c:869
#16 do_basic_setup () at init/main.c:887
Yury
^ permalink raw reply
* [GIT PULL] ARM: mvebu: arm64 for v4.12 (#1)
From: Gregory CLEMENT @ 2017-04-28 15:09 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Here is the first pull request for arm64 for mvebu for v4.12.
It comes very late but the driver part has been merged just this week.
Gregory
The following changes since commit c1ae3cfa0e89fa1a7ecc4c99031f5e9ae99d9201:
Linux 4.11-rc1 (2017-03-05 12:59:56 -0800)
are available in the git repository at:
git://git.infradead.org/linux-mvebu.git tags/mvebu-arm64-4.12-1
for you to fetch changes up to d2718d1365f7fce624fd7ed163f60532f92ed016:
arm64: marvell: enable the Armada 37xx pinctrl driver (2017-04-26 12:23:27 +0200)
----------------------------------------------------------------
mvebu arm64 for 4.12
enable the Armada 37xx pinctrl driver
----------------------------------------------------------------
Gregory CLEMENT (1):
arm64: marvell: enable the Armada 37xx pinctrl driver
arch/arm64/Kconfig.platforms | 5 +++++
1 file changed, 5 insertions(+)
^ permalink raw reply
* [GIT PULL] ARM: mvebu: dt64 for v4.12 (#3)
From: Gregory CLEMENT @ 2017-04-28 15:08 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Here is the third pull request for dt64 for mvebu for v4.12.
It comes very late but the driver part has been merged just this week.
Gregory
The following changes since commit 7ba2ef7c7200e476ee2cede7bcffcf7749e02f5c:
arm64: marvell: dts: enable the crypto engine on the Armada 8040 DB (2017-04-12 10:36:30 +0200)
are available in the git repository at:
git://git.infradead.org/linux-mvebu.git tags/mvebu-dt64-4.12-3
for you to fetch changes up to 6a680783aaadd168557eec695374929ac066536f:
ARM64: dts: marvell: armada37xx: add pinctrl definition (2017-04-28 16:08:12 +0200)
----------------------------------------------------------------
mvebu dt64 for 4.12 (part 3)
pinctrl and GPIO description for Armada 37xx SoCs
----------------------------------------------------------------
Gregory CLEMENT (2):
ARM64: dts: marvell: Add pinctrl nodes for Armada 3700
ARM64: dts: marvell: armada37xx: add pinctrl definition
arch/arm64/boot/dts/marvell/armada-3720-db.dts | 8 +++
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 73 ++++++++++++++++++++++++--
2 files changed, 78 insertions(+), 3 deletions(-)
^ permalink raw reply
* [PATCH v2] drm/rockchip: Set line flag config register in vop_crtc_enable
From: Sean Paul @ 2017-04-28 15:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1493365067-29541-1-git-send-email-jeffy.chen@rock-chips.com>
On Fri, Apr 28, 2017 at 03:37:47PM +0800, Jeffy Chen wrote:
> We need to set vop config done after update line flag config, it's a
> new requirement for chips newer than rk3368.
>
> Since we would only use line flag irq for vact_end, let's move it to
> vop_crtc_enable.
>
> v2: Remove unused check and variables.
Hi Jeffy,
v1 was already applied. Please send a follow-on patch to clean this up.
Sean
>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
>
> ---
>
> Changes in v2:
> Remove unused check and variables.
>
> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 14 +++-----------
> drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 3 +--
> drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +++++++++-----------
> 3 files changed, 13 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index d8fa7a9..1bccd82 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -104,26 +104,18 @@ static void analogix_dp_psr_work(struct work_struct *work)
> {
> struct rockchip_dp_device *dp =
> container_of(work, typeof(*dp), psr_work);
> - struct drm_crtc *crtc = dp->encoder.crtc;
> - int psr_state = dp->psr_state;
> - int vact_end;
> int ret;
> unsigned long flags;
>
> - if (!crtc)
> - return;
> -
> - vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay;
> -
> - ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,
> - PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
> + ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
> + PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
> if (ret) {
> dev_err(dp->dev, "line flag interrupt did not arrive\n");
> return;
> }
>
> spin_lock_irqsave(&dp->psr_lock, flags);
> - if (psr_state == EDP_VSC_PSR_STATE_ACTIVE)
> + if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
> analogix_dp_enable_psr(dp->dev);
> else
> analogix_dp_disable_psr(dp->dev);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> index a48fcce..47905fa 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
> @@ -62,8 +62,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
> struct device *dev);
> void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
> struct device *dev);
> -int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
> - unsigned int mstimeout);
> +int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
>
> extern struct platform_driver cdn_dp_driver;
> extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 3f7a82d..40a5e6e 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop)
> return !!line_flag_irq;
> }
>
> -static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
> +static void vop_line_flag_irq_enable(struct vop *vop)
> {
> unsigned long flags;
>
> @@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
>
> spin_lock_irqsave(&vop->irq_lock, flags);
>
> - VOP_CTRL_SET(vop, line_flag_num[0], line_num);
> VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
> VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
>
> @@ -981,6 +980,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
> VOP_CTRL_SET(vop, vact_st_end, val);
> VOP_CTRL_SET(vop, vpost_st_end, val);
>
> + VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
> +
> clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
>
> VOP_CTRL_SET(vop, standby, 0);
> @@ -1507,19 +1508,16 @@ static void vop_win_init(struct vop *vop)
> }
>
> /**
> - * rockchip_drm_wait_line_flag - acqiure the give line flag event
> + * rockchip_drm_wait_vact_end
> * @crtc: CRTC to enable line flag
> - * @line_num: interested line number
> * @mstimeout: millisecond for timeout
> *
> - * Driver would hold here until the interested line flag interrupt have
> - * happened or timeout to wait.
> + * Wait for vact_end line flag irq or timeout.
> *
> * Returns:
> * Zero on success, negative errno on failure.
> */
> -int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
> - unsigned int mstimeout)
> +int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
> {
> struct vop *vop = to_vop(crtc);
> unsigned long jiffies_left;
> @@ -1527,14 +1525,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
> if (!crtc || !vop->is_enabled)
> return -ENODEV;
>
> - if (line_num > crtc->mode.vtotal || mstimeout <= 0)
> + if (mstimeout <= 0)
> return -EINVAL;
>
> if (vop_line_flag_irq_is_enabled(vop))
> return -EBUSY;
>
> reinit_completion(&vop->line_flag_completion);
> - vop_line_flag_irq_enable(vop, line_num);
> + vop_line_flag_irq_enable(vop);
>
> jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
> msecs_to_jiffies(mstimeout));
> @@ -1547,7 +1545,7 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
>
> return 0;
> }
> -EXPORT_SYMBOL(rockchip_drm_wait_line_flag);
> +EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
>
> static int vop_bind(struct device *dev, struct device *master, void *data)
> {
> --
> 2.1.4
>
--
Sean Paul, Software Engineer, Google / Chromium OS
^ permalink raw reply
* [PATCH] arm64: Print DT machine model in setup_machine_fdt()
From: Will Deacon @ 2017-04-28 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1493296385-14140-1-git-send-email-geert+renesas@glider.be>
On Thu, Apr 27, 2017 at 02:33:05PM +0200, Geert Uytterhoeven wrote:
> On arm32, the machine model specified in the device tree is printed
> during boot-up, courtesy of of_flat_dt_match_machine().
>
> On arm64, of_flat_dt_match_machine() is not called, and the machine
> model information is not available from the kernel log.
>
> Print the machine model to make it easier to derive the machine model
> from an arbitrary kernel boot log.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> I have scripts to save kernel boot logs, and compare logs[*] for
> subsequent boots on the same machine. Having a way to extract the
> machine model from an arbitrary kernel boot log makes this easier.
>
> Yes, I'm also a big fan of CONFIG_LOCALVERSION_AUTO and
> CONFIG_LOCALVERSION.
>
> [*] and clock and PM domain lists...
> ---
> arch/arm64/kernel/setup.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 28855ec1be95e113..2c822ef94f341417 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -180,6 +180,7 @@ static void __init smp_build_mpidr_hash(void)
> static void __init setup_machine_fdt(phys_addr_t dt_phys)
> {
> void *dt_virt = fixmap_remap_fdt(dt_phys);
> + const char *name;
>
> if (!dt_virt || !early_init_dt_scan(dt_virt)) {
> pr_crit("\n"
> @@ -192,7 +193,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
> cpu_relax();
> }
>
> - dump_stack_set_arch_desc("%s (DT)", of_flat_dt_get_machine_name());
> + name = of_flat_dt_get_machine_name();
> + pr_info("Machine model: %s\n", name);
> + dump_stack_set_arch_desc("%s (DT)", name);
> }
I think your use-case is slightly questionable (e.g. for ACPI, we print
something different, and this isn't generally considered to be ABI), but
the patch is harmless and if you find it useful then:
Acked-by: Will Deacon <will.deacon@arm.com>
Will
^ permalink raw reply
* [PATCH] clk: stm32h7: Add stm32h743 clock driver
From: Gabriel Fernandez @ 2017-04-28 14:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170407195152.GH7065@codeaurora.org>
Hi Stephen
Sorry for delay i was on sick live
On 04/07/2017 09:51 PM, Stephen Boyd wrote:
> On 04/06, Gabriel Fernandez wrote:
>> On 04/06/2017 12:32 AM, Stephen Boyd wrote:
>>> On 03/15, gabriel.fernandez at st.com wrote:
>>>> diff --git a/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt
>>>> new file mode 100644
>>>> index 0000000..9d4b587
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt
>>>> @@ -0,0 +1,152 @@
>>>> +
>>>> + rcc: rcc at 58024400 {
>>>> + #reset-cells = <1>;
>>>> + #clock-cells = <2>
>>>> + compatible = "st,stm32h743-rcc", "st,stm32-rcc";
>>>> + reg = <0x58024400 0x400>;
>>>> + clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>;
>>>> +
>>>> + st,syscfg = <&pwrcfg>;
>>>> +
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + vco1 at 58024430 {
>>>> + #clock-cells = <0>;
>>>> + compatible = "stm32,pll";
>>>> + reg = <0>;
>>> reg is super confusing and doesn't match unit address.
>> ok i fixed it in the v2
>>
>>>> + };
>>> Why? Shouldn't we know this from the compatible string how many
>>> PLLs there are and where they're located? Export the PLLs through
>>> rcc node's clock-cells?
>>>
>> Because i need to offer the possibility to change the PLL VCO
>> frequencies at the start-up of this driver clock.
>> The VCO algorithm needs a division factor, a multiplication factor
>> and a fractional factor.
>> Lot's of solution are possible for one frequency and it's nightmare
>> to satisfy the 3 output dividers of the PLL.
> Sure, but do we need to configure that on a per-board basis or a
> per-SoC basis? If it's just some configuration, I wonder why we
> don't put that into the driver and base it off some compatible
> string that includes the SoC the device is for.
>
I prefer to let in first, the responsibility of the boot loader to
change VCO parameters.
Then i propose a new version without DT configuration of PLL's
are you ok for that ?
best regards
Gabriel
To simply
^ permalink raw reply
* [PATCH] iio: stm32 trigger: Add support for TRGO2 triggers
From: Fabrice Gasnier @ 2017-04-28 14:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <11825bb8-ebb3-0679-7c65-3ee6b5ed2214@kernel.org>
On 04/27/2017 07:49 AM, Jonathan Cameron wrote:
> On 26/04/17 09:55, Benjamin Gaignard wrote:
>> 2017-04-26 10:17 GMT+02:00 Fabrice Gasnier <fabrice.gasnier@st.com>:
>>> Add support for TRGO2 trigger that can be found on STM32F7.
>>> Add additional master modes supported by TRGO2.
> These additional modes would benefit from more information in the
> ABI docs. Otherwise patch seems fine, though this may win
> the award for hardest hardware to come up with a generic
> interface for...
>>> Register additional "tim[1/8]_trgo2" triggers for timer1 & timer8.
>>> Detect TRGO2 timer capability (master mode selection 2).
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>>> ---
>>> .../ABI/testing/sysfs-bus-iio-timer-stm32 | 15 +++
>>> drivers/iio/trigger/stm32-timer-trigger.c | 113 ++++++++++++++++++---
>>> include/linux/iio/timer/stm32-timer-trigger.h | 2 +
>>> include/linux/mfd/stm32-timers.h | 2 +
>>> 4 files changed, 118 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
>>> index 230020e..47647b4 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
>>> +++ b/Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
>>> @@ -16,6 +16,21 @@ Description:
>>> - "OC2REF" : OC2REF signal is used as trigger output.
>>> - "OC3REF" : OC3REF signal is used as trigger output.
>>> - "OC4REF" : OC4REF signal is used as trigger output.
>>> + Additional modes (on TRGO2 only):
>>> + - "OC5REF" : OC5REF signal is used as trigger output.
>>> + - "OC6REF" : OC6REF signal is used as trigger output.
>>> + - "compare_pulse_OC4REF":
>>> + OC4REF rising or falling edges generate pulses.
> I'd like this to be fairly understandable without resorting to reading the
> datasheet. As I understand it you get a fixed term pulse on both edges
> of the waveform? Perhaps this calls for some ascii art :)
Hi Jonathan,
If you feel like it needs more documentation, I'd rather prefer to add
reference or link to the datasheet... That will be more accurate,
up-to-date (e.g. like RM0385 pdf). Does this sound ok ? Or...
Just in case, I prepared some ascii art, hope it clarify things.
I'm wondering if this is best place to put it ?
Shouldn't this be added in source code, instead of ABI Doc ?
Maybe I can skip 1st part of it, heading boxes? (only example is enough?
or not...)
+-----------+ +-------------+ +---------+
| Prescaler +-> | Counter | +-> | Master | TRGO(2)
+-----------+ +--+--------+-+ |-> | Control +-->
| | || +---------+
+--v--------+-+ OCxREF || +---------+
| Chx compare +----------> | Output | ChX
+-----------+-+ | | Control +-->
. | | +---------+
. | | .
+-----------v-+ OC6REF | .
| Ch6 compare +---------+>
+-------------+
Example with: "compare_pulse_OC4REF_r_or_OC6REF_r":
X
X X
X . . X
X . . X
X . . X
count X . . . . X
. . . .
. . . .
+---------------+
OC4REF | . . |
+-+ . . +-+
. +---+ .
OC6REF . | | .
+-------+ +-------+
+-+ +-+
TRGO2 | | | |
+-+ +---+ +---------+
side note: this isn't my house ;-)
Please advise,
Thanks,
Fabrice
>>> + - "compare_pulse_OC6REF":
>>> + OC6REF rising or falling edges generate pulses.
>>> + - "compare_pulse_OC4REF_r_or_OC6REF_r":
>>> + OC4REF or OC6REF rising edges generate pulses.
>>> + - "compare_pulse_OC4REF_r_or_OC6REF_f":
>>> + OC4REF rising or OC6REF falling edges generate pulses.
>>> + - "compare_pulse_OC5REF_r_or_OC6REF_r":
>>> + OC5REF or OC6REF rising edges generate pulses.
>>> + - "compare_pulse_OC5REF_r_or_OC6REF_f":
>>> + OC5REF rising or OC6REF falling edges generate pulses.
>>>
>>> What: /sys/bus/iio/devices/triggerX/master_mode
>>> KernelVersion: 4.11
>>> diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c
>>> index 0f1a2cf..a0031b7 100644
>>> --- a/drivers/iio/trigger/stm32-timer-trigger.c
>>> +++ b/drivers/iio/trigger/stm32-timer-trigger.c
>>> @@ -14,19 +14,19 @@
>>> #include <linux/module.h>
>>> #include <linux/platform_device.h>
>>>
>>> -#define MAX_TRIGGERS 6
>>> +#define MAX_TRIGGERS 7
>>> #define MAX_VALIDS 5
>>>
>>> /* List the triggers created by each timer */
>>> static const void *triggers_table[][MAX_TRIGGERS] = {
>>> - { TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,},
>>> + { TIM1_TRGO, TIM1_TRGO2, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,},
>>> { TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,},
>>> { TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,},
>>> { TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,},
>>> { TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,},
>>> { TIM6_TRGO,},
>>> { TIM7_TRGO,},
>>> - { TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
>>> + { TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
>>> { TIM9_TRGO, TIM9_CH1, TIM9_CH2,},
>>> { }, /* timer 10 */
>>> { }, /* timer 11 */
>>> @@ -56,9 +56,16 @@ struct stm32_timer_trigger {
>>> u32 max_arr;
>>> const void *triggers;
>>> const void *valids;
>>> + bool has_trgo2;
>>> };
>>>
>>> +static bool stm32_timer_is_trgo2_name(const char *name)
>>> +{
>>> + return !!strstr(name, "trgo2");
>>> +}
>>> +
>>> static int stm32_timer_start(struct stm32_timer_trigger *priv,
>>> + struct iio_trigger *trig,
>>> unsigned int frequency)
>>> {
>>> unsigned long long prd, div;
>>> @@ -102,7 +109,12 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv,
>>> regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
>>>
>>> /* Force master mode to update mode */
>>> - regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0x20);
>>> + if (stm32_timer_is_trgo2_name(trig->name))
>>> + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2,
>>> + 0x2 << TIM_CR2_MMS2_SHIFT);
>>> + else
>>> + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS,
>>> + 0x2 << TIM_CR2_MMS_SHIFT);
>>>
>>> /* Make sure that registers are updated */
>>> regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
>>> @@ -150,7 +162,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev,
>>> if (freq == 0) {
>>> stm32_timer_stop(priv);
>>> } else {
>>> - ret = stm32_timer_start(priv, freq);
>>> + ret = stm32_timer_start(priv, trig, freq);
>>> if (ret)
>>> return ret;
>>> }
>>> @@ -183,6 +195,9 @@ static IIO_DEV_ATTR_SAMP_FREQ(0660,
>>> stm32_tt_read_frequency,
>>> stm32_tt_store_frequency);
>>>
>>> +#define MASTER_MODE_MAX 7
>>> +#define MASTER_MODE2_MAX 15
>>> +
>>> static char *master_mode_table[] = {
>>> "reset",
>>> "enable",
>>> @@ -191,7 +206,16 @@ static IIO_DEV_ATTR_SAMP_FREQ(0660,
>>> "OC1REF",
>>> "OC2REF",
>>> "OC3REF",
>>> - "OC4REF"
>>> + "OC4REF",
>>> + /* Master mode selection 2 only */
>>> + "OC5REF",
>>> + "OC6REF",
>>> + "compare_pulse_OC4REF",
>>> + "compare_pulse_OC6REF",
>>> + "compare_pulse_OC4REF_r_or_OC6REF_r",
>>> + "compare_pulse_OC4REF_r_or_OC6REF_f",
>>> + "compare_pulse_OC5REF_r_or_OC6REF_r",
>>> + "compare_pulse_OC5REF_r_or_OC6REF_f",
>>> };
>>>
>>> static ssize_t stm32_tt_show_master_mode(struct device *dev,
>>> @@ -199,10 +223,15 @@ static ssize_t stm32_tt_show_master_mode(struct device *dev,
>>> char *buf)
>>> {
>>> struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
>>> + struct iio_trigger *trig = to_iio_trigger(dev);
>>> u32 cr2;
>>>
>>> regmap_read(priv->regmap, TIM_CR2, &cr2);
>>> - cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT;
>>> +
>>> + if (stm32_timer_is_trgo2_name(trig->name))
>>> + cr2 = (cr2 & TIM_CR2_MMS2) >> TIM_CR2_MMS2_SHIFT;
>>> + else
>>> + cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT;
>>>
>>> return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]);
>>> }
>>> @@ -212,13 +241,25 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
>>> const char *buf, size_t len)
>>> {
>>> struct stm32_timer_trigger *priv = dev_get_drvdata(dev);
>>> + struct iio_trigger *trig = to_iio_trigger(dev);
>>> + u32 mask, shift, master_mode_max;
>>> int i;
>>>
>>> - for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) {
>>> + if (stm32_timer_is_trgo2_name(trig->name)) {
>>> + mask = TIM_CR2_MMS2;
>>> + shift = TIM_CR2_MMS2_SHIFT;
>>> + master_mode_max = MASTER_MODE2_MAX;
>>> + } else {
>>> + mask = TIM_CR2_MMS;
>>> + shift = TIM_CR2_MMS_SHIFT;
>>> + master_mode_max = MASTER_MODE_MAX;
>>> + }
>>> +
>>> + for (i = 0; i <= master_mode_max; i++) {
>>> if (!strncmp(master_mode_table[i], buf,
>>> strlen(master_mode_table[i]))) {
>>> - regmap_update_bits(priv->regmap, TIM_CR2,
>>> - TIM_CR2_MMS, i << TIM_CR2_MMS_SHIFT);
>>> + regmap_update_bits(priv->regmap, TIM_CR2, mask,
>>> + i << shift);
>>> /* Make sure that registers are updated */
>>> regmap_update_bits(priv->regmap, TIM_EGR,
>>> TIM_EGR_UG, TIM_EGR_UG);
>>> @@ -229,8 +270,31 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev,
>>> return -EINVAL;
>>> }
>>>
>>> -static IIO_CONST_ATTR(master_mode_available,
>>> - "reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF");
>>> +static ssize_t stm32_tt_show_master_mode_avail(struct device *dev,
>>> + struct device_attribute *attr,
>>> + char *buf)
>>> +{
>>> + struct iio_trigger *trig = to_iio_trigger(dev);
>>> + unsigned int i, master_mode_max;
>>> + size_t len = 0;
>>> +
>>> + if (stm32_timer_is_trgo2_name(trig->name))
>>> + master_mode_max = MASTER_MODE2_MAX;
>>> + else
>>> + master_mode_max = MASTER_MODE_MAX;
>>> +
>>> + for (i = 0; i <= master_mode_max; i++)
>>> + len += scnprintf(buf + len, PAGE_SIZE - len,
>>> + "%s ", master_mode_table[i]);
>>> +
>>> + /* replace trailing space by newline */
>>> + buf[len - 1] = '\n';
>>> +
>>> + return len;
>>> +}
>>> +
>>> +static IIO_DEVICE_ATTR(master_mode_available, 0444,
>>> + stm32_tt_show_master_mode_avail, NULL, 0);
>>>
>>> static IIO_DEVICE_ATTR(master_mode, 0660,
>>> stm32_tt_show_master_mode,
>>> @@ -240,7 +304,7 @@ static IIO_DEVICE_ATTR(master_mode, 0660,
>>> static struct attribute *stm32_trigger_attrs[] = {
>>> &iio_dev_attr_sampling_frequency.dev_attr.attr,
>>> &iio_dev_attr_master_mode.dev_attr.attr,
>>> - &iio_const_attr_master_mode_available.dev_attr.attr,
>>> + &iio_dev_attr_master_mode_available.dev_attr.attr,
>>> NULL,
>>> };
>>>
>>> @@ -264,6 +328,12 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
>>>
>>> while (cur && *cur) {
>>> struct iio_trigger *trig;
>>> + bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur);
>>> +
>>> + if (cur_is_trgo2 && !priv->has_trgo2) {
>>> + cur++;
>>> + continue;
>>> + }
>>>
>>> trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur);
>>> if (!trig)
>>> @@ -277,7 +347,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
>>> * should only be available on trgo trigger which
>>> * is always the first in the list.
>>> */
>>> - if (cur == priv->triggers)
>>> + if (cur == priv->triggers || cur_is_trgo2)
>>> trig->dev.groups = stm32_trigger_attr_groups;
>>>
>>> iio_trigger_set_drvdata(trig, priv);
>>> @@ -584,6 +654,20 @@ bool is_stm32_timer_trigger(struct iio_trigger *trig)
>>> }
>>> EXPORT_SYMBOL(is_stm32_timer_trigger);
>>>
>>> +static void stm32_timer_detect_trgo2(struct stm32_timer_trigger *priv)
>>> +{
>>> + u32 val;
>>> +
>>> + /*
>>> + * Master mode selection 2 bits can only be written and read back when
>>> + * timer supports it.
>>> + */
>>> + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, TIM_CR2_MMS2);
>>> + regmap_read(priv->regmap, TIM_CR2, &val);
>>> + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0);
>>> + priv->has_trgo2 = !!val;
>>> +}
>>> +
>>> static int stm32_timer_trigger_probe(struct platform_device *pdev)
>>> {
>>> struct device *dev = &pdev->dev;
>>> @@ -614,6 +698,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
>>> priv->max_arr = ddata->max_arr;
>>> priv->triggers = triggers_table[index];
>>> priv->valids = valids_table[index];
>>> + stm32_timer_detect_trgo2(priv);
>>>
>>> ret = stm32_setup_iio_triggers(priv);
>>> if (ret)
>>> diff --git a/include/linux/iio/timer/stm32-timer-trigger.h b/include/linux/iio/timer/stm32-timer-trigger.h
>>> index 55535ae..fa7d786 100644
>>> --- a/include/linux/iio/timer/stm32-timer-trigger.h
>>> +++ b/include/linux/iio/timer/stm32-timer-trigger.h
>>> @@ -10,6 +10,7 @@
>>> #define _STM32_TIMER_TRIGGER_H_
>>>
>>> #define TIM1_TRGO "tim1_trgo"
>>> +#define TIM1_TRGO2 "tim1_trgo2"
>>> #define TIM1_CH1 "tim1_ch1"
>>> #define TIM1_CH2 "tim1_ch2"
>>> #define TIM1_CH3 "tim1_ch3"
>>> @@ -44,6 +45,7 @@
>>> #define TIM7_TRGO "tim7_trgo"
>>>
>>> #define TIM8_TRGO "tim8_trgo"
>>> +#define TIM8_TRGO2 "tim8_trgo2"
>>> #define TIM8_CH1 "tim8_ch1"
>>> #define TIM8_CH2 "tim8_ch2"
>>> #define TIM8_CH3 "tim8_ch3"
>>> diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
>>> index 4a0abbc..ce7346e 100644
>>> --- a/include/linux/mfd/stm32-timers.h
>>> +++ b/include/linux/mfd/stm32-timers.h
>>> @@ -34,6 +34,7 @@
>>> #define TIM_CR1_DIR BIT(4) /* Counter Direction */
>>> #define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */
>>> #define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
>>> +#define TIM_CR2_MMS2 GENMASK(23, 20) /* Master mode selection 2 */
>>> #define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
>>> #define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
>>> #define TIM_DIER_UIE BIT(0) /* Update interrupt */
>>> @@ -60,6 +61,7 @@
>>>
>>> #define MAX_TIM_PSC 0xFFFF
>>> #define TIM_CR2_MMS_SHIFT 4
>>> +#define TIM_CR2_MMS2_SHIFT 20
>>> #define TIM_SMCR_TS_SHIFT 4
>>> #define TIM_BDTR_BKF_MASK 0xF
>>> #define TIM_BDTR_BKF_SHIFT 16
>>> --
>>> 1.9.1
>>>
>>
>> Acked-by: Benjamin Gaiganrd <benjamin.gaignard@linaro.org>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
^ permalink raw reply
* arm64: next-20170428 hangs on boot
From: Mark Rutland @ 2017-04-28 14:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428132429.c3dlxbmt7iqs2isl@yury-N73SV>
On Fri, Apr 28, 2017 at 04:24:29PM +0300, Yury Norov wrote:
> Hi all,
Hi,
[adding Dave Miller, netdev, lkml]
> On QEMU the next-20170428 hangs on boot for me due to kernel panic in
> rtnetlink_init():
>
> void __init rtnetlink_init(void)
> {
> if (register_pernet_subsys(&rtnetlink_net_ops))
> panic("rtnetlink_init: cannot initialize rtnetlink\n");
>
> ...
> }
I see the same thing with a next-20170428 arm64 defconfig, on a Juno R1
system:
[ 0.531949] Kernel panic - not syncing: rtnetlink_init: cannot initialize rtnetlink
[ 0.531949]
[ 0.541271] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.11.0-rc8-next-20170428-00002-g6ee3799 #10
[ 0.550307] Hardware name: ARM Juno development board (r1) (DT)
[ 0.556332] Call trace:
[ 0.558833] [<ffff000008088538>] dump_backtrace+0x0/0x238
[ 0.564332] [<ffff000008088834>] show_stack+0x14/0x20
[ 0.569477] [<ffff00000839dd54>] dump_stack+0x9c/0xc0
[ 0.574622] [<ffff000008175344>] panic+0x11c/0x28c
[ 0.579505] [<ffff000008d80034>] rtnetlink_init+0x2c/0x1d0
[ 0.585092] [<ffff000008d8047c>] netlink_proto_init+0x14c/0x17c
[ 0.591119] [<ffff000008083150>] do_one_initcall+0x38/0x120
[ 0.596796] [<ffff000008d30d00>] kernel_init_freeable+0x1a0/0x240
[ 0.603003] [<ffff00000892a790>] kernel_init+0x10/0x100
[ 0.608324] [<ffff000008082ec0>] ret_from_fork+0x10/0x50
[ 0.613736] SMP: stopping secondary CPUs
[ 0.617738] ---[ end Kernel panic - not syncing: rtnetlink_init: cannot initialize rtnetlink
If this isn't a known issue, it would be worth trying to bisect this.
Thanks,
Mark.
> The backtrace is:
> #0 arch_counter_get_cntvct () at ./arch/arm64/include/asm/arch_timer.h:160
> #1 __delay (cycles=62500) at arch/arm64/lib/delay.c:31
> #2 0xffff00000838a430 in __const_udelay (xloops=<optimized out>) at arch/arm64/lib/delay.c:41
> #3 0xffff000008165eac in panic (fmt=<optimized out>) at kernel/panic.c:297
> #4 0xffff000008b5b9c8 in rtnetlink_init () at net/core/rtnetlink.c:4196
> #5 0xffff000008b5be08 in netlink_proto_init () at net/netlink/af_netlink.c:2730
> #6 0xffff000008083158 in do_one_initcall (fn=0xffff000008b5bcc4 <netlink_proto_init>) at init/main.c:795
> #7 0xffff000008b20d04 in do_initcall_level (level=<optimized out>) at init/main.c:861
> #8 do_initcalls () at init/main.c:869
> #9 do_basic_setup () at init/main.c:887
> #10 kernel_init_freeable () at init/main.c:1039
> #11 0xffff000008817bb0 in kernel_init (unused=<optimized out>) at init/main.c:962
> #12 0xffff000008082ec0 in ret_from_fork () at arch/arm64/kernel/entry.S:789
> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>
> next-20170426 is OK though.
>
> Yury
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2] arm64: Add ASM modifier for xN register operands
From: Will Deacon @ 2017-04-28 14:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8h46WS4dq9ge4VnmBTvo5L9RJYUSYXnVpJf+G+av6+dg@mail.gmail.com>
On Fri, Apr 28, 2017 at 03:43:56PM +0100, Ard Biesheuvel wrote:
> On 28 April 2017 at 15:33, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Fri, Apr 28, 2017 at 08:18:52AM +0100, Ard Biesheuvel wrote:
> OK, good. That is a departure from previous behavior of Clang, which
> was causing build errors before due to the fact that msr/mrs
> instructions involving 32-bit values must still use x registers.
>
> > * If an operand type is 64 bits in size, clang will not produce a warning
> > regarding the operand size.
> >
> > * If an x or w modifier is used, clang will not produce a warning
> > regarding the operand size, regardless of whether it matches the
> > register size. Clang is happy for %wN to be used on a pointer type.
> >
> > * If an operand type is less than 64 bits in size, and neither an x or
> > w modifier is used, clang will produce a warning as above.
> >
> > * If an operand type is greater than 64 bits in size, clang encounters
> > an internal error.
> >
> > Given that, I think we *should not* use the x modifier to suppress this
> > warning, as I think for those cases we have a potential bug as outlined
> > in my prior reply.
> >
> > Instead, we should use a temporary 64-bit variable (or cast input
> > operands to 64-bit), which avoids that and makes clang happy.
> >
>
> Yes, I think that makes sense.
Likewise, we could even raise a feature request against GCC because these
warnings actually sound useful. Thanks for getting to the bottom of this.
Will
^ permalink raw reply
* [PATCH v5 1/4] printk/nmi: generic solution for safe printk in NMI
From: Steven Rostedt @ 2017-04-28 14:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428135810.gljrbuwgrypu5jkn@hirez.programming.kicks-ass.net>
On Fri, 28 Apr 2017 15:58:10 +0200
Peter Zijlstra <peterz@infradead.org> wrote:
> On Fri, Apr 28, 2017 at 03:44:23PM +0200, Petr Mladek wrote:
> > On Fri 2017-04-28 11:02:26, Peter Zijlstra wrote:
> > > On Thu, Apr 27, 2017 at 03:38:19PM +0200, Petr Mladek wrote:
> > > > Also we need to look for alternatives. There is a chance
> > > > to create crashdump and get the ftrace messages from it.
> > > > Also this might be scenario when we might need to suggest
> > > > the early_printk() patchset from Peter Zijlstra.
> > >
> > > I'd be happy to repost those. I still carry them in my tree.
> >
> > You do not need to if they are still the same as
> > https://lkml.kernel.org/r/20161018170830.405990950 at infradead.org
>
> More or less, I think I fixed an intermediate compile fail reported by
> you and the 0-day thing and I wrote a few comments in the last patch.
>
> They live here fwiw:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/peterz/queue.git debug/tmp
>
> > I rather do not promise anything but I would like to look at them
> > within next few weeks (after the merge window).
>
> Sure, I'll post them again during/after the merge window.
BTW, this is what I ended up using to get the debug information I
needed.
-- Steve
^ permalink raw reply
* [PATCH v2] arm64: Add ASM modifier for xN register operands
From: Ard Biesheuvel @ 2017-04-28 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428143333.GA5292@leverpostej>
On 28 April 2017 at 15:33, Mark Rutland <mark.rutland@arm.com> wrote:
> On Fri, Apr 28, 2017 at 08:18:52AM +0100, Ard Biesheuvel wrote:
>> On 27 April 2017 at 23:52, Matthias Kaehlcke <mka@chromium.org> wrote:
>> > El Thu, Apr 27, 2017 at 12:02:56PM +0100 Mark Rutland ha dit:
>> >> On Wed, Apr 26, 2017 at 02:46:16PM -0700, Matthias Kaehlcke wrote:
>> >> > Many inline assembly statements don't include the 'x' modifier when
>> >> > using xN registers as operands. This is perfectly valid, however it
>> >> > causes clang to raise warnings like this:
>> >> >
>> >> > warning: value size does not match register size specified by the
>> >> > constraint and modifier [-Wasm-operand-widths]
>
> [...]
>
>> >> > - asm volatile("strb %w0, [%1]" : : "rZ" (val), "r" (addr));
>> >> > + asm volatile("strb %w0, [%x1]" : : "rZ" (val), "r" (addr));
>> >>
>> >> In general, the '[%xN]' pattern looks *very* suspicious to me. Any
>> >> address must be 64-bit, so this would mask a legitimate warning.
>> >>
>> >> Given the prototype of this function the code if fine either way, but
>> >> were we to refactor things (e.g. making this a macro), that might not be
>> >> true.
>> >>
>> >> ... so I'm not sure it make sense to alter instances used for addresses.
>> >
>> > Good point, I'll leave instances dealing with addresses untouched for now.
>> >
>>
>> OK, I am confused now. We started this thread under the assumption
>> that all unqualified placeholders are warned about by Clang. Given
>> that this appears not to be the case, could we please first find out
>> what causes the warnings? Is it necessary at all to add the x
>> modifiers for 64-bit types?
>
> FWIW, I grabbed a clang 4.0.0 binary and had a play.
>
> It looks like clang only warns when an operand is less than 64 bits
> wide, and there is no 'x' or 'w' modifier. Pointers a 64 bits wide, so
> never produce a warning.
>
> As far as I can tell, applying to both integers and pointers:
>
> * GCC and clang always treat %N as meaning xN for an r constraint, and
> you need to use %wN to get wN.
>
OK, good. That is a departure from previous behavior of Clang, which
was causing build errors before due to the fact that msr/mrs
instructions involving 32-bit values must still use x registers.
> * If an operand type is 64 bits in size, clang will not produce a warning
> regarding the operand size.
>
> * If an x or w modifier is used, clang will not produce a warning
> regarding the operand size, regardless of whether it matches the
> register size. Clang is happy for %wN to be used on a pointer type.
>
> * If an operand type is less than 64 bits in size, and neither an x or
> w modifier is used, clang will produce a warning as above.
>
> * If an operand type is greater than 64 bits in size, clang encounters
> an internal error.
>
> Given that, I think we *should not* use the x modifier to suppress this
> warning, as I think for those cases we have a potential bug as outlined
> in my prior reply.
>
> Instead, we should use a temporary 64-bit variable (or cast input
> operands to 64-bit), which avoids that and makes clang happy.
>
Yes, I think that makes sense.
> I've included my test below. Note that clang will produce other errors for
> invalid asm (e.g. for mov w0, x0).
>
> Thanks,
> Mark.
>
> ---->8----
> #define TEST(t, w1, w2) \
> t foo_##t##w1##_##w2(t a, t b) \
> { \
> asm ( \
> "mov %" #w1 "0, %" #w2 "1" \
> : "=r" (a) : "r" (b) \
> ); \
> \
> return a; \
> }
>
> #define TEST_TYPE(t) \
> TEST(t, , ) \
> TEST(t, w, ) \
> TEST(t, w, w) \
> TEST(t, w, x) \
> TEST(t, x, ) \
> TEST(t, x, w) \
> TEST(t, x, x) \
>
> TEST_TYPE(int)
>
> TEST_TYPE(long)
>
> typedef long * longp;
> TEST_TYPE(longp)
>
> TEST_TYPE(__int128)
^ permalink raw reply
* [PATCH v2] arm64: Add ASM modifier for xN register operands
From: Mark Rutland @ 2017-04-28 14:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu9s2t+Nt7JCcTxkr5BYSN05f_zxYkKzfrD-4owWQLvF_Q@mail.gmail.com>
On Fri, Apr 28, 2017 at 08:18:52AM +0100, Ard Biesheuvel wrote:
> On 27 April 2017 at 23:52, Matthias Kaehlcke <mka@chromium.org> wrote:
> > El Thu, Apr 27, 2017 at 12:02:56PM +0100 Mark Rutland ha dit:
> >> On Wed, Apr 26, 2017 at 02:46:16PM -0700, Matthias Kaehlcke wrote:
> >> > Many inline assembly statements don't include the 'x' modifier when
> >> > using xN registers as operands. This is perfectly valid, however it
> >> > causes clang to raise warnings like this:
> >> >
> >> > warning: value size does not match register size specified by the
> >> > constraint and modifier [-Wasm-operand-widths]
[...]
> >> > - asm volatile("strb %w0, [%1]" : : "rZ" (val), "r" (addr));
> >> > + asm volatile("strb %w0, [%x1]" : : "rZ" (val), "r" (addr));
> >>
> >> In general, the '[%xN]' pattern looks *very* suspicious to me. Any
> >> address must be 64-bit, so this would mask a legitimate warning.
> >>
> >> Given the prototype of this function the code if fine either way, but
> >> were we to refactor things (e.g. making this a macro), that might not be
> >> true.
> >>
> >> ... so I'm not sure it make sense to alter instances used for addresses.
> >
> > Good point, I'll leave instances dealing with addresses untouched for now.
> >
>
> OK, I am confused now. We started this thread under the assumption
> that all unqualified placeholders are warned about by Clang. Given
> that this appears not to be the case, could we please first find out
> what causes the warnings? Is it necessary at all to add the x
> modifiers for 64-bit types?
FWIW, I grabbed a clang 4.0.0 binary and had a play.
It looks like clang only warns when an operand is less than 64 bits
wide, and there is no 'x' or 'w' modifier. Pointers a 64 bits wide, so
never produce a warning.
As far as I can tell, applying to both integers and pointers:
* GCC and clang always treat %N as meaning xN for an r constraint, and
you need to use %wN to get wN.
* If an operand type is 64 bits in size, clang will not produce a warning
regarding the operand size.
* If an x or w modifier is used, clang will not produce a warning
regarding the operand size, regardless of whether it matches the
register size. Clang is happy for %wN to be used on a pointer type.
* If an operand type is less than 64 bits in size, and neither an x or
w modifier is used, clang will produce a warning as above.
* If an operand type is greater than 64 bits in size, clang encounters
an internal error.
Given that, I think we *should not* use the x modifier to suppress this
warning, as I think for those cases we have a potential bug as outlined
in my prior reply.
Instead, we should use a temporary 64-bit variable (or cast input
operands to 64-bit), which avoids that and makes clang happy.
I've included my test below. Note that clang will produce other errors for
invalid asm (e.g. for mov w0, x0).
Thanks,
Mark.
---->8----
#define TEST(t, w1, w2) \
t foo_##t##w1##_##w2(t a, t b) \
{ \
asm ( \
"mov %" #w1 "0, %" #w2 "1" \
: "=r" (a) : "r" (b) \
); \
\
return a; \
}
#define TEST_TYPE(t) \
TEST(t, , ) \
TEST(t, w, ) \
TEST(t, w, w) \
TEST(t, w, x) \
TEST(t, x, ) \
TEST(t, x, w) \
TEST(t, x, x) \
TEST_TYPE(int)
TEST_TYPE(long)
typedef long * longp;
TEST_TYPE(longp)
TEST_TYPE(__int128)
^ permalink raw reply
* [PATCH 1/8] [RFC] dt-bindings: renesas: Document R-Car H3 and M3-W SiP DT bindings
From: Geert Uytterhoeven @ 2017-04-28 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428133923.ycbqixcxvcsonocn@rob-hp-laptop>
Hi Rob,
On Fri, Apr 28, 2017 at 3:39 PM, Rob Herring <robh@kernel.org> wrote:
> On Wed, Apr 19, 2017 at 11:15:44AM +0200, Geert Uytterhoeven wrote:
>> Document the SiP ("System-in-Package") versions of the R-Car H3 and M3-W
>> SoCs, which contain an R-Car H3 or M3-W SoC, RAM, and HyperFlash.
>>
>> Add their compatible values to all boards equipped with R-Car Gen3 SiPs.
>>
>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>> ---
>> Questions:
>> - Do we need more compatible values, for different configurations?
>> At least r8j7796 is available with either 2 GiB or 4 GiB of RAM,
>> possibly using RAM parts from different vendors.
>
> Same die, just a different package? If so, I don't think you need a
> different compatible. It's going to be a different board from any
> non-SiP which should be enough to distinguish.
An SiP is more like a CPU daughterboard.
The different SiP-versions based on r8a7795 contain the same r8a7795 SoC die,
but different amounts of RAM, i.e. different RAM dies.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 2/2] arm64: pmu: Wire-up L2 cache events for ARMv8 PMUv3
From: Will Deacon @ 2017-04-28 14:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428141500.GE6368@e104818-lin.cambridge.arm.com>
On Fri, Apr 28, 2017 at 03:15:01PM +0100, Catalin Marinas wrote:
> On Thu, Apr 27, 2017 at 06:36:42PM +0100, Will Deacon wrote:
> > On Tue, Apr 25, 2017 at 10:13:51AM -0700, Florian Fainelli wrote:
> > > On 04/25/2017 05:44 AM, Will Deacon wrote:
> > > > On Thu, Apr 20, 2017 at 12:05:46PM -0700, Florian Fainelli wrote:
> > > >> The ARMv8 PMUv3 cache map did not include the L2 cache events, add
> > > >> them.
> > > >>
> > > >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> > > >> ---
> > > >> arch/arm64/kernel/perf_event.c | 5 +++++
> > > >> 1 file changed, 5 insertions(+)
> > > >>
> > > >> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > > >> index 4f011cdd756d..a664c575f3fd 100644
> > > >> --- a/arch/arm64/kernel/perf_event.c
> > > >> +++ b/arch/arm64/kernel/perf_event.c
> > > >> @@ -264,6 +264,11 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
> > > >> [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE,
> > > >> [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL,
> > > >>
> > > >> + [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE,
> > > >> + [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL,
> > > >> + [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE,
> > > >> + [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL,
> > > >
> > > > I don't think this is correct in general. 'LL' stands for "last-level",
> > > > which may be L3 or even a system cache in the interconnect. Tying that to L2
> > > > is the wrong thing to do from perf's generic event perspective.
> > > >
> > > > I'm ok with what you're proposing for A53 (where the PMU can only count
> > > > events out to the L2), but I'm reluctant to make this change for the generic
> > > > PMUv3 events.
> > >
> > > That makes sense, shall I resubmit the first patch by itself or can you
> > > or Catalin take it as-is?
> >
> > I'll talk to Catalin tomorrow and try to get the A53 bit queued.
>
> I queued patch 1/2. Shall I add your ack?
Yes, please.
Will
^ permalink raw reply
* [PATCH v5 1/4] printk/nmi: generic solution for safe printk in NMI
From: Steven Rostedt @ 2017-04-28 14:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428125725.GA3452@pathway.suse.cz>
On Fri, 28 Apr 2017 14:57:25 +0200
Petr Mladek <pmladek@suse.com> wrote:
> Of course, if the problem is reproducible, the easiest solution
> is to use bigger main log buffer, for example boot with
> log_buf_len=32M.
Of course that may not be enough. Especially when I have a machine with
240 CPUs. But it also has a ton of RAM, I could easily do
log_buf_len=32G
-- Steve
^ permalink raw reply
* [PATCH 2/2] arm64: pmu: Wire-up L2 cache events for ARMv8 PMUv3
From: Catalin Marinas @ 2017-04-28 14:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170427173642.GM1890@arm.com>
On Thu, Apr 27, 2017 at 06:36:42PM +0100, Will Deacon wrote:
> On Tue, Apr 25, 2017 at 10:13:51AM -0700, Florian Fainelli wrote:
> > On 04/25/2017 05:44 AM, Will Deacon wrote:
> > > On Thu, Apr 20, 2017 at 12:05:46PM -0700, Florian Fainelli wrote:
> > >> The ARMv8 PMUv3 cache map did not include the L2 cache events, add
> > >> them.
> > >>
> > >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> > >> ---
> > >> arch/arm64/kernel/perf_event.c | 5 +++++
> > >> 1 file changed, 5 insertions(+)
> > >>
> > >> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > >> index 4f011cdd756d..a664c575f3fd 100644
> > >> --- a/arch/arm64/kernel/perf_event.c
> > >> +++ b/arch/arm64/kernel/perf_event.c
> > >> @@ -264,6 +264,11 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
> > >> [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE,
> > >> [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL,
> > >>
> > >> + [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE,
> > >> + [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL,
> > >> + [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE,
> > >> + [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL,
> > >
> > > I don't think this is correct in general. 'LL' stands for "last-level",
> > > which may be L3 or even a system cache in the interconnect. Tying that to L2
> > > is the wrong thing to do from perf's generic event perspective.
> > >
> > > I'm ok with what you're proposing for A53 (where the PMU can only count
> > > events out to the L2), but I'm reluctant to make this change for the generic
> > > PMUv3 events.
> >
> > That makes sense, shall I resubmit the first patch by itself or can you
> > or Catalin take it as-is?
>
> I'll talk to Catalin tomorrow and try to get the A53 bit queued.
I queued patch 1/2. Shall I add your ack?
--
Catalin
^ permalink raw reply
* [PATCH v5 1/1] pinctrl: armada-37xx: Add irqchip support
From: Gregory CLEMENT @ 2017-04-28 14:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.5e6e6649efd7d0482a5df17fb7f94fde29a54210.1493387770.git-series.gregory.clement@free-electrons.com>
The Armada 37xx SoCs can handle interrupt through GPIO. However it can
only manage the edge ones.
The way the interrupt are managed is classical so we can use the generic
interrupt chip model.
The only unusual "feature" is that many interrupts are connected to the
parent interrupt controller. But we do not take advantage of this and use
the chained irq with all of them.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 229 +++++++++++++++++++++-
1 file changed, 229 insertions(+)
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index 5c96f5558310..001542f68627 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -13,7 +13,9 @@
#include <linux/gpio/driver.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
@@ -30,6 +32,11 @@
#define OUTPUT_CTL 0x20
#define SELECTION 0x30
+#define IRQ_EN 0x0
+#define IRQ_POL 0x08
+#define IRQ_STATUS 0x10
+#define IRQ_WKUP 0x18
+
#define NB_FUNCS 2
#define GPIO_PER_REG 32
@@ -75,9 +82,12 @@ struct armada_37xx_pmx_func {
struct armada_37xx_pinctrl {
struct regmap *regmap;
+ void __iomem *base;
const struct armada_37xx_pin_data *data;
struct device *dev;
struct gpio_chip gpio_chip;
+ struct irq_chip irq_chip;
+ spinlock_t irq_lock;
struct pinctrl_desc pctl;
struct pinctrl_dev *pctl_dev;
struct armada_37xx_pin_group *groups;
@@ -346,6 +356,14 @@ static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
return armada_37xx_pmx_set_by_name(pctldev, name, grp);
}
+static inline void armada_37xx_irq_update_reg(unsigned int *reg,
+ struct irq_data *d)
+{
+ int offset = irqd_to_hwirq(d);
+
+ armada_37xx_update_reg(reg, offset);
+}
+
static int armada_37xx_gpio_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
@@ -468,6 +486,214 @@ static const struct gpio_chip armada_37xx_gpiolib_chip = {
.owner = THIS_MODULE,
};
+static void armada_37xx_irq_ack(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
+ u32 reg = IRQ_STATUS;
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+ spin_lock_irqsave(&info->irq_lock, flags);
+ writel(d->mask, info->base + reg);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+}
+
+static void armada_37xx_irq_mask(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
+ u32 val, reg = IRQ_EN;
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+ spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ writel(val & ~d->mask, info->base + reg);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+}
+
+static void armada_37xx_irq_unmask(struct irq_data *d)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
+ u32 val, reg = IRQ_EN;
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+ spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ writel(val | d->mask, info->base + reg);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+}
+
+static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
+ u32 val, reg = IRQ_WKUP;
+ unsigned long flags;
+
+ armada_37xx_irq_update_reg(®, d);
+ spin_lock_irqsave(&info->irq_lock, flags);
+ val = readl(info->base + reg);
+ if (on)
+ val |= d->mask;
+ else
+ val &= ~d->mask;
+ writel(val, info->base + reg);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+
+ return 0;
+}
+
+static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+ struct armada_37xx_pinctrl *info = gpiochip_get_data(chip);
+ u32 val, reg = IRQ_POL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&info->irq_lock, flags);
+ armada_37xx_irq_update_reg(®, d);
+ val = readl(info->base + reg);
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ val &= ~d->mask;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ val |= d->mask;
+ break;
+ default:
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+ return -EINVAL;
+ }
+ writel(val, info->base + reg);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+
+ return 0;
+}
+
+
+static void armada_37xx_irq_handler(struct irq_desc *desc)
+{
+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct armada_37xx_pinctrl *info = gpiochip_get_data(gc);
+ struct irq_domain *d = gc->irqdomain;
+ int i;
+
+ chained_irq_enter(chip, desc);
+ for (i = 0; i <= d->revmap_size / GPIO_PER_REG; i++) {
+ u32 status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&info->irq_lock, flags);
+ status = readl_relaxed(info->base + IRQ_STATUS + 4 * i);
+ /* Manage only the interrupt that was enabled */
+ status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+ while (status) {
+ u32 hwirq = ffs(status) - 1;
+ u32 virq = irq_find_mapping(d, hwirq +
+ i * GPIO_PER_REG);
+
+ generic_handle_irq(virq);
+
+ /* Update status in case a new IRQ appears */
+ spin_lock_irqsave(&info->irq_lock, flags);
+ status = readl_relaxed(info->base +
+ IRQ_STATUS + 4 * i);
+ /* Manage only the interrupt that was enabled */
+ status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
+ spin_unlock_irqrestore(&info->irq_lock, flags);
+ }
+ }
+ chained_irq_exit(chip, desc);
+}
+
+static int armada_37xx_irqchip_register(struct platform_device *pdev,
+ struct armada_37xx_pinctrl *info)
+{
+ struct device_node *np = info->dev->of_node;
+ int nrirqs = info->data->nr_pins;
+ struct gpio_chip *gc = &info->gpio_chip;
+ struct irq_chip *irqchip = &info->irq_chip;
+ struct resource res;
+ int ret = -ENODEV, i, nr_irq_parent;
+
+ /* Check if we have at least one gpio-controller child node */
+ for_each_child_of_node(info->dev->of_node, np) {
+ if (of_property_read_bool(np, "gpio-controller")) {
+ ret = 0;
+ break;
+ }
+ };
+ if (ret)
+ return ret;
+
+ nr_irq_parent = of_irq_count(np);
+ spin_lock_init(&info->irq_lock);
+
+ if (!nr_irq_parent) {
+ dev_err(&pdev->dev, "Invalid or no IRQ\n");
+ return 0;
+ }
+
+ if (of_address_to_resource(info->dev->of_node, 1, &res)) {
+ dev_err(info->dev, "cannot find IO resource\n");
+ return -ENOENT;
+ }
+
+ info->base = devm_ioremap_resource(info->dev, &res);
+ if (IS_ERR(info->base))
+ return PTR_ERR(info->base);
+
+ irqchip->irq_ack = armada_37xx_irq_ack;
+ irqchip->irq_mask = armada_37xx_irq_mask;
+ irqchip->irq_unmask = armada_37xx_irq_unmask;
+ irqchip->irq_set_wake = armada_37xx_irq_set_wake;
+ irqchip->irq_set_type = armada_37xx_irq_set_type;
+ irqchip->name = info->data->name;
+
+ ret = gpiochip_irqchip_add(gc, irqchip, 0,
+ handle_edge_irq, IRQ_TYPE_NONE);
+ if (ret) {
+ dev_info(&pdev->dev, "could not add irqchip\n");
+ return ret;
+ }
+
+ /*
+ * Many interrupts are connected to the parent interrupt
+ * controller. But we do not take advantage of this and use
+ * the chained irq with all of them.
+ */
+ for (i = 0; i < nrirqs; i++) {
+ struct irq_data *d = irq_get_irq_data(gc->irq_base + i);
+
+ /*
+ * The mask field is a "precomputed bitmask for
+ * accessing the chip registers" which was introduced
+ * for the generic irqchip framework. As we don't use
+ * this framework, we can reuse this field for our own
+ * usage.
+ */
+ d->mask = BIT(i % GPIO_PER_REG);
+ }
+
+ for (i = 0; i < nr_irq_parent; i++) {
+ int irq = irq_of_parse_and_map(np, i);
+
+ if (irq < 0)
+ continue;
+
+ gpiochip_set_chained_irqchip(gc, irqchip, irq,
+ armada_37xx_irq_handler);
+ }
+
+ return 0;
+}
+
static int armada_37xx_gpiochip_register(struct platform_device *pdev,
struct armada_37xx_pinctrl *info)
{
@@ -496,6 +722,9 @@ static int armada_37xx_gpiochip_register(struct platform_device *pdev,
ret = devm_gpiochip_add_data(&pdev->dev, gc, info);
if (ret)
return ret;
+ ret = armada_37xx_irqchip_register(pdev, info);
+ if (ret)
+ return ret;
return 0;
}
--
git-series 0.9.1
^ permalink raw reply related
* [PATCH v5 0/1] Add support for pinctrl/gpio on Armada 37xx
From: Gregory CLEMENT @ 2017-04-28 14:01 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This fifth version contain only one patch all the other ones have been
applied on the pinctrl or the mvebu trees.
For the record, this series adds support for the pin and gpio
controllers present on the Armada 37xx SoCs.
Each Armada 37xx SoC comes with 2 pin controllers: one on the south
bridge (managing 28 pins) and one on the north bridge (managing 36 pins).
At the hardware level the controller configure the pins by group and not
pin by pin.
The gpio controller is also capable to handle interrupt from gpio.
Changelog
v4 -> v5
- Removed all the patches already applied
- Rebased on linux-next
- Applied binding changes asked by Rob by removing the -nb and -sb part
- Use d->mask directly directly when possible
- Add comment about the check on gpio-controller child node
- Use of_property_read_bool() instead of of_find_property()
- Declared the armada_37xx_irq_*() functions as static
- check status register for each iteration inside the irq handler
v3 -> v4
- Some group are configured by several bits in the register:
extend the armada_37xx_pin_group struct to manage it.
- Fix the uart2 and cspi2/3 configuration
- Document the armada_37xx_add_function(), armada_37xx_fill_group()
and armada_37xx_fill_funcs().
- Use devm_gpiochip_add_data()
- Use irq_find_mapping instead of irq_linear_revmap
- Use handle_edge_irq instead of the wrong handle_level_irq
- Add comment about the fact the we have multiple parent interrupt
- Add comment about the mask usage of the irq_data struct
- Use BIT() macro when possible
- Select more CONFIG symbol needed for GPIO and interrupt support
v2 -> v3
- use gpio-ranges (patch 4)
- Document gpio-ranges usage (patch 1)
- do not use anymore a global pin index (patch 3)
v1 -> v2:
- Update binding documentation making clear that mfd and syscon must
be used (patch 1).
- Split the fist patch adding pin controller support for Armada 37xx
in arm64 part (for kconfig) and pinctrl part (patch 2 and 3)
- Add MFD_SYSCON dependency (patch 3)
- Add kerneldoc for the armada_37xx_pin_group struct (patch 3)
- Rename _add_function() to armada_37xx_add_function() (patch 3)
- Use an inline function to update the reg offset (patch 4)
- Rename gpiolib_register to gpiochip_register (patch 4)
- Add a comment about the two registers limit (patch 4)
- Add explicit gpio node in the device tree (patch 4)
- Convert the driver to use GPIOLIB_IRQCHIP (patch 5)
- Add a critical section when accessing the hardware registers (patch 5)
- Use the gpio subnode (patch 5)
Thanks,
Gregory
Gregory CLEMENT (1):
pinctrl: armada-37xx: Add irqchip support
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 229 +++++++++++++++++++++-
1 file changed, 229 insertions(+)
base-commit: 5ae46f24f9b42187beeb512a5203126789cc791b
--
git-series 0.9.1
^ permalink raw reply
* [PATCH v5 1/4] printk/nmi: generic solution for safe printk in NMI
From: Peter Zijlstra @ 2017-04-28 13:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428134423.GB3452@pathway.suse.cz>
On Fri, Apr 28, 2017 at 03:44:23PM +0200, Petr Mladek wrote:
> On Fri 2017-04-28 11:02:26, Peter Zijlstra wrote:
> > On Thu, Apr 27, 2017 at 03:38:19PM +0200, Petr Mladek wrote:
> > > Also we need to look for alternatives. There is a chance
> > > to create crashdump and get the ftrace messages from it.
> > > Also this might be scenario when we might need to suggest
> > > the early_printk() patchset from Peter Zijlstra.
> >
> > I'd be happy to repost those. I still carry them in my tree.
>
> You do not need to if they are still the same as
> https://lkml.kernel.org/r/20161018170830.405990950 at infradead.org
More or less, I think I fixed an intermediate compile fail reported by
you and the 0-day thing and I wrote a few comments in the last patch.
They live here fwiw:
git://git.kernel.org/pub/scm/linux/kernel/git/peterz/queue.git debug/tmp
> I rather do not promise anything but I would like to look at them
> within next few weeks (after the merge window).
Sure, I'll post them again during/after the merge window.
^ permalink raw reply
* [PATCH v2 1/9] dt-bindings: display: sun4i: Add component endpoint ID numbering scheme
From: Rob Herring @ 2017-04-28 13:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170421083857.29636-2-wens@csie.org>
On Fri, Apr 21, 2017 at 04:38:49PM +0800, Chen-Yu Tsai wrote:
> The Allwinner display pipeline contains many hardware components, some
> of which can consume data from one of multiple upstream components.
> The numbering scheme of these components must be encoded into the device
> tree so the driver can figure out which component out of two or more of
> the same type it is supposed to use or program.
>
> This patch adds the constraint that local endpoint IDs must be the index
> or number of the remote endpoint's hardware block, for all components
> in the display pipeline up to the TCONs.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> index 57a8d0610062..7acdbf14ae1c 100644
> --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
> @@ -4,6 +4,16 @@ Allwinner A10 Display Pipeline
> The Allwinner A10 Display pipeline is composed of several components
> that are going to be documented below:
>
> +For the input port of all components up to the TCON in the display
> +pipeline, if there are multiple components, the local endpoint IDs
> +must correspond to the index of the upstream block. For example, if
> +the remote endpoint is Frontend 1, then the local endpoint ID must
> +be 1.
> +
> +Conversely, for the output ports of the same group, the remote endpoint
> +ID must be the index of the local hardware block. If the local backend
> +is backend 1, then the remote endpoint ID must be 1.
It would be clearer if you just explicitly listed IDs and their
connections. From how this is worded, it would not work if you had
connections like this:
DevA 0
DevA 1
DevB 0
DevB 1
These would need to be endpoints 0-3 in TCON, and that doesn't reflect
the remote devices' index.
Rob
^ permalink raw reply
* [PATCH v2] arm64: perf: Use only exclude_kernel attribute when kernel is running in HYP
From: Jayachandran C @ 2017-04-28 13:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170427173758.GN1890@arm.com>
On Thu, Apr 27, 2017 at 06:37:59PM +0100, Will Deacon wrote:
> On Wed, Apr 26, 2017 at 01:41:42PM +0000, Jayachandran C wrote:
> > On Wed, Apr 26, 2017 at 11:10:21AM +0100, Will Deacon wrote:
> > > On Wed, Apr 26, 2017 at 07:22:46AM +0000, Pinski, Andrew wrote:
> > > > On 4/25/2017 11:53 PM, Jayachandran C. wrote:
> > > > > On Tue, Apr 25, 2017 at 10:23 PM, Will Deacon <will.deacon@arm.com> wrote:
> > > > >> On Tue, Apr 25, 2017 at 09:13:40AM +0530, Ganapatrao Kulkarni wrote:
> > > > >>> On Mon, Apr 24, 2017 at 9:15 PM, Will Deacon <will.deacon@arm.com> wrote:
> > > > >>>> On Thu, Apr 20, 2017 at 02:56:50PM +0530, Ganapatrao Kulkarni wrote:
> > > > >>>>> OK, if you are ok with sysfs part, i can send next version with that
> > > > >>>>> change only?.
> > > > >>>> I think the sysfs part is still a little dodgy, since you still expose the
> > > > >>>> "exclude_hv" file with a value of 0 when not running at EL2, which would
> > > > >>>> imply that exclude_hv is forced to zero. I don't think that's correct.
> > > > >>> okay, i can make exclude_hv visible only when kernel booted in EL2.
> > > > >>> is it ok to have empty directory "attr" when kernel booted to EL1?
> > > > >>> attr can be place holder for any other miscellaneous attributes, that
> > > > >>> can be added in future.
> > > > >> Sounds good to me, although I'll seek comment from the other perf folks
> > > > >> before merging anything with ABI implications.
> > > > > Do you really think this is the solution given:
> > > > > - this is an arm64 specific sysfs interface that is tied to the perf API
> > >
> > > That's why I want feedback from others. The intention would be that this can
> > > be used by other PMUs as well, since it's not uncommon that parts of the
> > > sizeable perf_event_attr structure are not used by a given PMU.
> > >
> > > > > - the perf API documentation has to be updated for this
> > >
> > > So? If having to update documentation means we shouldn't change the kernel,
> > > then we may as well all find new jobs.
> > >
> > > > > - All the applications that use the perf API have to be modified to
> > > > > check this sysfs interface
> > > > > - If the application fails to do so, a very narrow corner case
> > > > > (exclude_hv != exclude_kernel and VHE enabled) fails.
> > >
> > > See below, but apparently people care about it.
> > >
> > > > > Any application that really cares can already do see if exclude_hv !=
> > > > > exclude_kernel case works by calling perf_open_event() with those
> > > > > options and checking the return value.
> > >
> > > That's a good point: there is *something* userspace can do, although that
> > > would be arm64-specific and doesn't really help with the state-space
> > > explosion you get with combinations of invalid/unused perf_event_attr
> > > fields.
> > >
> > > > An example of an application which needs to changed is HHVM. Currently
> > > > it sets exclude_hv to true but exclude_kernel to false as it does not
> > > > care about the hypervisor associated perf events associated with the
> > > > code, only the kernel and userspace associated evnts.
> > > > Yes we could submit a patch to use the sysfs interface to check but it
> > > > would look funny and the facebook folks might reject the patch as it is
> > > > ARM64 specific in generic code. Note this is how all of this discussion
> > > > started was HHVM's call to perf_open_event was failing.
> > >
> > > Hmm, if you're saying that HHVM won't be changed to use the sysfs stuff,
> > > then why are we bothering?
> > >
> > > Not sure where this leaves us.
> >
> > If my understanding is correct, the sysfs suggestion above is going to
> > add API complexity without solving the issue. Ignoring the exclude_hv if
> > it cannot be honored would be a better solution.
>
> Better for HHVM, sure, but I don't think it's better in general. It means
> that we silently do the opposite of what the user has requested in some
> configurations.
If my understanding is correct, when is_kernel_in_hyp_mode() is true,
the kernel is in EL2 and there is no real hypervisor with hvc calls
from kernel. Ignoring the exclude_hv would be correct.
When kernel is in EL1, it would be correct to consider exclude_hv to
skip events in EL2 (reached with hvc).
I don't see the issue, can you please give more detail on the config
with unexpected behavior?
JC.
^ permalink raw reply
* [PATCH v5 1/4] printk/nmi: generic solution for safe printk in NMI
From: Petr Mladek @ 2017-04-28 13:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170428090226.qqoe6qbewjeo57kd@hirez.programming.kicks-ass.net>
On Fri 2017-04-28 11:02:26, Peter Zijlstra wrote:
> On Thu, Apr 27, 2017 at 03:38:19PM +0200, Petr Mladek wrote:
> > Also we need to look for alternatives. There is a chance
> > to create crashdump and get the ftrace messages from it.
> > Also this might be scenario when we might need to suggest
> > the early_printk() patchset from Peter Zijlstra.
>
> I'd be happy to repost those. I still carry them in my tree.
You do not need to if they are still the same as
https://lkml.kernel.org/r/20161018170830.405990950 at infradead.org
I rather do not promise anything but I would like to look at them
within next few weeks (after the merge window).
Best Regards,
Petr
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox