From nobody Fri Nov 14 18:23:21 2025 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=1761062303; cv=none; d=zohomail.com; s=zohoarc; b=CqYs0bUV9Q3XehT9kccFQ6TKkw6GMei2iuxL+zgdcnfrR55YozY45/wZPsjoDxq85MjtEwBLm3mYcS9/5od1X4mdeAc6BQj6TFsXeJrXbRvzAd+ApuabM10I/4NgD2ZHzrmtQzq8Fsa1on05OSzBpccxjAwLnCuMOXjPlnAxfkg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1761062303; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GY9PGMdFzEQRlghTOzCeBl7G03PRuXs1m7DET48CoN0=; b=jDgpI4ib0e9TwGIMNTnZooTucVWkav7jaUnOOmAQeYeJpiv2XKB/gK0ryl93sZu0duqHhKw2fICl40LKQRtfOmSGy6gJdmvgU49aEuGEuoPe/eJnMZClTjOnNmgrk5AyZih4g4O7rc8P27QEdKXwbiHZoR8XhvXkCIvJaUZ89sU= 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 1761062303195858.3498042178555; Tue, 21 Oct 2025 08:58:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vBEj4-000148-1S; Tue, 21 Oct 2025 11:56:42 -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 1vBEiw-00010v-Jo for qemu-devel@nongnu.org; Tue, 21 Oct 2025 11:56:34 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vBEir-0007nx-Dm for qemu-devel@nongnu.org; Tue, 21 Oct 2025 11:56:33 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-339e71ccf48so7813078a91.3 for ; Tue, 21 Oct 2025 08:56:29 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33d5de11392sm11490177a91.7.2025.10.21.08.56.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Oct 2025 08:56:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1761062187; x=1761666987; darn=nongnu.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=GY9PGMdFzEQRlghTOzCeBl7G03PRuXs1m7DET48CoN0=; b=KP224jKXNV1VWNgHzTXph3qaIzTHYR1seBF5C1IHX2C3nHGRPs2z5pH90dnhCAhuLI q0lsuGOQKT6N2q4GT3zBbkWSI5rdl9so8Lwn7nA+Adnc/4Ymj6JbwQyNOTtbI5aPgNpK XqqfASZeX0TyZ16KODsrI5orV+Y+aycDVAuEE/DZ3OTx2zCblpidbM7hkxiS1iljukp7 8S29gAq4IQWpdfyFkdAEejEHsLwF6NUXPgZoQBX+Qh7jgLmdPdI7jqVbT2qUNEGG9ohw kqp/ypuuNe3aV2poWhSP1dbMbxF9pctIBp8cimieyCrj2A4hzu9SzPQ1iq37S1UgROTA OCSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761062187; x=1761666987; 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=GY9PGMdFzEQRlghTOzCeBl7G03PRuXs1m7DET48CoN0=; b=R8M28UhaZJWtbUHzNtsrgZ+q+++3vkNrYPJGGmh8gAI8XGDNNDkOCj8zST+IyV8E32 aoiESpw2g8w4EEnn3O0oWZxTK2+3i/2/lOGYv3muMLjf0IyXC9M4memAUCRUUPpTZ2Ww dK2r2BmiRH167wg0VsFM3JYf3cS4WDa4Eo60UTnPaNR6vMYE7JLNFdoSrmStFOv01H8p rMlqhzjfeHeORxF/gcCyUtgyclj17OKaogJOhVUeAgIOH09GJe7JijUm7QzuB0GrpqVn iCZtpq/4NihA1qvthm6ayXut6WLphjtqJKvxURJ9Wbx1cZ2LQXyZvjQ622SvmYZx6Q3+ LdHw== X-Gm-Message-State: AOJu0Yy8mg6Tc33MKIF4uMmGrrJE8+8bYQuIdjo3xZ0azb02Guc5Ks89 1oZ2RM2PETqyhTKfjlRkxBvmHO5FaSyGYcOyPNymiy8D2gZUHE9WnONNOfufi1Y86/y7g0eCwpg 5R0gI9EFGesue1aY8vpmr2AwbYbn/4t24zU6QkxY921W9Tn3eVFtJiZUoJWOdHdolUA3HzbHOrP 9KgAXPAQOQjNiFyF3qFo4BXhZeXolpN8DRJqeCEw== X-Gm-Gg: ASbGncugVpkSrozFf4UWN8NGUmuFUpYU40MejGS1dz/2LhZFWKJnPunBadqa2XtsREC TRK0puH5A2WoOVTKLoCVO0KyLfYVhtsaFmXlF7AloaDSPrzfAbu/d3iJNeKB0TZJYRcz1Nx3GTL +wPSEogBb5/VL91wf0JVfHnDQFAMvqEjYM4H0AWWv7V9VoPRuuSJMJeUDUdLr9BL0ADHRL/aSca MY3NeiTh3mmPVvNgEw56QLOyd/IPS9L5CbbGmEvFJQn/4PC740lfaI7u+FKGSz9EnV0WlZFUowO pY1+flKJRZnPLnGwH78MShcOOshtrgPK3b32EK1snb9vIL+u5CPAkin1QDbq3fCAMXrKzPDE/dk 6uLVz7Y9/uYLJKr41YXLlyMrNbYM3s6IdoOlS0L26lgs+wNU4k8xTYPQrxGjgRIxdWMmXLGt9zW 5d7MmT8x5DqMw31Kvw73RF9tDaH4Lrw1eY X-Google-Smtp-Source: AGHT+IFvxjuyQ6KypntX7BYav7ZYE0DcCPs/GqeUQUAFmqaHWW8T+XrZaFKcZZDsOY83GxRm9PjDAw== X-Received: by 2002:a17:90b:4b09:b0:32e:d600:4fe9 with SMTP id 98e67ed59e1d1-33bcf85ceacmr25366723a91.4.1761062186890; Tue, 21 Oct 2025 08:56:26 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Daniel Henrique Barboza , Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Liu Zhiwei , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Marcel Apfelbaum , Yanan Wang , Zhao Liu , Peter Xu , David Hildenbrand , Michael Rolnik , Helge Deller , Song Gao , Laurent Vivier , "Edgar E. Iglesias" , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Chinmay Rath , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [PATCH v3 05/18] hw/misc: riscv_worldguard: Add RISC-V WorldGuard global config Date: Tue, 21 Oct 2025 23:55:35 +0800 Message-ID: <20251021155548.584543-6-jim.shu@sifive.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251021155548.584543-1-jim.shu@sifive.com> References: <20251021155548.584543-1-jim.shu@sifive.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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::1032; envelope-from=jim.shu@sifive.com; helo=mail-pj1-x1032.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 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: 1761062308321158500 Content-Type: text/plain; charset="utf-8" Add a device for RISCV WG global config, which contains the number of worlds, reset value, and trusted WID ... etc. This global config is used by both CPU WG extension and wgChecker devices. Signed-off-by: Jim Shu Reviewed-by: Daniel Henrique Barboza --- hw/misc/Kconfig | 3 + hw/misc/meson.build | 1 + hw/misc/riscv_worldguard.c | 182 +++++++++++++++++++++++++++++ include/hw/misc/riscv_worldguard.h | 56 +++++++++ 4 files changed, 242 insertions(+) create mode 100644 hw/misc/riscv_worldguard.c create mode 100644 include/hw/misc/riscv_worldguard.h diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 4e35657468..bee8824868 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -235,4 +235,7 @@ config IOSB config XLNX_VERSAL_TRNG bool =20 +config RISCV_WORLDGUARD + bool + source macio/Kconfig diff --git a/hw/misc/meson.build b/hw/misc/meson.build index b1d8d8e5d2..200ccc96c0 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -34,6 +34,7 @@ system_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: file= s('sifive_e_prci.c')) system_ss.add(when: 'CONFIG_SIFIVE_E_AON', if_true: files('sifive_e_aon.c'= )) system_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'= )) system_ss.add(when: 'CONFIG_SIFIVE_U_PRCI', if_true: files('sifive_u_prci.= c')) +specific_ss.add(when: 'CONFIG_RISCV_WORLDGUARD', if_true: files('riscv_wor= ldguard.c')) =20 subdir('macio') =20 diff --git a/hw/misc/riscv_worldguard.c b/hw/misc/riscv_worldguard.c new file mode 100644 index 0000000000..588c16ae9a --- /dev/null +++ b/hw/misc/riscv_worldguard.c @@ -0,0 +1,182 @@ +/* + * RISC-V WorldGuard Device + * + * Copyright (c) 2022 SiFive, Inc. + * + * This provides WorldGuard global config. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "exec/hwaddr.h" +#include "hw/registerfields.h" +#include "hw/sysbus.h" +#include "hw/hw.h" +#include "hw/qdev-properties.h" +#include "hw/misc/riscv_worldguard.h" +#include "hw/core/cpu.h" +#include "target/riscv/cpu.h" +#include "trace.h" + +/* + * WorldGuard global config: + * List the global setting of WG, like num-of-worlds. It is unique in the = machine. + * All CPUs with WG extension and wgChecker devices will use it. + */ +struct RISCVWorldGuardState *worldguard_config; + +static Property riscv_worldguard_properties[] =3D { + DEFINE_PROP_UINT32("nworlds", RISCVWorldGuardState, nworlds, 0), + + /* Only Trusted WID could access wgCheckers if it is enabled. */ + DEFINE_PROP_UINT32("trustedwid", RISCVWorldGuardState, trustedwid, NO_= TRUSTEDWID), + + /* + * WG reset value is bypass mode in HW. All WG permission checkings are + * pass by default, so SW could correctly run on the machine w/o any WG + * programming. + */ + DEFINE_PROP_BOOL("hw-bypass", RISCVWorldGuardState, hw_bypass, false), + + /* + * TrustZone compatible mode: + * This mode is only supported in 2 worlds system. It converts WorldGu= ard + * WID to TZ NS signal on the bus so WG could be cooperated with + * TZ components. In QEMU, it converts WID to 'MemTxAttrs.secure' bit = used + * by TZ. + */ + DEFINE_PROP_BOOL("tz-compat", RISCVWorldGuardState, tz_compat, false), +}; + +/* WID to MemTxAttrs converter */ +void wid_to_mem_attrs(MemTxAttrs *attrs, uint32_t wid) +{ + g_assert(wid < worldguard_config->nworlds); + + attrs->unspecified =3D 0; + if (worldguard_config->tz_compat) { + attrs->secure =3D wid; + } else { + attrs->world_id =3D wid; + } +} + +/* MemTxAttrs to WID converter */ +uint32_t mem_attrs_to_wid(MemTxAttrs attrs) +{ + if (attrs.unspecified) { + if (worldguard_config->trustedwid !=3D NO_TRUSTEDWID) { + return worldguard_config->trustedwid; + } else { + return worldguard_config->nworlds - 1; + } + } + + if (worldguard_config->tz_compat) { + return attrs.secure; + } else { + return attrs.world_id; + } +} + +bool could_access_wgblocks(MemTxAttrs attrs, const char *wgblock) +{ + uint32_t wid =3D mem_attrs_to_wid(attrs); + uint32_t trustedwid =3D worldguard_config->trustedwid; + + if ((trustedwid =3D=3D NO_TRUSTEDWID) || (wid =3D=3D trustedwid)) { + return true; + } else { + /* + * Only Trusted WID could access WG blocks if having it. + * Access them from other WIDs will get failed. + */ + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid access to %s from non-trusted WID %d\n", + __func__, wgblock, wid); + + return false; + } +} + +static void riscv_worldguard_realize(DeviceState *dev, Error **errp) +{ + RISCVWorldGuardState *s =3D RISCV_WORLDGUARD(dev); + + if (worldguard_config !=3D NULL) { + error_setg(errp, "Couldn't realize multiple global WorldGuard conf= igs."); + return; + } + + if ((s->nworlds) & (s->nworlds - 1)) { + error_setg(errp, "Current implementation only support power-of-2 N= World."); + return; + } + + if ((s->trustedwid !=3D NO_TRUSTEDWID) && (s->trustedwid >=3D s->nworl= ds)) { + error_setg(errp, "Trusted WID must be less than the number of worl= d."); + return; + } + + if ((s->nworlds !=3D 2) && (s->tz_compat)) { + error_setg(errp, "Only 2 worlds system could use TrustZone compati= ble mode."); + return; + } + + /* Register WG global config */ + worldguard_config =3D s; + + /* Initialize global data for wgChecker */ + wgc_slot_perm_mask =3D MAKE_64BIT_MASK(0, 2 * worldguard_config->nworl= ds); +} + +static void riscv_worldguard_class_init(ObjectClass *klass, const void *da= ta) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + device_class_set_props(dc, riscv_worldguard_properties); + dc->user_creatable =3D true; + dc->realize =3D riscv_worldguard_realize; +} + +static const TypeInfo riscv_worldguard_info =3D { + .name =3D TYPE_RISCV_WORLDGUARD, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(RISCVWorldGuardState), + .class_init =3D riscv_worldguard_class_init, +}; + +/* + * Create WorldGuard global config + */ +DeviceState *riscv_worldguard_create(uint32_t nworlds, uint32_t trustedwid, + bool hw_bypass, bool tz_compat) +{ + DeviceState *dev =3D qdev_new(TYPE_RISCV_WORLDGUARD); + qdev_prop_set_uint32(dev, "nworlds", nworlds); + qdev_prop_set_uint32(dev, "trustedwid", trustedwid); + qdev_prop_set_bit(dev, "hw-bypass", hw_bypass); + qdev_prop_set_bit(dev, "tz-compat", tz_compat); + qdev_realize(DEVICE(dev), NULL, &error_fatal); + return dev; +} + +static void riscv_worldguard_register_types(void) +{ + type_register_static(&riscv_worldguard_info); +} + +type_init(riscv_worldguard_register_types) diff --git a/include/hw/misc/riscv_worldguard.h b/include/hw/misc/riscv_wor= ldguard.h new file mode 100644 index 0000000000..bb276e59b8 --- /dev/null +++ b/include/hw/misc/riscv_worldguard.h @@ -0,0 +1,56 @@ +/* + * RISC-V WorldGuard Devices + * + * Copyright (c) 2022 RISCV, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + */ + +#ifndef HW_RISCV_WORLDGUARD_H +#define HW_RISCV_WORLDGUARD_H + +#include "qom/object.h" +#include "hw/sysbus.h" +#include "exec/hwaddr.h" + +#define TYPE_RISCV_WORLDGUARD "riscv.worldguard" + +#define NO_TRUSTEDWID UINT32_MAX + +typedef struct RISCVWorldGuardState RISCVWorldGuardState; +DECLARE_INSTANCE_CHECKER(RISCVWorldGuardState, RISCV_WORLDGUARD, + TYPE_RISCV_WORLDGUARD) + +struct RISCVWorldGuardState { + /*< private >*/ + DeviceState parent_obj; + + /*< public >*/ + + /* Property */ + uint32_t nworlds; + uint32_t trustedwid; + bool hw_bypass; + bool tz_compat; +}; + +extern struct RISCVWorldGuardState *worldguard_config; + +DeviceState *riscv_worldguard_create(uint32_t nworlds, uint32_t trustedwid, + bool hw_bypass, bool tz_compat); + +void wid_to_mem_attrs(MemTxAttrs *attrs, uint32_t wid); +uint32_t mem_attrs_to_wid(MemTxAttrs attrs); +bool could_access_wgblocks(MemTxAttrs attrs, const char *wgblock); + +#endif --=20 2.43.0