Ping.

On 2024/4/7 16:17, Jinjie Ruan wrote:
> This patch set implements FEAT_NMI and FEAT_GICv3_NMI for ARMv8. These
> introduce support for a new category of interrupts in the architecture
> which we can use to provide NMI like functionality.
> 
> There are two modes for using this FEAT_NMI. When PSTATE.ALLINT or
> PSTATE.SP & SCTLR_ELx.SCTLR_SPINTMASK is set, any entry to ELx causes all
> interrupts including those with superpriority to be masked on entry to ELn
> until the mask is explicitly removed by software or hardware. PSTATE.ALLINT
> can be managed by software using the new register control ALLINT.ALLINT.
> Independent controls are provided for this feature at each EL, usage at EL1
> should not disrupt EL2 or EL3.
> 
> I have tested it with the following Linux patches which try to support
> FEAT_NMI in Linux kernel:
> 
>       
> https://lore.kernel.org/linux-arm-kernel/Y4sH5qX5bK9xfEBp@lpieralisi/T/#mb4ba4a2c045bf72c10c2202c1dd1b82d3240dc88
> 
> In the test, SGI, PPI and SPI interrupts can all be set to have super priority
> to be converted to a hardware NMI interrupt. The SGI is tested with kernel
> IPI as NMI framework, softlockup, hardlockup and kgdb test cases, and the PPI
> interrupt is tested with "perf top" command with hardware NMI enabled, and
> the SPI interrupt is tested with a custom test module, in which NMI interrupts
> can be received and sent normally.
> 
> And the Virtual NMI(VNMI) SGI, PPI and SPI interrupts has also been tested in
> nested QEMU Virtual Machine with host "virtualization=true". The SGI VNMI is
> tested by accessing GICR_INMIR0 and GICR_ISPENDR0 with devmem command, as well
> as hardlockup and kgdb testcases. The PPI VNMI is tested by accessing
> GICR_INMIR0 and GICR_ISPENDR0 with devmem command, as well as "perf top"
> command with hardware NMI enabled, which works well. The SPI VNMI is tested
> with a custom test module, in which SPI VNMI can be sent from the GIC and
> received normally.
> 
>          +-------------------------------------------------+
>          |               Distributor                       |
>          +-------------------------------------------------+
>              SPI |  NMI                        |  NMI
>                 \/                            \/
>             +--------+                     +-------+
>             | Redist |                     | Redist|
>             +--------+                     +-------+
>             SGI  | NMI                     PPI | NMI
>                 \/                            \/
>           +-------------+             +---------------+
>           |CPU Interface|   ...       | CPU Interface |
>           +-------------+             +---------------+
>                | NMI                         | NMI
>               \/                            \/
>             +-----+                       +-----+
>             |  PE |                       |  PE |
>             +-----+                       +-----+
> 
> Changes in v13:
> - Handle PSTATE.ALLINT the same way as PSTATE.DAIF in the illegal_return
>   exit path.
> - Adjust "hw/arm/virt: Wire NMI and VINMI irq lines from GIC to CPU" to after
>   "hw/intc/arm_gicv3: Add external IRQ lines for NMI" to fix the unexpected
>   error with patchseries at this point.
> - Only connect NMI irq lines from GIC to CPU if vms->gic_version is not
>   VIRT_GIC_VERSION_2 to fix the gic-version=2 unexpected error.
> - Enforce RES0 bit in NMI field when FEAT_GICv3_NMI is not implemented for
>   ICH_LR<n>_EL2.
> - Swap the order of the "irq" and "prio" args in gicv3_get_priority() to make
>   input before output.
> - Check tcg_enabled() for gicv3_nmi_present().
> - Update the comment for gicv3_nmi_present().
> - Update the commit message.
> - Add Reviewed-by.
> - Add Suggested-by.
> 
> Changes in v12:
> - pPriority<63> = ICC_AP1R_EL1NS<63> if HaveNMIExt() and HaveEL(EL3) and
>   (IsNonSecure(), fix the wrong writing.
> - Do not check nmi_support repetitively in icc_hppi_can_preempt(),
>   and icc_activate_irq, ich_highest_active_virt_prio(), hppvi_index(),
>   icv_hppi_can_preempt(), icv_rpr_read() and icv_activate_irq(),
>   gicv3_cpuif_virt_irq_fiq_update().
> - Check hppi.nmi after check icc_hppi_can_preempt() for icc_iar1_read() and
>   icc_nmiar1_read().
> - When NMI is 1, the virtual interrupt's priority is 0x0.
> - Make the thisnmi logic more concisely in hppvi_index().
> - Use is_nmi to simplify code and check is_nmi before comparing vpmr.
> - Also check sctlrx.NMI in icv_iar_read().
> - Check icv_hppi_can_preempt() for icv_nmiar1_read().
> - Check ICH_LR_EL2.NMI after check icv_hppi_can_preempt() as icv_iar_read()
>   do it in icv_nmiar1_read().
> - Correct thisnmi to bool in icv_eoir_write().
> - Check thisnmi and nmi both true instead of identical in icv_eoir_write().
> - nmi_needed -> gicv3_cpu_nmi_needed, needed_nmi -> gicv3_nmi_needed.
> - Correct the comment style in arm_cpu_initfn() and icv_nmiar1_read().
> - Fix the typo, "prioirty" -> "priority".
> - Remove the redundant blank line.
> - Update the subject and commit message, hppi.superprio -> hppi.nmi,
>   super priority -> non-maskable property.
> - Add Reviewed-by.
> 
> Changes in v11:
> - Put vmstate_gicv3_cpu_nmi and vmstate_gicv3_gicd_nmi into existing list.
> - Remove the excess != 0.
> - Handle NMI priority in icc_highest_active_prio() and handle NMI RPR in
>   icc_rpr_read() separately.
> - Only set NMI bit for a NMI and and ordinary priority bit for a non-NMI in
>   icc_activate_irq().
> - Only clear APR bit for AP1R0 in icc_drop_prio().
> - Check special INTID_* in callers instead of passing two extra boolean args
>   for ack functions.
> - Handle NMI in icc_hppi_can_preempt() and icc_highest_active_group().
> - Also check icc_hppi_can_preempt() for icc_nmiar1_read().
> - Deal with NMI in the callers instead of ich_highest_active_virt_prio().
> - Set either NMI or a group-priority bit, not both.
> - Only set AP NMI bits in the 0 reg.
> - Handle NMI in hppvi_index(), icv_hppi_can_preempt() and icv_eoir_write().
> - Add Reviewed-by.
> 
> Changes in v10:
> - Correct the exception_target_el(env) to 2 in msr_set_allint_el1 helper,
>   since it is a hypervisor trap from EL1 to EL2.
> - In arm_cpu_exec_interrupt(), if SCTLR_ELx.NMI is 0, NMI -> IRQ,
>   VINMI -> VIRQ, VFNMI -> VFIQ.
> - Make arm_cpu_update_virq() and arm_cpu_update_vfiq() check that it is not a
>   VINMI/VFNMI, so only set 1 bit in interrupt_request, not 2.
> - Adjust "hw/intc: Enable FEAT_GICv3_NMI Feature" to before "add irq
>   non-maskable property".
> - superprio -> nmi, gicr_isuperprio -> gicr_inmir0, is_nmi -> nmi,
>   is_hppi -> hppi, has_superprio -> nmi, superpriority -> non-maskable 
> property.
> - Save NMI state in vmstate_gicv3_cpu and vmstate_gicv3.
> - Exchange the order of nmi and hppi parameters.
> - Handle APR and RPR NMI bits, rename ICH_AP1R_EL2_NMI to ICV_AP1R_EL1_NMI.
> - Set ICV_RPR_EL1.NMI according to the ICV_AP1R<n>_EL1.NMI in
>   ich_highest_active_virt_prio()
> - Update the commit message.
> 
> Changes in v9:
> - Move nmi_reginfo and related functions inside an existing ifdef
>   TARGET_AARCH64 to solve the --target-list=aarch64-softmmu,arm-softmmu
>   compilation problem.
> - Check 'isread' when writing to ALLINT.
> - Update the GPIOs passed in the arm_cpu_kvm_set_irq, and update the comment.
> - Definitely not merge VINMI and VFNMI into EXCP_VNMI.
> - ARM_CPU_VNMI -> ARM_CPU_VINMI, CPU_INTERRUPT_VNMI -> CPU_INTERRUPT_VINMI.
> - Update VINMI and VFNMI when writing HCR_EL2 or HCRX_EL2.
> - Update the commit subject and message, VNMI -> VINMI.
> - Handle CPSR_F and ISR_FS according to CPU_INTERRUPT_VFNMI instead of
>   CPU_INTERRUPT_VFIQ and HCRX_EL2.VFNMI.
> - Not check SCTLR_NMI in arm_cpu_do_interrupt_aarch64().
> - Correct the INTID_NMI logic.
> - Declare cpu variable to reuse latter.
> 
> Changes in v8:
> - Fix the rcu stall after sending a VNMI in qemu VM.
> - Fix an unexpected interrupt bug when sending VNMI by running qemu VM.
> - Test the VNMI interrupt.
> - Update the commit message.
> - Add Reviewed-by.
> 
> Changes in v7:
> - env->cp15.hcrx_el2 -> arm_hcrx_el2_eff().
> - Reorder the irqbetter() code for clarity.
> - Eliminate the has_superprio local variable for gicv3_get_priority().
> - false -> cs->hpplpi.superprio in gicv3_redist_update_noirqset().
> - 0x0 -> false in arm_gicv3_common_reset_hold().
> - Clear superprio in several places for hppi, hpplpi and hppvlpi.
> - Add Reviewed-by.
> 
> Changes in v6:
> - Fix DISAS_TOO_MANY to DISAS_UPDATE_EXIT for ALLINT MSR (immediate).
> - Verify that HCR_EL2.VF is set before checking VFNMI.
> - env->cp15.hcr_el2 -> arm_hcr_el2_eff().
> - env->cp15.hcrx_el2 -> arm_hcrx_el2_eff().
> - Not combine VFNMI with CPU_INTERRUPT_VNMI.
> - Implement icv_nmiar1_read().
> - Put the "extract superprio info" code into gicv3_get_priority().
> - Update the comment in irqbetter().
> - Reset the cs->hppi.superprio to 0x0.
> - Set hppi.superprio to false for LPI.
> - Add Reviewed-by.
> 
> Changes in v5:
> - Remove the comment for ALLINT in cpu.h.
> - Merge allint_check() to msr_i_allint to clear the ALLINT MSR (immediate)
>   implementation.
> - Rename msr_i_allint() to msr_set_allint_el1() to make it clearer.
> - Drop the & 1 in trans_MSR_i_ALLINT().
> - Add Reviewed-by.
> 
> Changes in v4:
> - Handle VNMI within the CPU and the GIC.
> - Keep PSTATE.ALLINT in env->pstate but not env->allint.
> - Fix the ALLINT MSR (immediate) decodetree implementation.
> - Accept NMI unconditionally for arm_cpu_has_work() but add comment.
> - Improve nmi mask in arm_excp_unmasked().
> - Make the GICR_INMIR0 and GICD_INMIR implementation more clearer.
> - Improve ICC_NMIAR1_EL1 implementation
> - Extract gicv3_get_priority() to avoid priority code repetition.
> - Add Reviewed-by.
> 
> Changes in v3:
> - Remove the FIQ NMI.
> - Adjust the patches Sequence.
> - Reomve the patch "Set pstate.ALLINT in arm_cpu_reset_hold".
> - Check whether support FEAT_NMI and FEAT_GICv3 for FEAT_GICv3_NMI.
> - With CPU_INTERRUPT_NMI, both CPSR_I and ISR_IS must be set.
> - Not include NMI logic when FEAT_NMI or SCTLR_ELx.NMI not enabled.
> - Refator nmi mask in arm_excp_unmasked().
> - Add VNMI definitions, add HCRX_VINMI and HCRX_VFNMI support in HCRX_EL2.
> - Add Reviewed-by and Acked-by.
> - Update the commit message.
> 
> Changes in v2:
> - Break up the patches so that each one does only one thing.
> - Remove the command line option and just implement it in "max" cpu.
> 
> Jinjie Ruan (24):
>   target/arm: Handle HCR_EL2 accesses for bits introduced with FEAT_NMI
>   target/arm: Add PSTATE.ALLINT
>   target/arm: Add support for FEAT_NMI, Non-maskable Interrupt
>   target/arm: Implement ALLINT MSR (immediate)
>   target/arm: Support MSR access to ALLINT
>   target/arm: Add support for Non-maskable Interrupt
>   target/arm: Add support for NMI in arm_phys_excp_target_el()
>   target/arm: Handle IS/FS in ISR_EL1 for NMI, VINMI and VFNMI
>   target/arm: Handle PSTATE.ALLINT on taking an exception
>   hw/intc/arm_gicv3: Add external IRQ lines for NMI
>   hw/arm/virt: Wire NMI and VINMI irq lines from GIC to CPU
>   target/arm: Handle NMI in arm_cpu_do_interrupt_aarch64()
>   hw/intc/arm_gicv3: Add has-nmi property to GICv3 device
>   hw/intc/arm_gicv3_kvm: Not set has-nmi=true for the KVM GICv3
>   hw/intc/arm_gicv3: Add irq non-maskable property
>   hw/intc/arm_gicv3_redist: Implement GICR_INMIR0
>   hw/intc/arm_gicv3: Implement GICD_INMIR
>   hw/intc/arm_gicv3: Add NMI handling CPU interface registers
>   hw/intc/arm_gicv3: Handle icv_nmiar1_read() for icc_nmiar1_read()
>   hw/intc/arm_gicv3: Implement NMI interrupt priority
>   hw/intc/arm_gicv3: Report the NMI interrupt in gicv3_cpuif_update()
>   hw/intc/arm_gicv3: Report the VINMI interrupt
>   target/arm: Add FEAT_NMI to max
>   hw/arm/virt: Add FEAT_GICv3_NMI feature support in virt GIC
> 
>  docs/system/arm/emulation.rst      |   1 +
>  hw/arm/virt.c                      |  27 ++-
>  hw/intc/arm_gicv3.c                |  67 +++++++-
>  hw/intc/arm_gicv3_common.c         |  48 ++++++
>  hw/intc/arm_gicv3_cpuif.c          | 258 +++++++++++++++++++++++++++--
>  hw/intc/arm_gicv3_dist.c           |  36 ++++
>  hw/intc/arm_gicv3_kvm.c            |   5 +
>  hw/intc/arm_gicv3_redist.c         |  22 +++
>  hw/intc/gicv3_internal.h           |  13 ++
>  hw/intc/trace-events               |   2 +
>  include/hw/intc/arm_gic_common.h   |   2 +
>  include/hw/intc/arm_gicv3_common.h |   7 +
>  target/arm/cpu-features.h          |   5 +
>  target/arm/cpu-qom.h               |   5 +-
>  target/arm/cpu.c                   | 147 ++++++++++++++--
>  target/arm/cpu.h                   |   9 +
>  target/arm/helper.c                | 101 ++++++++++-
>  target/arm/internals.h             |  21 +++
>  target/arm/tcg/a64.decode          |   1 +
>  target/arm/tcg/cpu64.c             |   1 +
>  target/arm/tcg/helper-a64.c        |  16 +-
>  target/arm/tcg/helper-a64.h        |   1 +
>  target/arm/tcg/translate-a64.c     |  19 +++
>  23 files changed, 767 insertions(+), 47 deletions(-)
> 

Reply via email to