lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 16 Mar 2017 12:25:35 -0500 From: Shanker Donthineni <shankerd@...eaurora.org> To: Andre Przywara <andre.przywara@....com>, Thomas Gleixner <tglx@...utronix.de>, Jason Cooper <jason@...edaemon.net>, Marc Zyngier <marc.zyngier@....com> Cc: linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org Subject: Re: [PATCH 1/2] irqchip/gic-v3-its: bail out on already enabled LPIs Hi Andre, On 03/16/2017 12:05 PM, Andre Przywara wrote: > The GICv3 spec says that once LPIs have been enabled, they can't be > disabled anymore: > "When a write changes this bit from 0 to 1, this bit becomes RES1 ..." > As we can't setup the pending and property table registers when LPIs are > enabled, we have to bail out here in this case. > But first try to disable LPIs anyway, to check whether this actually works. > If not, return an error. > > Signed-off-by: Andre Przywara <andre.przywara@....com> > --- > drivers/irqchip/irq-gic-v3-its.c | 36 ++++++++++++++++++++++++++++-------- > 1 file changed, 28 insertions(+), 8 deletions(-) > > diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c > index f77f840..b777c57 100644 > --- a/drivers/irqchip/irq-gic-v3-its.c > +++ b/drivers/irqchip/irq-gic-v3-its.c > @@ -1082,12 +1082,30 @@ static int its_alloc_collections(struct its_node *its) > return 0; > } > > -static void its_cpu_init_lpis(void) > +static int its_cpu_init_lpis(void) > { > void __iomem *rbase = gic_data_rdist_rd_base(); > struct page *pend_page; > u64 val, tmp; > > + /* > + * Architecturally, once LPIs have been enabled on a specific > + * redistributor, they can't be disabled anymore (the enable > + * bit becomes RES1). > + * But as we can't setup the pending and property table registers > + * while LPIs are enabled, we are basically screwed in this case. > + * But be slightly more optimistic here, and actually check whether > + * this is really implemented like this. > + */ > + val = readl_relaxed(rbase + GICR_CTLR); > + val &= ~GICR_CTLR_ENABLE_LPIS; > + writel_relaxed(val, rbase + GICR_CTLR); Spec says we are not supposed to disable once it is enabled, why code is trying to disable? Why can't we check the enable bit without a write operation? > + if (readl_relaxed(rbase + GICR_CTLR) & GICR_CTLR_ENABLE_LPIS) { > + pr_warn("CPU%d: LPIs already enabled, cannot initialize redistributor\n", > + smp_processor_id()); > + return -EBUSY; > + } > + > /* If we didn't allocate the pending table yet, do it now */ > pend_page = gic_data_rdist()->pend_page; > if (!pend_page) { > @@ -1101,7 +1119,7 @@ static void its_cpu_init_lpis(void) > if (!pend_page) { > pr_err("Failed to allocate PENDBASE for CPU%d\n", > smp_processor_id()); > - return; > + return -ENOMEM; > } > > /* Make sure the GIC will observe the zero-ed page */ > @@ -1113,11 +1131,6 @@ static void its_cpu_init_lpis(void) > gic_data_rdist()->pend_page = pend_page; > } > > - /* Disable LPIs */ > - val = readl_relaxed(rbase + GICR_CTLR); > - val &= ~GICR_CTLR_ENABLE_LPIS; > - writel_relaxed(val, rbase + GICR_CTLR); > - > /* > * Make sure any change to the table is observable by the GIC. > */ > @@ -1174,6 +1187,8 @@ static void its_cpu_init_lpis(void) > > /* Make sure the GIC has seen the above */ > dsb(sy); > + > + return 0; > } > > static void its_cpu_init_collection(void) > @@ -1789,12 +1804,17 @@ static bool gic_rdists_supports_plpis(void) > > int its_cpu_init(void) > { > + int ret; > + > if (!list_empty(&its_nodes)) { > if (!gic_rdists_supports_plpis()) { > pr_info("CPU%d: LPIs not supported\n", smp_processor_id()); > return -ENXIO; > } > - its_cpu_init_lpis(); > + ret = its_cpu_init_lpis(); > + if (ret) > + return ret; This is not enough, you have to skip all the disabled collections inside the function its_set_affinity() when mapping an event to collection. Otherwise all LPIs might mapped to collection 0, causes the possibility of memory corruption by GICR hardware on updating incorrect PENDING table. I believe better fix would be disable ITS on this condition. > + > its_cpu_init_collection(); > } > -- Shanker Donthineni Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Powered by blists - more mailing lists