From nobody Tue Oct 22 22:19:00 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=sifive.com ARC-Seal: i=1; a=rsa-sha256; t=1718180293; cv=none; d=zohomail.com; s=zohoarc; b=MH05gD12EJkotKr43PQqzPXb/wwYECrhV5U8zSpvTZnWZSvI8oAP9ACKQnmOfSQD+A4Nu7Q8h6EHq7eIib7XKQI7SgaOxsIdhX39Hy4h7Hepd57tyenJtmsUUohs/WfTmcIL9vaVdVH4syisf5FvnAbHlK7KhvyvbOkoileQdSk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1718180293; h=Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=7Zs56IfQW4V8sqUEW1KobOHNpim94d18CajV+uj3sek=; b=M4V4hAn+QWz9PNkf+F8iAnXt1MKiLVa5g2cXGzqkgxgqHDWQTb6LAbDlz4rKaHSuhlDLeUQzhUC7BH24qoxh6zQ69jT07uHDTD+NvJHQeAgxQoE7zL2rtioHZK+GPxufEbG6rpnYZ1wWjDFl2jyhO5Y0NhNVwDw1rCAByfWa/8c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1718180293292698.7679285263154; Wed, 12 Jun 2024 01:18:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ9V-0005nL-Fg; Wed, 12 Jun 2024 04:16:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sHJ9U-0005eA-4i for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:16 -0400 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ9P-0006qm-Ar for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:15 -0400 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-1f70131063cso16961535ad.2 for ; Wed, 12 Jun 2024 01:16:10 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.16.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:16:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180169; x=1718784969; darn=nongnu.org; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=7Zs56IfQW4V8sqUEW1KobOHNpim94d18CajV+uj3sek=; b=iU64JaUXOpMTAeRp3dYWTrEaWAPX9MxC/5KwT9aQFYKYeUyR0x9FjvYhH+N/tbXcFC KJjBHzIR8c1YGSDbrVsx/zobqZhoVQQdkWfNYAiRkxeZRwqALZduk4GESaQM5BkCVwd8 nkXzO567aml6DK9B3ABS8i+wRtjRD6gs1NO/GORqfwPwKDwifwvy17MBwPPFnDt4E7P/ FyZ2RvmTSLnm2QS1y9ncXoQJAGxX67IutFKATEP6Xoi3+Gc1Fhd7U2RDsp8IHcjbIE5H kWq5LFIaor+lHNJTQbHqobHWXIIrGf01HhmLR4jFeb94WdzrKLOLjmqn1zHIpn4q+Hu1 wbFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180169; x=1718784969; h=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=7Zs56IfQW4V8sqUEW1KobOHNpim94d18CajV+uj3sek=; b=JczqtIUIrvhsjqDR4L7u5r0MXPDh0HzK+ciiGflFMIDa2mKmWYwUpI/InwhJZFnqnU EO3zMZ7OZRolCbdV0xr+pA2liVmJF/Wy8MgRNxeXc8jPJCmwhqtW+euOPpaaH1j5tFpW UvWhU0QPOT+lxFan2XjLw7QiFxJjYgcDSiWHEH9GHR9TVPT9zgtEJpka1pWlZDq1utwB yxEAx+YgjwEka1zV6TohxmXdJEy+AEOYgc/i0NdtzInuFn20HoRwYLvTEuCYz10Dwnke uofXaBFxXmTFYL+FoXghT3MNIABRWV5cRYd0UET6IDqPfd6h/brFInw28WoGvqQkbwRQ rgWQ== X-Gm-Message-State: AOJu0Ywqb0qA/zecvr1Z4/bqC0Odq6Do3smg5LZK4zUnxbs6Tf1LKkKh xY0wQhddn6AnKr1pfBIDv1jpsjbbNutnUkieQtynd3WnwFpyY6kmAIvE+fv+MNgSMwtF04inuKT US69mz02fnDXi6zaX2ZKe2rCWk1bqDGn72bKojrmBgPX1uCU8vlXjiHWq2JU769dYPcdoaJa4kp PkpF+Ml4FtnY6P3J0jGzgQxMDWECmLAGTd/LuFUKNirw== X-Google-Smtp-Source: AGHT+IFZI0uD97KN8S3AD0WaGGdqs9bMHQ35x0UNs/HsiXiPw2iJARhoCvv/DnkcypVwlwTRn0BWFQ== X-Received: by 2002:a17:903:2283:b0:1f7:187f:cb5a with SMTP id d9443c01a7336-1f83b565eb1mr12729405ad.11.1718180168578; Wed, 12 Jun 2024 01:16:08 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 16/16] hw/riscv: virt: Add WorldGuard support Date: Wed, 12 Jun 2024 16:14:16 +0800 Message-Id: <20240612081416.29704-17-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::630; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x630.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @sifive.com) X-ZM-MESSAGEID: 1718180295037100003 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" * Add 'wg=3Don' option to enable RISC-V WorldGuard * Add wgChecker to protect several resources: DRAM, FLASH, UART. Signed-off-by: Jim Shu --- docs/system/riscv/virt.rst | 10 +++ hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 163 ++++++++++++++++++++++++++++++++++++- include/hw/riscv/virt.h | 17 +++- 4 files changed, 186 insertions(+), 5 deletions(-) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index 9a06f95a34..2d2992dc34 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -116,6 +116,16 @@ The following machine-specific options are supported: having AIA IMSIC (i.e. "aia=3Daplic-imsic" selected). When not specified, the default number of per-HART VS-level AIA IMSIC pages is 0. =20 +- wg=3D[on|off] + + When this option is "on", RISC-V WorldGuard will be enabled in the system + to provide the isolation of multiple worlds. RISC-V HARTS will enable WG + extensions to have WID in memory transaction. wgCheckers in front of RAMs + and device MMIO will be enabled to provide the access control of resourc= es + if the transaction contains WID. When not specified, this option is assu= med + to be "off". + This option is restricted to the TCG accelerator. + Running Linux kernel -------------------- =20 diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index a2030e3a6f..7804fdbb7a 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -56,6 +56,7 @@ config RISCV_VIRT select PLATFORM_BUS select ACPI select ACPI_PCI + select RISCV_WORLDGUARD =20 config SHAKTI_C bool diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 4fdb660525..eed49ebd02 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -55,6 +55,7 @@ #include "hw/acpi/aml-build.h" #include "qapi/qapi-visit-common.h" #include "hw/virtio/virtio-iommu.h" +#include "hw/misc/riscv_worldguard.h" =20 /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU= . */ static bool virt_use_kvm_aia(RISCVVirtState *s) @@ -76,6 +77,9 @@ static const MemMapEntry virt_memmap[] =3D { [VIRT_ACLINT_SSWI] =3D { 0x2F00000, 0x4000 }, [VIRT_PCIE_PIO] =3D { 0x3000000, 0x10000 }, [VIRT_PLATFORM_BUS] =3D { 0x4000000, 0x2000000 }, + [VIRT_WGC_DRAM] =3D { 0x6000000, 0x1000 }, + [VIRT_WGC_FLASH] =3D { 0x6001000, 0x1000 }, + [VIRT_WGC_UART] =3D { 0x6002000, 0x1000 }, [VIRT_PLIC] =3D { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2= ) }, [VIRT_APLIC_M] =3D { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) }, [VIRT_APLIC_S] =3D { 0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) }, @@ -101,6 +105,38 @@ static MemMapEntry virt_high_pcie_memmap; =20 #define VIRT_FLASH_SECTOR_SIZE (256 * KiB) =20 +/* wgChecker helpers */ +typedef struct WGCInfo { + int memmap_idx; + uint32_t irq_num; + uint32_t slot_count; + + int num_of_child; + MemoryRegion *c_region[WGC_NUM_REGIONS]; + uint64_t c_offset[WGC_NUM_REGIONS]; +} WGCInfo; + +enum { + WGC_DRAM, + WGC_FLASH, + WGC_UART, + WGC_NUM, +}; + +static WGCInfo virt_wgcinfo[] =3D { + [WGC_DRAM] =3D { VIRT_WGC_DRAM, WGC_DRAM_IRQ, 16 }, + [WGC_FLASH] =3D { VIRT_WGC_FLASH, WGC_FLASH_IRQ, 16 }, + [WGC_UART] =3D { VIRT_WGC_UART, WGC_UART_IRQ, 1 }, +}; + +static void wgc_append_child(WGCInfo *info, MemoryRegion *region, + uint64_t offset) +{ + info->c_region[info->num_of_child] =3D region; + info->c_offset[info->num_of_child] =3D offset; + info->num_of_child +=3D 1; +} + static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s, const char *name, const char *alias_prop_name) @@ -151,7 +187,8 @@ static void virt_flash_map1(PFlashCFI01 *flash, } =20 static void virt_flash_map(RISCVVirtState *s, - MemoryRegion *sysmem) + MemoryRegion *sysmem, + WGCInfo *info) { hwaddr flashsize =3D virt_memmap[VIRT_FLASH].size / 2; hwaddr flashbase =3D virt_memmap[VIRT_FLASH].base; @@ -160,6 +197,15 @@ static void virt_flash_map(RISCVVirtState *s, sysmem); virt_flash_map1(s->flash[1], flashbase + flashsize, flashsize, sysmem); + + if (info) { + wgc_append_child(info, + sysbus_mmio_get_region(SYS_BUS_DEVICE(s->flash[0]= ), 0), + flashbase); + wgc_append_child(info, + sysbus_mmio_get_region(SYS_BUS_DEVICE(s->flash[1]= ), 0), + flashbase + flashsize); + } } =20 static void create_pcie_irq_map(RISCVVirtState *s, void *fdt, char *nodena= me, @@ -1303,6 +1349,71 @@ static void virt_build_smbios(RISCVVirtState *s) } } =20 +static DeviceState *create_wgc(WGCInfo *info, DeviceState *irqchip) +{ + MemoryRegion *system_memory =3D get_system_memory(); + DeviceState *wgc; + MemoryRegion *upstream_mr, *downstream_mr; + qemu_irq irq =3D qdev_get_gpio_in(irqchip, info->irq_num); + hwaddr base, size; + + /* Unmap downstream_mr from system_memory if it is already mapped. */ + for (int i=3D0; inum_of_child; i++) { + downstream_mr =3D info->c_region[i]; + + g_assert(downstream_mr); + if (downstream_mr->container =3D=3D system_memory) { + memory_region_del_subregion(system_memory, downstream_mr); + } + + /* + * Clear the offset of downstream_mr, so we could correctly do + * address_space_init() to it in wgchecker. + */ + memory_region_set_address(downstream_mr, 0); + } + + base =3D virt_memmap[info->memmap_idx].base; + size =3D virt_memmap[info->memmap_idx].size; + + wgc =3D riscv_wgchecker_create( + base, size, irq, info->slot_count, 0, 0, + info->num_of_child, info->c_region, info->c_offset, 0, NULL); + + /* Map upstream_mr to system_memory */ + for (int i=3D0; inum_of_child; i++) { + upstream_mr =3D sysbus_mmio_get_region(SYS_BUS_DEVICE(wgc), i+1); + g_assert(upstream_mr); + memory_region_add_subregion(system_memory, info->c_offset[i], upst= ream_mr); + } + + return wgc; +} + +static void virt_create_worldguard(WGCInfo *wgcinfo, int wgc_num, + DeviceState *irqchip) +{ + CPUState *cpu; + + /* Global WG config */ + riscv_worldguard_create(VIRT_WG_NWORLDS, + VIRT_WG_TRUSTEDWID, + VIRT_WG_HWBYPASS, + VIRT_WG_TZCOMPAT); + + /* Enable WG extension of each CPU */ + CPU_FOREACH(cpu) { + CPURISCVState *env =3D cpu ? cpu_env(cpu) : NULL; + + riscv_worldguard_apply_cpu(env->mhartid); + } + + /* Create all wgChecker devices */ + for (int i=3D0; ihave_wg) { + error_report("'wg' is only available with TCG acceleration"); + exit(1); + } + /* Initialize sockets */ mmio_irqchip =3D virtio_irqchip =3D pcie_irqchip =3D NULL; for (i =3D 0; i < socket_count; i++) { @@ -1547,6 +1665,10 @@ static void virt_machine_init(MachineState *machine) memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base, machine->ram); =20 + if (tcg_enabled() && s->have_wg) { + wgc_append_child(&wgcinfo[WGC_DRAM], machine->ram, memmap[VIRT_DRA= M].base); + } + /* boot rom */ memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom", memmap[VIRT_MROM].size, &error_fatal); @@ -1574,10 +1696,16 @@ static void virt_machine_init(MachineState *machine) =20 create_platform_bus(s, mmio_irqchip); =20 - serial_mm_init(system_memory, memmap[VIRT_UART0].base, + uart =3D serial_mm_init(system_memory, memmap[VIRT_UART0].base, 0, qdev_get_gpio_in(mmio_irqchip, UART0_IRQ), 399193, serial_hd(0), DEVICE_LITTLE_ENDIAN); =20 + if (tcg_enabled() && s->have_wg) { + wgc_append_child(&wgcinfo[WGC_UART], + sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0), + memmap[VIRT_UART0].base); + } + sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base, qdev_get_gpio_in(mmio_irqchip, RTC_IRQ)); =20 @@ -1586,7 +1714,16 @@ static void virt_machine_init(MachineState *machine) pflash_cfi01_legacy_drive(s->flash[i], drive_get(IF_PFLASH, 0, i)); } - virt_flash_map(s, system_memory); + + if (tcg_enabled() && s->have_wg) { + virt_flash_map(s, system_memory, &wgcinfo[WGC_FLASH]); + } else { + virt_flash_map(s, system_memory, NULL); + } + + if (tcg_enabled() && s->have_wg) { + virt_create_worldguard(wgcinfo, WGC_NUM, mmio_irqchip); + } =20 /* load/create device tree */ if (machine->dtb) { @@ -1614,6 +1751,20 @@ static void virt_machine_instance_init(Object *obj) s->acpi =3D ON_OFF_AUTO_AUTO; } =20 +static bool virt_get_wg(Object *obj, Error **errp) +{ + RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); + + return s->have_wg; +} + +static void virt_set_wg(Object *obj, bool value, Error **errp) +{ + RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); + + s->have_wg =3D value; +} + static char *virt_get_aia_guests(Object *obj, Error **errp) { RISCVVirtState *s =3D RISCV_VIRT_MACHINE(obj); @@ -1794,6 +1945,12 @@ static void virt_machine_class_init(ObjectClass *oc,= void *data) NULL, NULL); object_class_property_set_description(oc, "acpi", "Enable ACPI"); + + object_class_property_add_bool(oc, "wg", virt_get_wg, + virt_set_wg); + object_class_property_set_description(oc, "wg", + "Set on/off to enable/disabl= e the " + "RISC-V WorldGuard."); } =20 static const TypeInfo virt_machine_typeinfo =3D { diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 3db839160f..4d78702daf 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -57,6 +57,7 @@ struct RISCVVirtState { bool have_aclint; RISCVVirtAIAType aia_type; int aia_guests; + bool have_wg; char *oem_id; char *oem_table_id; OnOffAuto acpi; @@ -84,12 +85,18 @@ enum { VIRT_PCIE_MMIO, VIRT_PCIE_PIO, VIRT_PLATFORM_BUS, - VIRT_PCIE_ECAM + VIRT_PCIE_ECAM, + VIRT_WGC_DRAM, + VIRT_WGC_FLASH, + VIRT_WGC_UART }; =20 enum { UART0_IRQ =3D 10, RTC_IRQ =3D 11, + WGC_DRAM_IRQ =3D 15, + WGC_FLASH_IRQ =3D 16, + WGC_UART_IRQ =3D 17, VIRTIO_IRQ =3D 1, /* 1 to 8 */ VIRTIO_COUNT =3D 8, PCIE_IRQ =3D 0x20, /* 32 to 35 */ @@ -99,7 +106,7 @@ enum { #define VIRT_PLATFORM_BUS_NUM_IRQS 32 =20 #define VIRT_IRQCHIP_NUM_MSIS 255 -#define VIRT_IRQCHIP_NUM_SOURCES 96 +#define VIRT_IRQCHIP_NUM_SOURCES 128 #define VIRT_IRQCHIP_NUM_PRIO_BITS 3 #define VIRT_IRQCHIP_MAX_GUESTS_BITS 3 #define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U) @@ -153,4 +160,10 @@ uint32_t imsic_num_bits(uint32_t count); #error "Can't accommodate all IMSIC groups in address space" #endif =20 +/* WorldGuard */ +#define VIRT_WG_NWORLDS 4 +#define VIRT_WG_TRUSTEDWID 3 +#define VIRT_WG_HWBYPASS true +#define VIRT_WG_TZCOMPAT false + #endif --=20 2.17.1