freeze: allow interrupts in frozen state
Change-Id: I1d502f828ab9f9c0e1223d021979ac3dcf4d0c25
This commit is contained in:
committed by
Masamichi Takagi
parent
ff982b8594
commit
8e4073c2ca
@ -796,6 +796,21 @@ unsigned long cpu_disable_interrupt_save(void)
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* save ICC_PMR_EL1 & enable interrupt (ICC_PMR_EL1 <= ICC_PMR_EL1_UNMASKED) */
|
||||
unsigned long cpu_enable_interrupt_save(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long masked = ICC_PMR_EL1_UNMASKED;
|
||||
|
||||
asm volatile(
|
||||
"mrs_s %0, " __stringify(ICC_PMR_EL1) "\n"
|
||||
"msr_s " __stringify(ICC_PMR_EL1) ",%1"
|
||||
: "=&r" (flags)
|
||||
: "r" (masked)
|
||||
: "memory");
|
||||
return flags;
|
||||
}
|
||||
|
||||
#else /* defined(CONFIG_HAS_NMI) */
|
||||
|
||||
/* @ref.impl arch/arm64/include/asm/irqflags.h::arch_local_irq_enable */
|
||||
@ -844,6 +859,20 @@ unsigned long cpu_disable_interrupt_save(void)
|
||||
: "memory");
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* save PSTATE.DAIF & enable interrupt (PSTATE.DAIF I bit set) */
|
||||
unsigned long cpu_enable_interrupt_save(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
asm volatile(
|
||||
"mrs %0, daif // arch_local_irq_save\n"
|
||||
"msr daifclr, #2"
|
||||
: "=r" (flags)
|
||||
:
|
||||
: "memory");
|
||||
return flags;
|
||||
}
|
||||
#endif /* defined(CONFIG_HAS_NMI) */
|
||||
|
||||
/* we not have "pause" instruction, instead "yield" instruction */
|
||||
|
||||
@ -1203,6 +1203,15 @@ unsigned long cpu_disable_interrupt_save(void)
|
||||
return flags;
|
||||
}
|
||||
|
||||
unsigned long cpu_enable_interrupt_save(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
asm volatile("pushf; pop %0; sti" : "=r"(flags) : : "memory", "cc");
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*@
|
||||
@ behavior valid_vector:
|
||||
@ assumes 32 <= vector <= 255;
|
||||
|
||||
@ -14,14 +14,17 @@ extern void __freeze();
|
||||
void
|
||||
freeze()
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ihk_os_cpu_monitor *monitor = cpu_local_var(monitor);
|
||||
|
||||
monitor->status_bak = monitor->status;
|
||||
monitor->status = IHK_OS_MONITOR_KERNEL_FROZEN;
|
||||
flags = cpu_enable_interrupt_save();
|
||||
while (monitor->status == IHK_OS_MONITOR_KERNEL_FROZEN) {
|
||||
cpu_halt();
|
||||
cpu_pause();
|
||||
}
|
||||
cpu_restore_interrupt(flags);
|
||||
monitor->status = monitor->status_bak;
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
/*
|
||||
* HISTORY
|
||||
*/
|
||||
/* cpu.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
|
||||
/* cpu.h COPYRIGHT FUJITSU LIMITED 2015-2019 */
|
||||
|
||||
#ifndef IHK_CPU_H
|
||||
#define IHK_CPU_H
|
||||
@ -28,6 +28,7 @@ void cpu_restore_interrupt(unsigned long);
|
||||
void cpu_pause(void);
|
||||
|
||||
unsigned long cpu_disable_interrupt_save(void);
|
||||
unsigned long cpu_enable_interrupt_save(void);
|
||||
|
||||
struct ihk_mc_interrupt_handler {
|
||||
struct list_head list;
|
||||
|
||||
Reference in New Issue
Block a user