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;
|
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) */
|
#else /* defined(CONFIG_HAS_NMI) */
|
||||||
|
|
||||||
/* @ref.impl arch/arm64/include/asm/irqflags.h::arch_local_irq_enable */
|
/* @ref.impl arch/arm64/include/asm/irqflags.h::arch_local_irq_enable */
|
||||||
@@ -844,6 +859,20 @@ unsigned long cpu_disable_interrupt_save(void)
|
|||||||
: "memory");
|
: "memory");
|
||||||
return flags;
|
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) */
|
#endif /* defined(CONFIG_HAS_NMI) */
|
||||||
|
|
||||||
/* we not have "pause" instruction, instead "yield" instruction */
|
/* we not have "pause" instruction, instead "yield" instruction */
|
||||||
|
|||||||
@@ -1203,6 +1203,15 @@ unsigned long cpu_disable_interrupt_save(void)
|
|||||||
return flags;
|
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:
|
@ behavior valid_vector:
|
||||||
@ assumes 32 <= vector <= 255;
|
@ assumes 32 <= vector <= 255;
|
||||||
|
|||||||
@@ -14,14 +14,17 @@ extern void __freeze();
|
|||||||
void
|
void
|
||||||
freeze()
|
freeze()
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
struct ihk_os_cpu_monitor *monitor = cpu_local_var(monitor);
|
struct ihk_os_cpu_monitor *monitor = cpu_local_var(monitor);
|
||||||
|
|
||||||
monitor->status_bak = monitor->status;
|
monitor->status_bak = monitor->status;
|
||||||
monitor->status = IHK_OS_MONITOR_KERNEL_FROZEN;
|
monitor->status = IHK_OS_MONITOR_KERNEL_FROZEN;
|
||||||
|
flags = cpu_enable_interrupt_save();
|
||||||
while (monitor->status == IHK_OS_MONITOR_KERNEL_FROZEN) {
|
while (monitor->status == IHK_OS_MONITOR_KERNEL_FROZEN) {
|
||||||
cpu_halt();
|
cpu_halt();
|
||||||
cpu_pause();
|
cpu_pause();
|
||||||
}
|
}
|
||||||
|
cpu_restore_interrupt(flags);
|
||||||
monitor->status = monitor->status_bak;
|
monitor->status = monitor->status_bak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
/*
|
/*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
*/
|
*/
|
||||||
/* cpu.h COPYRIGHT FUJITSU LIMITED 2015-2016 */
|
/* cpu.h COPYRIGHT FUJITSU LIMITED 2015-2019 */
|
||||||
|
|
||||||
#ifndef IHK_CPU_H
|
#ifndef IHK_CPU_H
|
||||||
#define IHK_CPU_H
|
#define IHK_CPU_H
|
||||||
@@ -28,6 +28,7 @@ void cpu_restore_interrupt(unsigned long);
|
|||||||
void cpu_pause(void);
|
void cpu_pause(void);
|
||||||
|
|
||||||
unsigned long cpu_disable_interrupt_save(void);
|
unsigned long cpu_disable_interrupt_save(void);
|
||||||
|
unsigned long cpu_enable_interrupt_save(void);
|
||||||
|
|
||||||
struct ihk_mc_interrupt_handler {
|
struct ihk_mc_interrupt_handler {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|||||||
Reference in New Issue
Block a user