From nobody Mon Mar 23 21:29:22 2026 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=1774283481; cv=none; d=zohomail.com; s=zohoarc; b=M4g7NTxOrG5GuP7VZ0Lg+W+8TUnVgMrbi+lYVi4ix7nCAbfgyrcwIZVo/STSuwsUaM1U1ObVH7oHXfKFgXWhY2iqN1LKEx8qI5e38V4DJuy3Gb6yS19NNfIDBmOsG2/Q++VKT4hR99ZXz69KiO5gAWL8WK+R44lru4aW7mgJl6I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1774283481; 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=1r0zN6nVpndBbZj2EAngA6PIoeO7gCPLDD4SqQQvZ3o=; b=dq2ZpySGeMs0AgavxNHCIPK9+XiijGWAkxH3UKMsflJjEb1klmiKf9ennSSXrjbfK99C2Ks2Oh1ztCvbVaOSVrm5zKCoct/0eSJQ0bzijhtsuOxSsWZ+CjwfOSgBm2ZgdbO344rWT7gF3k9BlR93T0ak89WyNzIYIYnzz6zbiBw= 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 1774283481034758.4352004459282; Mon, 23 Mar 2026 09:31:21 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1259458.1552780 (Exim 4.92) (envelope-from ) id 1w4iBG-0006j9-H2; Mon, 23 Mar 2026 16:31:06 +0000 Received: by outflank-mailman (output) from mailman id 1259458.1552780; Mon, 23 Mar 2026 16:31:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w4iBG-0006iy-DZ; Mon, 23 Mar 2026 16:31:06 +0000 Received: by outflank-mailman (input) for mailman id 1259458; Mon, 23 Mar 2026 16:31:05 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1w4iBF-0006dN-5M for xen-devel@lists.xenproject.org; Mon, 23 Mar 2026 16:31:05 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1w4iBC-005uwX-VW for xen-devel@lists.xenproject.org; Mon, 23 Mar 2026 17:31:04 +0100 Received: from [10.42.69.8] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69c16ab9-e002-0a2a0a5209dd-0a2a45089f86-26 for ; Mon, 23 Mar 2026 17:31:04 +0100 Received: from [209.85.208.49] (helo=mail-ed1-f49.google.com) by tlsNG-c1860d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2) (envelope-from ) id 69c16ac8-1950-0a2a45080019-d155d031c55d-3 for ; Mon, 23 Mar 2026 17:31:04 +0100 Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-668d70fabc4so918666a12.1 for ; Mon, 23 Mar 2026 09:31:04 -0700 (PDT) Received: from fedora (user-109-243-69-121.play-internet.pl. [109.243.69.121]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9832f8be14sm536248166b.17.2026.03.23.09.30.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Mar 2026 09:30:56 -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" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20230601 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1774283464; x=1774888264; 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=1r0zN6nVpndBbZj2EAngA6PIoeO7gCPLDD4SqQQvZ3o=; b=jqKHXS6HrPhdC9i/U5gPSuFSfO7HIaO8bY2w5nFxVk5ey3Dmti5UGPzhDBKiEH8qck U7YaYJaywuGg8dBpuY62o/JTI2mGGf13i/dVlAkOnhCyrUfqpDeelg/gOU1sFXqgf78h fGT2Kpz33UAw7rnffg7ZT/nl4hSgfQHA6rC0388RReaqEn9u3iTg1BUh4tULPGeBLdiZ 2BBS/O+XCnAIyypuZy68bV9PQKnQ17flTrXBJBDnE6xEQKHZ+S/d8H+HDLc4Uv5WrK2h qkVAUkqJrJ83xO/kvaGl53nafBaAKHrm0b4gC4KxCXvmVjy3H2Ba11s5/VjGDGCPitkT 6iYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774283464; x=1774888264; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=1r0zN6nVpndBbZj2EAngA6PIoeO7gCPLDD4SqQQvZ3o=; b=DmDBODJvJy6wu7e9ree5w/PXJZDw6EkZ4b4emkuJihM/T5N10EZt/ur2GKWLZRuSlA Ge34y+QWzjAP8NGTYIIsgC4/9aIZtAidUFKnu2qnGa7QbxbVa+zuro2BOGXlfoMLbi75 m7agUIiz1I7s2k0JNlSKwmaNviqe6T7QkUq5f4p36fHYMLuVIqzPDXmhaqtX2yoRTroz MV74ZZcj1uSGVzjRcySFFuF2ldf0Mxiuyn57FjXlsrRviLa/DfLDPt+IExJBngCT0OP9 BcTtKKSAxdiK77Nd+ifaIPaH5NTcU5t1dpvOregTvz8UTKs0p6OUFOdSXYJpR8ly9ww2 SH5Q== X-Gm-Message-State: AOJu0Yy8m0GA9Qt4GBpHnRDmvL93x5dfKP7oR0o59+9kujvitWV09WXW VAr3kYGJlD2z/7YITLu+alAXyTpY/ZKHSXYsSJiO6Ip0u7ItC+nlsUACbop81Q== X-Gm-Gg: ATEYQzxgBrOS+8nJbnkEsHSmrWUcm3E55TaXVJX8MdcKNQJZQAbnWLX6lrLq3CHbVBl qChkS1bz4G3L3W77cPXuzDrfs7QTYPbmPsUKbwYRLY7C13H9O+8FVzazBNUz4kWFice0waoBhOP NjwZxitXpqhfJ91mK7JV0Nf/pLzZDNDZfwTF1Pn8qiK7/uzbrzXKSfNVLM+uED/T2FC3fCaSe5+ 539m7eBX75xFe2ehY8X3KrTo6hivSGU+RpllOOsO9jN+LhL1cvc2efGQzvON9LXkOlzVx+Dcu0p 1uSeA+7KeY3iWauJdb3mEHIum3g83/v3MfEwnQgTQ7cMdE3F37PSQRPcD676+gNyeFbo2VMfUlu VkOkR396dadF2p0qjnyHTNR0erJeso5yphVk1XVnv7HUFdYPQK5Gt8+vf+WCkBuqpR7ESMARWb5 6NcKuQFKMeJ1ml86gq8s8l3xy3vVzKX/jbFqNM7KnW0P4RyIaMhla08RZrYXHbSO+mgQ== X-Received: by 2002:a17:907:7fa3:b0:b98:4799:e6de with SMTP id a640c23a62f3a-b984799e8afmr731143366b.48.1774283463418; Mon, 23 Mar 2026 09:31:03 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Romain Caritey , Oleksii Kurochko , Alistair Francis , Connor Davis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini Subject: [PATCH v2 05/11] xen/riscv: add kernel loading support Date: Mon, 23 Mar 2026 17:29:46 +0100 Message-ID: <1688c6e0e616b2d1bc1a9050d66f007e0e65d3b2.1774281309.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-c1860d/1774283464-E3A9B726-99E1AC7C/0/0 X-purgate-type: clean X-purgate-size: 7282 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1774283482933154100 Content-Type: text/plain; charset="utf-8" Introduce support for loading a Linux kernel Image (its compressed version) on RISC-V. kernel_image_load() and place_modules() currently call panic() on failure rather than returning an error. This is because the common kernel_load() in common/device-tree/kernel.c does not expect a return code. Handling errors gracefully would require a separate refactor. The implementation is based on the Xen Arm kernel loading code. Signed-off-by: Oleksii Kurochko --- Changes in v2: - s/zimage/image as RISC-V doesn't support zImages, only Image and Image.{gz,...}. - Update the commit message. --- xen/arch/riscv/Makefile | 1 + xen/arch/riscv/include/asm/config.h | 13 +++ xen/arch/riscv/kernel.c | 158 ++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 xen/arch/riscv/kernel.c diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index 6d3c822409b8..d90afc7ad23f 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -8,6 +8,7 @@ obj-y +=3D guestcopy.o obj-y +=3D imsic.o obj-y +=3D intc.o obj-y +=3D irq.o +obj-y +=3D kernel.o obj-y +=3D mm.o obj-y +=3D p2m.o obj-y +=3D paging.o diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/a= sm/config.h index 0613de008b13..fd69057826e1 100644 --- a/xen/arch/riscv/include/asm/config.h +++ b/xen/arch/riscv/include/asm/config.h @@ -151,6 +151,19 @@ extern unsigned long phys_offset; /* =3D load_start - XEN_VIRT_START */ #endif =20 +/* + * KERNEL_LOAD_ADDR_ALIGNMENT is defined based on paragraph of + * "Kernel location" of boot.rst: + * https://docs.kernel.org/arch/riscv/boot.html#kernel-location + */ +#if defined(CONFIG_RISCV_32) +#define KERNEL_LOAD_ADDR_ALIGNMENT MB(4) +#elif defined(CONFIG_RISCV_64) +#define KERNEL_LOAD_ADDR_ALIGNMENT MB(2) +#else +#error "Define KERNEL_LOAD_ADDR_ALIGNMENT" +#endif + #endif /* ASM__RISCV__CONFIG_H */ /* * Local variables: diff --git a/xen/arch/riscv/kernel.c b/xen/arch/riscv/kernel.c new file mode 100644 index 000000000000..be5b17dc22c3 --- /dev/null +++ b/xen/arch/riscv/kernel.c @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define IMAGE64_MAGIC_V2 0x05435352 /* Magic number 2, le, "RSC\x05" */ + +static void __init place_modules(struct kernel_info *info, paddr_t kernbas= e, + paddr_t kernend) +{ + const struct boot_module *mod =3D info->bd.initrd; + + const paddr_t initrd_len =3D ROUNDUP(mod ? mod->size : 0, MB(2)); + const paddr_t dtb_len =3D ROUNDUP(fdt_totalsize(info->fdt), MB(2)); + const paddr_t modsize =3D initrd_len + dtb_len; + + const paddr_t ramsize =3D info->mem.bank[0].size; + const paddr_t kernsize =3D ROUNDUP(kernend, MB(2)) - kernbase; + + if ( modsize + kernsize > ramsize ) + panic("Not enough memory in the first bank for the kernel+dtb+init= rd\n"); + + info->dtb_paddr =3D ROUNDUP(kernend, MB(2)); + + info->initrd_paddr =3D info->dtb_paddr + dtb_len; +} + +static paddr_t __init kernel_image_place(struct kernel_info *info) +{ + paddr_t load_addr; + + /* + * At the moment, RISC-V's Linux kernel should be always position + * independent based on "Per-MMU execution" of boot.rst: + * https://docs.kernel.org/arch/riscv/boot.html#pre-mmu-execution + * + * But just for the case when RISC-V's Linux kernel isn't position + * independent it is needed to take load address from + * info->image.start. + * + * If `start` is zero, the Image is position independent. */ + if ( likely(!info->image.start) ) + /* + * According to boot.rst kernel load address should be properly + * aligned: + * https://docs.kernel.org/arch/riscv/boot.html#kernel-location + */ + load_addr =3D ROUNDUP(info->mem.bank[0].start, KERNEL_LOAD_ADDR_AL= IGNMENT); + else + load_addr =3D info->image.start; + + return load_addr; +} + +static void __init kernel_image_load(struct kernel_info *info) +{ + int rc; + paddr_t load_addr =3D kernel_image_place(info); + paddr_t paddr =3D info->image.kernel_addr; + paddr_t len =3D info->image.len; + void *kernel; + + info->entry =3D load_addr; + + place_modules(info, load_addr, load_addr + len); + + printk("Loading Image from %"PRIpaddr" to %"PRIpaddr"-%"PRIpaddr"\n", + paddr, load_addr, load_addr + len); + + kernel =3D ioremap_wc(paddr, len); + + if ( !kernel ) + panic("Unable to map kernel\n"); + + /* Move kernel to proper location in guest phys map */ + rc =3D copy_to_guest_phys(info->bd.d, load_addr, kernel, len); + + if ( rc ) + panic("Unable to copy kernel to proper guest location\n"); + + iounmap(kernel); +} + +/* Check if the image is a 64-bit Image */ +static int __init kernel_image64_probe(struct kernel_info *info, + paddr_t addr, paddr_t size) +{ + /* riscv/boot-image-header.rst */ + struct { + u32 code0; /* Executable code */ + u32 code1; /* Executable code */ + u64 text_offset; /* Image load offset, little endian */ + u64 image_size; /* Effective Image size, little endian */ + u64 flags; /* kernel flags, little endian */ + u32 version; /* Version of this header */ + u32 res1; /* Reserved */ + u64 res2; /* Reserved */ + u64 magic; /* Deprecated: Magic number, little endian, "RIS= CV" */ + u32 magic2; /* Magic number 2, little endian, "RSC\x05" */ + u32 res3; /* Reserved for PE COFF offset */ + } image; + uint64_t start, end; + + if ( size < sizeof(image) ) + return -EINVAL; + + copy_from_paddr(&image, addr, sizeof(image)); + + /* Magic v1 is deprecated and may be removed. Only use v2 */ + if ( image.magic2 !=3D IMAGE64_MAGIC_V2 ) + return -EINVAL; + + /* Currently there is no length in the header, so just use the size */ + start =3D 0; + end =3D size; + + /* + * Given the above this check is a bit pointless, but leave it + * here in case someone adds a length field in the future. + */ + if ( (end - start) > size ) + return -EINVAL; + + info->image.kernel_addr =3D addr; + info->image.len =3D end - start; + info->image.text_offset =3D image.text_offset; + info->image.start =3D 0; + + info->load =3D kernel_image_load; + + return 0; +} + +int __init kernel_image_probe(struct kernel_info *info, paddr_t addr, + paddr_t size) +{ + int rc; + +#ifdef CONFIG_RISCV_64 + rc =3D kernel_image64_probe(info, addr, size); + if ( rc < 0 ) + panic("Failed to probe kernel image\n"); +#else + panic("Only RISC-V 64 is supported\n"); +#endif + + return rc; +} --=20 2.53.0