* [PATCH 00/18] genirq: Remove setup_irq()
From: afzal mohammed @ 2020-02-12 8:01 UTC (permalink / raw)
To: linux-kernel, linux-rpi-kernel, linux-arm-kernel,
linux-samsung-soc, x86, linux-sh, linux-s390, linuxppc-dev,
linux-parisc, linux-mips, linux-m68k, linux-ia64, linux-hexagon,
linux-c6x-dev, linux-omap, linux-alpha
Cc: Julia Lawall, Thomas Gleixner, Michal Marek, Nicolas Palix,
Gilles Muller
While trying to understand internals of irq handling, came across a
thread [1] in which tglx was referring to avoid usage of setup_irq().
Existing callers of setup_irq() reached mostly via 'init_IRQ()' &
'time_init()', while memory allocators are ready by 'mm_init()'.
Hence instances of setup_irq() is replaced by request_irq() &
setup_irq() (along with remove_irq()) definition deleted in the last
patch.
Seldom remove_irq() usage has been observed coupled with setup_irq(),
wherever that has been found, it too has been replaced by free_irq().
Build & boot tested on ARM & x86_64 platforms (ensured that on the
machines used for testing there was an existing setup_irq()
invocation occuring at runtime)
Much of the changes were created using Coccinelle with an intention
to learn it. spatch command was directly run w/ semantic patch below.
But not everything could be automated.
Searching with 'git grep -n '\Wsetup_irq('' & avoiding the irrelevant
ones, 153 invocation's of setup_irq() were found. 112 could be replaced
w/ cocci, of which in a few files some desired hunks were missing or
not as expected, these were fixed up manually. Also the remaining 41
had to be done manually.
Although cocci could replace 112, because of line continue not
happening at paranthesis for request_irq(), around 80 had to be
manually aligned in the request_irq() statement. Problem was with my
below cocci snippet,
- setup_irq(E1,&act);
+ if (request_irq(E1,f_handler,f_flags,f_name,f_dev_id))
+ pr_err("request_irq() on %s failed\n", f_name);
Instead of the above, if below is used, line continue happens exactly
at paranthesis, but it lacks addition of printing on request_irq()
failure where existing setup_irq() failure was not doing it.
- setup_irq(E1,&act)
+ request_irq(E1,f_handler,f_flags,f_name,f_dev_id)
Above had an additional advantage of replacing instances of
if (setup_irq()) & BUG(setup_irq()), but luckily those instances were
very few.
So though many changes could be automated, there are a considerable
amount of manual changes, please review carefully especially mips &
alpha.
Usage of setup_percpu_irq() is untouched w/ this series.
There are 2 checkpatch warning about usage of BUG() [which was already
there w/ setup_irq()], they are left as is as it seems appropriate for
tick timer interrupt.
[1] https://lkml.kernel.org/r/alpine.DEB.2.20.1710191609480.1971@nanos
--->8---
@r1@
identifier ret;
@@
(
setup_irq(...);
|
ret = setup_irq(...);
)
@r2 depends on r1@
identifier act;
@@
static struct irqaction act = {
};
@r11 depends on r2@
identifier r2.act;
identifier f_handler;
@@
(
- act.handler = f_handler;
|
static struct irqaction act = {
.handler = f_handler,
};
)
@r12 depends on r2@
identifier r2.act;
expression f_name;
@@
(
- act.name = f_name;
|
static struct irqaction act = {
.name = f_name,
};
)
@r15 depends on r2@
identifier r2.act;
expression f_dev_id;
@@
(
- act.dev_id = f_dev_id;
|
static struct irqaction act = {
.dev_id = f_dev_id,
};
)
@r16 depends on r2@
identifier r2.act;
expression f_flags;
@@
(
- act.flags = f_flags;
|
static struct irqaction act = {
.flags = f_flags,
};
)
@r21 depends on r2@
identifier r2.act;
@@
- static struct irqaction act = {
- ...
- };
@r22 depends on r2 && r11 && r12 && r15 && r16@
identifier r2.act;
identifier r11.f_handler;
expression r12.f_name;
expression r15.f_dev_id;
expression r16.f_flags;
expression E1;
identifier ret;
@@
(
- setup_irq(E1,&act);
+ if (request_irq(E1,f_handler,f_flags,f_name,f_dev_id))
+ pr_err("request_irq() on %s failed\n", f_name);
|
- ret = setup_irq(E1,&act);
+ ret = request_irq(E1,f_handler,f_flags,f_name,f_dev_id);
)
@r23 depends on r2 && r11 && r12 && !r15 && r16@
identifier r2.act;
identifier r11.f_handler;
expression r12.f_name;
expression r16.f_flags;
expression E1;
identifier ret;
@@
(
- setup_irq(E1,&act);
+ if (request_irq(E1,f_handler,f_flags,f_name,NULL))
+ pr_err("request_irq() on %s failed\n", f_name);
|
- ret = setup_irq(E1,&act);
+ ret = request_irq(E1,f_handler,f_flags,f_name,NULL);
)
@r24 depends on r2 && r11 && r12 && r15 && !r16@
identifier r2.act;
identifier r11.f_handler;
expression r12.f_name;
expression r15.f_dev_id;
expression E1;
identifier ret;
@@
(
- setup_irq(E1,&act);
+ if (request_irq(E1,f_handler,0,f_name,f_dev_id))
+ pr_err("request_irq() on %s failed\n", f_name);
|
- ret = setup_irq(E1,&act);
+ ret = request_irq(E1,f_handler,0,f_name,f_dev_id);
)
@r25 depends on r2 && r11 && r12 && !r15 && !r16@
identifier r2.act;
identifier r11.f_handler;
expression r12.f_name;
expression E1;
identifier ret;
@@
(
- setup_irq(E1,&act);
+ if (request_irq(E1,f_handler,0,f_name,NULL))
+ pr_err("request_irq() on %s failed\n", f_name);
|
- ret = setup_irq(E1,&act);
+ ret = request_irq(E1,f_handler,0,f_name,NULL);
)
--->8---
afzal mohammed (18):
alpha: replace setup_irq() by request_irq()
ARM: replace setup_irq() by request_irq()
c6x: replace setup_irq() by request_irq()
hexagon: replace setup_irq() by request_irq()
ia64: replace setup_irq() by request_irq()
m68k: Replace setup_irq() by request_irq()
microblaze: Replace setup_irq() by request_irq()
MIPS: Replace setup_irq() by request_irq()
parisc: Replace setup_irq() by request_irq()
powerpc: Replace setup_irq() by request_irq()
s390: replace setup_irq() by request_irq()
sh: replace setup_irq() by request_irq()
unicore32: replace setup_irq() by request_irq()
x86: Replace setup_irq() by request_irq()
xtensa: replace setup_irq() by request_irq()
clocksource: Replace setup_irq() by request_irq()
irqchip: Replace setup_irq() by request_irq()
genirq: Remove setup_irq() and remove_irq()
arch/alpha/kernel/irq_alpha.c | 29 ++-------
arch/alpha/kernel/irq_i8259.c | 8 +--
arch/alpha/kernel/irq_impl.h | 7 +--
arch/alpha/kernel/irq_pyxis.c | 3 +-
arch/alpha/kernel/sys_alcor.c | 3 +-
arch/alpha/kernel/sys_cabriolet.c | 3 +-
arch/alpha/kernel/sys_eb64p.c | 3 +-
arch/alpha/kernel/sys_marvel.c | 2 +-
arch/alpha/kernel/sys_miata.c | 6 +-
arch/alpha/kernel/sys_ruffian.c | 3 +-
arch/alpha/kernel/sys_rx164.c | 3 +-
arch/alpha/kernel/sys_sx164.c | 3 +-
arch/alpha/kernel/sys_wildfire.c | 7 +--
arch/alpha/kernel/time.c | 6 +-
arch/arm/mach-cns3xxx/core.c | 10 +---
arch/arm/mach-ebsa110/core.c | 10 +---
arch/arm/mach-ep93xx/timer-ep93xx.c | 12 ++--
arch/arm/mach-footbridge/dc21285-timer.c | 11 +---
arch/arm/mach-footbridge/isa-irq.c | 8 +--
arch/arm/mach-footbridge/isa-timer.c | 11 +---
arch/arm/mach-iop32x/time.c | 12 ++--
arch/arm/mach-mmp/time.c | 11 +---
arch/arm/mach-omap1/pm.c | 22 ++++---
arch/arm/mach-omap1/time.c | 10 +---
arch/arm/mach-omap1/timer32k.c | 10 +---
arch/arm/mach-omap2/timer.c | 11 +---
arch/arm/mach-rpc/time.c | 8 +--
arch/arm/mach-spear/time.c | 9 +--
arch/arm/plat-orion/time.c | 10 +---
arch/c6x/platforms/timer64.c | 11 +---
arch/hexagon/kernel/smp.c | 17 +++---
arch/hexagon/kernel/time.c | 11 +---
arch/ia64/kernel/irq_ia64.c | 42 +++++--------
arch/ia64/kernel/mca.c | 51 +++++-----------
arch/m68k/68000/timers.c | 9 +--
arch/m68k/coldfire/pit.c | 9 +--
arch/m68k/coldfire/sltimers.c | 19 ++----
arch/m68k/coldfire/timers.c | 19 ++----
arch/microblaze/kernel/timer.c | 10 +---
arch/mips/alchemy/common/time.c | 11 +---
arch/mips/ar7/irq.c | 18 +++---
arch/mips/ath25/ar2315.c | 9 +--
arch/mips/ath25/ar5312.c | 9 +--
arch/mips/bcm63xx/irq.c | 38 +++++-------
arch/mips/cobalt/irq.c | 14 ++---
arch/mips/dec/setup.c | 59 ++++++++-----------
arch/mips/emma/markeins/irq.c | 20 +++----
arch/mips/include/asm/sni.h | 2 +-
arch/mips/jazz/irq.c | 12 +---
arch/mips/kernel/cevt-bcm1480.c | 11 +---
arch/mips/kernel/cevt-ds1287.c | 9 +--
arch/mips/kernel/cevt-gt641xx.c | 9 +--
arch/mips/kernel/cevt-r4k.c | 4 +-
arch/mips/kernel/cevt-sb1250.c | 11 +---
arch/mips/kernel/cevt-txx9.c | 11 +---
arch/mips/kernel/i8253.c | 10 +---
arch/mips/kernel/rtlx-mt.c | 8 +--
arch/mips/kernel/smp.c | 33 ++++-------
arch/mips/lasat/interrupt.c | 10 +---
arch/mips/loongson2ef/common/bonito-irq.c | 9 +--
.../loongson2ef/common/cs5536/cs5536_mfgpt.c | 10 +---
arch/mips/loongson2ef/fuloong-2e/irq.c | 14 ++---
arch/mips/loongson2ef/lemote-2f/irq.c | 20 ++-----
arch/mips/loongson32/common/irq.c | 21 ++++---
arch/mips/loongson32/common/time.c | 12 ++--
arch/mips/loongson64/hpet.c | 10 +---
arch/mips/mti-malta/malta-int.c | 10 +---
arch/mips/netlogic/xlr/fmn.c | 9 +--
arch/mips/pmcs-msp71xx/msp_irq.c | 28 ++++-----
arch/mips/pmcs-msp71xx/msp_smp.c | 22 ++-----
arch/mips/pmcs-msp71xx/msp_time.c | 7 ++-
arch/mips/ralink/cevt-rt3352.c | 17 +++---
arch/mips/sgi-ip22/ip22-eisa.c | 8 +--
arch/mips/sgi-ip22/ip22-int.c | 49 +++++----------
arch/mips/sgi-ip32/ip32-irq.c | 18 ++----
arch/mips/sni/a20r.c | 4 +-
arch/mips/sni/irq.c | 8 +--
arch/mips/sni/pcit.c | 8 ++-
arch/mips/sni/rm200.c | 23 +++-----
arch/mips/sni/time.c | 10 +---
arch/mips/vr41xx/common/irq.c | 9 +--
arch/parisc/kernel/irq.c | 21 ++-----
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 10 +---
arch/powerpc/platforms/8xx/cpm1.c | 9 +--
arch/powerpc/platforms/8xx/m8xx_setup.c | 9 +--
arch/powerpc/platforms/chrp/setup.c | 14 ++---
arch/powerpc/platforms/powermac/pic.c | 31 ++++------
arch/powerpc/platforms/powermac/smp.c | 9 +--
arch/s390/kernel/irq.c | 8 +--
arch/sh/boards/mach-cayman/irq.c | 18 ++----
arch/sh/drivers/dma/dma-pvr2.c | 9 +--
arch/unicore32/kernel/time.c | 11 +---
arch/x86/kernel/irqinit.c | 18 +++---
arch/x86/kernel/time.c | 10 +---
arch/xtensa/kernel/smp.c | 8 +--
arch/xtensa/kernel/time.c | 10 +---
drivers/clocksource/bcm2835_timer.c | 8 +--
drivers/clocksource/bcm_kona_timer.c | 10 +---
drivers/clocksource/dw_apb_timer.c | 11 +---
drivers/clocksource/exynos_mct.c | 12 ++--
drivers/clocksource/mxs_timer.c | 10 +---
drivers/clocksource/nomadik-mtu.c | 11 +---
drivers/clocksource/samsung_pwm_timer.c | 12 ++--
drivers/clocksource/timer-atlas7.c | 50 ++++++++--------
drivers/clocksource/timer-cs5535.c | 10 +---
drivers/clocksource/timer-efm32.c | 10 +---
drivers/clocksource/timer-fsl-ftm.c | 10 +---
drivers/clocksource/timer-imx-gpt.c | 10 +---
drivers/clocksource/timer-integrator-ap.c | 11 +---
drivers/clocksource/timer-meson6.c | 11 +---
drivers/clocksource/timer-orion.c | 9 +--
drivers/clocksource/timer-prima2.c | 11 +---
drivers/clocksource/timer-pxa.c | 10 +---
drivers/clocksource/timer-sp804.c | 11 +---
drivers/clocksource/timer-u300.c | 9 +--
drivers/clocksource/timer-vf-pit.c | 10 +---
drivers/clocksource/timer-vt8500.c | 11 +---
drivers/clocksource/timer-zevio.c | 13 ++--
drivers/irqchip/irq-i8259.c | 9 +--
drivers/irqchip/irq-ingenic.c | 11 ++--
drivers/parisc/eisa.c | 8 +--
drivers/s390/cio/airq.c | 8 +--
drivers/s390/cio/cio.c | 8 +--
include/linux/dw_apb_timer.h | 1 -
include/linux/irq.h | 2 -
kernel/irq/manage.c | 44 --------------
126 files changed, 528 insertions(+), 1111 deletions(-)
base-commit: v5.6-rc1
--
2.24.1
^ permalink raw reply
* [PATCH 10/18] powerpc: Replace setup_irq() by request_irq()
From: afzal mohammed @ 2020-02-12 8:04 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: Scott Wood, Paul Mackerras, Thomas Gleixner
In-Reply-To: <cover.1581478323.git.afzal.mohd.ma@gmail.com>
request_irq() is preferred over setup_irq(). Existing callers of
setup_irq() reached mostly via 'init_IRQ()' & 'time_init()', while
memory allocators are ready by 'mm_init()'.
Per tglx[1], setup_irq() existed in olden days when allocators were not
ready by the time early interrupts were initialized.
Hence replace setup_irq() by request_irq().
Seldom remove_irq() usage has been observed coupled with setup_irq(),
wherever that has been found, it too has been replaced by free_irq().
[1] https://lkml.kernel.org/r/alpine.DEB.2.20.1710191609480.1971@nanos
Signed-off-by: afzal mohammed <afzal.mohd.ma@gmail.com>
---
Since cc'ing cover letter to all maintainers/reviewers would be too
many, refer for cover letter,
https://lkml.kernel.org/r/cover.1581478323.git.afzal.mohd.ma@gmail.com
arch/powerpc/platforms/85xx/mpc85xx_cds.c | 10 +++-----
arch/powerpc/platforms/8xx/cpm1.c | 9 ++-----
arch/powerpc/platforms/8xx/m8xx_setup.c | 9 ++-----
arch/powerpc/platforms/chrp/setup.c | 14 ++++------
arch/powerpc/platforms/powermac/pic.c | 31 ++++++++++-------------
arch/powerpc/platforms/powermac/smp.c | 9 ++-----
6 files changed, 27 insertions(+), 55 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 6b1436abe9b1..1c5598877d70 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -218,12 +218,6 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id)
{
return IRQ_HANDLED;
}
-
-static struct irqaction mpc85xxcds_8259_irqaction = {
- .handler = mpc85xx_8259_cascade_action,
- .flags = IRQF_SHARED | IRQF_NO_THREAD,
- .name = "8259 cascade",
-};
#endif /* PPC_I8259 */
#endif /* CONFIG_PCI */
@@ -271,7 +265,9 @@ static int mpc85xx_cds_8259_attach(void)
* disabled when the last user of the shared IRQ line frees their
* interrupt.
*/
- if ((ret = setup_irq(cascade_irq, &mpc85xxcds_8259_irqaction))) {
+ ret = request_irq(cascade_irq, mpc85xx_8259_cascade_action,
+ IRQF_SHARED | IRQF_NO_THREAD, "8259 cascade", NULL);
+ if (ret) {
printk(KERN_ERR "Failed to setup cascade interrupt\n");
return ret;
}
diff --git a/arch/powerpc/platforms/8xx/cpm1.c b/arch/powerpc/platforms/8xx/cpm1.c
index a43ee7d1ff85..4db4ca2e1222 100644
--- a/arch/powerpc/platforms/8xx/cpm1.c
+++ b/arch/powerpc/platforms/8xx/cpm1.c
@@ -120,12 +120,6 @@ static irqreturn_t cpm_error_interrupt(int irq, void *dev)
return IRQ_HANDLED;
}
-static struct irqaction cpm_error_irqaction = {
- .handler = cpm_error_interrupt,
- .flags = IRQF_NO_THREAD,
- .name = "error",
-};
-
static const struct irq_domain_ops cpm_pic_host_ops = {
.map = cpm_pic_host_map,
};
@@ -187,7 +181,8 @@ unsigned int __init cpm_pic_init(void)
if (!eirq)
goto end;
- if (setup_irq(eirq, &cpm_error_irqaction))
+ if (request_irq(eirq, cpm_error_interrupt, IRQF_NO_THREAD, "error",
+ NULL))
printk(KERN_ERR "Could not allocate CPM error IRQ!");
setbits32(&cpic_reg->cpic_cicr, CICR_IEN);
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index f1c805c8adbc..df4d57d07f9a 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -39,12 +39,6 @@ static irqreturn_t timebase_interrupt(int irq, void *dev)
return IRQ_HANDLED;
}
-static struct irqaction tbint_irqaction = {
- .handler = timebase_interrupt,
- .flags = IRQF_NO_THREAD,
- .name = "tbint",
-};
-
/* per-board overridable init_internal_rtc() function. */
void __init __attribute__ ((weak))
init_internal_rtc(void)
@@ -157,7 +151,8 @@ void __init mpc8xx_calibrate_decr(void)
(TBSCR_TBF | TBSCR_TBE));
immr_unmap(sys_tmr2);
- if (setup_irq(virq, &tbint_irqaction))
+ if (request_irq(virq, timebase_interrupt, IRQF_NO_THREAD, "tbint",
+ NULL))
panic("Could not allocate timer IRQ!");
}
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index fcf6f2342ef4..95ac1f510b1e 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -451,13 +451,6 @@ static void __init chrp_find_openpic(void)
of_node_put(np);
}
-#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON)
-static struct irqaction xmon_irqaction = {
- .handler = xmon_irq,
- .name = "XMON break",
-};
-#endif
-
static void __init chrp_find_8259(void)
{
struct device_node *np, *pic = NULL;
@@ -541,8 +534,11 @@ static void __init chrp_init_IRQ(void)
if (of_node_is_type(kbd->parent, "adb"))
break;
of_node_put(kbd);
- if (kbd)
- setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
+ if (kbd) {
+ if (request_irq(HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break",
+ NULL))
+ pr_err("request_irq() on %s failed\n", "XMON break");
+ }
#endif
}
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 2e969073473d..939ae39d81db 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -250,20 +250,6 @@ static unsigned int pmac_pic_get_irq(void)
return irq_linear_revmap(pmac_pic_host, irq);
}
-#ifdef CONFIG_XMON
-static struct irqaction xmon_action = {
- .handler = xmon_irq,
- .flags = IRQF_NO_THREAD,
- .name = "NMI - XMON"
-};
-#endif
-
-static struct irqaction gatwick_cascade_action = {
- .handler = gatwick_action,
- .flags = IRQF_NO_THREAD,
- .name = "cascade",
-};
-
static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node,
enum irq_domain_bus_token bus_token)
{
@@ -384,12 +370,17 @@ static void __init pmac_pic_probe_oldstyle(void)
out_le32(&pmac_irq_hw[i]->enable, 0);
/* Hookup cascade irq */
- if (slave && pmac_irq_cascade)
- setup_irq(pmac_irq_cascade, &gatwick_cascade_action);
+ if (slave && pmac_irq_cascade) {
+ if (request_irq(pmac_irq_cascade, gatwick_action,
+ IRQF_NO_THREAD, "cascade", NULL))
+ pr_err("request_irq() on %s failed\n", "cascade");
+ }
printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
#ifdef CONFIG_XMON
- setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
+ if (request_irq(irq_create_mapping(NULL, 20), xmon_irq, IRQF_NO_THREAD,
+ "NMI - XMON", NULL))
+ pr_err("request_irq() on %s failed\n", "NMI - XMON");
#endif
}
@@ -441,7 +432,11 @@ static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
nmi_irq = irq_of_parse_and_map(pswitch, 0);
if (nmi_irq) {
mpic_irq_set_priority(nmi_irq, 9);
- setup_irq(nmi_irq, &xmon_action);
+ if (request_irq(nmi_irq, xmon_irq, IRQF_NO_THREAD,
+ "NMI - XMON", NULL)) {
+ pr_err("request_irq() on %s failed\n",
+ "NMI - XMON");
+ }
}
of_node_put(pswitch);
}
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index f95fbdee6efe..0121b31a9e7b 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -399,12 +399,6 @@ static int __init smp_psurge_kick_cpu(int nr)
return 0;
}
-static struct irqaction psurge_irqaction = {
- .handler = psurge_ipi_intr,
- .flags = IRQF_PERCPU | IRQF_NO_THREAD,
- .name = "primary IPI",
-};
-
static void __init smp_psurge_setup_cpu(int cpu_nr)
{
if (cpu_nr != 0 || !psurge_start)
@@ -413,7 +407,8 @@ static void __init smp_psurge_setup_cpu(int cpu_nr)
/* reset the entry point so if we get another intr we won't
* try to startup again */
out_be32(psurge_start, 0x100);
- if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction))
+ if (request_irq(irq_create_mapping(NULL, 30), psurge_ipi_intr,
+ IRQF_PERCPU | IRQF_NO_THREAD, "primary IPI", NULL))
printk(KERN_ERR "Couldn't get primary IPI interrupt");
}
--
2.24.1
^ permalink raw reply related
* Re: [PATCH v6 4/4] powerpc: Book3S 64-bit "heavyweight" KASAN support
From: Daniel Axtens @ 2020-02-12 10:12 UTC (permalink / raw)
To: Christophe Leroy, linux-kernel, linux-mm, linuxppc-dev, kasan-dev,
aneesh.kumar, bsingharora
In-Reply-To: <224745f3-db66-fe46-1459-d1d41867b4f3@c-s.fr>
Christophe Leroy <christophe.leroy@c-s.fr> writes:
> Le 12/02/2020 à 06:47, Daniel Axtens a écrit :
>> diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
>> index fbff9ff9032e..2911fdd3a6a0 100644
>> --- a/arch/powerpc/include/asm/kasan.h
>> +++ b/arch/powerpc/include/asm/kasan.h
>> @@ -2,6 +2,8 @@
>> #ifndef __ASM_KASAN_H
>> #define __ASM_KASAN_H
>>
>> +#include <asm/page.h>
>> +
>> #ifdef CONFIG_KASAN
>> #define _GLOBAL_KASAN(fn) _GLOBAL(__##fn)
>> #define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(__##fn)
>> @@ -14,29 +16,41 @@
>>
>> #ifndef __ASSEMBLY__
>>
>> -#include <asm/page.h>
>> -
>> #define KASAN_SHADOW_SCALE_SHIFT 3
>>
>> #define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
>> (PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
>>
>> +#ifdef CONFIG_KASAN_SHADOW_OFFSET
>> #define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET)
>> +#endif
>>
>> +#ifdef CONFIG_PPC32
>> #define KASAN_SHADOW_END 0UL
>>
>> -#define KASAN_SHADOW_SIZE (KASAN_SHADOW_END - KASAN_SHADOW_START)
>> +#ifdef CONFIG_KASAN
>> +void kasan_late_init(void);
>> +#else
>> +static inline void kasan_late_init(void) { }
>> +#endif
>> +
>> +#endif
>> +
>> +#ifdef CONFIG_PPC_BOOK3S_64
>> +#define KASAN_SHADOW_END (KASAN_SHADOW_OFFSET + \
>> + (RADIX_VMEMMAP_END >> KASAN_SHADOW_SCALE_SHIFT))
>> +
>> +static inline void kasan_late_init(void) { }
>> +#endif
>>
>> #ifdef CONFIG_KASAN
>> void kasan_early_init(void);
>> void kasan_mmu_init(void);
>> void kasan_init(void);
>> -void kasan_late_init(void);
>> #else
>> static inline void kasan_init(void) { }
>> static inline void kasan_mmu_init(void) { }
>> -static inline void kasan_late_init(void) { }
>> #endif
>
> Why modify all this kasan_late_init() stuff ?
>
> This function is only called from kasan init_32.c, it is never called by
> PPC64, so you should not need to modify anything at all.
I got a compile error for a missing symbol. I'll repro it and attach it.
Regards,
Daniel
>
> Christophe
^ permalink raw reply
* [PATCH] powerpc/time: Replace <linux/clk-provider.h> by <linux/of_clk.h>
From: Geert Uytterhoeven @ 2020-02-12 10:17 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-clk, Geert Uytterhoeven, linux-kernel
The PowerPC time code is not a clock provider, and just needs to call
of_clk_init().
Hence it can include <linux/of_clk.h> instead of <linux/clk-provider.h>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
arch/powerpc/kernel/time.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 1168e8b37e30696d..af0b6834f75c7007 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -50,7 +50,7 @@
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/irq_work.h>
-#include <linux/clk-provider.h>
+#include <linux/of_clk.h>
#include <linux/suspend.h>
#include <linux/sched/cputime.h>
#include <linux/processor.h>
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v6 4/4] powerpc: Book3S 64-bit "heavyweight" KASAN support
From: Christophe Leroy @ 2020-02-12 10:35 UTC (permalink / raw)
To: Daniel Axtens, linux-kernel, linux-mm, linuxppc-dev, kasan-dev,
aneesh.kumar, bsingharora
In-Reply-To: <87imkcru6b.fsf@dja-thinkpad.axtens.net>
Le 12/02/2020 à 11:12, Daniel Axtens a écrit :
> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>
>> Le 12/02/2020 à 06:47, Daniel Axtens a écrit :
>>> diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
>>> index fbff9ff9032e..2911fdd3a6a0 100644
>>> --- a/arch/powerpc/include/asm/kasan.h
>>> +++ b/arch/powerpc/include/asm/kasan.h
>>> @@ -2,6 +2,8 @@
>>> #ifndef __ASM_KASAN_H
>>> #define __ASM_KASAN_H
>>>
>>> +#include <asm/page.h>
>>> +
>>> #ifdef CONFIG_KASAN
>>> #define _GLOBAL_KASAN(fn) _GLOBAL(__##fn)
>>> #define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(__##fn)
>>> @@ -14,29 +16,41 @@
>>>
>>> #ifndef __ASSEMBLY__
>>>
>>> -#include <asm/page.h>
>>> -
>>> #define KASAN_SHADOW_SCALE_SHIFT 3
>>>
>>> #define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
>>> (PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
>>>
>>> +#ifdef CONFIG_KASAN_SHADOW_OFFSET
>>> #define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET)
>>> +#endif
>>>
>>> +#ifdef CONFIG_PPC32
>>> #define KASAN_SHADOW_END 0UL
>>>
>>> -#define KASAN_SHADOW_SIZE (KASAN_SHADOW_END - KASAN_SHADOW_START)
>>> +#ifdef CONFIG_KASAN
>>> +void kasan_late_init(void);
>>> +#else
>>> +static inline void kasan_late_init(void) { }
>>> +#endif
>>> +
>>> +#endif
>>> +
>>> +#ifdef CONFIG_PPC_BOOK3S_64
>>> +#define KASAN_SHADOW_END (KASAN_SHADOW_OFFSET + \
>>> + (RADIX_VMEMMAP_END >> KASAN_SHADOW_SCALE_SHIFT))
>>> +
>>> +static inline void kasan_late_init(void) { }
>>> +#endif
>>>
>>> #ifdef CONFIG_KASAN
>>> void kasan_early_init(void);
>>> void kasan_mmu_init(void);
>>> void kasan_init(void);
>>> -void kasan_late_init(void);
>>> #else
>>> static inline void kasan_init(void) { }
>>> static inline void kasan_mmu_init(void) { }
>>> -static inline void kasan_late_init(void) { }
>>> #endif
>>
>> Why modify all this kasan_late_init() stuff ?
>>
>> This function is only called from kasan init_32.c, it is never called by
>> PPC64, so you should not need to modify anything at all.
>
> I got a compile error for a missing symbol. I'll repro it and attach it.
>
Oops, sorry. I looked too quickly. It is defined in kasan_init_32.c and
called from mm/mem.c
We don't have a performance issue here, since this is called only once
during startup. Could you define an empty kasan_late_init() in
init_book3s_64.c instead ?
Christophe
^ permalink raw reply
* [PATCH v3] asm-generic: Fix unistd_32.h generation format
From: Michal Simek @ 2020-02-12 10:53 UTC (permalink / raw)
To: linux-kernel, monstr, michal.simek, git, arnd, akpm
Cc: Rich Felker, linux-ia64, linux-sh, James E.J. Bottomley,
Max Filippov, Paul Mackerras, sparclinux, Stefan Asserhall,
Yoshinori Sato, Helge Deller, Matt Turner, Fenghua Yu,
linux-xtensa, Ivan Kokshaysky, Richard Henderson, Chris Zankel,
Tony Luck, Paul Burton, linux-parisc, linux-mips, Ralf Baechle,
linux-alpha, linuxppc-dev, David S. Miller
Generated files are also checked by sparse that's why add newline
to remove sparse (C=1) warning.
The issue was found on Microblaze and reported like this:
./arch/microblaze/include/generated/uapi/asm/unistd_32.h:438:45:
warning: no newline at end of file
Mips and PowerPC have it already but let's align with style used by m68k.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Reviewed-by: Stefan Asserhall <stefan.asserhall@xilinx.com>
Acked-by: Max Filippov <jcmvbkbc@gmail.com> (xtensa)
---
Changes in v3:
- Add notes about mips/ppc and m68 - Max/Geert
Changes in v2:
- Update also others archs not just microblaze - Arnd
- Align subject and description to match multiarch change
arch/alpha/kernel/syscalls/syscallhdr.sh | 2 +-
arch/ia64/kernel/syscalls/syscallhdr.sh | 2 +-
arch/microblaze/kernel/syscalls/syscallhdr.sh | 2 +-
arch/mips/kernel/syscalls/syscallhdr.sh | 3 +--
arch/parisc/kernel/syscalls/syscallhdr.sh | 2 +-
arch/powerpc/kernel/syscalls/syscallhdr.sh | 3 +--
arch/sh/kernel/syscalls/syscallhdr.sh | 2 +-
arch/sparc/kernel/syscalls/syscallhdr.sh | 2 +-
arch/xtensa/kernel/syscalls/syscallhdr.sh | 2 +-
9 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/arch/alpha/kernel/syscalls/syscallhdr.sh b/arch/alpha/kernel/syscalls/syscallhdr.sh
index e5b99bd2e5e7..1780e861492a 100644
--- a/arch/alpha/kernel/syscalls/syscallhdr.sh
+++ b/arch/alpha/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/ia64/kernel/syscalls/syscallhdr.sh b/arch/ia64/kernel/syscalls/syscallhdr.sh
index 0c2d2c748565..f407b6e53283 100644
--- a/arch/ia64/kernel/syscalls/syscallhdr.sh
+++ b/arch/ia64/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/microblaze/kernel/syscalls/syscallhdr.sh b/arch/microblaze/kernel/syscalls/syscallhdr.sh
index 2e9062a926a3..a914854f8d9f 100644
--- a/arch/microblaze/kernel/syscalls/syscallhdr.sh
+++ b/arch/microblaze/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/mips/kernel/syscalls/syscallhdr.sh b/arch/mips/kernel/syscalls/syscallhdr.sh
index d2bcfa8f4d1a..2e241e713a7d 100644
--- a/arch/mips/kernel/syscalls/syscallhdr.sh
+++ b/arch/mips/kernel/syscalls/syscallhdr.sh
@@ -32,6 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
- printf "\n"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/parisc/kernel/syscalls/syscallhdr.sh b/arch/parisc/kernel/syscalls/syscallhdr.sh
index 50242b747d7c..730db288fe54 100644
--- a/arch/parisc/kernel/syscalls/syscallhdr.sh
+++ b/arch/parisc/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/powerpc/kernel/syscalls/syscallhdr.sh b/arch/powerpc/kernel/syscalls/syscallhdr.sh
index c0a9a32937f1..02d6751f3be3 100644
--- a/arch/powerpc/kernel/syscalls/syscallhdr.sh
+++ b/arch/powerpc/kernel/syscalls/syscallhdr.sh
@@ -32,6 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
- printf "\n"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/sh/kernel/syscalls/syscallhdr.sh b/arch/sh/kernel/syscalls/syscallhdr.sh
index 1de0334e577f..4c0519861e97 100644
--- a/arch/sh/kernel/syscalls/syscallhdr.sh
+++ b/arch/sh/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/sparc/kernel/syscalls/syscallhdr.sh b/arch/sparc/kernel/syscalls/syscallhdr.sh
index 626b5740a9f1..cf50a75cc0bb 100644
--- a/arch/sparc/kernel/syscalls/syscallhdr.sh
+++ b/arch/sparc/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
diff --git a/arch/xtensa/kernel/syscalls/syscallhdr.sh b/arch/xtensa/kernel/syscalls/syscallhdr.sh
index d37db641ca31..eebfb8a8ace6 100644
--- a/arch/xtensa/kernel/syscalls/syscallhdr.sh
+++ b/arch/xtensa/kernel/syscalls/syscallhdr.sh
@@ -32,5 +32,5 @@ grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
printf "#define __NR_syscalls\t%s\n" "${nxt}"
printf "#endif\n"
printf "\n"
- printf "#endif /* %s */" "${fileguard}"
+ printf "#endif /* %s */\n" "${fileguard}"
) > "$out"
--
2.25.0
^ permalink raw reply related
* [PATCH v4 0/3] Introduce Self-Save API for deep stop states
From: Pratik Rajesh Sampat @ 2020-02-12 11:20 UTC (permalink / raw)
To: linux-kernel, linuxppc-dev, mpe, svaidy, ego, linuxram,
pratik.sampat, psampat, pratik.r.sampat
Skiboot patches v4: https://lists.ozlabs.org/pipermail/skiboot/2020-February/016404.html
v3 patches: https://lkml.org/lkml/2020/1/13/333
Changelog
v3 --> v4
Device tree interface change: Cease to use the active property for
self-save and self-restore and use only presence/absence of the node to
signify the status.
Currently the stop-API supports a mechanism called as self-restore
which allows us to restore the values of certain SPRs on wakeup from a
deep-stop state to a desired value. To use this, the Kernel makes an
OPAL call passing the PIR of the CPU, the SPR number and the value to
which the SPR should be restored when that CPU wakes up from a deep
stop state.
Recently, a new feature, named self-save has been enabled in the
stop-api, which is an alternative mechanism to do the same, except
that self-save will save the current content of the SPR before
entering a deep stop state and also restore the content back on
waking up from a deep stop state.
This patch series aims at introducing and leveraging the self-save feature in
the kernel.
Now, as the kernel has a choice to prefer one mode over the other and
there can be registers in both the save/restore SPR list which are sent
from the device tree, a new interface has been defined for the seamless
handing of the modes for each SPR.
A list of preferred SPRs are maintained in the kernel which contains two
properties:
1. supported_mode: Helps in identifying if it strictly supports self
save or restore or both.
Initialized using the information from device tree.
2. preferred_mode: Calls out what mode is preferred for each SPR. It
could be strictly self save or restore, or it can also
determine the preference of mode over the other if both
are present by encapsulating the other in bitmask from
LSB to MSB.
Initialized statically.
Below is a table to show the Scenario::Consequence when the self save and
self restore modes are available or disabled in different combinations as
perceived from the device tree thus giving complete backwards compatibly
regardless of an older firmware running a newer kernel or vise-versa.
Support for self save or self-restore is embedded in the device tree,
along with the set of registers it supports.
SR = Self restore; SS = Self save
.-----------------------------------.----------------------------------------.
| Scenario | Consequence |
:-----------------------------------+----------------------------------------:
| Legacy Firmware. No SS or SR node | Self restore is called for all |
| | supported SPRs |
:-----------------------------------+----------------------------------------:
| SR: !active SS: !active | Deep stop states disabled |
:-----------------------------------+----------------------------------------:
| SR: active SS: !active | Self restore is called for all |
| | supported SPRs |
:-----------------------------------+----------------------------------------:
| SR: active SS: active | Goes through the preferences for each |
| | SPR and executes of the modes |
| | accordingly. Currently, Self restore is|
| | called for all the SPRs except PSSCR |
| | which is self saved |
:-----------------------------------+----------------------------------------:
| SR: active(only HID0) SS: active | Self save called for all supported |
| | registers expect HID0 (as HID0 cannot |
| | be self saved currently) |
:-----------------------------------+----------------------------------------:
| SR: !active SS: active | currently will disable deep states as |
| | HID0 is needed to be self restored and |
| | cannot be self saved |
'-----------------------------------'----------------------------------------'
Pratik Rajesh Sampat (3):
powerpc/powernv: Interface to define support and preference for a SPR
powerpc/powernv: Introduce Self save support
powerpc/powernv: Parse device tree, population of SPR support
arch/powerpc/include/asm/opal-api.h | 3 +-
arch/powerpc/include/asm/opal.h | 1 +
arch/powerpc/platforms/powernv/idle.c | 420 ++++++++++++++++++---
arch/powerpc/platforms/powernv/opal-call.c | 1 +
4 files changed, 367 insertions(+), 58 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH v4 3/3] powerpc/powernv: Parse device tree, population of SPR support
From: Pratik Rajesh Sampat @ 2020-02-12 11:20 UTC (permalink / raw)
To: linux-kernel, linuxppc-dev, mpe, svaidy, ego, linuxram,
pratik.sampat, psampat, pratik.r.sampat
In-Reply-To: <cover.1581505210.git.psampat@linux.ibm.com>
Parse the device tree for nodes self-save, self-restore and populate
support for the preferred SPRs based what was advertised by the device
tree.
Signed-off-by: Pratik Rajesh Sampat <psampat@linux.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
---
arch/powerpc/platforms/powernv/idle.c | 82 +++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 97aeb45e897b..27dfadf609e8 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -1436,6 +1436,85 @@ static void __init pnv_probe_idle_states(void)
supported_cpuidle_states |= pnv_idle_states[i].flags;
}
+/*
+ * Extracts and populates the self save or restore capabilities
+ * passed from the device tree node
+ */
+static int extract_save_restore_state_dt(struct device_node *np, int type)
+{
+ int nr_sprns = 0, i, bitmask_index;
+ int rc = 0;
+ u64 *temp_u64;
+ u64 bit_pos;
+
+ nr_sprns = of_property_count_u64_elems(np, "sprn-bitmask");
+ if (nr_sprns <= 0)
+ return rc;
+ temp_u64 = kcalloc(nr_sprns, sizeof(u64), GFP_KERNEL);
+ if (of_property_read_u64_array(np, "sprn-bitmask",
+ temp_u64, nr_sprns)) {
+ pr_warn("cpuidle-powernv: failed to find registers in DT\n");
+ kfree(temp_u64);
+ return -EINVAL;
+ }
+ /*
+ * Populate acknowledgment of support for the sprs in the global vector
+ * gotten by the registers supplied by the firmware.
+ * The registers are in a bitmask, bit index within
+ * that specifies the SPR
+ */
+ for (i = 0; i < nr_preferred_sprs; i++) {
+ bitmask_index = preferred_sprs[i].spr / 64;
+ bit_pos = preferred_sprs[i].spr % 64;
+ if ((temp_u64[bitmask_index] & (1UL << bit_pos)) == 0) {
+ if (type == SELF_RESTORE_TYPE)
+ preferred_sprs[i].supported_mode &=
+ ~SELF_RESTORE_STRICT;
+ else
+ preferred_sprs[i].supported_mode &=
+ ~SELF_SAVE_STRICT;
+ continue;
+ }
+ if (type == SELF_RESTORE_TYPE) {
+ preferred_sprs[i].supported_mode |=
+ SELF_RESTORE_STRICT;
+ } else {
+ preferred_sprs[i].supported_mode |=
+ SELF_SAVE_STRICT;
+ }
+ }
+
+ kfree(temp_u64);
+ return rc;
+}
+
+static int pnv_parse_deepstate_dt(void)
+{
+ struct device_node *sr_np, *ss_np;
+ int rc = 0, i;
+
+ /* Self restore register population */
+ sr_np = of_find_node_by_path("/ibm,opal/power-mgt/self-restore");
+ if (!sr_np) {
+ pr_warn("opal: self restore Node not found");
+ } else {
+ rc = extract_save_restore_state_dt(sr_np, SELF_RESTORE_TYPE);
+ if (rc != 0)
+ return rc;
+ }
+ /* Self save register population */
+ ss_np = of_find_node_by_path("/ibm,opal/power-mgt/self-save");
+ if (!ss_np) {
+ pr_warn("opal: self save Node not found");
+ pr_warn("Legacy firmware. Assuming default self-restore support");
+ for (i = 0; i < nr_preferred_sprs; i++)
+ preferred_sprs[i].supported_mode &= ~SELF_SAVE_STRICT;
+ } else {
+ rc = extract_save_restore_state_dt(ss_np, SELF_SAVE_TYPE);
+ }
+ return rc;
+}
+
/*
* This function parses device-tree and populates all the information
* into pnv_idle_states structure. It also sets up nr_pnv_idle_states
@@ -1584,6 +1663,9 @@ static int __init pnv_init_idle_states(void)
return rc;
pnv_probe_idle_states();
+ rc = pnv_parse_deepstate_dt();
+ if (rc)
+ return rc;
if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
if (!(supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
power7_fastsleep_workaround_entry = false;
--
2.17.1
^ permalink raw reply related
* [PATCH v4 2/3] powerpc/powernv: Introduce Self save support
From: Pratik Rajesh Sampat @ 2020-02-12 11:20 UTC (permalink / raw)
To: linux-kernel, linuxppc-dev, mpe, svaidy, ego, linuxram,
pratik.sampat, psampat, pratik.r.sampat
In-Reply-To: <cover.1581505210.git.psampat@linux.ibm.com>
This commit introduces and leverages the Self save API which OPAL now
supports.
Add the new Self Save OPAL API call in the list of OPAL calls.
Implement the self saving of the SPRs based on the support populated
while respecting it's preferences.
This implementation allows mixing of support for the SPRs, which
means that a SPR can be self restored while another SPR be self saved if
they support and prefer it to be so.
Signed-off-by: Pratik Rajesh Sampat <psampat@linux.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
---
arch/powerpc/include/asm/opal-api.h | 3 ++-
arch/powerpc/include/asm/opal.h | 1 +
arch/powerpc/platforms/powernv/idle.c | 22 ++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-call.c | 1 +
4 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index c1f25a760eb1..1b6e1a68d431 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -214,7 +214,8 @@
#define OPAL_SECVAR_GET 176
#define OPAL_SECVAR_GET_NEXT 177
#define OPAL_SECVAR_ENQUEUE_UPDATE 178
-#define OPAL_LAST 178
+#define OPAL_SLW_SELF_SAVE_REG 181
+#define OPAL_LAST 181
#define QUIESCE_HOLD 1 /* Spin all calls at entry */
#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9986ac34b8e2..389a85b63805 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -203,6 +203,7 @@ int64_t opal_handle_hmi(void);
int64_t opal_handle_hmi2(__be64 *out_flags);
int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
int64_t opal_unregister_dump_region(uint32_t id);
+int64_t opal_slw_self_save_reg(uint64_t cpu_pir, uint64_t sprn);
int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
int64_t opal_config_cpu_idle_state(uint64_t state, uint64_t flag);
int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t pe_number);
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 03fe835aadd1..97aeb45e897b 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -279,6 +279,26 @@ static int pnv_self_save_restore_sprs(void)
if (rc != 0)
return rc;
break;
+ } else if (preferred & curr_spr.supported_mode
+ & SELF_SAVE_STRICT) {
+ is_initialized = true;
+ if (curr_spr.spr == SPRN_HMEER &&
+ cpu_thread_in_core(cpu) != 0) {
+ continue;
+ }
+ rc = opal_slw_self_save_reg(pir,
+ curr_spr.spr);
+ if (rc != 0)
+ return rc;
+ switch (curr_spr.spr) {
+ case SPRN_LPCR:
+ is_lpcr_self_save = true;
+ break;
+ case SPRN_PTCR:
+ is_ptcr_self_save = true;
+ break;
+ }
+ break;
}
preferred_sprs[index].preferred_mode =
preferred_sprs[index].preferred_mode >>
@@ -1159,6 +1179,8 @@ void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val)
if (!is_lpcr_self_save)
opal_slw_set_reg(pir, SPRN_LPCR,
lpcr_val);
+ else
+ opal_slw_self_save_reg(pir, SPRN_LPCR);
}
}
diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c
index 5cd0f52d258f..11e0ceb90de0 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -223,6 +223,7 @@ OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
OPAL_CALL(opal_handle_hmi2, OPAL_HANDLE_HMI2);
OPAL_CALL(opal_config_cpu_idle_state, OPAL_CONFIG_CPU_IDLE_STATE);
OPAL_CALL(opal_slw_set_reg, OPAL_SLW_SET_REG);
+OPAL_CALL(opal_slw_self_save_reg, OPAL_SLW_SELF_SAVE_REG);
OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION);
OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CAPI_MODE);
--
2.17.1
^ permalink raw reply related
* [PATCH v4 1/3] powerpc/powernv: Interface to define support and preference for a SPR
From: Pratik Rajesh Sampat @ 2020-02-12 11:20 UTC (permalink / raw)
To: linux-kernel, linuxppc-dev, mpe, svaidy, ego, linuxram,
pratik.sampat, psampat, pratik.r.sampat
In-Reply-To: <cover.1581505210.git.psampat@linux.ibm.com>
Define a bitmask interface to determine support for the Self Restore,
Self Save or both.
Also define an interface to determine the preference of that SPR to
be strictly saved or restored or encapsulated with an order of preference.
The preference bitmask is shown as below:
----------------------------
|... | 2nd pref | 1st pref |
----------------------------
MSB LSB
The preference from higher to lower is from LSB to MSB with a shift of 8
bits.
Example:
Prefer self save first, if not available then prefer self
restore
The preference mask for this scenario will be seen as below.
((SELF_RESTORE_STRICT << PREFERENCE_SHIFT) | SELF_SAVE_STRICT)
---------------------------------
|... | Self restore | Self save |
---------------------------------
MSB LSB
Finally, declare a list of preferred SPRs which encapsulate the bitmaks
for preferred and supported with defaults of both being set to support
legacy firmware.
This commit also implements using the above interface and retains the
legacy functionality of self restore.
Signed-off-by: Pratik Rajesh Sampat <psampat@linux.ibm.com>
Reviewed-by: Ram Pai <linuxram@us.ibm.com>
---
arch/powerpc/platforms/powernv/idle.c | 316 +++++++++++++++++++++-----
1 file changed, 259 insertions(+), 57 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 78599bca66c2..03fe835aadd1 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -32,9 +32,112 @@
#define P9_STOP_SPR_MSR 2000
#define P9_STOP_SPR_PSSCR 855
+/* Interface for the stop state supported and preference */
+#define SELF_RESTORE_TYPE 0
+#define SELF_SAVE_TYPE 1
+
+#define NR_PREFERENCES 2
+#define PREFERENCE_SHIFT 4
+#define PREFERENCE_MASK 0xf
+
+#define UNSUPPORTED 0x0
+#define SELF_RESTORE_STRICT 0x1
+#define SELF_SAVE_STRICT 0x2
+
+/*
+ * Bitmask defining the kind of preferences available.
+ * Note : The higher to lower preference is from LSB to MSB, with a shift of
+ * 4 bits.
+ * ----------------------------
+ * | | 2nd pref | 1st pref |
+ * ----------------------------
+ * MSB LSB
+ */
+/* Prefer Restore if available, otherwise unsupported */
+#define PREFER_SELF_RESTORE_ONLY SELF_RESTORE_STRICT
+/* Prefer Save if available, otherwise unsupported */
+#define PREFER_SELF_SAVE_ONLY SELF_SAVE_STRICT
+/* Prefer Restore when available, otherwise prefer Save */
+#define PREFER_RESTORE_SAVE ((SELF_SAVE_STRICT << \
+ PREFERENCE_SHIFT)\
+ | SELF_RESTORE_STRICT)
+/* Prefer Save when available, otherwise prefer Restore*/
+#define PREFER_SAVE_RESTORE ((SELF_RESTORE_STRICT <<\
+ PREFERENCE_SHIFT)\
+ | SELF_SAVE_STRICT)
static u32 supported_cpuidle_states;
struct pnv_idle_states_t *pnv_idle_states;
int nr_pnv_idle_states;
+/* Caching the lpcr & ptcr support to use later */
+static bool is_lpcr_self_save;
+static bool is_ptcr_self_save;
+
+struct preferred_sprs {
+ u64 spr;
+ u32 preferred_mode;
+ u32 supported_mode;
+};
+
+/*
+ * Preferred mode: Order of precedence when both self-save and self-restore
+ * supported
+ * Supported mode: Default support. Can be overwritten during system
+ * initialization
+ */
+struct preferred_sprs preferred_sprs[] = {
+ {
+ .spr = SPRN_HSPRG0,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_LPCR,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_PTCR,
+ .preferred_mode = PREFER_SAVE_RESTORE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_HMEER,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_HID0,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = P9_STOP_SPR_MSR,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = P9_STOP_SPR_PSSCR,
+ .preferred_mode = PREFER_SAVE_RESTORE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_HID1,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_HID4,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ },
+ {
+ .spr = SPRN_HID5,
+ .preferred_mode = PREFER_RESTORE_SAVE,
+ .supported_mode = SELF_RESTORE_STRICT,
+ }
+};
+
+const int nr_preferred_sprs = ARRAY_SIZE(preferred_sprs);
/*
* The default stop state that will be used by ppc_md.power_save
@@ -61,78 +164,170 @@ static bool deepest_stop_found;
static unsigned long power7_offline_type;
-static int pnv_save_sprs_for_deep_states(void)
+static int pnv_self_restore_sprs(u64 pir, int cpu, u64 spr)
{
- int cpu;
+ u64 reg_val;
int rc;
- /*
- * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric across
- * all cpus at boot. Get these reg values of current cpu and use the
- * same across all cpus.
- */
- uint64_t lpcr_val = mfspr(SPRN_LPCR);
- uint64_t hid0_val = mfspr(SPRN_HID0);
- uint64_t hid1_val = mfspr(SPRN_HID1);
- uint64_t hid4_val = mfspr(SPRN_HID4);
- uint64_t hid5_val = mfspr(SPRN_HID5);
- uint64_t hmeer_val = mfspr(SPRN_HMEER);
- uint64_t msr_val = MSR_IDLE;
- uint64_t psscr_val = pnv_deepest_stop_psscr_val;
-
- for_each_present_cpu(cpu) {
- uint64_t pir = get_hard_smp_processor_id(cpu);
- uint64_t hsprg0_val = (uint64_t)paca_ptrs[cpu];
-
- rc = opal_slw_set_reg(pir, SPRN_HSPRG0, hsprg0_val);
+ switch (spr) {
+ case SPRN_HSPRG0:
+ reg_val = (uint64_t)paca_ptrs[cpu];
+ rc = opal_slw_set_reg(pir, SPRN_HSPRG0, reg_val);
if (rc != 0)
return rc;
-
- rc = opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val);
+ break;
+ case SPRN_LPCR:
+ reg_val = mfspr(SPRN_LPCR);
+ rc = opal_slw_set_reg(pir, SPRN_LPCR, reg_val);
if (rc != 0)
return rc;
-
+ break;
+ case P9_STOP_SPR_MSR:
+ reg_val = MSR_IDLE;
if (cpu_has_feature(CPU_FTR_ARCH_300)) {
- rc = opal_slw_set_reg(pir, P9_STOP_SPR_MSR, msr_val);
+ rc = opal_slw_set_reg(pir, P9_STOP_SPR_MSR, reg_val);
if (rc)
return rc;
-
- rc = opal_slw_set_reg(pir,
- P9_STOP_SPR_PSSCR, psscr_val);
-
+ }
+ break;
+ case P9_STOP_SPR_PSSCR:
+ reg_val = pnv_deepest_stop_psscr_val;
+ if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+ rc = opal_slw_set_reg(pir, P9_STOP_SPR_PSSCR, reg_val);
if (rc)
return rc;
}
-
- /* HIDs are per core registers */
+ break;
+ case SPRN_HMEER:
+ reg_val = mfspr(SPRN_HMEER);
if (cpu_thread_in_core(cpu) == 0) {
-
- rc = opal_slw_set_reg(pir, SPRN_HMEER, hmeer_val);
- if (rc != 0)
+ rc = opal_slw_set_reg(pir, SPRN_HMEER, reg_val);
+ if (rc)
return rc;
-
- rc = opal_slw_set_reg(pir, SPRN_HID0, hid0_val);
- if (rc != 0)
+ }
+ break;
+ case SPRN_HID0:
+ reg_val = mfspr(SPRN_HID0);
+ if (cpu_thread_in_core(cpu) == 0) {
+ rc = opal_slw_set_reg(pir, SPRN_HID0, reg_val);
+ if (rc)
return rc;
+ }
+ break;
+ case SPRN_HID1:
+ reg_val = mfspr(SPRN_HID1);
+ if (cpu_thread_in_core(cpu) == 0 &&
+ !cpu_has_feature(CPU_FTR_ARCH_300)) {
+ rc = opal_slw_set_reg(pir, SPRN_HID1, reg_val);
+ if (rc)
+ return rc;
+ }
+ break;
+ case SPRN_HID4:
+ reg_val = mfspr(SPRN_HID4);
+ if (cpu_thread_in_core(cpu) == 0 &&
+ !cpu_has_feature(CPU_FTR_ARCH_300)) {
+ rc = opal_slw_set_reg(pir, SPRN_HID4, reg_val);
+ if (rc)
+ return rc;
+ }
+ break;
+ case SPRN_HID5:
+ reg_val = mfspr(SPRN_HID5);
+ if (cpu_thread_in_core(cpu) == 0 &&
+ !cpu_has_feature(CPU_FTR_ARCH_300)) {
+ rc = opal_slw_set_reg(pir, SPRN_HID5, reg_val);
+ if (rc)
+ return rc;
+ }
+ break;
+ case SPRN_PTCR:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- /* Only p8 needs to set extra HID regiters */
- if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
-
- rc = opal_slw_set_reg(pir, SPRN_HID1, hid1_val);
- if (rc != 0)
- return rc;
-
- rc = opal_slw_set_reg(pir, SPRN_HID4, hid4_val);
- if (rc != 0)
- return rc;
-
- rc = opal_slw_set_reg(pir, SPRN_HID5, hid5_val);
- if (rc != 0)
- return rc;
+static int pnv_self_save_restore_sprs(void)
+{
+ int rc, index, cpu, k;
+ u64 pir;
+ struct preferred_sprs curr_spr;
+ bool is_initialized;
+ u32 preferred;
+
+ is_lpcr_self_save = false;
+ is_ptcr_self_save = false;
+ for_each_present_cpu(cpu) {
+ pir = get_hard_smp_processor_id(cpu);
+ for (index = 0; index < nr_preferred_sprs; index++) {
+ curr_spr = preferred_sprs[index];
+ is_initialized = false;
+ /*
+ * Go through each of the preferences
+ * Check if it is preferred as well as supported
+ */
+ for (k = 0; k < NR_PREFERENCES; k++) {
+ preferred = curr_spr.preferred_mode
+ & PREFERENCE_MASK;
+ if (preferred & curr_spr.supported_mode
+ & SELF_RESTORE_STRICT) {
+ is_initialized = true;
+ rc = pnv_self_restore_sprs(pir, cpu,
+ curr_spr.spr);
+ if (rc != 0)
+ return rc;
+ break;
+ }
+ preferred_sprs[index].preferred_mode =
+ preferred_sprs[index].preferred_mode >>
+ PREFERENCE_SHIFT;
+ curr_spr = preferred_sprs[index];
+ }
+ if (!is_initialized) {
+ if (preferred_sprs[index].spr == SPRN_PTCR ||
+ (cpu_has_feature(CPU_FTR_ARCH_300) &&
+ (preferred_sprs[index].spr == SPRN_HID1 ||
+ preferred_sprs[index].spr == SPRN_HID4 ||
+ preferred_sprs[index].spr == SPRN_HID5)))
+ continue;
+ return OPAL_UNSUPPORTED;
}
}
}
+ return 0;
+}
+static int pnv_save_sprs_for_deep_states(void)
+{
+ int rc;
+ int index;
+
+ /*
+ * Iterate over the preffered SPRs and if even one of them is
+ * still unsupported We cut support for deep stop states
+ */
+ for (index = 0; index < nr_preferred_sprs; index++) {
+ if (preferred_sprs[index].supported_mode == UNSUPPORTED) {
+ if (preferred_sprs[index].spr == SPRN_PTCR ||
+ (cpu_has_feature(CPU_FTR_ARCH_300) &&
+ (preferred_sprs[index].spr == SPRN_HID1 ||
+ preferred_sprs[index].spr == SPRN_HID4 ||
+ preferred_sprs[index].spr == SPRN_HID5)))
+ continue;
+ return OPAL_UNSUPPORTED;
+ }
+ }
+ /*
+ * Try to self-restore the registers that can be self restored if self
+ * restore is active, try the same for the registers that
+ * can be self saved too.
+ * Note : If both are supported, self restore is given more priority
+ */
+ rc = pnv_self_save_restore_sprs();
+ if (rc != 0)
+ return rc;
return 0;
}
@@ -658,7 +853,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
mmcr0 = mfspr(SPRN_MMCR0);
}
if ((psscr & PSSCR_RL_MASK) >= pnv_first_spr_loss_level) {
- sprs.lpcr = mfspr(SPRN_LPCR);
+ if (!is_lpcr_self_save)
+ sprs.lpcr = mfspr(SPRN_LPCR);
sprs.hfscr = mfspr(SPRN_HFSCR);
sprs.fscr = mfspr(SPRN_FSCR);
sprs.pid = mfspr(SPRN_PID);
@@ -672,7 +868,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
sprs.mmcr1 = mfspr(SPRN_MMCR1);
sprs.mmcr2 = mfspr(SPRN_MMCR2);
- sprs.ptcr = mfspr(SPRN_PTCR);
+ if (!is_ptcr_self_save)
+ sprs.ptcr = mfspr(SPRN_PTCR);
sprs.rpr = mfspr(SPRN_RPR);
sprs.tscr = mfspr(SPRN_TSCR);
if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
@@ -756,7 +953,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
goto core_woken;
/* Per-core SPRs */
- mtspr(SPRN_PTCR, sprs.ptcr);
+ if (!is_ptcr_self_save)
+ mtspr(SPRN_PTCR, sprs.ptcr);
mtspr(SPRN_RPR, sprs.rpr);
mtspr(SPRN_TSCR, sprs.tscr);
@@ -777,7 +975,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
atomic_unlock_and_stop_thread_idle();
/* Per-thread SPRs */
- mtspr(SPRN_LPCR, sprs.lpcr);
+ if (!is_lpcr_self_save)
+ mtspr(SPRN_LPCR, sprs.lpcr);
mtspr(SPRN_HFSCR, sprs.hfscr);
mtspr(SPRN_FSCR, sprs.fscr);
mtspr(SPRN_PID, sprs.pid);
@@ -956,8 +1155,11 @@ void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val)
* Program the LPCR via stop-api only if the deepest stop state
* can lose hypervisor context.
*/
- if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT)
- opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val);
+ if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) {
+ if (!is_lpcr_self_save)
+ opal_slw_set_reg(pir, SPRN_LPCR,
+ lpcr_val);
+ }
}
/*
--
2.17.1
^ permalink raw reply related
* [PATCH] powerpc/32s: Fix DSI and ISI exceptions for CONFIG_VMAP_STACK
From: Christophe Leroy @ 2020-02-12 11:47 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Erhard F.
Cc: linuxppc-dev, linux-kernel
hash_page() needs to read page tables from kernel memory. When entire
kernel memory is mapped by BATs, which is normally the case when
CONFIG_STRICT_KERNEL_RWX is not set, it works even if the page hosting
the page table is not referenced in the MMU hash table.
However, if the page where the page table resides is not covered by
a BAT, a DSI fault can be encountered from hash_page(), and it loops
forever. This can happen when CONFIG_STRICT_KERNEL_RWX is selected
and the alignment of the different regions is too small to allow
covering the entire memory with BATs. This also happens when
CONFIG_DEBUG_PAGEALLOC is selected or when booting with 'nobats'
flag.
Also, if the page containing the kernel stack is not present in the
MMU hash table, registers cannot be saved and a recursive DSI fault
is encountered.
To allow hash_page() to properly do its job at all time and load the
MMU hash table whenever needed, it must run with data MMU disabled.
This means it must be called before re-enabling data MMU. To allow
this, registers clobbered by hash_page() and create_hpte() have to
be save in the thread struct together with SRR0, SSR1, DAR and DSISR.
This also fixes the Oops reported by Erhard when create_hpte() is
called by add_hash_page().
Fixes: cd08f109e262 ("powerpc/32s: Enable CONFIG_VMAP_STACK")
Reported-by: Erhard F. <erhard_f@mailbox.org>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206501
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/processor.h | 4 +
arch/powerpc/kernel/asm-offsets.c | 11 +++
arch/powerpc/kernel/head_32.S | 119 +++++++++++++++++++++++++++
arch/powerpc/mm/book3s32/hash_low.S | 52 ++++++------
arch/powerpc/mm/book3s32/mmu.c | 7 +-
5 files changed, 158 insertions(+), 35 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 8387698bd5b6..437481a329ce 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -168,6 +168,10 @@ struct thread_struct {
unsigned long srr1;
unsigned long dar;
unsigned long dsisr;
+#ifdef CONFIG_PPC_BOOK3S_32
+ unsigned long r0, r3, r4, r5, r6, r8, r9;
+ unsigned long lr, ctr;
+#endif
#endif
/* Debug Registers */
struct debug_reg debug;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index c25e562f1cd9..6519f9011ca6 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -132,6 +132,17 @@ int main(void)
OFFSET(SRR1, thread_struct, srr1);
OFFSET(DAR, thread_struct, dar);
OFFSET(DSISR, thread_struct, dsisr);
+#ifdef CONFIG_PPC_BOOK3S_32
+ OFFSET(THR0, thread_struct, r0);
+ OFFSET(THR3, thread_struct, r3);
+ OFFSET(THR4, thread_struct, r4);
+ OFFSET(THR5, thread_struct, r5);
+ OFFSET(THR6, thread_struct, r6);
+ OFFSET(THR8, thread_struct, r8);
+ OFFSET(THR9, thread_struct, r9);
+ OFFSET(THLR, thread_struct, lr);
+ OFFSET(THCTR, thread_struct, ctr);
+#endif
#endif
#ifdef CONFIG_SPE
OFFSET(THREAD_EVR0, thread_struct, evr[0]);
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 0493fcac6409..061dee186737 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -301,6 +301,36 @@ MachineCheck:
. = 0x300
DO_KVM 0x300
DataAccess:
+#ifdef CONFIG_VMAP_STACK
+ mtspr SPRN_SPRG_SCRATCH0,r10
+ mtspr SPRN_SPRG_SCRATCH1,r11
+ mfspr r10, SPRN_SPRG_THREAD
+ mfspr r11, SPRN_DAR
+ stw r11, DAR(r10)
+ mfspr r11, SPRN_DSISR
+ stw r11, DSISR(r10)
+ mfspr r11, SPRN_SRR0
+ stw r11, SRR0(r10)
+ mfspr r11, SPRN_SRR1 /* check whether user or kernel */
+ stw r11, SRR1(r10)
+ mfcr r10
+BEGIN_MMU_FTR_SECTION
+ mfspr r11, SPRN_DSISR
+#ifdef CONFIG_PPC_KUAP
+ andis. r11, r11, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH | DSISR_PROTFAULT)@h
+#else
+ andis. r11, r11, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
+#endif
+ beq hash_page_dsi
+.Lhash_page_dsi_cont:
+ mfspr r11, SPRN_SRR1 /* check whether user or kernel */
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
+ andi. r11, r11, MSR_PR
+
+ EXCEPTION_PROLOG_1
+ EXCEPTION_PROLOG_2 handle_dar_dsisr=1
+ b handle_page_fault_tramp_1
+#else /* CONFIG_VMAP_STACK */
EXCEPTION_PROLOG handle_dar_dsisr=1
get_and_save_dar_dsisr_on_stack r4, r5, r11
BEGIN_MMU_FTR_SECTION
@@ -316,11 +346,32 @@ BEGIN_MMU_FTR_SECTION
FTR_SECTION_ELSE
b handle_page_fault_tramp_2
ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
+#endif /* CONFIG_VMAP_STACK */
/* Instruction access exception. */
. = 0x400
DO_KVM 0x400
InstructionAccess:
+#ifdef CONFIG_VMAP_STACK
+ mtspr SPRN_SPRG_SCRATCH0,r10
+ mtspr SPRN_SPRG_SCRATCH1,r11
+ mfspr r10, SPRN_SPRG_THREAD
+ mfspr r11, SPRN_SRR0
+ stw r11, SRR0(r10)
+ mfspr r11, SPRN_SRR1 /* check whether user or kernel */
+ stw r11, SRR1(r10)
+ mfcr r10
+BEGIN_MMU_FTR_SECTION
+ andis. r11, r11, SRR1_ISI_NOPT@h /* no pte found? */
+ bne hash_page_isi
+.Lhash_page_isi_cont:
+ mfspr r11, SPRN_SRR1 /* check whether user or kernel */
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
+ andi. r11, r11, MSR_PR
+
+ EXCEPTION_PROLOG_1
+ EXCEPTION_PROLOG_2
+#else /* CONFIG_VMAP_STACK */
EXCEPTION_PROLOG
andis. r0,r9,SRR1_ISI_NOPT@h /* no pte found? */
beq 1f /* if so, try to put a PTE */
@@ -329,6 +380,7 @@ InstructionAccess:
BEGIN_MMU_FTR_SECTION
bl hash_page
END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
+#endif /* CONFIG_VMAP_STACK */
1: mr r4,r12
andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
stw r4, _DAR(r11)
@@ -652,8 +704,75 @@ handle_page_fault_tramp_1:
handle_page_fault_tramp_2:
EXC_XFER_LITE(0x300, handle_page_fault)
+#ifdef CONFIG_VMAP_STACK
+.macro save_regs_thread thread
+ stw r0, THR0(\thread)
+ stw r3, THR3(\thread)
+ stw r4, THR4(\thread)
+ stw r5, THR5(\thread)
+ stw r6, THR6(\thread)
+ stw r8, THR8(\thread)
+ stw r9, THR9(\thread)
+ mflr r0
+ stw r0, THLR(\thread)
+ mfctr r0
+ stw r0, THCTR(\thread)
+.endm
+
+.macro restore_regs_thread thread
+ lwz r0, THLR(\thread)
+ mtlr r0
+ lwz r0, THCTR(\thread)
+ mtctr r0
+ lwz r0, THR0(\thread)
+ lwz r3, THR3(\thread)
+ lwz r4, THR4(\thread)
+ lwz r5, THR5(\thread)
+ lwz r6, THR6(\thread)
+ lwz r8, THR8(\thread)
+ lwz r9, THR9(\thread)
+.endm
+
+hash_page_dsi:
+ mr r11, r10
+ mfspr r10, SPRN_SPRG_THREAD
+ save_regs_thread r10
+ lwz r3, DSISR(r10)
+ mfdar r4
+ lwz r9, SRR1(r10)
+ rlwinm r3, r3, 32 - 15, 21, 21 /* DSISR_STORE -> _PAGE_RW */
+ bl hash_page
+ mfspr r10, SPRN_SPRG_THREAD
+ restore_regs_thread r10
+ mr r10, r11
+ b .Lhash_page_dsi_cont
+
+hash_page_isi:
+ mr r11, r10
+ mfspr r10, SPRN_SPRG_THREAD
+ save_regs_thread r10
+ li r3, 0
+ lwz r4, SRR0(r10)
+ lwz r9, SRR1(r10)
+ bl hash_page
+ mfspr r10, SPRN_SPRG_THREAD
+ restore_regs_thread r10
+ mr r10, r11
+ b .Lhash_page_isi_cont
+
+ .globl fast_hash_page_return
+fast_hash_page_return:
+ mfspr r10, SPRN_SPRG_THREAD
+ restore_regs_thread r10
+ mtcr r11
+ mfspr r10, SPRN_SPRG_SCRATCH0
+ mfspr r11, SPRN_SPRG_SCRATCH1
+ SYNC
+ RFI
+
stack_overflow:
vmap_stack_overflow_exception
+#endif
AltiVecUnavailable:
EXCEPTION_PROLOG
diff --git a/arch/powerpc/mm/book3s32/hash_low.S b/arch/powerpc/mm/book3s32/hash_low.S
index c11b0a005196..2015c4f96238 100644
--- a/arch/powerpc/mm/book3s32/hash_low.S
+++ b/arch/powerpc/mm/book3s32/hash_low.S
@@ -25,12 +25,6 @@
#include <asm/feature-fixups.h>
#include <asm/code-patching-asm.h>
-#ifdef CONFIG_VMAP_STACK
-#define ADDR_OFFSET 0
-#else
-#define ADDR_OFFSET PAGE_OFFSET
-#endif
-
#ifdef CONFIG_SMP
.section .bss
.align 2
@@ -53,8 +47,8 @@ mmu_hash_lock:
.text
_GLOBAL(hash_page)
#ifdef CONFIG_SMP
- lis r8, (mmu_hash_lock - ADDR_OFFSET)@h
- ori r8, r8, (mmu_hash_lock - ADDR_OFFSET)@l
+ lis r8, (mmu_hash_lock - PAGE_OFFSET)@h
+ ori r8, r8, (mmu_hash_lock - PAGE_OFFSET)@l
lis r0,0x0fff
b 10f
11: lwz r6,0(r8)
@@ -72,12 +66,9 @@ _GLOBAL(hash_page)
cmplw 0,r4,r0
ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
mfspr r5, SPRN_SPRG_PGDIR /* phys page-table root */
-#ifdef CONFIG_VMAP_STACK
- tovirt(r5, r5)
-#endif
blt+ 112f /* assume user more likely */
- lis r5, (swapper_pg_dir - ADDR_OFFSET)@ha /* if kernel address, use */
- addi r5 ,r5 ,(swapper_pg_dir - ADDR_OFFSET)@l /* kernel page table */
+ lis r5, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
+ addi r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */
112:
#ifndef CONFIG_PTE_64BIT
@@ -89,9 +80,6 @@ _GLOBAL(hash_page)
lwzx r8,r8,r5 /* Get L1 entry */
rlwinm. r8,r8,0,0,20 /* extract pt base address */
#endif
-#ifdef CONFIG_VMAP_STACK
- tovirt(r8, r8)
-#endif
#ifdef CONFIG_SMP
beq- hash_page_out /* return if no mapping */
#else
@@ -143,30 +131,36 @@ retry:
bne- retry /* retry if someone got there first */
mfsrin r3,r4 /* get segment reg for segment */
+#ifndef CONFIG_VMAP_STACK
mfctr r0
stw r0,_CTR(r11)
+#endif
bl create_hpte /* add the hash table entry */
#ifdef CONFIG_SMP
eieio
- lis r8, (mmu_hash_lock - ADDR_OFFSET)@ha
+ lis r8, (mmu_hash_lock - PAGE_OFFSET)@ha
li r0,0
- stw r0, (mmu_hash_lock - ADDR_OFFSET)@l(r8)
+ stw r0, (mmu_hash_lock - PAGE_OFFSET)@l(r8)
#endif
+#ifdef CONFIG_VMAP_STACK
+ b fast_hash_page_return
+#else
/* Return from the exception */
lwz r5,_CTR(r11)
mtctr r5
lwz r0,GPR0(r11)
lwz r8,GPR8(r11)
b fast_exception_return
+#endif
#ifdef CONFIG_SMP
hash_page_out:
eieio
- lis r8, (mmu_hash_lock - ADDR_OFFSET)@ha
+ lis r8, (mmu_hash_lock - PAGE_OFFSET)@ha
li r0,0
- stw r0, (mmu_hash_lock - ADDR_OFFSET)@l(r8)
+ stw r0, (mmu_hash_lock - PAGE_OFFSET)@l(r8)
blr
#endif /* CONFIG_SMP */
@@ -341,7 +335,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
patch_site 1f, patch__hash_page_A1
patch_site 2f, patch__hash_page_A2
/* Get the address of the primary PTE group in the hash table (r3) */
-0: lis r0, (Hash_base - ADDR_OFFSET)@h /* base address of hash table */
+0: lis r0, (Hash_base - PAGE_OFFSET)@h /* base address of hash table */
1: rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */
2: rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
xor r3,r3,r0 /* make primary hash */
@@ -355,10 +349,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
beq+ 10f /* no PTE: go look for an empty slot */
tlbie r4
- lis r4, (htab_hash_searches - ADDR_OFFSET)@ha
- lwz r6, (htab_hash_searches - ADDR_OFFSET)@l(r4)
+ lis r4, (htab_hash_searches - PAGE_OFFSET)@ha
+ lwz r6, (htab_hash_searches - PAGE_OFFSET)@l(r4)
addi r6,r6,1 /* count how many searches we do */
- stw r6, (htab_hash_searches - ADDR_OFFSET)@l(r4)
+ stw r6, (htab_hash_searches - PAGE_OFFSET)@l(r4)
/* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
mtctr r0
@@ -390,10 +384,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
beq+ found_empty
/* update counter of times that the primary PTEG is full */
- lis r4, (primary_pteg_full - ADDR_OFFSET)@ha
- lwz r6, (primary_pteg_full - ADDR_OFFSET)@l(r4)
+ lis r4, (primary_pteg_full - PAGE_OFFSET)@ha
+ lwz r6, (primary_pteg_full - PAGE_OFFSET)@l(r4)
addi r6,r6,1
- stw r6, (primary_pteg_full - ADDR_OFFSET)@l(r4)
+ stw r6, (primary_pteg_full - PAGE_OFFSET)@l(r4)
patch_site 0f, patch__hash_page_C
/* Search the secondary PTEG for an empty slot */
@@ -427,8 +421,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
* lockup here but that shouldn't happen
*/
-1: lis r4, (next_slot - ADDR_OFFSET)@ha /* get next evict slot */
- lwz r6, (next_slot - ADDR_OFFSET)@l(r4)
+1: lis r4, (next_slot - PAGE_OFFSET)@ha /* get next evict slot */
+ lwz r6, (next_slot - PAGE_OFFSET)@l(r4)
addi r6,r6,HPTE_SIZE /* search for candidate */
andi. r6,r6,7*HPTE_SIZE
stw r6,next_slot@l(r4)
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 0a1c65a2c565..b47c75f5386d 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -413,7 +413,7 @@ void __init MMU_init_hw(void)
void __init MMU_init_hw_patch(void)
{
unsigned int hmask = Hash_mask >> (16 - LG_HPTEG_SIZE);
- unsigned int hash;
+ unsigned int hash = (unsigned int)Hash - PAGE_OFFSET;
if (ppc_md.progress)
ppc_md.progress("hash:patch", 0x345);
@@ -425,11 +425,6 @@ void __init MMU_init_hw_patch(void)
/*
* Patch up the instructions in hashtable.S:create_hpte
*/
- if (IS_ENABLED(CONFIG_VMAP_STACK))
- hash = (unsigned int)Hash;
- else
- hash = (unsigned int)Hash - PAGE_OFFSET;
-
modify_instruction_site(&patch__hash_page_A0, 0xffff, hash >> 16);
modify_instruction_site(&patch__hash_page_A1, 0x7c0, hash_mb << 6);
modify_instruction_site(&patch__hash_page_A2, 0x7c0, hash_mb2 << 6);
--
2.25.0
^ permalink raw reply related
* [Bug 206501] Kernel 5.6-rc1 fails to boot on a PowerMac G4 3,6 with CONFIG_VMAP_STACK=y: Oops! Machine check, sig: 7 [#1]
From: bugzilla-daemon @ 2020-02-12 11:53 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-206501-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=206501
--- Comment #3 from Christophe Leroy (christophe.leroy@c-s.fr) ---
Could you also test the patch https://patchwork.ozlabs.org/patch/1236804/
instead of the above patch.
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* Re: [PATCH v6 4/4] powerpc: Book3S 64-bit "heavyweight" KASAN support
From: Daniel Axtens @ 2020-02-12 12:16 UTC (permalink / raw)
To: Christophe Leroy, linux-kernel, linux-mm, linuxppc-dev, kasan-dev,
aneesh.kumar, bsingharora
In-Reply-To: <5e392944-50ac-ed06-5896-2664894335d9@c-s.fr>
Christophe Leroy <christophe.leroy@c-s.fr> writes:
> Le 12/02/2020 à 11:12, Daniel Axtens a écrit :
>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>
>>> Le 12/02/2020 à 06:47, Daniel Axtens a écrit :
>>>> diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
>>>> index fbff9ff9032e..2911fdd3a6a0 100644
>>>> --- a/arch/powerpc/include/asm/kasan.h
>>>> +++ b/arch/powerpc/include/asm/kasan.h
>>>> @@ -2,6 +2,8 @@
>>>> #ifndef __ASM_KASAN_H
>>>> #define __ASM_KASAN_H
>>>>
>>>> +#include <asm/page.h>
>>>> +
>>>> #ifdef CONFIG_KASAN
>>>> #define _GLOBAL_KASAN(fn) _GLOBAL(__##fn)
>>>> #define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(__##fn)
>>>> @@ -14,29 +16,41 @@
>>>>
>>>> #ifndef __ASSEMBLY__
>>>>
>>>> -#include <asm/page.h>
>>>> -
>>>> #define KASAN_SHADOW_SCALE_SHIFT 3
>>>>
>>>> #define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
>>>> (PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
>>>>
>>>> +#ifdef CONFIG_KASAN_SHADOW_OFFSET
>>>> #define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET)
>>>> +#endif
>>>>
>>>> +#ifdef CONFIG_PPC32
>>>> #define KASAN_SHADOW_END 0UL
>>>>
>>>> -#define KASAN_SHADOW_SIZE (KASAN_SHADOW_END - KASAN_SHADOW_START)
>>>> +#ifdef CONFIG_KASAN
>>>> +void kasan_late_init(void);
>>>> +#else
>>>> +static inline void kasan_late_init(void) { }
>>>> +#endif
>>>> +
>>>> +#endif
>>>> +
>>>> +#ifdef CONFIG_PPC_BOOK3S_64
>>>> +#define KASAN_SHADOW_END (KASAN_SHADOW_OFFSET + \
>>>> + (RADIX_VMEMMAP_END >> KASAN_SHADOW_SCALE_SHIFT))
>>>> +
>>>> +static inline void kasan_late_init(void) { }
>>>> +#endif
>>>>
>>>> #ifdef CONFIG_KASAN
>>>> void kasan_early_init(void);
>>>> void kasan_mmu_init(void);
>>>> void kasan_init(void);
>>>> -void kasan_late_init(void);
>>>> #else
>>>> static inline void kasan_init(void) { }
>>>> static inline void kasan_mmu_init(void) { }
>>>> -static inline void kasan_late_init(void) { }
>>>> #endif
>>>
>>> Why modify all this kasan_late_init() stuff ?
>>>
>>> This function is only called from kasan init_32.c, it is never called by
>>> PPC64, so you should not need to modify anything at all.
>>
>> I got a compile error for a missing symbol. I'll repro it and attach it.
>>
>
> Oops, sorry. I looked too quickly. It is defined in kasan_init_32.c and
> called from mm/mem.c
>
> We don't have a performance issue here, since this is called only once
> during startup. Could you define an empty kasan_late_init() in
> init_book3s_64.c instead ?
Yeah, I can do that, will respin tomorrow.
Would you mind having a quick check of the documentation changes in
patches 2 and 4? I just want to confirm I've accurately captured the
state of ppc32 kasan work.
Thanks!
Daniel
>
> Christophe
^ permalink raw reply
* Re: QEMU/KVM snapshot restore bug
From: Greg Kurz @ 2020-02-12 11:05 UTC (permalink / raw)
To: dftxbs3e; +Cc: linuxppc-dev, Cédric Le Goater
In-Reply-To: <7544eb90-71a6-3709-c530-9c83beb943a7@free.fr>
[-- Attachment #1: Type: text/plain, Size: 5340 bytes --]
On Tue, 11 Feb 2020 04:57:52 +0100
dftxbs3e <dftxbs3e@free.fr> wrote:
> Hello,
>
> I took a snapshot of a ppc64 (big endian) VM from a ppc64 (little endian) host using `virsh snapshot-create-as --domain <name> --name <name>`
>
A big endian guest doing XIVE ?!? I'm pretty sure we didn't do much testing, if
any, on such a setup... What distro is used in the VM ?
> Then I restarted my system and tried restoring the snapshot:
>
> # virsh snapshot-revert --domain <name> --snapshotname <name>
> error: internal error: process exited while connecting to monitor: 2020-02-11T03:18:08.110582Z qemu-system-ppc64: KVM_SET_DEVICE_ATTR failed: Group 3 attr 0x0000000000001309: Device or resource busy
> 2020-02-11T03:18:08.110605Z qemu-system-ppc64: error while loading state for instance 0x0 of device 'spapr'
> 2020-02-11T03:18:08.112843Z qemu-system-ppc64: Error -1 while loading VM state
>
This indicates that QEMU failed to configure the source targeting
for the HW interrupt 0x1309, which is an MSI interrupt used by
a PCI device plugged in the default PHB. Especially, -EBUSY means
-EBUSY: No CPU available to serve interrupt
> And dmesg shows each time the restore command is executed:
>
> [ 180.176606] WARNING: CPU: 16 PID: 5528 at arch/powerpc/kvm/book3s_xive.c:345 xive_try_pick_queue+0x40/0xb8 [kvm]
This warning means that we have vCPU without a configured event queue.
Since kvmppc_xive_select_target() is trying all vCPUs before bailing out
with -EBUSY, you might be seeing several WARNINGs (1 per vCPU) in dmesg,
correct ?
Anyway, this looks wrong since QEMU is supposed to have already configured
the event queues at this point... Not sure what's happening here...
> [ 180.176608] Modules linked in: vhost_net vhost tap kvm_hv kvm xt_CHECKSUM xt_MASQUERADE nf_nat_tftp nf_conntrack_tftp tun bridge 8021q garp mrp stp llc rfkill nf_conntrack_netbios_ns nf_conntrack_broadcast xt_CT ip6t_REJECT nf_reject_ipv6 ip6t_rpfilter ipt_REJECT nf_reject_ipv4 xt_conntrack ebtable_nat ebtable_broute ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat iptable_mangle iptable_raw iptable_security nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nfnetlink ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter sunrpc raid1 at24 regmap_i2c snd_hda_codec_hdmi snd_hda_intel snd_intel_dspcfg joydev snd_hda_codec snd_hda_core ofpart snd_hwdep crct10dif_vpmsum snd_seq ipmi_powernv powernv_flash ipmi_devintf snd_seq_device mtd ipmi_msghandler rtc_opal snd_pcm opal_prd i2c_opal snd_timer snd soundcore lz4 lz4_compress zram ip_tables xfs libcrc32c dm_crypt amdgpu ast drm_vram_helper mfd_core i2c_algo_bit gpu_sched drm_kms_helper mpt3sas
> [ 180.176652] syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm vmx_crypto tg3 crc32c_vpmsum nvme raid_class scsi_transport_sas nvme_core drm_panel_orientation_quirks i2c_core fuse
> [ 180.176663] CPU: 16 PID: 5528 Comm: qemu-system-ppc Not tainted 5.4.17-200.fc31.ppc64le #1
> [ 180.176665] NIP: c00800000a883c80 LR: c00800000a886db8 CTR: c00800000a88a9e0
> [ 180.176667] REGS: c000000767a17890 TRAP: 0700 Not tainted (5.4.17-200.fc31.ppc64le)
> [ 180.176668] MSR: 9000000000029033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 48224248 XER: 20040000
> [ 180.176673] CFAR: c00800000a886db4 IRQMASK: 0
> GPR00: c00800000a886db8 c000000767a17b20 c00800000a8aed00 c0002005468a4480
> GPR04: 0000000000000000 0000000000000000 0000000000000000 0000000000000001
> GPR08: c0002007142b2400 c0002007142b2400 0000000000000000 c00800000a8910f0
> GPR12: c00800000a88a488 c0000007fffed000 0000000000000000 0000000000000000
> GPR16: 0000000149524180 00007ffff39bda78 00007ffff39bda30 000000000000025c
> GPR20: 0000000000000000 0000000000000003 c0002006f13a0000 0000000000000000
> GPR24: 0000000000001359 0000000000000000 c0000002f8c96c38 c0000002f8c80000
> GPR28: 0000000000000000 c0002006f13a0000 c0002006f13a4038 c000000767a17be4
> [ 180.176688] NIP [c00800000a883c80] xive_try_pick_queue+0x40/0xb8 [kvm]
> [ 180.176693] LR [c00800000a886db8] kvmppc_xive_select_target+0x100/0x210 [kvm]
> [ 180.176694] Call Trace:
> [ 180.176696] [c000000767a17b20] [c000000767a17b70] 0xc000000767a17b70 (unreliable)
> [ 180.176701] [c000000767a17b70] [c00800000a88b420] kvmppc_xive_native_set_attr+0xf98/0x1760 [kvm]
> [ 180.176705] [c000000767a17cc0] [c00800000a86392c] kvm_device_ioctl+0xf4/0x180 [kvm]
> [ 180.176710] [c000000767a17d10] [c0000000005380b0] do_vfs_ioctl+0xaa0/0xd90
> [ 180.176712] [c000000767a17dd0] [c000000000538464] sys_ioctl+0xc4/0x110
> [ 180.176716] [c000000767a17e20] [c00000000000b9d0] system_call+0x5c/0x68
> [ 180.176717] Instruction dump:
> [ 180.176719] 794ad182 0b0a0000 2c290000 41820080 89490010 2c0a0000 41820074 78883664
> [ 180.176723] 7d094214 e9480070 7d470074 78e7d182 <0b070000> 2c2a0000 41820054 81480078
> [ 180.176727] ---[ end trace 056a6dd275e20684 ]---
>
> Let me know if I can provide more information
Yeah, QEMU command line, QEMU version, guest kernel version can help. Also,
what kind of workload is running inside the guest ? Is this easy to reproduce ?
Cheers,
--
Greg
>
> Thanks
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Stephen Smalley @ 2020-02-12 13:32 UTC (permalink / raw)
To: Alexey Budankov
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <2e38c33d-f085-1320-8cc2-45f74b6ad86d@linux.intel.com>
On 2/12/20 3:53 AM, Alexey Budankov wrote:
> Hi Stephen,
>
> On 22.01.2020 17:07, Stephen Smalley wrote:
>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>
>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>
>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>
>>>>>>
>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>
> <SNIP>
>>>>>>>> Introduce CAP_PERFMON capability designed to secure system performance
>>>>>>>
>>>>>>> Why _noaudit()? Normally only used when a permission failure is non-fatal to the operation. Otherwise, we want the audit message.
>>>
>>> So far so good, I suggest using the simplest version for v6:
>>>
>>> static inline bool perfmon_capable(void)
>>> {
>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>> }
>>>
>>> It keeps the implementation simple and readable. The implementation is more
>>> performant in the sense of calling the API - one capable() call for CAP_PERFMON
>>> privileged process.
>>>
>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and unprivileged processes,
>>> but this bloating also advertises and leverages using more secure CAP_PERFMON
>>> based approach to use perf_event_open system call.
>>
>> I can live with that. We just need to document that when you see both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process, try only allowing CAP_PERFMON first and see if that resolves the issue. We have a similar issue with CAP_DAC_READ_SEARCH versus CAP_DAC_OVERRIDE.
>
> I am trying to reproduce this double logging with CAP_PERFMON.
> I am using the refpolicy version with enabled perf_event tclass [1], in permissive mode.
> When running perf stat -a I am observing this AVC audit messages:
>
> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
> type=AVC msg=audit(1581496695.666:8692): avc: denied { write } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>
> However there is no capability related messages around. I suppose my refpolicy should
> be modified somehow to observe capability related AVCs.
>
> Could you please comment or clarify on how to enable caps related AVCs in order
> to test the concerned logging.
The new perfmon permission has to be defined in your policy; you'll have
a message in dmesg about "Permission perfmon in class capability2 not
defined in policy.". You can either add it to the common cap2
definition in refpolicy/policy/flask/access_vectors and rebuild your
policy or extract your base module as CIL, add it there, and insert the
updated module.
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Alexey Budankov @ 2020-02-12 13:53 UTC (permalink / raw)
To: Stephen Smalley
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <dd6a1382-7b2f-a6e6-a1ac-009566d7f556@tycho.nsa.gov>
On 12.02.2020 16:32, Stephen Smalley wrote:
> On 2/12/20 3:53 AM, Alexey Budankov wrote:
>> Hi Stephen,
>>
>> On 22.01.2020 17:07, Stephen Smalley wrote:
>>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>>
>>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>>
>>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>>
>> <SNIP>
>>>>>>>>> Introduce CAP_PERFMON capability designed to secure system performance
>>>>>>>>
>>>>>>>> Why _noaudit()? Normally only used when a permission failure is non-fatal to the operation. Otherwise, we want the audit message.
>>>>
>>>> So far so good, I suggest using the simplest version for v6:
>>>>
>>>> static inline bool perfmon_capable(void)
>>>> {
>>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>>> }
>>>>
>>>> It keeps the implementation simple and readable. The implementation is more
>>>> performant in the sense of calling the API - one capable() call for CAP_PERFMON
>>>> privileged process.
>>>>
>>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and unprivileged processes,
>>>> but this bloating also advertises and leverages using more secure CAP_PERFMON
>>>> based approach to use perf_event_open system call.
>>>
>>> I can live with that. We just need to document that when you see both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process, try only allowing CAP_PERFMON first and see if that resolves the issue. We have a similar issue with CAP_DAC_READ_SEARCH versus CAP_DAC_OVERRIDE.
>>
>> I am trying to reproduce this double logging with CAP_PERFMON.
>> I am using the refpolicy version with enabled perf_event tclass [1], in permissive mode.
>> When running perf stat -a I am observing this AVC audit messages:
>>
>> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>> type=AVC msg=audit(1581496695.666:8692): avc: denied { write } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>
>> However there is no capability related messages around. I suppose my refpolicy should
>> be modified somehow to observe capability related AVCs.
>>
>> Could you please comment or clarify on how to enable caps related AVCs in order
>> to test the concerned logging.
>
> The new perfmon permission has to be defined in your policy; you'll have a message in dmesg about "Permission perfmon in class capability2 not defined in policy.". You can either add it to the common cap2 definition in refpolicy/policy/flask/access_vectors and rebuild your policy or extract your base module as CIL, add it there, and insert the updated module.
Yes, I already have it like this:
common cap2
{
<------>mac_override<--># unused by SELinux
<------>mac_admin
<------>syslog
<------>wake_alarm
<------>block_suspend
<------>audit_read
<------>perfmon
}
dmesg stopped reporting perfmon as not defined but audit.log still doesn't report CAP_PERFMON denials.
BTW, audit even doesn't report CAP_SYS_ADMIN denials, however perfmon_capable() does check for it.
~Alexey
>
>
^ permalink raw reply
* [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't boot anymore
From: Christophe Leroy @ 2020-02-12 14:24 UTC (permalink / raw)
To: Rasmus Villemoes, Li Yang, Qiang Zhao, Greg Kroah-Hartman
Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org, LKML, linux-arm-kernel
Hi Rasmus,
Kernel 5.6-rc1 silently fails on boot.
I bisected the problem to commit b6231ea2b3c6 ("soc: fsl: qe: drop
broken lazy call of cpm_muram_init()")
I get a bad_page_fault() for an access at address 8 in
cpm_muram_alloc_common(), called from cpm_uart_console_setup() via
cpm_uart_allocbuf()
Reverting the guilty commit on top of 5.6-rc1 is not trivial.
In your commit text you explain that cpm_muram_init() is called via
subsys_initcall. But console init is done before that, so it cannot work.
Do you have a fix for that ?
Thanks
Christophe
NB: Next time, can you please copy powerpc mailing list when changing
such core parts of powerpc CPUs ?
^ permalink raw reply
* Re: [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't boot anymore
From: Christophe Leroy @ 2020-02-12 14:42 UTC (permalink / raw)
To: Rasmus Villemoes, Li Yang, Qiang Zhao, Greg Kroah-Hartman
Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org, LKML, linux-arm-kernel
In-Reply-To: <0d45fa64-51ee-0052-cb34-58c770c5b3ce@c-s.fr>
Le 12/02/2020 à 15:24, Christophe Leroy a écrit :
> Hi Rasmus,
>
[...]
>
> NB: Next time, can you please copy powerpc mailing list when changing
> such core parts of powerpc CPUs ?
Apologise for that comment, in fact I was part of the recipients so it
didn't land in my linuxppc mailbox.
Seems like I missed that series.
^ permalink raw reply
* Re: [Regression 5.6-rc1][Bisected b6231ea2b3c6] Powerpc 8xx doesn't boot anymore
From: Christophe Leroy @ 2020-02-12 14:50 UTC (permalink / raw)
To: Rasmus Villemoes, Li Yang, Qiang Zhao, Greg Kroah-Hartman
Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org, LKML, linux-arm-kernel
In-Reply-To: <0d45fa64-51ee-0052-cb34-58c770c5b3ce@c-s.fr>
On 02/12/2020 02:24 PM, Christophe Leroy wrote:
> Hi Rasmus,
>
> Kernel 5.6-rc1 silently fails on boot.
>
> I bisected the problem to commit b6231ea2b3c6 ("soc: fsl: qe: drop
> broken lazy call of cpm_muram_init()")
>
> I get a bad_page_fault() for an access at address 8 in
> cpm_muram_alloc_common(), called from cpm_uart_console_setup() via
> cpm_uart_allocbuf()
>
> Reverting the guilty commit on top of 5.6-rc1 is not trivial.
>
> In your commit text you explain that cpm_muram_init() is called via
> subsys_initcall. But console init is done before that, so it cannot work.
>
> Do you have a fix for that ?
>
The following patch allows powerpc 8xx to boot again. Don't know if
that's the good place and way to do the fix though.
---
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
index 4cabded8390b..341d682ec6eb 100644
--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
@@ -1351,6 +1351,7 @@ static int __init cpm_uart_console_setup(struct
console *co, char *options)
clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
+ cpm_muram_init();
ret = cpm_uart_allocbuf(pinfo, 1);
if (ret)
---
Christophe
^ permalink raw reply related
* [Bug 206501] Kernel 5.6-rc1 fails to boot on a PowerMac G4 3,6 with CONFIG_VMAP_STACK=y: Oops! Machine check, sig: 7 [#1]
From: bugzilla-daemon @ 2020-02-12 15:10 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-206501-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=206501
--- Comment #4 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 287329
--> https://bugzilla.kernel.org/attachment.cgi?id=287329&action=edit
dmesg (5.6.0-rc1 + Fix DSI and ISI... patch , PowerMac G4 DP)
First patch was not successful, I got no stacktrace but the boot process still
got still stuck.
Second patch was succesful to the point where the G4 was able to boot up to the
point of revealing a dmesg full of other problems, e.g. some 'Unrecoverable
exceptions' ;)
Please find the dmesg attached.
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Stephen Smalley @ 2020-02-12 15:21 UTC (permalink / raw)
To: Alexey Budankov
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <8141da2e-49cf-c02d-69e9-8a7cbdc91431@linux.intel.com>
On 2/12/20 8:53 AM, Alexey Budankov wrote:
> On 12.02.2020 16:32, Stephen Smalley wrote:
>> On 2/12/20 3:53 AM, Alexey Budankov wrote:
>>> Hi Stephen,
>>>
>>> On 22.01.2020 17:07, Stephen Smalley wrote:
>>>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>>>
>>>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>>>
>>>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>>>
>>> <SNIP>
>>>>>>>>>> Introduce CAP_PERFMON capability designed to secure system performance
>>>>>>>>>
>>>>>>>>> Why _noaudit()? Normally only used when a permission failure is non-fatal to the operation. Otherwise, we want the audit message.
>>>>>
>>>>> So far so good, I suggest using the simplest version for v6:
>>>>>
>>>>> static inline bool perfmon_capable(void)
>>>>> {
>>>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>>>> }
>>>>>
>>>>> It keeps the implementation simple and readable. The implementation is more
>>>>> performant in the sense of calling the API - one capable() call for CAP_PERFMON
>>>>> privileged process.
>>>>>
>>>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and unprivileged processes,
>>>>> but this bloating also advertises and leverages using more secure CAP_PERFMON
>>>>> based approach to use perf_event_open system call.
>>>>
>>>> I can live with that. We just need to document that when you see both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process, try only allowing CAP_PERFMON first and see if that resolves the issue. We have a similar issue with CAP_DAC_READ_SEARCH versus CAP_DAC_OVERRIDE.
>>>
>>> I am trying to reproduce this double logging with CAP_PERFMON.
>>> I am using the refpolicy version with enabled perf_event tclass [1], in permissive mode.
>>> When running perf stat -a I am observing this AVC audit messages:
>>>
>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>> type=AVC msg=audit(1581496695.666:8692): avc: denied { write } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>
>>> However there is no capability related messages around. I suppose my refpolicy should
>>> be modified somehow to observe capability related AVCs.
>>>
>>> Could you please comment or clarify on how to enable caps related AVCs in order
>>> to test the concerned logging.
>>
>> The new perfmon permission has to be defined in your policy; you'll have a message in dmesg about "Permission perfmon in class capability2 not defined in policy.". You can either add it to the common cap2 definition in refpolicy/policy/flask/access_vectors and rebuild your policy or extract your base module as CIL, add it there, and insert the updated module.
>
> Yes, I already have it like this:
> common cap2
> {
> <------>mac_override<--># unused by SELinux
> <------>mac_admin
> <------>syslog
> <------>wake_alarm
> <------>block_suspend
> <------>audit_read
> <------>perfmon
> }
>
> dmesg stopped reporting perfmon as not defined but audit.log still doesn't report CAP_PERFMON denials.
> BTW, audit even doesn't report CAP_SYS_ADMIN denials, however perfmon_capable() does check for it.
Some denials may be silenced by dontaudit rules; semodule -DB will strip
those and semodule -B will restore them. Other possibility is that the
process doesn't have CAP_PERFMON in its effective set and therefore
never reaches SELinux at all; denied first by the capability module.
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Stephen Smalley @ 2020-02-12 15:45 UTC (permalink / raw)
To: Alexey Budankov
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <7c367905-e8c9-7665-d923-c850e05c757a@tycho.nsa.gov>
On 2/12/20 10:21 AM, Stephen Smalley wrote:
> On 2/12/20 8:53 AM, Alexey Budankov wrote:
>> On 12.02.2020 16:32, Stephen Smalley wrote:
>>> On 2/12/20 3:53 AM, Alexey Budankov wrote:
>>>> Hi Stephen,
>>>>
>>>> On 22.01.2020 17:07, Stephen Smalley wrote:
>>>>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>>>>
>>>>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>>>>
>>>>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>>>>
>>>> <SNIP>
>>>>>>>>>>> Introduce CAP_PERFMON capability designed to secure system
>>>>>>>>>>> performance
>>>>>>>>>>
>>>>>>>>>> Why _noaudit()? Normally only used when a permission failure
>>>>>>>>>> is non-fatal to the operation. Otherwise, we want the audit
>>>>>>>>>> message.
>>>>>>
>>>>>> So far so good, I suggest using the simplest version for v6:
>>>>>>
>>>>>> static inline bool perfmon_capable(void)
>>>>>> {
>>>>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>>>>> }
>>>>>>
>>>>>> It keeps the implementation simple and readable. The
>>>>>> implementation is more
>>>>>> performant in the sense of calling the API - one capable() call
>>>>>> for CAP_PERFMON
>>>>>> privileged process.
>>>>>>
>>>>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and
>>>>>> unprivileged processes,
>>>>>> but this bloating also advertises and leverages using more secure
>>>>>> CAP_PERFMON
>>>>>> based approach to use perf_event_open system call.
>>>>>
>>>>> I can live with that. We just need to document that when you see
>>>>> both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process,
>>>>> try only allowing CAP_PERFMON first and see if that resolves the
>>>>> issue. We have a similar issue with CAP_DAC_READ_SEARCH versus
>>>>> CAP_DAC_OVERRIDE.
>>>>
>>>> I am trying to reproduce this double logging with CAP_PERFMON.
>>>> I am using the refpolicy version with enabled perf_event tclass [1],
>>>> in permissive mode.
>>>> When running perf stat -a I am observing this AVC audit messages:
>>>>
>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for
>>>> pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t
>>>> tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel }
>>>> for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t
>>>> tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for
>>>> pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t
>>>> tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>> type=AVC msg=audit(1581496695.666:8692): avc: denied { write }
>>>> for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t
>>>> tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>
>>>> However there is no capability related messages around. I suppose my
>>>> refpolicy should
>>>> be modified somehow to observe capability related AVCs.
>>>>
>>>> Could you please comment or clarify on how to enable caps related
>>>> AVCs in order
>>>> to test the concerned logging.
>>>
>>> The new perfmon permission has to be defined in your policy; you'll
>>> have a message in dmesg about "Permission perfmon in class
>>> capability2 not defined in policy.". You can either add it to the
>>> common cap2 definition in refpolicy/policy/flask/access_vectors and
>>> rebuild your policy or extract your base module as CIL, add it there,
>>> and insert the updated module.
>>
>> Yes, I already have it like this:
>> common cap2
>> {
>> <------>mac_override<--># unused by SELinux
>> <------>mac_admin
>> <------>syslog
>> <------>wake_alarm
>> <------>block_suspend
>> <------>audit_read
>> <------>perfmon
>> }
>>
>> dmesg stopped reporting perfmon as not defined but audit.log still
>> doesn't report CAP_PERFMON denials.
>> BTW, audit even doesn't report CAP_SYS_ADMIN denials, however
>> perfmon_capable() does check for it.
>
> Some denials may be silenced by dontaudit rules; semodule -DB will strip
> those and semodule -B will restore them. Other possibility is that the
> process doesn't have CAP_PERFMON in its effective set and therefore
> never reaches SELinux at all; denied first by the capability module.
Also, the fact that your denials are showing up in user_systemd_t
suggests that something is off in your policy or userspace/distro; I
assume that is a domain type for the systemd --user instance, but your
shell and commands shouldn't be running in that domain (user_t would be
more appropriate for that).
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Alexey Budankov @ 2020-02-12 16:16 UTC (permalink / raw)
To: Stephen Smalley
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <7c367905-e8c9-7665-d923-c850e05c757a@tycho.nsa.gov>
On 12.02.2020 18:21, Stephen Smalley wrote:
> On 2/12/20 8:53 AM, Alexey Budankov wrote:
>> On 12.02.2020 16:32, Stephen Smalley wrote:
>>> On 2/12/20 3:53 AM, Alexey Budankov wrote:
>>>> Hi Stephen,
>>>>
>>>> On 22.01.2020 17:07, Stephen Smalley wrote:
>>>>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>>>>
>>>>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>>>>
>>>>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>>>>
>>>> <SNIP>
>>>>>>>>>>> Introduce CAP_PERFMON capability designed to secure system performance
>>>>>>>>>>
>>>>>>>>>> Why _noaudit()? Normally only used when a permission failure is non-fatal to the operation. Otherwise, we want the audit message.
>>>>>>
>>>>>> So far so good, I suggest using the simplest version for v6:
>>>>>>
>>>>>> static inline bool perfmon_capable(void)
>>>>>> {
>>>>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>>>>> }
>>>>>>
>>>>>> It keeps the implementation simple and readable. The implementation is more
>>>>>> performant in the sense of calling the API - one capable() call for CAP_PERFMON
>>>>>> privileged process.
>>>>>>
>>>>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and unprivileged processes,
>>>>>> but this bloating also advertises and leverages using more secure CAP_PERFMON
>>>>>> based approach to use perf_event_open system call.
>>>>>
>>>>> I can live with that. We just need to document that when you see both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process, try only allowing CAP_PERFMON first and see if that resolves the issue. We have a similar issue with CAP_DAC_READ_SEARCH versus CAP_DAC_OVERRIDE.
>>>>
>>>> I am trying to reproduce this double logging with CAP_PERFMON.
>>>> I am using the refpolicy version with enabled perf_event tclass [1], in permissive mode.
>>>> When running perf stat -a I am observing this AVC audit messages:
>>>>
>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>> type=AVC msg=audit(1581496695.666:8692): avc: denied { write } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>
>>>> However there is no capability related messages around. I suppose my refpolicy should
>>>> be modified somehow to observe capability related AVCs.
>>>>
>>>> Could you please comment or clarify on how to enable caps related AVCs in order
>>>> to test the concerned logging.
>>>
>>> The new perfmon permission has to be defined in your policy; you'll have a message in dmesg about "Permission perfmon in class capability2 not defined in policy.". You can either add it to the common cap2 definition in refpolicy/policy/flask/access_vectors and rebuild your policy or extract your base module as CIL, add it there, and insert the updated module.
>>
>> Yes, I already have it like this:
>> common cap2
>> {
>> <------>mac_override<--># unused by SELinux
>> <------>mac_admin
>> <------>syslog
>> <------>wake_alarm
>> <------>block_suspend
>> <------>audit_read
>> <------>perfmon
>> }
>>
>> dmesg stopped reporting perfmon as not defined but audit.log still doesn't report CAP_PERFMON denials.
>> BTW, audit even doesn't report CAP_SYS_ADMIN denials, however perfmon_capable() does check for it.
>
> Some denials may be silenced by dontaudit rules; semodule -DB will strip those and semodule -B will restore them. Other possibility is that the process doesn't have CAP_PERFMON in its effective set and therefore never reaches SELinux at all; denied first by the capability module.
Yes, that all makes sense.
selinux_capable() calls avc_audit() logging but cap_capable() doesn't, so proper order matters.
I am doing debug tracing of the kernel code to reveal the exact reasons.
~Alexey
^ permalink raw reply
* Re: [PATCH v5 01/10] capabilities: introduce CAP_PERFMON to kernel and user space
From: Alexey Budankov @ 2020-02-12 16:56 UTC (permalink / raw)
To: Stephen Smalley
Cc: Mark Rutland, Song Liu, Peter Zijlstra,
joonas.lahtinen@linux.intel.com, Will Deacon, Alexei Starovoitov,
Stephane Eranian, james.bottomley@hansenpartnership.com,
Paul Mackerras, Jiri Olsa, Alexei Starovoitov, Andi Kleen,
Igor Lubashev, James Morris, Alexander Shishkin, Ingo Molnar,
oprofile-list, Serge Hallyn, Robert Richter,
selinux@vger.kernel.org, intel-gfx@lists.freedesktop.org,
jani.nikula@linux.intel.com, Arnaldo Carvalho de Melo,
rodrigo.vivi@intel.com, Namhyung Kim, Thomas Gleixner,
linux-arm-kernel, linux-parisc@vger.kernel.org, linux-kernel,
Lionel Landwerlin, Andy Lutomirski,
linux-perf-users@vger.kernel.org,
linux-security-module@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <280e6644-c129-15f6-ea5c-0f66bf764e0f@tycho.nsa.gov>
On 12.02.2020 18:45, Stephen Smalley wrote:
> On 2/12/20 10:21 AM, Stephen Smalley wrote:
>> On 2/12/20 8:53 AM, Alexey Budankov wrote:
>>> On 12.02.2020 16:32, Stephen Smalley wrote:
>>>> On 2/12/20 3:53 AM, Alexey Budankov wrote:
>>>>> Hi Stephen,
>>>>>
>>>>> On 22.01.2020 17:07, Stephen Smalley wrote:
>>>>>> On 1/22/20 5:45 AM, Alexey Budankov wrote:
>>>>>>>
>>>>>>> On 21.01.2020 21:27, Alexey Budankov wrote:
>>>>>>>>
>>>>>>>> On 21.01.2020 20:55, Alexei Starovoitov wrote:
>>>>>>>>> On Tue, Jan 21, 2020 at 9:31 AM Alexey Budankov
>>>>>>>>> <alexey.budankov@linux.intel.com> wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 21.01.2020 17:43, Stephen Smalley wrote:
>>>>>>>>>>> On 1/20/20 6:23 AM, Alexey Budankov wrote:
>>>>>>>>>>>>
>>>>> <SNIP>
>>>>>>>>>>>> Introduce CAP_PERFMON capability designed to secure system performance
>>>>>>>>>>>
>>>>>>>>>>> Why _noaudit()? Normally only used when a permission failure is non-fatal to the operation. Otherwise, we want the audit message.
>>>>>>>
>>>>>>> So far so good, I suggest using the simplest version for v6:
>>>>>>>
>>>>>>> static inline bool perfmon_capable(void)
>>>>>>> {
>>>>>>> return capable(CAP_PERFMON) || capable(CAP_SYS_ADMIN);
>>>>>>> }
>>>>>>>
>>>>>>> It keeps the implementation simple and readable. The implementation is more
>>>>>>> performant in the sense of calling the API - one capable() call for CAP_PERFMON
>>>>>>> privileged process.
>>>>>>>
>>>>>>> Yes, it bloats audit log for CAP_SYS_ADMIN privileged and unprivileged processes,
>>>>>>> but this bloating also advertises and leverages using more secure CAP_PERFMON
>>>>>>> based approach to use perf_event_open system call.
>>>>>>
>>>>>> I can live with that. We just need to document that when you see both a CAP_PERFMON and a CAP_SYS_ADMIN audit message for a process, try only allowing CAP_PERFMON first and see if that resolves the issue. We have a similar issue with CAP_DAC_READ_SEARCH versus CAP_DAC_OVERRIDE.
>>>>>
>>>>> I am trying to reproduce this double logging with CAP_PERFMON.
>>>>> I am using the refpolicy version with enabled perf_event tclass [1], in permissive mode.
>>>>> When running perf stat -a I am observing this AVC audit messages:
>>>>>
>>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { open } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { kernel } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>> type=AVC msg=audit(1581496695.666:8691): avc: denied { cpu } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>> type=AVC msg=audit(1581496695.666:8692): avc: denied { write } for pid=2779 comm="perf" scontext=user_u:user_r:user_systemd_t tcontext=user_u:user_r:user_systemd_t tclass=perf_event permissive=1
>>>>>
>>>>> However there is no capability related messages around. I suppose my refpolicy should
>>>>> be modified somehow to observe capability related AVCs.
>>>>>
>>>>> Could you please comment or clarify on how to enable caps related AVCs in order
>>>>> to test the concerned logging.
>>>>
>>>> The new perfmon permission has to be defined in your policy; you'll have a message in dmesg about "Permission perfmon in class capability2 not defined in policy.". You can either add it to the common cap2 definition in refpolicy/policy/flask/access_vectors and rebuild your policy or extract your base module as CIL, add it there, and insert the updated module.
>>>
>>> Yes, I already have it like this:
>>> common cap2
>>> {
>>> <------>mac_override<--># unused by SELinux
>>> <------>mac_admin
>>> <------>syslog
>>> <------>wake_alarm
>>> <------>block_suspend
>>> <------>audit_read
>>> <------>perfmon
>>> }
>>>
>>> dmesg stopped reporting perfmon as not defined but audit.log still doesn't report CAP_PERFMON denials.
>>> BTW, audit even doesn't report CAP_SYS_ADMIN denials, however perfmon_capable() does check for it.
>>
>> Some denials may be silenced by dontaudit rules; semodule -DB will strip those and semodule -B will restore them. Other possibility is that the process doesn't have CAP_PERFMON in its effective set and therefore never reaches SELinux at all; denied first by the capability module.
>
> Also, the fact that your denials are showing up in user_systemd_t suggests that something is off in your policy or userspace/distro; I assume that is a domain type for the systemd --user instance, but your shell and commands shouldn't be running in that domain (user_t would be more appropriate for that).
It is user_t for local terminal session:
ps -Z
LABEL PID TTY TIME CMD
user_u:user_r:user_t 11317 pts/9 00:00:00 bash
user_u:user_r:user_t 11796 pts/9 00:00:00 ps
For local terminal root session:
ps -Z
LABEL PID TTY TIME CMD
user_u:user_r:user_su_t 2926 pts/3 00:00:00 bash
user_u:user_r:user_su_t 10995 pts/3 00:00:00 ps
For remote ssh session:
ps -Z
LABEL PID TTY TIME CMD
user_u:user_r:user_t 7540 pts/8 00:00:00 ps
user_u:user_r:user_systemd_t 8875 pts/8 00:00:00 bash
~Alexey
^ permalink raw reply
* Re: [PATCH] powerpc/time: Replace <linux/clk-provider.h> by <linux/of_clk.h>
From: Stephen Boyd @ 2020-02-12 17:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Geert Uytterhoeven, Michael Ellerman,
Paul Mackerras
Cc: linuxppc-dev, linux-clk, Geert Uytterhoeven, linux-kernel
In-Reply-To: <20200212101736.9126-1-geert+renesas@glider.be>
Quoting Geert Uytterhoeven (2020-02-12 02:17:36)
> The PowerPC time code is not a clock provider, and just needs to call
> of_clk_init().
>
> Hence it can include <linux/of_clk.h> instead of <linux/clk-provider.h>.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
Reviewed-by: Stephen Boyd <sboyd@kernel.org>
This has an ifdef around the of_clk_init() call. Can you remove that too
given that we stub it out in the header?
^ 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