misc: Register a PPI for the vcpu stall detection virtual device

Request a PPI for each vCPU during probe which will be used by the host
to communicate a stall detected event on the vCPU. When the host raises
this interrupt from the virtual machine monitor, the guest is expected to
handle the interrupt and panic.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
Link: https://lore.kernel.org/r/20240703153732.3214238-3-sebastianene@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Sebastian Ene 2024-07-03 15:37:32 +00:00 committed by Greg Kroah-Hartman
parent 173c044752
commit d2b88700ea

View File

@ -32,6 +32,7 @@
struct vcpu_stall_detect_config {
u32 clock_freq_hz;
u32 stall_timeout_sec;
int ppi_irq;
void __iomem *membase;
struct platform_device *dev;
@ -77,6 +78,12 @@ vcpu_stall_detect_timer_fn(struct hrtimer *hrtimer)
return HRTIMER_RESTART;
}
static irqreturn_t vcpu_stall_detector_irq(int irq, void *dev)
{
panic("vCPU stall detector");
return IRQ_HANDLED;
}
static int start_stall_detector_cpu(unsigned int cpu)
{
u32 ticks, ping_timeout_ms;
@ -132,7 +139,7 @@ static int stop_stall_detector_cpu(unsigned int cpu)
static int vcpu_stall_detect_probe(struct platform_device *pdev)
{
int ret;
int ret, irq;
struct resource *r;
void __iomem *membase;
u32 clock_freq_hz = VCPU_STALL_DEFAULT_CLOCK_HZ;
@ -169,9 +176,22 @@ static int vcpu_stall_detect_probe(struct platform_device *pdev)
vcpu_stall_config = (struct vcpu_stall_detect_config) {
.membase = membase,
.clock_freq_hz = clock_freq_hz,
.stall_timeout_sec = stall_timeout_sec
.stall_timeout_sec = stall_timeout_sec,
.ppi_irq = -1,
};
irq = platform_get_irq_optional(pdev, 0);
if (irq > 0) {
ret = request_percpu_irq(irq,
vcpu_stall_detector_irq,
"vcpu_stall_detector",
vcpu_stall_detectors);
if (ret)
goto err;
vcpu_stall_config.ppi_irq = irq;
}
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
"virt/vcpu_stall_detector:online",
start_stall_detector_cpu,
@ -184,6 +204,9 @@ static int vcpu_stall_detect_probe(struct platform_device *pdev)
vcpu_stall_config.hp_online = ret;
return 0;
err:
if (vcpu_stall_config.ppi_irq > 0)
free_percpu_irq(vcpu_stall_config.ppi_irq,
vcpu_stall_detectors);
return ret;
}
@ -193,6 +216,10 @@ static void vcpu_stall_detect_remove(struct platform_device *pdev)
cpuhp_remove_state(vcpu_stall_config.hp_online);
if (vcpu_stall_config.ppi_irq > 0)
free_percpu_irq(vcpu_stall_config.ppi_irq,
vcpu_stall_detectors);
for_each_possible_cpu(cpu)
stop_stall_detector_cpu(cpu);
}