mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 00:16:48 +07:00
arm64: Fix incorrect irqflag restore for priority masking
When using IRQ priority masking to disable interrupts, in order to deal
with the PSR.I state, local_irq_save() would convert the I bit into a
PMR value (GIC_PRIO_IRQOFF). This resulted in local_irq_restore()
potentially modifying the value of PMR in undesired location due to the
state of PSR.I upon flag saving [1].
In an attempt to solve this issue in a less hackish manner, introduce
a bit (GIC_PRIO_IGNORE_PMR) for the PMR values that can represent
whether PSR.I is being used to disable interrupts, in which case it
takes precedence of the status of interrupt masking via PMR.
GIC_PRIO_PSR_I_SET is chosen such that (<pmr_value> |
GIC_PRIO_PSR_I_SET) does not mask more interrupts than <pmr_value> as
some sections (e.g. arch_cpu_idle(), interrupt acknowledge path)
requires PMR not to mask interrupts that could be signaled to the
CPU when using only PSR.I.
[1] https://www.spinics.net/lists/arm-kernel/msg716956.html
Fixes: 4a503217ce
("arm64: irqflags: Use ICC_PMR_EL1 for interrupt masking")
Cc: <stable@vger.kernel.org> # 5.1.x-
Reported-by: Zenghui Yu <yuzenghui@huawei.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Wei Li <liwei391@huawei.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Suzuki K Pouloze <suzuki.poulose@arm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Julien Thierry <julien.thierry@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
17ce302f31
commit
bd82d4bd21
@ -163,7 +163,9 @@ static inline bool gic_prio_masking_enabled(void)
|
|||||||
|
|
||||||
static inline void gic_pmr_mask_irqs(void)
|
static inline void gic_pmr_mask_irqs(void)
|
||||||
{
|
{
|
||||||
BUILD_BUG_ON(GICD_INT_DEF_PRI <= GIC_PRIO_IRQOFF);
|
BUILD_BUG_ON(GICD_INT_DEF_PRI < (GIC_PRIO_IRQOFF |
|
||||||
|
GIC_PRIO_PSR_I_SET));
|
||||||
|
BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON);
|
||||||
gic_write_pmr(GIC_PRIO_IRQOFF);
|
gic_write_pmr(GIC_PRIO_IRQOFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <linux/irqflags.h>
|
#include <linux/irqflags.h>
|
||||||
|
|
||||||
|
#include <asm/arch_gicv3.h>
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeature.h>
|
||||||
|
|
||||||
#define DAIF_PROCCTX 0
|
#define DAIF_PROCCTX 0
|
||||||
@ -32,6 +33,11 @@ static inline void local_daif_mask(void)
|
|||||||
:
|
:
|
||||||
:
|
:
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
|
/* Don't really care for a dsb here, we don't intend to enable IRQs */
|
||||||
|
if (system_uses_irq_prio_masking())
|
||||||
|
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||||
|
|
||||||
trace_hardirqs_off();
|
trace_hardirqs_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +49,7 @@ static inline unsigned long local_daif_save(void)
|
|||||||
|
|
||||||
if (system_uses_irq_prio_masking()) {
|
if (system_uses_irq_prio_masking()) {
|
||||||
/* If IRQs are masked with PMR, reflect it in the flags */
|
/* If IRQs are masked with PMR, reflect it in the flags */
|
||||||
if (read_sysreg_s(SYS_ICC_PMR_EL1) <= GIC_PRIO_IRQOFF)
|
if (read_sysreg_s(SYS_ICC_PMR_EL1) != GIC_PRIO_IRQON)
|
||||||
flags |= PSR_I_BIT;
|
flags |= PSR_I_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,15 +65,24 @@ static inline void local_daif_restore(unsigned long flags)
|
|||||||
if (!irq_disabled) {
|
if (!irq_disabled) {
|
||||||
trace_hardirqs_on();
|
trace_hardirqs_on();
|
||||||
|
|
||||||
if (system_uses_irq_prio_masking())
|
if (system_uses_irq_prio_masking()) {
|
||||||
arch_local_irq_enable();
|
gic_write_pmr(GIC_PRIO_IRQON);
|
||||||
} else if (!(flags & PSR_A_BIT)) {
|
dsb(sy);
|
||||||
|
}
|
||||||
|
} else if (system_uses_irq_prio_masking()) {
|
||||||
|
u64 pmr;
|
||||||
|
|
||||||
|
if (!(flags & PSR_A_BIT)) {
|
||||||
/*
|
/*
|
||||||
* If interrupts are disabled but we can take
|
* If interrupts are disabled but we can take
|
||||||
* asynchronous errors, we can take NMIs
|
* asynchronous errors, we can take NMIs
|
||||||
*/
|
*/
|
||||||
if (system_uses_irq_prio_masking()) {
|
|
||||||
flags &= ~PSR_I_BIT;
|
flags &= ~PSR_I_BIT;
|
||||||
|
pmr = GIC_PRIO_IRQOFF;
|
||||||
|
} else {
|
||||||
|
pmr = GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There has been concern that the write to daif
|
* There has been concern that the write to daif
|
||||||
* might be reordered before this write to PMR.
|
* might be reordered before this write to PMR.
|
||||||
@ -87,8 +102,7 @@ static inline void local_daif_restore(unsigned long flags)
|
|||||||
*
|
*
|
||||||
* So we don't need additional synchronization here.
|
* So we don't need additional synchronization here.
|
||||||
*/
|
*/
|
||||||
arch_local_irq_disable();
|
gic_write_pmr(pmr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_sysreg(flags, daif);
|
write_sysreg(flags, daif);
|
||||||
|
@ -67,42 +67,45 @@ static inline void arch_local_irq_disable(void)
|
|||||||
*/
|
*/
|
||||||
static inline unsigned long arch_local_save_flags(void)
|
static inline unsigned long arch_local_save_flags(void)
|
||||||
{
|
{
|
||||||
unsigned long daif_bits;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
daif_bits = read_sysreg(daif);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The asm is logically equivalent to:
|
|
||||||
*
|
|
||||||
* if (system_uses_irq_prio_masking())
|
|
||||||
* flags = (daif_bits & PSR_I_BIT) ?
|
|
||||||
* GIC_PRIO_IRQOFF :
|
|
||||||
* read_sysreg_s(SYS_ICC_PMR_EL1);
|
|
||||||
* else
|
|
||||||
* flags = daif_bits;
|
|
||||||
*/
|
|
||||||
asm volatile(ALTERNATIVE(
|
asm volatile(ALTERNATIVE(
|
||||||
"mov %0, %1\n"
|
"mrs %0, daif",
|
||||||
"nop\n"
|
__mrs_s("%0", SYS_ICC_PMR_EL1),
|
||||||
"nop",
|
|
||||||
__mrs_s("%0", SYS_ICC_PMR_EL1)
|
|
||||||
"ands %1, %1, " __stringify(PSR_I_BIT) "\n"
|
|
||||||
"csel %0, %0, %2, eq",
|
|
||||||
ARM64_HAS_IRQ_PRIO_MASKING)
|
ARM64_HAS_IRQ_PRIO_MASKING)
|
||||||
: "=&r" (flags), "+r" (daif_bits)
|
: "=&r" (flags)
|
||||||
: "r" ((unsigned long) GIC_PRIO_IRQOFF)
|
:
|
||||||
: "cc", "memory");
|
: "memory");
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int arch_irqs_disabled_flags(unsigned long flags)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
asm volatile(ALTERNATIVE(
|
||||||
|
"and %w0, %w1, #" __stringify(PSR_I_BIT),
|
||||||
|
"eor %w0, %w1, #" __stringify(GIC_PRIO_IRQON),
|
||||||
|
ARM64_HAS_IRQ_PRIO_MASKING)
|
||||||
|
: "=&r" (res)
|
||||||
|
: "r" ((int) flags)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned long arch_local_irq_save(void)
|
static inline unsigned long arch_local_irq_save(void)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
flags = arch_local_save_flags();
|
flags = arch_local_save_flags();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are too many states with IRQs disabled, just keep the current
|
||||||
|
* state if interrupts are already disabled/masked.
|
||||||
|
*/
|
||||||
|
if (!arch_irqs_disabled_flags(flags))
|
||||||
arch_local_irq_disable();
|
arch_local_irq_disable();
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
@ -124,21 +127,5 @@ static inline void arch_local_irq_restore(unsigned long flags)
|
|||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int arch_irqs_disabled_flags(unsigned long flags)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
asm volatile(ALTERNATIVE(
|
|
||||||
"and %w0, %w1, #" __stringify(PSR_I_BIT) "\n"
|
|
||||||
"nop",
|
|
||||||
"cmp %w1, #" __stringify(GIC_PRIO_IRQOFF) "\n"
|
|
||||||
"cset %w0, ls",
|
|
||||||
ARM64_HAS_IRQ_PRIO_MASKING)
|
|
||||||
: "=&r" (res)
|
|
||||||
: "r" ((int) flags)
|
|
||||||
: "cc", "memory");
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -608,12 +608,13 @@ static inline void kvm_arm_vhe_guest_enter(void)
|
|||||||
* will not signal the CPU of interrupts of lower priority, and the
|
* will not signal the CPU of interrupts of lower priority, and the
|
||||||
* only way to get out will be via guest exceptions.
|
* only way to get out will be via guest exceptions.
|
||||||
* Naturally, we want to avoid this.
|
* Naturally, we want to avoid this.
|
||||||
|
*
|
||||||
|
* local_daif_mask() already sets GIC_PRIO_PSR_I_SET, we just need a
|
||||||
|
* dsb to ensure the redistributor is forwards EL2 IRQs to the CPU.
|
||||||
*/
|
*/
|
||||||
if (system_uses_irq_prio_masking()) {
|
if (system_uses_irq_prio_masking())
|
||||||
gic_write_pmr(GIC_PRIO_IRQON);
|
|
||||||
dsb(sy);
|
dsb(sy);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static inline void kvm_arm_vhe_guest_exit(void)
|
static inline void kvm_arm_vhe_guest_exit(void)
|
||||||
{
|
{
|
||||||
|
@ -35,9 +35,15 @@
|
|||||||
* means masking more IRQs (or at least that the same IRQs remain masked).
|
* means masking more IRQs (or at least that the same IRQs remain masked).
|
||||||
*
|
*
|
||||||
* To mask interrupts, we clear the most significant bit of PMR.
|
* To mask interrupts, we clear the most significant bit of PMR.
|
||||||
|
*
|
||||||
|
* Some code sections either automatically switch back to PSR.I or explicitly
|
||||||
|
* require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included
|
||||||
|
* in the the priority mask, it indicates that PSR.I should be set and
|
||||||
|
* interrupt disabling temporarily does not rely on IRQ priorities.
|
||||||
*/
|
*/
|
||||||
#define GIC_PRIO_IRQON 0xf0
|
#define GIC_PRIO_IRQON 0xc0
|
||||||
#define GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80)
|
#define GIC_PRIO_IRQOFF (GIC_PRIO_IRQON & ~0x80)
|
||||||
|
#define GIC_PRIO_PSR_I_SET (1 << 4)
|
||||||
|
|
||||||
/* Additional SPSR bits not exposed in the UABI */
|
/* Additional SPSR bits not exposed in the UABI */
|
||||||
#define PSR_IL_BIT (1 << 20)
|
#define PSR_IL_BIT (1 << 20)
|
||||||
|
@ -258,6 +258,7 @@ alternative_else_nop_endif
|
|||||||
/*
|
/*
|
||||||
* Registers that may be useful after this macro is invoked:
|
* Registers that may be useful after this macro is invoked:
|
||||||
*
|
*
|
||||||
|
* x20 - ICC_PMR_EL1
|
||||||
* x21 - aborted SP
|
* x21 - aborted SP
|
||||||
* x22 - aborted PC
|
* x22 - aborted PC
|
||||||
* x23 - aborted PSTATE
|
* x23 - aborted PSTATE
|
||||||
@ -449,6 +450,24 @@ alternative_endif
|
|||||||
.endm
|
.endm
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.macro gic_prio_kentry_setup, tmp:req
|
||||||
|
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||||
|
alternative_if ARM64_HAS_IRQ_PRIO_MASKING
|
||||||
|
mov \tmp, #(GIC_PRIO_PSR_I_SET | GIC_PRIO_IRQON)
|
||||||
|
msr_s SYS_ICC_PMR_EL1, \tmp
|
||||||
|
alternative_else_nop_endif
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro gic_prio_irq_setup, pmr:req, tmp:req
|
||||||
|
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||||
|
alternative_if ARM64_HAS_IRQ_PRIO_MASKING
|
||||||
|
orr \tmp, \pmr, #GIC_PRIO_PSR_I_SET
|
||||||
|
msr_s SYS_ICC_PMR_EL1, \tmp
|
||||||
|
alternative_else_nop_endif
|
||||||
|
#endif
|
||||||
|
.endm
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -627,6 +646,7 @@ el1_dbg:
|
|||||||
cmp x24, #ESR_ELx_EC_BRK64 // if BRK64
|
cmp x24, #ESR_ELx_EC_BRK64 // if BRK64
|
||||||
cinc x24, x24, eq // set bit '0'
|
cinc x24, x24, eq // set bit '0'
|
||||||
tbz x24, #0, el1_inv // EL1 only
|
tbz x24, #0, el1_inv // EL1 only
|
||||||
|
gic_prio_kentry_setup tmp=x3
|
||||||
mrs x0, far_el1
|
mrs x0, far_el1
|
||||||
mov x2, sp // struct pt_regs
|
mov x2, sp // struct pt_regs
|
||||||
bl do_debug_exception
|
bl do_debug_exception
|
||||||
@ -644,12 +664,10 @@ ENDPROC(el1_sync)
|
|||||||
.align 6
|
.align 6
|
||||||
el1_irq:
|
el1_irq:
|
||||||
kernel_entry 1
|
kernel_entry 1
|
||||||
|
gic_prio_irq_setup pmr=x20, tmp=x1
|
||||||
enable_da_f
|
enable_da_f
|
||||||
|
|
||||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||||
alternative_if ARM64_HAS_IRQ_PRIO_MASKING
|
|
||||||
ldr x20, [sp, #S_PMR_SAVE]
|
|
||||||
alternative_else_nop_endif
|
|
||||||
test_irqs_unmasked res=x0, pmr=x20
|
test_irqs_unmasked res=x0, pmr=x20
|
||||||
cbz x0, 1f
|
cbz x0, 1f
|
||||||
bl asm_nmi_enter
|
bl asm_nmi_enter
|
||||||
@ -679,8 +697,9 @@ alternative_else_nop_endif
|
|||||||
|
|
||||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||||
/*
|
/*
|
||||||
* if IRQs were disabled when we received the interrupt, we have an NMI
|
* When using IRQ priority masking, we can get spurious interrupts while
|
||||||
* and we are not re-enabling interrupt upon eret. Skip tracing.
|
* PMR is set to GIC_PRIO_IRQOFF. An NMI might also have occurred in a
|
||||||
|
* section with interrupts disabled. Skip tracing in those cases.
|
||||||
*/
|
*/
|
||||||
test_irqs_unmasked res=x0, pmr=x20
|
test_irqs_unmasked res=x0, pmr=x20
|
||||||
cbz x0, 1f
|
cbz x0, 1f
|
||||||
@ -809,6 +828,7 @@ el0_ia:
|
|||||||
* Instruction abort handling
|
* Instruction abort handling
|
||||||
*/
|
*/
|
||||||
mrs x26, far_el1
|
mrs x26, far_el1
|
||||||
|
gic_prio_kentry_setup tmp=x0
|
||||||
enable_da_f
|
enable_da_f
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
bl trace_hardirqs_off
|
bl trace_hardirqs_off
|
||||||
@ -854,6 +874,7 @@ el0_sp_pc:
|
|||||||
* Stack or PC alignment exception handling
|
* Stack or PC alignment exception handling
|
||||||
*/
|
*/
|
||||||
mrs x26, far_el1
|
mrs x26, far_el1
|
||||||
|
gic_prio_kentry_setup tmp=x0
|
||||||
enable_da_f
|
enable_da_f
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
bl trace_hardirqs_off
|
bl trace_hardirqs_off
|
||||||
@ -888,6 +909,7 @@ el0_dbg:
|
|||||||
* Debug exception handling
|
* Debug exception handling
|
||||||
*/
|
*/
|
||||||
tbnz x24, #0, el0_inv // EL0 only
|
tbnz x24, #0, el0_inv // EL0 only
|
||||||
|
gic_prio_kentry_setup tmp=x3
|
||||||
mrs x0, far_el1
|
mrs x0, far_el1
|
||||||
mov x1, x25
|
mov x1, x25
|
||||||
mov x2, sp
|
mov x2, sp
|
||||||
@ -909,7 +931,9 @@ ENDPROC(el0_sync)
|
|||||||
el0_irq:
|
el0_irq:
|
||||||
kernel_entry 0
|
kernel_entry 0
|
||||||
el0_irq_naked:
|
el0_irq_naked:
|
||||||
|
gic_prio_irq_setup pmr=x20, tmp=x0
|
||||||
enable_da_f
|
enable_da_f
|
||||||
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
bl trace_hardirqs_off
|
bl trace_hardirqs_off
|
||||||
#endif
|
#endif
|
||||||
@ -931,6 +955,7 @@ ENDPROC(el0_irq)
|
|||||||
el1_error:
|
el1_error:
|
||||||
kernel_entry 1
|
kernel_entry 1
|
||||||
mrs x1, esr_el1
|
mrs x1, esr_el1
|
||||||
|
gic_prio_kentry_setup tmp=x2
|
||||||
enable_dbg
|
enable_dbg
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
bl do_serror
|
bl do_serror
|
||||||
@ -941,6 +966,7 @@ el0_error:
|
|||||||
kernel_entry 0
|
kernel_entry 0
|
||||||
el0_error_naked:
|
el0_error_naked:
|
||||||
mrs x1, esr_el1
|
mrs x1, esr_el1
|
||||||
|
gic_prio_kentry_setup tmp=x2
|
||||||
enable_dbg
|
enable_dbg
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
bl do_serror
|
bl do_serror
|
||||||
@ -965,6 +991,7 @@ work_pending:
|
|||||||
*/
|
*/
|
||||||
ret_to_user:
|
ret_to_user:
|
||||||
disable_daif
|
disable_daif
|
||||||
|
gic_prio_kentry_setup tmp=x3
|
||||||
ldr x1, [tsk, #TSK_TI_FLAGS]
|
ldr x1, [tsk, #TSK_TI_FLAGS]
|
||||||
and x2, x1, #_TIF_WORK_MASK
|
and x2, x1, #_TIF_WORK_MASK
|
||||||
cbnz x2, work_pending
|
cbnz x2, work_pending
|
||||||
@ -981,6 +1008,7 @@ ENDPROC(ret_to_user)
|
|||||||
*/
|
*/
|
||||||
.align 6
|
.align 6
|
||||||
el0_svc:
|
el0_svc:
|
||||||
|
gic_prio_kentry_setup tmp=x1
|
||||||
mov x0, sp
|
mov x0, sp
|
||||||
bl el0_svc_handler
|
bl el0_svc_handler
|
||||||
b ret_to_user
|
b ret_to_user
|
||||||
|
@ -94,7 +94,7 @@ static void __cpu_do_idle_irqprio(void)
|
|||||||
* be raised.
|
* be raised.
|
||||||
*/
|
*/
|
||||||
pmr = gic_read_pmr();
|
pmr = gic_read_pmr();
|
||||||
gic_write_pmr(GIC_PRIO_IRQON);
|
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||||
|
|
||||||
__cpu_do_idle();
|
__cpu_do_idle();
|
||||||
|
|
||||||
|
@ -192,11 +192,13 @@ static void init_gic_priority_masking(void)
|
|||||||
|
|
||||||
WARN_ON(!(cpuflags & PSR_I_BIT));
|
WARN_ON(!(cpuflags & PSR_I_BIT));
|
||||||
|
|
||||||
gic_write_pmr(GIC_PRIO_IRQOFF);
|
|
||||||
|
|
||||||
/* We can only unmask PSR.I if we can take aborts */
|
/* We can only unmask PSR.I if we can take aborts */
|
||||||
if (!(cpuflags & PSR_A_BIT))
|
if (!(cpuflags & PSR_A_BIT)) {
|
||||||
|
gic_write_pmr(GIC_PRIO_IRQOFF);
|
||||||
write_sysreg(cpuflags & ~PSR_I_BIT, daif);
|
write_sysreg(cpuflags & ~PSR_I_BIT, daif);
|
||||||
|
} else {
|
||||||
|
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -615,7 +615,7 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
|
|||||||
* Naturally, we want to avoid this.
|
* Naturally, we want to avoid this.
|
||||||
*/
|
*/
|
||||||
if (system_uses_irq_prio_masking()) {
|
if (system_uses_irq_prio_masking()) {
|
||||||
gic_write_pmr(GIC_PRIO_IRQON);
|
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||||
dsb(sy);
|
dsb(sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user