From nobody Mon Dec 15 21:30:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1744128186; cv=none; d=zohomail.com; s=zohoarc; b=eaOADhggFmllv9O5z47akTyCwsbUIZe8T9Eb6zzg1PFdovcFNkuMhXVxxhE8P0hK+1FgcDS7mAWMLc68I9VxgyQjIUfkYh+mcH7WtkTo67JXL6DMabpklyH1eUweQQ5v8ptc/xS8VYd4k1DxGvXHW9vuq0HL8MQRI7h53Dsd9rc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1744128186; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=sc7wfWEtEETos3Xy4ASDsRUDXv0bfhmJEvEO/7TawQo=; b=Ebex6i7li7ovDCf8YYfnBgrkzjsdBT5Y60itSenVGBTL7uDKJZnD55ZhIv8vvUyEi+HRPnjY+ZioxXghRstdta9s4OrU6u6Myl0cXznmaDvzjE92wlxAoUZX9iubg1Y9zlBD7Yn3YI6O+zilnHNxRHjlfnuKZSe4x1dX3dAM2Uk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1744128186289869.2951842031547; Tue, 8 Apr 2025 09:03:06 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.942664.1341777 (Exim 4.92) (envelope-from ) id 1u2BPX-0006pK-0R; Tue, 08 Apr 2025 16:02:51 +0000 Received: by outflank-mailman (output) from mailman id 942664.1341777; Tue, 08 Apr 2025 16:02:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u2BPW-0006oo-S8; Tue, 08 Apr 2025 16:02:50 +0000 Received: by outflank-mailman (input) for mailman id 942664; Tue, 08 Apr 2025 16:02:49 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u2BKc-0004Yq-KZ for xen-devel@lists.xenproject.org; Tue, 08 Apr 2025 15:57:46 +0000 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [2a00:1450:4864:20::536]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 3168b3ad-1492-11f0-9ffb-bf95429c2676; Tue, 08 Apr 2025 17:57:37 +0200 (CEST) Received: by mail-ed1-x536.google.com with SMTP id 4fb4d7f45d1cf-5e61da95244so9512658a12.2 for ; Tue, 08 Apr 2025 08:57:37 -0700 (PDT) Received: from fedora.. (user-109-243-64-225.play-internet.pl. [109.243.64.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ac7c018556bsm929934566b.156.2025.04.08.08.57.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Apr 2025 08:57:36 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3168b3ad-1492-11f0-9ffb-bf95429c2676 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1744127857; x=1744732657; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sc7wfWEtEETos3Xy4ASDsRUDXv0bfhmJEvEO/7TawQo=; b=D61MvuwlhhT/iHjVl6KJsI8boKoCmvfGA8ZBmL52WQt30wmheVc8wPZtdIbPUW2Aa0 TAc4ZBm13fVg/R1b48S8DyT95OJTxlaSDzUeBJrM/IaJcjxYRiLziYkuPyieotta6Wd6 g5HdJS0LRcmGXvQFa0IR97w4yOn+dJ74FcKRH+g+9tapkCugDrXLwE0lfudbHMXCj4ec diTvT84ZzH4xlPVP1L7o2NCp+T5M2yvk/9aniLpVAjskrcfpoVMhUhXBlk1/r4+kV9NL 2Ust8vMSuCCHPziUnhoxHx8TlzreByuz6sqLwPvWXMne7VsThNRcpH3yLerLLnLMIrZ7 HOVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744127857; x=1744732657; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sc7wfWEtEETos3Xy4ASDsRUDXv0bfhmJEvEO/7TawQo=; b=H6vr8TuqfbwdJkT4KP75hvJYQ7gc8XfgdeKXkRVRmqeAVm49iS//IUwIU+qsBQjjva IeO8qzFjJXolpDY5U29LwDXLhNXmGh6K9wgmJWsWvc3pE7Ok+3GyIu6OAosCWt5mCKAo hERpLXyvl5ECNdKBGhE/gXCHa7aJM60F8EEdO0kkX0WvmJvR//au1W4nasct5RLuXKj/ dDZsQQMTdE+4aq9WSggkfSGT2QFdROPCtxKnhSDugC+ldbMhEFOzRsExvxmZmIQN/InE vR4WvK/e8Q2K7xonMTSwIKTq4mpPRVEjA0yaXx5d/NO4EBaIWd43M3jP4TKJTuIPUqTO 4QmA== X-Gm-Message-State: AOJu0Yw2MOmEhOqhkBgPi/yHx6gKvAE6hF3Bm4YR27GAQmzZnQThQsTz 9ce8ICRQSrbZgJ28dcZSwwe53mtCd23tMceYe1Qq+Wnpjhqpf84IqfGopA== X-Gm-Gg: ASbGnctq48V1gmSzFSqFg7k5rnH8U18aA3NryJkijw98rObfjuekTWFlgL+9SeZRPuY j6dMV4UyqLTttwukM7Qf2GjQ1nGWQcRJyxA8JgjKXkyrb3f3WOimotccVQNvEDGTUryOBfwSB1V XR3O6F1USGLQ3rST8Tbsbx3zWEUdczI4PFEIjKdkraTCsF9YwjsL7PLqy0sj77WATLT3Y9bV1KZ iiA8JYZ/deQUekXEWp48jXaiWThkoN3jPlxBL7obBzDyCNsoF8Q/5+Z/5zG6lb7fcf/ZDyWe6/n rRrZx9uqXALgybDsa6brvGY728QuYBBGDU5G/l+0qOLyWmGutPR1xlCFNiLcmj/4YGUqkvgPJQ+ o/IfzPOnuGDNWkg== X-Google-Smtp-Source: AGHT+IFL3WNhj77fFPxV0cWMP8yo+oe1QoIkzk3e18tqqolBdgOLMj6ctPGIvdYduEJRVIBY++KgZA== X-Received: by 2002:a17:907:97d6:b0:ac7:391b:e68a with SMTP id a640c23a62f3a-ac7d1c14826mr1306772666b.60.1744127856612; Tue, 08 Apr 2025 08:57:36 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Romain Caritey Subject: [PATCH v1 11/14] xen/riscv: add external interrupt handling for hypervisor mode Date: Tue, 8 Apr 2025 17:57:16 +0200 Message-ID: <1685488b8c1b48149e94bd3625c7b46b78c72e8e.1744126720.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1744128189179019100 Content-Type: text/plain; charset="utf-8" Implement functions necessarry to have working external interrupts in hypervisor mode. The following changes are done: - Add a common function intc_handle_external_irq() to call APLIC specific function to handle an interrupt. - Update do_trap() function to handle IRQ_S_EXT case; add the check to cat= ch case when cause of trap is an interrupt. - Add handle_interrrupt() member to intc_hw_operations structure. - Enable local interrupt delivery for IMSIC by implementation and calling = of imsic_ids_local_delivery() in imsic_init(); additionally introduce helper imsic_csr_write() to update IMSIC_EITHRESHOLD and IMSIC_EITHRESHOLD. - Enable hypervisor external interrupts. - Implement aplic_handler_interrupt() and use it to init ->handle_interrupt member of intc_hw_operations for APLIC. - Add implementation of do_IRQ() to dispatch the interrupt. The current patch is based on the code from [1]. [1] https://gitlab.com/xen-project/people/olkur/xen/-/commit/7390e2365828b8= 3e27ead56b03114a56e3699dd5 Co-developed-by: Romain Caritey Signed-off-by: Oleksii Kurochko --- xen/arch/riscv/aplic.c | 19 +++++++++++++ xen/arch/riscv/imsic.c | 25 +++++++++++++++++ xen/arch/riscv/include/asm/imsic.h | 7 +++++ xen/arch/riscv/include/asm/intc.h | 5 ++++ xen/arch/riscv/include/asm/irq.h | 3 +++ xen/arch/riscv/intc.c | 7 +++++ xen/arch/riscv/irq.c | 43 ++++++++++++++++++++++++++++++ xen/arch/riscv/traps.c | 18 +++++++++++++ 8 files changed, 127 insertions(+) diff --git a/xen/arch/riscv/aplic.c b/xen/arch/riscv/aplic.c index 4b60cb9a77..38b57ed1ac 100644 --- a/xen/arch/riscv/aplic.c +++ b/xen/arch/riscv/aplic.c @@ -261,6 +261,21 @@ static void aplic_set_irq_affinity(struct irq_desc *de= sc, const cpumask_t *mask) spin_unlock(&aplic.lock); } =20 +static void aplic_handle_interrupt(unsigned long cause, struct cpu_user_re= gs *regs) +{ + /* disable to avoid more external interrupts */ + csr_clear(CSR_SIE, 1UL << IRQ_S_EXT); + + /* clear the pending bit */ + csr_clear(CSR_SIP, 1UL << IRQ_S_EXT); + + /* dispatch the interrupt */ + do_IRQ(regs, csr_swap(CSR_STOPEI, 0) >> TOPI_IID_SHIFT); + + /* enable external interrupts */ + csr_set(CSR_SIE, 1UL << IRQ_S_EXT); +} + static hw_irq_controller aplic_host_irq_type =3D { .typename =3D "aplic", .startup =3D aplic_irq_startup, @@ -278,6 +293,7 @@ static const struct intc_hw_operations aplic_ops =3D { .host_irq_type =3D &aplic_host_irq_type, .set_irq_priority =3D aplic_set_irq_priority, .set_irq_type =3D aplic_set_irq_type, + .handle_interrupt =3D aplic_handle_interrupt, }; =20 static int aplic_irq_xlate(const uint32_t *intspec, unsigned int intsize, @@ -318,6 +334,9 @@ static int __init aplic_preinit(struct dt_device_node *= node, const void *dat) =20 register_intc_ops(&aplic_ops); =20 + /* Enable supervisor external interrupt */ + csr_set(CSR_SIE, 1UL << IRQ_S_EXT); + return 0; } =20 diff --git a/xen/arch/riscv/imsic.c b/xen/arch/riscv/imsic.c index 8198d008ef..e00f2d69df 100644 --- a/xen/arch/riscv/imsic.c +++ b/xen/arch/riscv/imsic.c @@ -19,8 +19,19 @@ =20 #include =20 +#define IMSIC_DISABLE_EIDELIVERY 0 +#define IMSIC_ENABLE_EIDELIVERY 1 +#define IMSIC_DISABLE_EITHRESHOLD 1 +#define IMSIC_ENABLE_EITHRESHOLD 0 + static struct imsic_config imsic_cfg; =20 +#define imsic_csr_write(c, v) \ +do { \ + csr_write(CSR_SISELECT, c); \ + csr_write(CSR_SIREG, v); \ +} while (0) + #define imsic_csr_set(c, v) \ do { \ csr_write(CSR_SISELECT, c); \ @@ -33,6 +44,20 @@ do { \ csr_clear(CSR_SIREG, v); \ } while (0) =20 +void imsic_ids_local_delivery(bool enable) +{ + if ( enable ) + { + imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESHOLD); + imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY); + } + else + { + imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD); + imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY); + } +} + static void imsic_local_eix_update(unsigned long base_id, unsigned long nu= m_id, bool pend, bool val) { diff --git a/xen/arch/riscv/include/asm/imsic.h b/xen/arch/riscv/include/as= m/imsic.h index d2c0178529..b2c674f271 100644 --- a/xen/arch/riscv/include/asm/imsic.h +++ b/xen/arch/riscv/include/asm/imsic.h @@ -12,6 +12,7 @@ #define ASM__RISCV__IMSIC_H =20 #include +#include #include =20 #define IMSIC_MMIO_PAGE_SHIFT 12 @@ -20,6 +21,10 @@ #define IMSIC_MIN_ID 63 #define IMSIC_MAX_ID 2048 =20 +#define IMSIC_EIDELIVERY 0x70 + +#define IMSIC_EITHRESHOLD 0x72 + #define IMSIC_EIP0 0x80 #define IMSIC_EIPx_BITS 32 =20 @@ -78,4 +83,6 @@ const struct imsic_config *imsic_get_config(void); void imsic_irq_enable(unsigned int hwirq); void imsic_irq_disable(unsigned int hwirq); =20 +void imsic_ids_local_delivery(bool enable); + #endif /* ASM__RISCV__IMSIC_H */ diff --git a/xen/arch/riscv/include/asm/intc.h b/xen/arch/riscv/include/asm= /intc.h index db53caa07b..e4363af87d 100644 --- a/xen/arch/riscv/include/asm/intc.h +++ b/xen/arch/riscv/include/asm/intc.h @@ -34,6 +34,8 @@ struct intc_hw_operations { /* Set IRQ priority */ void (*set_irq_priority)(struct irq_desc *desc, unsigned int priority); =20 + /* handle external interrupt */ + void (*handle_interrupt)(unsigned long cause, struct cpu_user_regs *re= gs); }; =20 void intc_preinit(void); @@ -45,4 +47,7 @@ void register_intc_ops(const struct intc_hw_operations *o= ps); struct irq_desc; void intc_route_irq_to_xen(struct irq_desc *desc, unsigned int priority); =20 +struct cpu_user_regs; +void intc_handle_external_irqs(unsigned long cause, struct cpu_user_regs *= regs); + #endif /* ASM__RISCV__INTERRUPT_CONTOLLER_H */ diff --git a/xen/arch/riscv/include/asm/irq.h b/xen/arch/riscv/include/asm/= irq.h index 163a478d78..9558d3fa61 100644 --- a/xen/arch/riscv/include/asm/irq.h +++ b/xen/arch/riscv/include/asm/irq.h @@ -51,6 +51,9 @@ int platform_get_irq(const struct dt_device_node *device,= int index); =20 void init_IRQ(void); =20 +struct cpu_user_regs; +void do_IRQ(struct cpu_user_regs *regs, unsigned int irq); + #endif /* ASM__RISCV__IRQ_H */ =20 /* diff --git a/xen/arch/riscv/intc.c b/xen/arch/riscv/intc.c index 8274897d8c..41a4310ead 100644 --- a/xen/arch/riscv/intc.c +++ b/xen/arch/riscv/intc.c @@ -51,6 +51,13 @@ static void intc_set_irq_priority(struct irq_desc *desc,= unsigned int priority) intc_hw_ops->set_irq_priority(desc, priority); } =20 +void intc_handle_external_irqs(unsigned long cause, struct cpu_user_regs *= regs) +{ + ASSERT(intc_hw_ops && intc_hw_ops->handle_interrupt); + + intc_hw_ops->handle_interrupt(cause, regs); +} + void intc_route_irq_to_xen(struct irq_desc *desc, unsigned int priority) { ASSERT(test_bit(_IRQ_DISABLED, &desc->status)); diff --git a/xen/arch/riscv/irq.c b/xen/arch/riscv/irq.c index c332e000c4..3c0b95220a 100644 --- a/xen/arch/riscv/irq.c +++ b/xen/arch/riscv/irq.c @@ -11,6 +11,10 @@ #include #include #include +#include + +#include +#include =20 static irq_desc_t irq_desc[NR_IRQS]; =20 @@ -83,3 +87,42 @@ void __init init_IRQ(void) if ( init_irq_data() < 0 ) panic("initialization of IRQ data failed\n"); } + +/* Dispatch an interrupt */ +void do_IRQ(struct cpu_user_regs *regs, unsigned int irq) +{ + struct irq_desc *desc =3D irq_to_desc(irq); + struct irqaction *action; + + irq_enter(); + + spin_lock(&desc->lock); + desc->handler->ack(desc); + + if ( test_bit(_IRQ_DISABLED, &desc->status) ) + goto out; + + set_bit(_IRQ_INPROGRESS, &desc->status); + + action =3D desc->action; + + spin_unlock_irq(&desc->lock); + +#ifndef CONFIG_IRQ_HAS_MULTIPLE_ACTION + action->handler(irq, action->dev_id); +#else + do { + action->handler(irq, action->dev_id); + action =3D action->next; + } while ( action ); +#endif /* CONFIG_IRQ_HAS_MULTIPLE_ACTION */ + + spin_lock_irq(&desc->lock); + + clear_bit(_IRQ_INPROGRESS, &desc->status); + +out: + desc->handler->end(desc); + spin_unlock(&desc->lock); + irq_exit(); +} diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c index ea3638a54f..da5813e34a 100644 --- a/xen/arch/riscv/traps.c +++ b/xen/arch/riscv/traps.c @@ -11,6 +11,7 @@ #include #include =20 +#include #include #include #include @@ -128,6 +129,23 @@ void do_trap(struct cpu_user_regs *cpu_regs) } fallthrough; default: + if ( cause & CAUSE_IRQ_FLAG ) + { + /* Handle interrupt */ + unsigned long icause =3D cause & ~CAUSE_IRQ_FLAG; + + switch ( icause ) + { + case IRQ_S_EXT: + intc_handle_external_irqs(cause, cpu_regs); + break; + default: + break; + } + + break; + } + do_unexpected_trap(cpu_regs); break; } --=20 2.49.0