[PATCH v1 14/15] xen/riscv: handle hypervisor timer interrupts

Oleksii Kurochko posted 15 patches 1 month, 2 weeks ago
[PATCH v1 14/15] xen/riscv: handle hypervisor timer interrupts
Posted by Oleksii Kurochko 1 month, 2 weeks ago
Introduce timer_interrupt() to process IRQ_S_TIMER interrupts.
The handler disables further timer interrupts by clearing
SIE.STIE and raises TIMER_SOFTIRQ so the generic timer subsystem
can perform its processing.

Update do_trap() to dispatch IRQ_S_TIMER to this new handler.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 xen/arch/riscv/traps.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
index e9c967786312..5fd12b1b21c3 100644
--- a/xen/arch/riscv/traps.c
+++ b/xen/arch/riscv/traps.c
@@ -10,6 +10,7 @@
 #include <xen/lib.h>
 #include <xen/nospec.h>
 #include <xen/sched.h>
+#include <xen/softirq.h>
 
 #include <asm/intc.h>
 #include <asm/processor.h>
@@ -108,6 +109,15 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
     die();
 }
 
+static void timer_interrupt(unsigned long cause)
+{
+    /* Disable the timer to avoid more interrupts */
+    csr_clear(CSR_SIE, BIT(IRQ_S_TIMER, UL));
+
+    /* Signal the generic timer code to do its work */
+    raise_softirq(TIMER_SOFTIRQ);
+}
+
 void do_trap(struct cpu_user_regs *cpu_regs)
 {
     register_t pc = cpu_regs->sepc;
@@ -148,6 +158,10 @@ void do_trap(struct cpu_user_regs *cpu_regs)
                 intc_handle_external_irqs(cpu_regs);
                 break;
 
+            case IRQ_S_TIMER:
+                timer_interrupt(cause);
+                break;
+
             default:
                 break;
             }
-- 
2.52.0
Re: [PATCH v1 14/15] xen/riscv: handle hypervisor timer interrupts
Posted by Jan Beulich 3 weeks, 6 days ago
On 24.12.2025 18:03, Oleksii Kurochko wrote:
> @@ -108,6 +109,15 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
>      die();
>  }
>  
> +static void timer_interrupt(unsigned long cause)
> +{
> +    /* Disable the timer to avoid more interrupts */
> +    csr_clear(CSR_SIE, BIT(IRQ_S_TIMER, UL));
> +
> +    /* Signal the generic timer code to do its work */
> +    raise_softirq(TIMER_SOFTIRQ);
> +}

Why is "cause" being passed when it's not used?

Jan
Re: [PATCH v1 14/15] xen/riscv: handle hypervisor timer interrupts
Posted by Oleksii Kurochko 3 weeks, 5 days ago
On 1/12/26 5:15 PM, Jan Beulich wrote:
> On 24.12.2025 18:03, Oleksii Kurochko wrote:
>> @@ -108,6 +109,15 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
>>       die();
>>   }
>>   
>> +static void timer_interrupt(unsigned long cause)
>> +{
>> +    /* Disable the timer to avoid more interrupts */
>> +    csr_clear(CSR_SIE, BIT(IRQ_S_TIMER, UL));
>> +
>> +    /* Signal the generic timer code to do its work */
>> +    raise_softirq(TIMER_SOFTIRQ);
>> +}
> Why is "cause" being passed when it's not used?

Good point. No any sense in it. Even more I think the cause is
pretty known in such handler, it should be definitely = IRQ_S_TIMER.

I will drop an argument for timer_interrupt().

Thanks.

~ Oleksii