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
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAFA6WYO7u5WTS8dfzqPUcLpHWTH+3sMNVL-9ob0stHE_nJw24Q@mail.gmail.com>
Date:   Tue, 29 Aug 2023 16:06:30 +0530
From:   Sumit Garg <sumit.garg@...aro.org>
To:     Douglas Anderson <dianders@...omium.org>
Cc:     Mark Rutland <mark.rutland@....com>,
        Catalin Marinas <catalin.marinas@....com>,
        Will Deacon <will@...nel.org>,
        Daniel Thompson <daniel.thompson@...aro.org>,
        Marc Zyngier <maz@...nel.org>,
        "Rafael J . Wysocki" <rafael.j.wysocki@...el.com>,
        Ard Biesheuvel <ardb@...nel.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        kgdb-bugreport@...ts.sourceforge.net,
        Lecopzer Chen <lecopzer.chen@...iatek.com>,
        linux-perf-users@...r.kernel.org,
        Masayoshi Mizuma <msys.mizuma@...il.com>,
        Chen-Yu Tsai <wens@...e.org>,
        linux-arm-kernel@...ts.infradead.org, ito-yuichi@...itsu.com,
        Stephen Boyd <swboyd@...omium.org>,
        Peter Zijlstra <peterz@...radead.org>,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH v11 1/6] irqchip/gic-v3: Enable support for SGIs to act as NMIs

On Thu, 24 Aug 2023 at 21:03, Douglas Anderson <dianders@...omium.org> wrote:
>
> As of commit 6abbd6988971 ("irqchip/gic, gic-v3: Make SGIs use
> handle_percpu_devid_irq()") SGIs are treated the same as PPIs/EPPIs
> and use handle_percpu_devid_irq() by default. Unfortunately,
> handle_percpu_devid_irq() isn't NMI safe, and so to run in an NMI
> context those should use handle_percpu_devid_fasteoi_nmi().
>
> In order to accomplish this, we just have to make room for SGIs in the
> array of refcounts that keeps track of which interrupts are set as
> NMI. We also rename the array and create a new indexing scheme that
> accounts for SGIs.
>
> Also, enable NMI support prior to gic_smp_init() as allocation of SGIs
> as IRQs/NMIs happen as part of this routine.
>
> Co-developed-by: Sumit Garg <sumit.garg@...aro.org>
> Signed-off-by: Sumit Garg <sumit.garg@...aro.org>
> Signed-off-by: Douglas Anderson <dianders@...omium.org>
> ---
> In v10 I removed the previous Reviewed-by and Tested-by tags since the
> patch contents changed pretty drastically.
>
> I'll also note that this change is a little more black magic to me
> than others in this series. I don't have a massive amounts of
> familiarity with all the moving parts of gic-v3, so I mostly just
> followed Mark Rutland's advice [1]. Please pay extra attention to make
> sure I didn't do anything too terrible.

The changes look good to me. I am not sure if my review tag will be
valuable here since I am a co-developer here.

-Sumit

>
> Mark's advice wasn't a full patch and I ended up doing a bit of work
> to translate it to reality, so I did not add him as "Co-developed-by"
> here. Mark: if you would like this tag then please provide it and your
> Signed-off-by. I certainly won't object.
>
> [1] https://lore.kernel.org/r/ZNC-YRQopO0PaIIo@FVFF77S0Q05N.cambridge.arm.com
>
> (no changes since v10)
>
> Changes in v10:
> - Rewrite as needed for 5.11+ as per Mark Rutland and Sumit.
>
>  drivers/irqchip/irq-gic-v3.c | 54 ++++++++++++++++++++++++------------
>  1 file changed, 36 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index eedfa8e9f077..49d18cf3f636 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -78,6 +78,8 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
>  #define GIC_LINE_NR    min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U)
>  #define GIC_ESPI_NR    GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer)
>
> +#define SGI_NR         16
> +
>  /*
>   * The behaviours of RPR and PMR registers differ depending on the value of
>   * SCR_EL3.FIQ, and the behaviour of non-secure priority registers of the
> @@ -125,8 +127,8 @@ EXPORT_SYMBOL(gic_nonsecure_priorities);
>                 __priority;                                             \
>         })
>
> -/* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> -static refcount_t *ppi_nmi_refs;
> +/* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */
> +static refcount_t *rdist_nmi_refs;
>
>  static struct gic_kvm_info gic_v3_kvm_info __initdata;
>  static DEFINE_PER_CPU(bool, has_rss);
> @@ -519,9 +521,22 @@ static u32 __gic_get_ppi_index(irq_hw_number_t hwirq)
>         }
>  }
>
> -static u32 gic_get_ppi_index(struct irq_data *d)
> +static u32 __gic_get_rdist_idx(irq_hw_number_t hwirq)
> +{
> +       switch (__get_intid_range(hwirq)) {
> +       case SGI_RANGE:
> +       case PPI_RANGE:
> +               return hwirq;
> +       case EPPI_RANGE:
> +               return hwirq - EPPI_BASE_INTID + 32;
> +       default:
> +               unreachable();
> +       }
> +}
> +
> +static u32 gic_get_rdist_idx(struct irq_data *d)
>  {
> -       return __gic_get_ppi_index(d->hwirq);
> +       return __gic_get_rdist_idx(d->hwirq);
>  }
>
>  static int gic_irq_nmi_setup(struct irq_data *d)
> @@ -545,11 +560,14 @@ static int gic_irq_nmi_setup(struct irq_data *d)
>
>         /* desc lock should already be held */
>         if (gic_irq_in_rdist(d)) {
> -               u32 idx = gic_get_ppi_index(d);
> +               u32 idx = gic_get_rdist_idx(d);
>
> -               /* Setting up PPI as NMI, only switch handler for first NMI */
> -               if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
> -                       refcount_set(&ppi_nmi_refs[idx], 1);
> +               /*
> +                * Setting up a percpu interrupt as NMI, only switch handler
> +                * for first NMI
> +                */
> +               if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
> +                       refcount_set(&rdist_nmi_refs[idx], 1);
>                         desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
>                 }
>         } else {
> @@ -582,10 +600,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
>
>         /* desc lock should already be held */
>         if (gic_irq_in_rdist(d)) {
> -               u32 idx = gic_get_ppi_index(d);
> +               u32 idx = gic_get_rdist_idx(d);
>
>                 /* Tearing down NMI, only switch handler for last NMI */
> -               if (refcount_dec_and_test(&ppi_nmi_refs[idx]))
> +               if (refcount_dec_and_test(&rdist_nmi_refs[idx]))
>                         desc->handle_irq = handle_percpu_devid_irq;
>         } else {
>                 desc->handle_irq = handle_fasteoi_irq;
> @@ -1279,10 +1297,10 @@ static void gic_cpu_init(void)
>         rbase = gic_data_rdist_sgi_base();
>
>         /* Configure SGIs/PPIs as non-secure Group-1 */
> -       for (i = 0; i < gic_data.ppi_nr + 16; i += 32)
> +       for (i = 0; i < gic_data.ppi_nr + SGI_NR; i += 32)
>                 writel_relaxed(~0, rbase + GICR_IGROUPR0 + i / 8);
>
> -       gic_cpu_config(rbase, gic_data.ppi_nr + 16, gic_redist_wait_for_rwp);
> +       gic_cpu_config(rbase, gic_data.ppi_nr + SGI_NR, gic_redist_wait_for_rwp);
>
>         /* initialise system registers */
>         gic_cpu_sys_reg_init();
> @@ -1939,12 +1957,13 @@ static void gic_enable_nmi_support(void)
>                 return;
>         }
>
> -       ppi_nmi_refs = kcalloc(gic_data.ppi_nr, sizeof(*ppi_nmi_refs), GFP_KERNEL);
> -       if (!ppi_nmi_refs)
> +       rdist_nmi_refs = kcalloc(gic_data.ppi_nr + SGI_NR,
> +                                sizeof(*rdist_nmi_refs), GFP_KERNEL);
> +       if (!rdist_nmi_refs)
>                 return;
>
> -       for (i = 0; i < gic_data.ppi_nr; i++)
> -               refcount_set(&ppi_nmi_refs[i], 0);
> +       for (i = 0; i < gic_data.ppi_nr + SGI_NR; i++)
> +               refcount_set(&rdist_nmi_refs[i], 0);
>
>         pr_info("Pseudo-NMIs enabled using %s ICC_PMR_EL1 synchronisation\n",
>                 gic_has_relaxed_pmr_sync() ? "relaxed" : "forced");
> @@ -2061,6 +2080,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
>
>         gic_dist_init();
>         gic_cpu_init();
> +       gic_enable_nmi_support();
>         gic_smp_init();
>         gic_cpu_pm_init();
>
> @@ -2073,8 +2093,6 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
>                         gicv2m_init(handle, gic_data.domain);
>         }
>
> -       gic_enable_nmi_support();
> -
>         return 0;
>
>  out_free:
> --
> 2.42.0.rc1.204.g551eb34607-goog
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ