Skip to content

Commit 93929fb

Browse files
committed
Merge branch 'asm-generic-mmiotrace' into asm-generic
A patch series from Sai Prakash Ranjan, who explains: Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors are typically used to read/write from/to memory mapped registers and can cause hangs or some undefined behaviour in following cases, * If the access to the register space is unclocked, for example: if there is an access to multimedia(MM) block registers without MM clocks. * If the register space is protected and not set to be accessible from non-secure world, for example: only EL3 (EL: Exception level) access is allowed and any EL2/EL1 access is forbidden. * If xPU(memory/register protection units) is controlling access to certain memory/register space for specific clients. and more... Such cases usually results in instant reboot/SErrors/NOC or interconnect hangs and tracing these register accesses can be very helpful to debug such issues during initial development stages and also in later stages. So use ftrace trace events to log such MMIO register accesses which provides rich feature set such as early enablement of trace events, filtering capability, dumping ftrace logs on console and many more. Sample output: rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700 rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700 rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610 rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610 This series is a follow-up for the series [1] and a recent series [2] making use of both. [1] https://lore.kernel.org/lkml/cover.1536430404.git.saiprakash.ranjan@codeaurora.org/ [2] https://lore.kernel.org/lkml/1604631386-178312-1-git-send-email-psodagud@codeaurora.org/ Note in v4 version, Arnd suggested to benchmark and compare size with callback based implementation, please see [3] for more details on that with brief comparison below. **Inline version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y** $ size vmlinux text data bss dec hex filename 23884219 14284468 532568 38701255 24e88c7 vmlinux **Callback version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y** $ size vmlinux text data bss dec hex filename 24108179 14279596 532568 38920343 251e097 vmlinux $ ./scripts/bloat-o-meter inline-vmlinux callback-vmlinux add/remove: 8/3 grow/shrink: 4889/89 up/down: 242244/-11564 (230680) Total: Before=25812612, After=26043292, chg +0.89% [3] https://lore.kernel.org/lkml/466449a1-36da-aaa9-7e4f-477f36b52c9e@quicinc.com/ Link: https://lore.kernel.org/lkml/cover.1652891705.git.quic_saipraka@quicinc.com/ * asm-generic-mmiotrace: soc: qcom: geni: Disable MMIO tracing for GENI SE serial: qcom_geni_serial: Disable MMIO tracing for geni serial asm-generic/io: Add logging support for MMIO accessors KVM: arm64: Add a flag to disable MMIO trace for nVHE KVM lib: Add register read/write tracing support drm/meson: Fix overflow implicit truncation warnings irqchip/tegra: Fix overflow implicit truncation warnings coresight: etm4x: Use asm-generic IO memory barriers arm64: io: Use asm-generic high level MMIO accessors arch/*: Disable softirq stacks on PREEMPT_RT.
2 parents b13bacc + 6f1de1d commit 93929fb

File tree

22 files changed

+303
-65
lines changed

22 files changed

+303
-65
lines changed

arch/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,9 @@ config ARCH_HAS_ELFCORE_COMPAT
13961396
config ARCH_HAS_PARANOID_L1D_FLUSH
13971397
bool
13981398

1399+
config ARCH_HAVE_TRACE_MMIO_ACCESS
1400+
bool
1401+
13991402
config DYNAMIC_SIGFRAME
14001403
bool
14011404

arch/arm/kernel/irq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static void __init init_irq_stacks(void)
7070
}
7171
}
7272

73+
#ifndef CONFIG_PREEMPT_RT
7374
static void ____do_softirq(void *arg)
7475
{
7576
__do_softirq();
@@ -80,7 +81,7 @@ void do_softirq_own_stack(void)
8081
call_with_stack(____do_softirq, NULL,
8182
__this_cpu_read(irq_stack_ptr));
8283
}
83-
84+
#endif
8485
#endif
8586

8687
int arch_show_interrupts(struct seq_file *p, int prec)

arch/arm64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ config ARM64
4949
select ARCH_HAS_ZONE_DMA_SET if EXPERT
5050
select ARCH_HAVE_ELF_PROT
5151
select ARCH_HAVE_NMI_SAFE_CMPXCHG
52+
select ARCH_HAVE_TRACE_MMIO_ACCESS
5253
select ARCH_INLINE_READ_LOCK if !PREEMPTION
5354
select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
5455
select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION

arch/arm64/include/asm/io.h

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
9191
}
9292

9393
/* IO barriers */
94-
#define __iormb(v) \
94+
#define __io_ar(v) \
9595
({ \
9696
unsigned long tmp; \
9797
\
@@ -108,39 +108,14 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
108108
: "memory"); \
109109
})
110110

111-
#define __io_par(v) __iormb(v)
112-
#define __iowmb() dma_wmb()
113-
#define __iomb() dma_mb()
114-
115-
/*
116-
* Relaxed I/O memory access primitives. These follow the Device memory
117-
* ordering rules but do not guarantee any ordering relative to Normal memory
118-
* accesses.
119-
*/
120-
#define readb_relaxed(c) ({ u8 __r = __raw_readb(c); __r; })
121-
#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
122-
#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
123-
#define readq_relaxed(c) ({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
111+
#define __io_bw() dma_wmb()
112+
#define __io_br(v)
113+
#define __io_aw(v)
124114

125-
#define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c)))
126-
#define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
127-
#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
128-
#define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
129-
130-
/*
131-
* I/O memory access primitives. Reads are ordered relative to any
132-
* following Normal memory access. Writes are ordered relative to any prior
133-
* Normal memory access.
134-
*/
135-
#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(__v); __v; })
136-
#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(__v); __v; })
137-
#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(__v); __v; })
138-
#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(__v); __v; })
139-
140-
#define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); })
141-
#define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); })
142-
#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); })
143-
#define writeq(v,c) ({ __iowmb(); writeq_relaxed((v),(c)); })
115+
/* arm64-specific, don't use in portable drivers */
116+
#define __iormb(v) __io_ar(v)
117+
#define __iowmb() __io_bw()
118+
#define __iomb() dma_mb()
144119

145120
/*
146121
* I/O port access primitives.

arch/arm64/kvm/hyp/nvhe/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
#
55

66
asflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
7-
ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
7+
8+
# Tracepoint and MMIO logging symbols should not be visible at nVHE KVM as
9+
# there is no way to execute them and any such MMIO access from nVHE KVM
10+
# will explode instantly (Words of Marc Zyngier). So introduce a generic flag
11+
# __DISABLE_TRACE_MMIO__ to disable MMIO tracing for nVHE KVM.
12+
ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS -D__DISABLE_TRACE_MMIO__
813

914
hostprogs := gen-hyprel
1015
HOST_EXTRACFLAGS += -I$(objtree)/include

arch/parisc/kernel/irq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,12 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
480480
*irq_stack_in_use = 1;
481481
}
482482

483+
#ifndef CONFIG_PREEMPT_RT
483484
void do_softirq_own_stack(void)
484485
{
485486
execute_on_irq_stack(__do_softirq, 0);
486487
}
488+
#endif
487489
#endif /* CONFIG_IRQSTACKS */
488490

489491
/* ONLY called from entry.S:intr_extint() */

arch/powerpc/kernel/irq.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ static inline void check_stack_overflow(void)
611611
}
612612
}
613613

614+
#ifndef CONFIG_PREEMPT_RT
614615
static __always_inline void call_do_softirq(const void *sp)
615616
{
616617
/* Temporarily switch r1 to sp, call __do_softirq() then restore r1. */
@@ -629,6 +630,7 @@ static __always_inline void call_do_softirq(const void *sp)
629630
"r11", "r12"
630631
);
631632
}
633+
#endif
632634

633635
static __always_inline void call_do_irq(struct pt_regs *regs, void *sp)
634636
{
@@ -747,10 +749,12 @@ void *mcheckirq_ctx[NR_CPUS] __read_mostly;
747749
void *softirq_ctx[NR_CPUS] __read_mostly;
748750
void *hardirq_ctx[NR_CPUS] __read_mostly;
749751

752+
#ifndef CONFIG_PREEMPT_RT
750753
void do_softirq_own_stack(void)
751754
{
752755
call_do_softirq(softirq_ctx[smp_processor_id()]);
753756
}
757+
#endif
754758

755759
irq_hw_number_t virq_to_hw(unsigned int virq)
756760
{

arch/s390/include/asm/softirq_stack.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
#include <asm/lowcore.h>
66
#include <asm/stacktrace.h>
77

8+
#ifndef CONFIG_PREEMPT_RT
89
static inline void do_softirq_own_stack(void)
910
{
1011
call_on_stack(0, S390_lowcore.async_stack, void, __do_softirq);
1112
}
12-
13+
#endif
1314
#endif /* __ASM_S390_SOFTIRQ_STACK_H */

arch/sh/kernel/irq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ void irq_ctx_exit(int cpu)
149149
hardirq_ctx[cpu] = NULL;
150150
}
151151

152+
#ifndef CONFIG_PREEMPT_RT
152153
void do_softirq_own_stack(void)
153154
{
154155
struct thread_info *curctx;
@@ -176,6 +177,7 @@ void do_softirq_own_stack(void)
176177
"r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
177178
);
178179
}
180+
#endif
179181
#else
180182
static inline void handle_one_irq(unsigned int irq)
181183
{

arch/sparc/kernel/irq_64.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs)
855855
set_irq_regs(old_regs);
856856
}
857857

858+
#ifndef CONFIG_PREEMPT_RT
858859
void do_softirq_own_stack(void)
859860
{
860861
void *orig_sp, *sp = softirq_stack[smp_processor_id()];
@@ -869,6 +870,7 @@ void do_softirq_own_stack(void)
869870
__asm__ __volatile__("mov %0, %%sp"
870871
: : "r" (orig_sp));
871872
}
873+
#endif
872874

873875
#ifdef CONFIG_HOTPLUG_CPU
874876
void fixup_irqs(void)

0 commit comments

Comments
 (0)