Unverified Commit 8847abb3 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4425 【OLK-6.6】arm64/nmi: Support for FEAT_NMI

Merge Pull Request from: @liujie-248683921 
 
This series enables the architecture and GIC support for the arm64
FEAT_NMI and FEAT_GICv3_NMI extensions in host kernels. These introduce
support for a new category of interrupts in the architecture code which
we can use to provide NMI like functionality, though the interrupts are
in fact maskable as the name would not imply. The GIC support was done
by Loreozo Pieralisi.

There are two modes for using this FEAT_NMI, the one we use is the one
where SCTLR_EL1.SPINTMASK is set which means that any entry to ELn
causes all interrupts including those with superpriority to be masked by
a new mask bit PSTATE.ALLINT on entry to ELn until the mask is
explicitly removed by software. 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.

To simplify integration we manage masking for superpriority interrupts
along with our masking for DAIF, much as is done for psedo NMIs. This
means that superpriority interrupts are unmasked whenever DAIF.A is
unmasked. This should ensure that no additional code can be preempted
when using the architected feature. The separate mask in the architected
feature means that we require management of this in the assembly code as
well as C code, masking DAIF is not sufficient to mask superpriority
interrupts.

In order to ensure that we do not have both pseudo NMIs and architected
NMIs simultaneously enabled we disable the architected NMIs if pseudo
NMI support is enabled in the kernel and has been requested on the
command line. This avoids any potential confusion or conflict between
the two mechanisms. Since pseudo NMIs require explicit enablement it
seemed most sensible to trust that the user preferred them for some
reason. A feature override is also provided for FEAT_NMI, allowing it to
be directly disabled in case of problems.

Using this feature in KVM guests will require the implementation of vGIC
support which is not present in this series, this is due to my and
Lorenzo's schedules not lining up perfectly and wanting to get the
review of the architecture side started.  The architecture code should
be fine when running in guests but doesn't accomplish anything and can't
be meaningfully tested without an interrupt controller.  As a result the
feature is not exposed to guests and we enable traps for writes to
ALLINT when running guests, detecting any guests that attempt to use the
feature.  The vGIC support should follow soon.  There is no other usage
of the feature in the hypervisor.  

https://gitee.com/openeuler/kernel/issues/I90N2C 
 
Link:https://gitee.com/openeuler/kernel/pulls/4425

 

Reviewed-by: default avatarLiu Chao <liuchao173@huawei.com>
Reviewed-by: default avatarKevin Zhu <zhukeqian1@huawei.com>
Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents e34c2d93 eefea615
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -411,6 +411,12 @@ Before jumping into the kernel, the following conditions must be met:

    - HFGRWR_EL2.nPIRE0_EL1 (bit 57) must be initialised to 0b1.

 For CPUs with Non-maskable Interrupts (FEAT_NMI):

 - If the kernel is entered at EL1 and EL2 is present:

   - HCRX_EL2.TALLINT must be initialised to 0b0.

The requirements described above for CPU mode, caches, MMUs, architected
timers, coherency and system registers apply to all CPUs.  All CPUs must
enter the kernel in the same exception level.  Where the values documented
+17 −0
Original line number Diff line number Diff line
@@ -2217,6 +2217,23 @@ config ARM64_EPAN
	  if the cpu does not implement the feature.
endmenu # "ARMv8.7 architectural features"

menu "ARMv8.8 architectural features"

config ARM64_NMI
	bool "Enable support for Non-maskable Interrupts (NMI)"
	default y
	help
	  Non-maskable interrupts are an architecture and GIC feature
	  which allow the system to configure some interrupts to be
	  configured to have superpriority, allowing them to be handled
	  before other interrupts and masked for shorter periods of time.

	  The feature is detected at runtime, and will remain disabled
	  if the cpu does not implement the feature. It will also be
	  disabled if pseudo NMIs are enabled at runtime.

endmenu # "ARMv8.8 architectural features"

config ARM64_SVE
	bool "ARM Scalable Vector Extension support"
	default y
+7 −1
Original line number Diff line number Diff line
@@ -548,6 +548,12 @@ CONFIG_ARM64_TWED=y
CONFIG_ARM64_EPAN=y
# end of ARMv8.7 architectural features

#
# ARMv8.8 architectural features
#
CONFIG_ARM64_NMI=y
# end of ARMv8.8 architectural features

CONFIG_ARM64_SVE=y
CONFIG_ARM64_SME=y
CONFIG_ARM64_PSEUDO_NMI=y
@@ -7923,7 +7929,7 @@ CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y
CONFIG_HARDLOCKUP_DETECTOR=y
# CONFIG_HARDLOCKUP_DETECTOR_PREFER_BUDDY is not set
# CONFIG_HARDLOCKUP_DETECTOR_PERF is not set
CONFIG_HARDLOCKUP_DETECTOR_PERF=y
# CONFIG_HARDLOCKUP_DETECTOR_BUDDY is not set
# CONFIG_HARDLOCKUP_DETECTOR_ARCH is not set
CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER=y
+18 −0
Original line number Diff line number Diff line
@@ -34,12 +34,30 @@
	wx\n	.req	w\n
	.endr

	.macro	disable_allint
#ifdef CONFIG_ARM64_NMI
alternative_if ARM64_HAS_NMI
	msr_s	SYS_ALLINT_SET, xzr
alternative_else_nop_endif
#endif
	.endm

	.macro	enable_allint
#ifdef CONFIG_ARM64_NMI
alternative_if ARM64_HAS_NMI
	msr_s	SYS_ALLINT_CLR, xzr
alternative_else_nop_endif
#endif
	.endm

	.macro disable_daif
	disable_allint
	msr	daifset, #0xf
	.endm

	.macro enable_daif
	msr	daifclr, #0xf
	enable_allint
	.endm

/*
+6 −0
Original line number Diff line number Diff line
@@ -815,6 +815,12 @@ static __always_inline bool system_uses_irq_prio_masking(void)
	       cpus_have_const_cap(ARM64_HAS_GIC_PRIO_MASKING);
}

static __always_inline bool system_uses_nmi(void)
{
	return IS_ENABLED(CONFIG_ARM64_NMI) &&
		cpus_have_const_cap(ARM64_USES_NMI);
}

static inline bool system_supports_mte(void)
{
	return IS_ENABLED(CONFIG_ARM64_MTE) &&
Loading