From patchwork Tue Apr 15 08:12:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051666 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7CC5BC369B9 for ; Tue, 15 Apr 2025 08:16:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bPh-0006Be-6k; Tue, 15 Apr 2025 04:13:01 -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 1u4bPe-0005uE-8N for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:12:58 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bPb-0001tf-BA for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:12:57 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-22928d629faso50533045ad.3 for ; Tue, 15 Apr 2025 01:12:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704773; x=1745309573; 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=GR/8z++2aqI3yyfjoa8U9+bhg7JVoM1t0POSqDl+R9E=; b=WZGa/14odk++z1oyT4MLm1/+TBg1NCJDNJo7msXWcbo9ZIJpSc0+RZ20ZDUI+JSUW4 PW8/7cdvwSUFJtCDgS5H1MMNz6c5vXcq91vpHSfVo++gDXlRAzsjCOnK+3UNirtN9c7s hvrmGYOxDtQTsi8vtXrTTLWNXtD7O542WoDOUrDFOy3JSHWwiF5pJ5VXxxiilJ7XfOMg R9VFVnA7O7HoA1wK4V5ncv/ScEh9lVXe3LlZnL36Hh2dt1Y+EHCMBgS2Tl9oJ49qKqKK w7at9pLVNql5uBLa1AipPZ6dZuSSQCjzxqcH6yrJng9SO5wMFr8n+n3RfyJCNBd8OiFA qBfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704773; x=1745309573; 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=GR/8z++2aqI3yyfjoa8U9+bhg7JVoM1t0POSqDl+R9E=; b=m4rSp3eI31yOHje2+jv9/nSzBWgMn2Web7HZojSjTj2tmdPQ8bGhtwnNza3+nN/6uI B0vjX5XbYmV2hdEanwx4pkMe7egDpDGDXFI6QcnqXRRYbJB1sMI1U9iF27haak4qcJ0c B8N5jtnJhhiKRmRXZu+yNrcL1xfJ4XaGKPxSmh810RoK/slwpU2216zVr/ssJVgFHqOw 8k/l+8hCB0Q6VFEWlLZaCvQjbdWeycIXDzBMPjOYRNn+Hh0B50b9DdAeOJhjFYBJ2cw9 EQsvncI0/ZzTYfBumIkobjRqIVCLJCBFdv4cmYYwAegEIxA6Tugt/iWqyRweftHTsXgP Bxbg== X-Gm-Message-State: AOJu0Yx7Q9FxiMCfAi20KObWHUcUzejx02oUEvT5PW0Qfh4cUDRUKewD 9Lonsnr1sGtPI2Re32ka9IUZbvMgqdRHDvZWzIn08IirikUHMZP62c+rLOT5/X/Yt9o6GPbmUio tKzb/PSjX9g81jbHFvzmzv7cu4xEPv2fLAELu3W/gCWAZnGvz9l0rVE5LJyx9BKMvd7/Cwdj9Me Ot+E7Jroisxf0qi/SzfUXy1UI8iL92utR6/3Tb X-Gm-Gg: ASbGncvokJ63H5Pqcy5au6/2YrpbIw61nU93aP20TU3186N7M90piHlnAI470DPNiDp kVlcdBCingyVBidgoFXwnHgERWh/4lwsWvcrwYhWJyN1ZO8XLWwjbtZwxRZaTP+NKwb/uQAqO7L aJzPb0WrOZdyJvt8oiQSAlejftankCnJEYNrVn59B1P4QSBQWTubBGGxaJWjje+XXxclNBj2f4k AaqxlRUM2wvlGRveA7ajuu0TyhCHoJJib+lq/ONHmX4Y0I4hpXsBOQSykdecXozkbxZOaVaQxlr pfkI7prn9aQb0vx/Mk4ms0TobMyUG4N8HHZIdF5VLo9hhvdP33gpZu7IPIXlTLM= X-Google-Smtp-Source: AGHT+IEvywpEavvmyOduEwwU9z9a/qrP8uMTOrmGOQ25BCjKptwcRQBPtDLlsB4i+g1TFvGzFaNUAA== X-Received: by 2002:a17:903:1a10:b0:220:c4e8:3b9d with SMTP id d9443c01a7336-22bea4efeefmr219540275ad.37.1744704772795; Tue, 15 Apr 2025 01:12:52 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.12.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:12:52 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 01/17] accel/tcg: Store section pointer in CPUTLBEntryFull Date: Tue, 15 Apr 2025 16:12:15 +0800 Message-Id: <20250415081231.21186-2-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::629; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x629.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 'CPUTLBEntryFull.xlat_section' stores section_index in last 12 bits to find the correct section when CPU access the IO region over the IOTLB (iotlb_to_section()). However, section_index is only unique inside single AddressSpace. If address space translation is over IOMMUMemoryRegion, it could return section from other AddressSpace. 'iotlb_to_section()' API only finds the sections from CPU's AddressSpace so that it couldn't find section in other AddressSpace. Thus, using 'iotlb_to_section()' API will find the wrong section and QEMU will have wrong load/store access. To fix this bug, store complete MemoryRegionSection pointer in CPUTLBEntryFull instead of section_index. This bug occurs only when (1) IOMMUMemoryRegion is in the path of CPU access. (2) IOMMUMemoryRegion returns different target_as and the section is in the IO region. Common IOMMU devices don't have this issue since they are only in the path of DMA access. Currently, the bug only occurs when ARM MPC device (hw/misc/tz-mpc.c) returns 'blocked_io_as' to emulate blocked access handling. Upcoming RISC-V wgChecker device is also affected by this bug. Signed-off-by: Jim Shu --- accel/tcg/cputlb.c | 19 +++++++++---------- include/hw/core/cpu.h | 3 +++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index fb22048876..581611d82d 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1150,6 +1150,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, desc->fulltlb[index] = *full; full = &desc->fulltlb[index]; full->xlat_section = iotlb - addr_page; + full->section = section; full->phys_addr = paddr_page; /* Now calculate the new entry */ @@ -1265,14 +1266,14 @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr, } static MemoryRegionSection * -io_prepare(hwaddr *out_offset, CPUState *cpu, hwaddr xlat, +io_prepare(hwaddr *out_offset, CPUState *cpu, CPUTLBEntryFull *full, MemTxAttrs attrs, vaddr addr, uintptr_t retaddr) { MemoryRegionSection *section; hwaddr mr_offset; - section = iotlb_to_section(cpu, xlat, attrs); - mr_offset = (xlat & TARGET_PAGE_MASK) + addr; + section = full->section; + mr_offset = (full->xlat_section & TARGET_PAGE_MASK) + addr; cpu->mem_io_pc = retaddr; if (!cpu->neg.can_do_io) { cpu_io_recompile(cpu, retaddr); @@ -1588,9 +1589,7 @@ bool tlb_plugin_lookup(CPUState *cpu, vaddr addr, int mmu_idx, /* We must have an iotlb entry for MMIO */ if (tlb_addr & TLB_MMIO) { - MemoryRegionSection *section = - iotlb_to_section(cpu, full->xlat_section & ~TARGET_PAGE_MASK, - full->attrs); + MemoryRegionSection *section = full->section; data->is_io = true; data->mr = section->mr; } else { @@ -1980,7 +1979,7 @@ static uint64_t do_ld_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full, tcg_debug_assert(size > 0 && size <= 8); attrs = full->attrs; - section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra); + section = io_prepare(&mr_offset, cpu, full, attrs, addr, ra); mr = section->mr; BQL_LOCK_GUARD(); @@ -2001,7 +2000,7 @@ static Int128 do_ld16_mmio_beN(CPUState *cpu, CPUTLBEntryFull *full, tcg_debug_assert(size > 8 && size <= 16); attrs = full->attrs; - section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra); + section = io_prepare(&mr_offset, cpu, full, attrs, addr, ra); mr = section->mr; BQL_LOCK_GUARD(); @@ -2521,7 +2520,7 @@ static uint64_t do_st_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full, tcg_debug_assert(size > 0 && size <= 8); attrs = full->attrs; - section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra); + section = io_prepare(&mr_offset, cpu, full, attrs, addr, ra); mr = section->mr; BQL_LOCK_GUARD(); @@ -2541,7 +2540,7 @@ static uint64_t do_st16_mmio_leN(CPUState *cpu, CPUTLBEntryFull *full, tcg_debug_assert(size > 8 && size <= 16); attrs = full->attrs; - section = io_prepare(&mr_offset, cpu, full->xlat_section, attrs, addr, ra); + section = io_prepare(&mr_offset, cpu, full, attrs, addr, ra); mr = section->mr; BQL_LOCK_GUARD(); diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index abd8764e83..8759e30fcc 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -218,6 +218,9 @@ struct CPUTLBEntryFull { */ hwaddr xlat_section; + /* @section contains physical section. */ + MemoryRegionSection *section; + /* * @phys_addr contains the physical address in the address space * given by cpu_asidx_from_attrs(cpu, @attrs). From patchwork Tue Apr 15 08:12:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051669 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 89A79C369B9 for ; Tue, 15 Apr 2025 08:16:27 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bPs-00071d-P3; Tue, 15 Apr 2025 04:13:12 -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 1u4bPp-0006qG-AM for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:10 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bPg-0001uM-JW for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:09 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-2254e0b4b79so70713345ad.2 for ; Tue, 15 Apr 2025 01:13:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704779; x=1745309579; 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=8XVOeOfpgChxLganDzzyf88m8uST52bHWyGBfbWAVek=; b=ab+NIYnx2Ufh3cSkAB6VG8jX/R84GaQx1EeZQI6MNGfRViBN9H7eZiOmDXOBpHqlrV c0duoBg6d5+B1eKk+JrDt65Cr0KEzujp01EmWmFFOLB1t2TE7BprIi0asnQIkEbXwqOq IBtk9Gd7r+PmaJbiuOaLPftXQNXPeZ8C48+oLWtw8P+T05gWVgmQsMCwEkhgBES6s9LG Wz4tQb4zKyIn/Lh8jyA8J7OxxmFoX1Y+OPQUGxPoE8VYWePPwMJbGWtTarJ5OIO1DvC5 3l8ylKYEC+9mBaC6MDeCnTY0+fHMBs+qf0yveuwCwp+0IOWZzahbd1sJKP90FSJHv5cK kbdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704779; x=1745309579; 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=8XVOeOfpgChxLganDzzyf88m8uST52bHWyGBfbWAVek=; b=lR986L3fceal3tNGlZgyBa7olOFm2I+g+aJv3ZWzMLT5exon0NUqQsOycVULsLOM6y FyDsm2X44B47wtbBuPYbCHiLHLeXnzoh8M95Q9janR8kfrO/qny3kIS2VFRi86g/aznP Ed/+CDFo59ruNp/PUf30Qmu/cOhgzay3v1OnpXPCUH9tmVxZ4c2ASLSFwcBiyu+9b2OD SRRnQnJ1FeHiEf31vkJzdo3pcyxCKLO5z0F+Gj7G6fBYiGu9wiWhLE7ze+QFRhNvcTFw bnSI/X6iXeSuYpjdc3Vbs/4jqXXiQNZHBMU0v+9x1/k3lspJqGthCww+zh0HVxUcG9lU PhRw== X-Gm-Message-State: AOJu0Ywawt8bH2nF2/JuI3vgpoKz2S7fAg2Q73jGcF+Zs08thjv2IFy4 NpnrWR+EFKAtbklSjZoABsRINLyvQPXX0s/2XHnQgi1ZumgPoTl1MGDtuZCnsyk9jAbw0HtQagl wAuEnRhnawit3X6FGLt1Z+XObTCgoDUpRPwxMMPMqpJMFGmid2eQQFrc5DaF9N6Fk1vp5qL95Gi XkpX/bWZi009ssd04ISTNfSzm4GJZQLzmJze7o X-Gm-Gg: ASbGncuoErlzU7CLbkKylF+0iFiHvzqAHCFw9xmIGvZqKq9W8PLI+AsuqDx+W4UchQp qJQ+3JkDdKW74DqigWf4eSAo/DckI16ndej5XTZ6jw/g46tsn4CfPstFEMIM08Rk6pTQJxxefrL /p0R6Rm9/FKbXWeqjA3pbby1kGg0s/eoQWtGl2HBE37mueRUSPbDOVQvD2yedv2vwLMoMLgI7p/ 2bpWIWpcS6bz3kA7MGDpNEczfXNYod9inYKYjLviswilqcnxvtZiqzamPoATXUGpLWKzzHmm6jv dgzUtXZOkHHKX10BzvRF9GiPjZ3t7S6N2Kkhr875y0gP1j3XnIg9LmfX4Qm8mDg= X-Google-Smtp-Source: AGHT+IH9OZfvqrH4qQqQXzZ5p3lwK3Pf1HO15ckRKsQ+Xca0EV52fTz0+O9lq4ryTLp5LBnI9xHoiA== X-Received: by 2002:a17:902:ea01:b0:224:1074:63a2 with SMTP id d9443c01a7336-22bea4fde13mr229732655ad.43.1744704778558; Tue, 15 Apr 2025 01:12:58 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.12.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:12:58 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 02/17] accel/tcg: memory access from CPU will pass access_type to IOMMU Date: Tue, 15 Apr 2025 16:12:16 +0800 Message-Id: <20250415081231.21186-3-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62c.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org It is the preparation patch for upcoming RISC-V wgChecker device. Since RISC-V wgChecker could permit access in RO/WO permission, the IOMMUMemoryRegion could return different section for read & write access. The memory access from CPU should also pass the access_type to IOMMU translate function so that IOMMU could return the correct section of specified access_type. Signed-off-by: Jim Shu --- accel/tcg/cputlb.c | 17 ++++++++++------- include/exec/cputlb.h | 11 +++++++---- include/exec/exec-all.h | 3 ++- system/physmem.c | 16 +++++++++++----- target/alpha/helper.c | 2 +- target/avr/helper.c | 2 +- target/hppa/mem_helper.c | 1 - target/i386/tcg/system/excp_helper.c | 3 ++- target/loongarch/tcg/tlb_helper.c | 2 +- target/m68k/helper.c | 10 +++++++--- target/microblaze/helper.c | 8 ++++---- target/mips/tcg/system/tlb_helper.c | 4 ++-- target/openrisc/mmu.c | 2 +- target/ppc/mmu_helper.c | 2 +- target/riscv/cpu_helper.c | 2 +- target/rx/cpu.c | 3 ++- target/s390x/tcg/excp_helper.c | 2 +- target/sh4/helper.c | 2 +- target/sparc/mmu_helper.c | 6 +++--- target/tricore/helper.c | 2 +- target/xtensa/helper.c | 3 ++- 21 files changed, 61 insertions(+), 42 deletions(-) diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 581611d82d..6e421b46cc 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1017,7 +1017,8 @@ static inline void tlb_set_compare(CPUTLBEntryFull *full, CPUTLBEntry *ent, * critical section. */ void tlb_set_page_full(CPUState *cpu, int mmu_idx, - vaddr addr, CPUTLBEntryFull *full) + vaddr addr, MMUAccessType access_type, + CPUTLBEntryFull *full) { CPUTLB *tlb = &cpu->neg.tlb; CPUTLBDesc *desc = &tlb->d[mmu_idx]; @@ -1044,7 +1045,8 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, prot = full->prot; asidx = cpu_asidx_from_attrs(cpu, full->attrs); section = address_space_translate_for_iotlb(cpu, asidx, paddr_page, - &xlat, &sz, full->attrs, &prot); + &xlat, &sz, full->attrs, &prot, + access_type); assert(sz >= TARGET_PAGE_SIZE); tlb_debug("vaddr=%016" VADDR_PRIx " paddr=0x" HWADDR_FMT_plx @@ -1181,7 +1183,8 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr, hwaddr paddr, MemTxAttrs attrs, int prot, - int mmu_idx, vaddr size) + MMUAccessType access_type, int mmu_idx, + vaddr size) { CPUTLBEntryFull full = { .phys_addr = paddr, @@ -1191,15 +1194,15 @@ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr, }; assert(is_power_of_2(size)); - tlb_set_page_full(cpu, mmu_idx, addr, &full); + tlb_set_page_full(cpu, mmu_idx, addr, access_type, &full); } void tlb_set_page(CPUState *cpu, vaddr addr, - hwaddr paddr, int prot, + hwaddr paddr, int prot, MMUAccessType access_type, int mmu_idx, vaddr size) { tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED, - prot, mmu_idx, size); + prot, access_type, mmu_idx, size); } /** @@ -1241,7 +1244,7 @@ static bool tlb_fill_align(CPUState *cpu, vaddr addr, MMUAccessType type, if (ops->tlb_fill_align) { if (ops->tlb_fill_align(cpu, &full, addr, type, mmu_idx, memop, size, probe, ra)) { - tlb_set_page_full(cpu, mmu_idx, addr, &full); + tlb_set_page_full(cpu, mmu_idx, addr, type, &full); return true; } } else { diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index 8125f6809c..a97e70319f 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -40,6 +40,7 @@ void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length); * @cpu: CPU context * @mmu_idx: mmu index of the tlb to modify * @addr: virtual address of the entry to add + * @access_type: access was read/write/execute * @full: the details of the tlb entry * * Add an entry to @cpu tlb index @mmu_idx. All of the fields of @@ -55,6 +56,7 @@ void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length); * used by tlb_flush_page. */ void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr, + MMUAccessType access_type, CPUTLBEntryFull *full); /** @@ -64,6 +66,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr, * @paddr: physical address of the page * @attrs: memory transaction attributes * @prot: access permissions (PAGE_READ/PAGE_WRITE/PAGE_EXEC bits) + * @access_type: access was read/write/execute * @mmu_idx: MMU index to insert TLB entry for * @size: size of the page in bytes * @@ -80,9 +83,9 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr, * used by tlb_flush_page. */ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr, - hwaddr paddr, MemTxAttrs attrs, - int prot, int mmu_idx, vaddr size); - + hwaddr paddr, MemTxAttrs attrs, int prot, + MMUAccessType access_type, int mmu_idx, + vaddr size); /** * tlb_set_page: * @@ -91,7 +94,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr, * as a convenience for CPUs which don't use memory transaction attributes. */ void tlb_set_page(CPUState *cpu, vaddr addr, - hwaddr paddr, int prot, + hwaddr paddr, int prot, MMUAccessType access_type, int mmu_idx, vaddr size); #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index dd5c40f223..d36e75f405 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -232,7 +232,8 @@ static inline tb_page_addr_t get_page_addr_code(CPUArchState *env, MemoryRegionSection * address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, hwaddr *xlat, hwaddr *plen, - MemTxAttrs attrs, int *prot); + MemTxAttrs attrs, int *prot, + MMUAccessType access_type); hwaddr memory_region_section_get_iotlb(CPUState *cpu, MemoryRegionSection *section); #endif diff --git a/system/physmem.c b/system/physmem.c index 333a5eb94d..aa0a9152da 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -681,12 +681,14 @@ void tcg_iommu_init_notifier_list(CPUState *cpu) MemoryRegionSection * address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr, hwaddr *xlat, hwaddr *plen, - MemTxAttrs attrs, int *prot) + MemTxAttrs attrs, int *prot, + MMUAccessType access_type) { MemoryRegionSection *section; IOMMUMemoryRegion *iommu_mr; IOMMUMemoryRegionClass *imrc; IOMMUTLBEntry iotlb; + IOMMUAccessFlags iommu_flags; int iommu_idx; hwaddr addr = orig_addr; AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch; @@ -703,10 +705,14 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr, iommu_idx = imrc->attrs_to_index(iommu_mr, attrs); tcg_register_iommu_notifier(cpu, iommu_mr, iommu_idx); - /* We need all the permissions, so pass IOMMU_NONE so the IOMMU - * doesn't short-cut its translation table walk. - */ - iotlb = imrc->translate(iommu_mr, addr, IOMMU_NONE, iommu_idx); + + if (access_type == MMU_DATA_STORE) { + iommu_flags = IOMMU_WO; + } else { + iommu_flags = IOMMU_RO; + } + + iotlb = imrc->translate(iommu_mr, addr, iommu_flags, iommu_idx); addr = ((iotlb.translated_addr & ~iotlb.addr_mask) | (addr & iotlb.addr_mask)); /* Update the caller's prot bits to remove permissions the IOMMU diff --git a/target/alpha/helper.c b/target/alpha/helper.c index 57cefcba14..e16dcde3ac 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c @@ -318,7 +318,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, } tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, - prot, mmu_idx, TARGET_PAGE_SIZE); + prot, access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } diff --git a/target/avr/helper.c b/target/avr/helper.c index 3412312ad5..05a89b3614 100644 --- a/target/avr/helper.c +++ b/target/avr/helper.c @@ -149,7 +149,7 @@ bool avr_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } } - tlb_set_page(cs, address, paddr, prot, mmu_idx, page_size); + tlb_set_page(cs, address, paddr, prot, access_type, mmu_idx, page_size); return true; } diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index fb1d93ef1f..4f0982a2c1 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -473,7 +473,6 @@ bool hppa_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, vaddr addr, out->prot = prot; out->attrs = MEMTXATTRS_UNSPECIFIED; out->lg_page_size = TARGET_PAGE_BITS; - return true; } diff --git a/target/i386/tcg/system/excp_helper.c b/target/i386/tcg/system/excp_helper.c index 6876329de2..831e178927 100644 --- a/target/i386/tcg/system/excp_helper.c +++ b/target/i386/tcg/system/excp_helper.c @@ -624,7 +624,8 @@ bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, tlb_set_page_with_attrs(cs, addr & TARGET_PAGE_MASK, out.paddr & TARGET_PAGE_MASK, cpu_get_mem_attrs(env), - out.prot, mmu_idx, out.page_size); + out.prot, access_type, mmu_idx, + out.page_size); return true; } diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 70d1b5cf99..b57775908d 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -522,7 +522,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TLBRET_MATCH) { tlb_set_page(cs, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot, - mmu_idx, TARGET_PAGE_SIZE); + access_type, mmu_idx, TARGET_PAGE_SIZE); qemu_log_mask(CPU_LOG_MMU, "%s address=%" VADDR_PRIx " physical " HWADDR_FMT_plx " prot %d\n", __func__, address, physical, prot); diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 0bf574830f..e652c23485 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -969,7 +969,7 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size, tlb_set_page(cs, address & TARGET_PAGE_MASK, address & TARGET_PAGE_MASK, PAGE_READ | PAGE_WRITE | PAGE_EXEC, - mmu_idx, TARGET_PAGE_SIZE); + qemu_access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } @@ -989,7 +989,8 @@ bool m68k_cpu_tlb_fill(CPUState *cs, vaddr address, int size, address, access_type, &page_size); if (likely(ret == 0)) { tlb_set_page(cs, address & TARGET_PAGE_MASK, - physical & TARGET_PAGE_MASK, prot, mmu_idx, page_size); + physical & TARGET_PAGE_MASK, prot, qemu_access_type, + mmu_idx, page_size); return true; } @@ -1461,6 +1462,7 @@ void HELPER(ptest)(CPUM68KState *env, uint32_t addr, uint32_t is_read) int prot; int ret; target_ulong page_size; + MMUAccessType qemu_access_type; access_type = ACCESS_PTEST; if (env->dfc & 4) { @@ -1468,9 +1470,11 @@ void HELPER(ptest)(CPUM68KState *env, uint32_t addr, uint32_t is_read) } if ((env->dfc & 3) == 2) { access_type |= ACCESS_CODE; + qemu_access_type = MMU_INST_FETCH; } if (!is_read) { access_type |= ACCESS_STORE; + qemu_access_type = MMU_DATA_STORE; } env->mmu.mmusr = 0; @@ -1480,7 +1484,7 @@ void HELPER(ptest)(CPUM68KState *env, uint32_t addr, uint32_t is_read) if (ret == 0) { tlb_set_page(env_cpu(env), addr & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, - prot, access_type & ACCESS_SUPER ? + prot, qemu_access_type, access_type & ACCESS_SUPER ? MMU_KERNEL_IDX : MMU_USER_IDX, page_size); } } diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c index 27fc929bee..fd8847e71f 100644 --- a/target/microblaze/helper.c +++ b/target/microblaze/helper.c @@ -53,8 +53,8 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size, /* MMU disabled or not available. */ address &= TARGET_PAGE_MASK; prot = PAGE_RWX; - tlb_set_page_with_attrs(cs, address, address, attrs, prot, mmu_idx, - TARGET_PAGE_SIZE); + tlb_set_page_with_attrs(cs, address, address, attrs, prot, access_type, + mmu_idx, TARGET_PAGE_SIZE); return true; } @@ -65,8 +65,8 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size, qemu_log_mask(CPU_LOG_MMU, "MMU map mmu=%d v=%x p=%x prot=%x\n", mmu_idx, vaddr, paddr, lu.prot); - tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, lu.prot, mmu_idx, - TARGET_PAGE_SIZE); + tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, lu.prot, access_type, + mmu_idx, TARGET_PAGE_SIZE); return true; } diff --git a/target/mips/tcg/system/tlb_helper.c b/target/mips/tcg/system/tlb_helper.c index df80301a41..172640aef0 100644 --- a/target/mips/tcg/system/tlb_helper.c +++ b/target/mips/tcg/system/tlb_helper.c @@ -933,7 +933,7 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TLBRET_MATCH) { tlb_set_page(cs, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot, - mmu_idx, TARGET_PAGE_SIZE); + access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } #if !defined(TARGET_MIPS64) @@ -951,7 +951,7 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TLBRET_MATCH) { tlb_set_page(cs, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot, - mmu_idx, TARGET_PAGE_SIZE); + access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } } diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c index 47ac783c52..5248c168b2 100644 --- a/target/openrisc/mmu.c +++ b/target/openrisc/mmu.c @@ -128,7 +128,7 @@ bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, if (likely(excp == 0)) { tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys_addr & TARGET_PAGE_MASK, prot, - mmu_idx, TARGET_PAGE_SIZE); + access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } if (probe) { diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index ad9ba8294c..d0e8f20e11 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -1369,7 +1369,7 @@ bool ppc_cpu_tlb_fill(CPUState *cs, vaddr eaddr, int size, if (ppc_xlate(cpu, eaddr, access_type, &raddr, &page_size, &prot, mmu_idx, !probe)) { tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, - prot, mmu_idx, 1UL << page_size); + prot, access_type, mmu_idx, 1UL << page_size); return true; } if (probe) { diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 6c4391d96b..f4c4b69a3c 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1967,7 +1967,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TRANSLATE_SUCCESS) { tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1), - prot, mmu_idx, tlb_size); + prot, access_type, mmu_idx, tlb_size); return true; } else if (probe) { return false; diff --git a/target/rx/cpu.c b/target/rx/cpu.c index 0ba0d55ab5..9d8afa150c 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -182,7 +182,8 @@ static bool rx_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, /* Linear mapping */ address = physical = addr & TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - tlb_set_page(cs, address, physical, prot, mmu_idx, TARGET_PAGE_SIZE); + tlb_set_page(cs, address, physical, prot, access_type, + mmu_idx, TARGET_PAGE_SIZE); return true; } diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c index f969850f87..ec6d4076e8 100644 --- a/target/s390x/tcg/excp_helper.c +++ b/target/s390x/tcg/excp_helper.c @@ -179,7 +179,7 @@ bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size, "%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __func__, (uint64_t)vaddr, (uint64_t)raddr, prot); tlb_set_page(cs, address & TARGET_PAGE_MASK, raddr, prot, - mmu_idx, TARGET_PAGE_SIZE); + access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } if (probe) { diff --git a/target/sh4/helper.c b/target/sh4/helper.c index 7567e6c8b6..7531f6d933 100644 --- a/target/sh4/helper.c +++ b/target/sh4/helper.c @@ -808,7 +808,7 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == MMU_OK) { address &= TARGET_PAGE_MASK; physical &= TARGET_PAGE_MASK; - tlb_set_page(cs, address, physical, prot, mmu_idx, TARGET_PAGE_SIZE); + tlb_set_page(cs, address, physical, prot, access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } if (probe) { diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c index 3821cd91ec..08dd73b210 100644 --- a/target/sparc/mmu_helper.c +++ b/target/sparc/mmu_helper.c @@ -229,7 +229,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, "Translate at %" VADDR_PRIx " -> " HWADDR_FMT_plx ", vaddr " TARGET_FMT_lx "\n", address, full.phys_addr, vaddr); - tlb_set_page_full(cs, mmu_idx, vaddr, &full); + tlb_set_page_full(cs, mmu_idx, vaddr, access_type, &full); return true; } @@ -245,7 +245,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, neverland. Fake/overridden mappings will be flushed when switching to normal mode. */ full.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - tlb_set_page_full(cs, mmu_idx, vaddr, &full); + tlb_set_page_full(cs, mmu_idx, vaddr, access_type, &full); return true; } else { if (access_type == MMU_INST_FETCH) { @@ -769,7 +769,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, trace_mmu_helper_mmu_fault(address, full.phys_addr, mmu_idx, env->tl, env->dmmu.mmu_primary_context, env->dmmu.mmu_secondary_context); - tlb_set_page_full(cs, mmu_idx, address, &full); + tlb_set_page_full(cs, mmu_idx, address, access_type, &full); return true; } if (probe) { diff --git a/target/tricore/helper.c b/target/tricore/helper.c index a64412e6bd..4a4688f109 100644 --- a/target/tricore/helper.c +++ b/target/tricore/helper.c @@ -84,7 +84,7 @@ bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TLBRET_MATCH) { tlb_set_page(cs, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, - mmu_idx, TARGET_PAGE_SIZE); + rw, mmu_idx, TARGET_PAGE_SIZE); return true; } else { assert(ret < 0); diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index 4824b97e37..5d5d69a811 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -281,7 +281,8 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, tlb_set_page(cs, address & TARGET_PAGE_MASK, paddr & TARGET_PAGE_MASK, - access, mmu_idx, page_size); + access, access_type, mmu_idx, + page_size); return true; } else if (probe) { return false; From patchwork Tue Apr 15 08:12:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051677 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 143C6C369B8 for ; Tue, 15 Apr 2025 08:19:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bPr-0006wA-Dd; Tue, 15 Apr 2025 04:13:11 -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 1u4bPo-0006nb-Si for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:08 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bPm-0001vT-Mq for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:08 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-227d6b530d8so50456755ad.3 for ; Tue, 15 Apr 2025 01:13:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704784; x=1745309584; 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=cbCfnAY8k2Soyd1n/D0nC/2pTKzsneNdm2pbb2owQHc=; b=HgQ6ixyCZAQ4VvQnfW/mj/N7gF0WpQwnrutb18idH32Flpo4f/s0+ePPL3Ny9zP9MJ hX67qgEvQJc0hplnblX1quJz+jK7Y7TFx8m3KlkqfbOZ2xMnJnvZn1mDa3U1OHPG6W5g P8vA7h+Mqb5v81TSdfKB8xZz+yyZe4K00IJ9bWnNRMh5SUvSBg9lZ25+gu5aGoJm1HpW 2uhXJ7CZn6LefAf9qCk3aiu0CKCaZvRs87v+21vNwJkpMUBGwBAzG8m9uJQrm/HxXATH QCF+krlTCylboW62yPXDInfGvEL1EaASGi9vIES6JN5rYuVxn+XgPdPlH/bxAsyNLsjr t2LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704784; x=1745309584; 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=cbCfnAY8k2Soyd1n/D0nC/2pTKzsneNdm2pbb2owQHc=; b=W4TTnSWJOz7ob5Sa1wQ5yvBa9tVwba3KMTNYDMlLWa/B+Z98aFG0HxlFKp32VJN6AP fgH0HCG2FMu825gz38rbl7TPSTKWEy1lz3d+ePno+KKQ+tNunPAWA9OH0724kRLVzrWc 7T4nkl/Wf0Jg0rSfMP8h4e1p5CDaTZYJG1GGPyHc8P5n+fUi53//DsGZmSDkC1g5Uoy4 WoHlgDx2Gh9nIZ5l25pfou4tibpmofMHnpDjjyMsUW8oQoILndOkTBaeCrXZy2TUVLJq U9byZNuew4zE85VhFjWatBHG7qKTGG+ou5q8iKO3HNXc+3q1n+b3BKzmACaRKP6mRNP5 tj5w== X-Gm-Message-State: AOJu0YxpjZBKC9xZw95fJ+ni+AJQX5EnyxVwst/HvJsUxcDwHm/mNHN9 iIqj8tr+0vWDU2jbC64xHzbL7y4NCH8i4E6n4BHVA6dmHiRNDiC7UobuhsHq+056zjWjGuWf0vT vAiU0D6O2rtly6gC1lyei+Xoc+8EIylZXyQD/OfGo0xiSB3o0PDtCYBAXNaSjx21apUzMRWbZxR l3TY3vJisPjAJt/W7LjHmgT9zDXpkQZJcX1AU3 X-Gm-Gg: ASbGncukdaAEQQLr7rqCi2c//B0AMADyEXhjSlNq4zhGQo016AsWgFLzL3nQe53MB1V UcJWYZpzUrA+x7C4TkuMiL4fszrWcbJ7+kEvUXZlT6XIVcyKpEZybDYJmLck47HJlbtOG/xNxLl F4zrITJdDsl/QIhD2i8uRWZX1+r/gH6vImyHnDx7WM93Opeq+qA4FJDG4WoegrMv8thacpklz/Y kbCM/Jj6BBZYGShLwyjm8fzWFO6A2BBi/WKAY/s5enknWHmhRm+BxoU+4yN0VFUFbMFam7p3szw qWR1E1wvweGl892+YPjh13M/eCS13Ul52gPPQKHGEyLVoqakNrmTXaP37JO/Q7q6NgLSZ9LAZw= = X-Google-Smtp-Source: AGHT+IHfKdGnCEQTD5NofF2J+e+AwCYuEOZQAjp/NYqoqKLGEbN1vmIPt92YBINEI+6c5wH19W9IgQ== X-Received: by 2002:a17:902:ea01:b0:21a:8300:b9ce with SMTP id d9443c01a7336-22bea4fd0a0mr220934125ad.49.1744704784188; Tue, 15 Apr 2025 01:13:04 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.12.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:03 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 03/17] exec: Add RISC-V WorldGuard WID to MemTxAttrs Date: Tue, 15 Apr 2025 16:12:17 +0800 Message-Id: <20250415081231.21186-4-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62c.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org RISC-V WorldGuard will add 5-bit world_id (WID) to the each memory transaction on the bus. The wgChecker in front of RAM or peripherals MMIO could do the access control based on the WID. It is similar to ARM TrustZone NS bit, but the WID is 5-bit. The common implementation of WID is AXI4 AxUSER signal. Signed-off-by: Jim Shu --- include/exec/memattrs.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h index 8db1d30464..7a6866fa41 100644 --- a/include/exec/memattrs.h +++ b/include/exec/memattrs.h @@ -54,6 +54,11 @@ typedef struct MemTxAttrs { */ unsigned int pid:8; + /* + * RISC-V WorldGuard: the 5-bit WID field of memory access. + */ + unsigned int world_id:5; + /* * Bus masters which don't specify any attributes will get this * (via the MEMTXATTRS_UNSPECIFIED constant), so that we can @@ -63,8 +68,7 @@ typedef struct MemTxAttrs { */ bool unspecified; - uint8_t _reserved1; - uint16_t _reserved2; + uint16_t _reserved1; } MemTxAttrs; QEMU_BUILD_BUG_ON(sizeof(MemTxAttrs) > 8); From patchwork Tue Apr 15 08:12:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051667 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C352AC369B8 for ; Tue, 15 Apr 2025 08:16:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bPy-0007Jv-RK; Tue, 15 Apr 2025 04:13:18 -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 1u4bPw-0007Em-SU for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:17 -0400 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bPr-0001wR-T4 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:15 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-225df540edcso61476615ad.0 for ; Tue, 15 Apr 2025 01:13:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704790; x=1745309590; 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=xHnyUVIUAy9EeD7Slw5HDOE0YtQ4rJTQDvRGE+rnGQs=; b=kOkjzh+awSPpfE/wqGKkTKxSIA/CKo5SshFWRlV2ECaqqyEVnFQHi2+Q70mUM0zmT3 IFETfytFhrFkEYiU23xTP2+kAqfTNCrNZrVioqV7WQebpSgltP6BllorIwemzaeCi/RS r+Okg7rkDkIok3mTlDcm/THKQt0nXCVUi64BSgLX/jdpe4Whxp1WlqoXu2fEbhgHxVo0 5StWdNadCPdXj4YP8r7crJSwuI4xiU6UBCZKD4mbKMkUwYt2vsbgwHurEDb7Ax7TRtdl 0siSx8opMfKi+CQ2OWxryfliUooBe8asRV5VwUuMwzebvZtmOPrz0XsFYWN0OexJ4SKT C/6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704790; x=1745309590; 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=xHnyUVIUAy9EeD7Slw5HDOE0YtQ4rJTQDvRGE+rnGQs=; b=EzDFBvl6bhAO9/01TRpEPtnYqcRoA33I8x3w8Qo5C8W608moxSBcpwZ8UsCVQ+jQd4 mMLEUPRX6r+QufEFj3eWjci/RWXq64W/Oofd4K/WnFW/VlZg53HmK7seFGgWtbHd55jt 1rv76y9e2Bn3gTgSw36fMCZwbjTwFDYnQNlWCZqtyaeIlb33zmF5MhK9EoUf+Z8VTNkm lvsAQeFH6HBYTZSSc2jwt9+Nvg+NuvwPVf5iZ2XJaHBPWydcqARuQ4YWiIu8odUTOTxl 2UsrcJb28YTnLsxvGOr2rdMkIK5jTXWEgiArKNWFz4X5hwuSbD3X8dJqPbG9bUvnJkU0 LfrQ== X-Gm-Message-State: AOJu0Yy+eKhnFMWqTN0WtPMAoFvmJggii/8Sebtqrb5OFXd3mO3VziaZ P/0KVKkyYSxg7Q9d5aYjHVjtWxIJ8o/hwvkTYygMAimTyd35psxZquZ3FNgWydJ1M2pNHWUSugc qCiOzesD7XA0AfYNQvF60oRLvt4nbPV03gjUA92MngL0Jhtv0dE3/8HXNXhUw6hrOG0+762TrMs g2PsbjLZf/8nc5M53VHMgid/L8yqZPU6e1gHwx X-Gm-Gg: ASbGncuwV9EdfC1UQ/yL5fBvgGaiQwf4CUIgdj03nYxLSAPsfI+w8i9aY7DZAt1GdDd HmppnKHqgRj5iGQGlfCSVWnpPQLoSEqP16xnWbCE282Jx/1f6YsWCRF1lncBQGgKK/a8JuTpMZt fKQzssnhxkXSezrr5M+nF58oZZB2p5KlgN8rSCiO9VGEuy+DY0TpWOYlhQELtNKanZQL+pme7I4 Nr/P2Fn7UKwGo2LxhSFFfR1G9ALTb41hFY/V9FTNwP7Ot+pSln3u/LYn8q92atunQp+my5DkOye 9L4u+4kWLn4NtEdgIZabfEGcH/fl3x/3Y/TSbWoph6FTqiH4TTgTYM22ufjIWro= X-Google-Smtp-Source: AGHT+IEQYMWfiOxs2M8vBmF8MpgizLLzFWXOp7UMoJudLYSYt+QnYMB5SkX++ICIfRjYoYa7U/MCBg== X-Received: by 2002:a17:902:e88d:b0:223:517a:d4ed with SMTP id d9443c01a7336-22c2498a2ffmr34994655ad.15.1744704789867; Tue, 15 Apr 2025 01:13:09 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:09 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 04/17] hw/misc: riscv_worldguard: Add RISC-V WorldGuard global config Date: Tue, 15 Apr 2025 16:12:18 +0800 Message-Id: <20250415081231.21186-5-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::631; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x631.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 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 --- hw/misc/Kconfig | 3 + hw/misc/meson.build | 1 + hw/misc/riscv_worldguard.c | 182 +++++++++++++++++++++++++++++ include/hw/misc/riscv_worldguard.h | 55 +++++++++ 4 files changed, 241 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 ec0fa5aa9f..7677c0e962 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -222,4 +222,7 @@ config IOSB config XLNX_VERSAL_TRNG bool +config RISCV_WORLDGUARD + bool + source macio/Kconfig diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 6d47de482c..3d2f4bb6a3 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: files('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_worldguard.c')) subdir('macio') diff --git a/hw/misc/riscv_worldguard.c b/hw/misc/riscv_worldguard.c new file mode 100644 index 0000000000..b02bd28d02 --- /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 for + * 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 = NULL; + +static Property riscv_worldguard_properties[] = { + 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 WorldGuard + * 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 */ +static void wid_to_mem_attrs(MemTxAttrs *attrs, uint32_t wid) +{ + g_assert(wid < worldguard_config->nworlds); + + attrs->unspecified = 0; + if (worldguard_config->tz_compat) { + attrs->secure = wid; + } else { + attrs->world_id = wid; + } +} + +/* MemTxAttrs to WID converter */ +uint32_t mem_attrs_to_wid(MemTxAttrs attrs) +{ + if (attrs.unspecified) { + if (worldguard_config->trustedwid != 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 = mem_attrs_to_wid(attrs); + uint32_t trustedwid = worldguard_config->trustedwid; + + if ((trustedwid == NO_TRUSTEDWID) || (wid == 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 = RISCV_WORLDGUARD(dev); + + if (worldguard_config != NULL) { + error_setg(errp, "Couldn't realize multiple global WorldGuard configs."); + return; + } + + if ((s->nworlds) & (s->nworlds - 1)) { + error_setg(errp, "Current implementation only support power-of-2 NWorld."); + return; + } + + if ((s->trustedwid != NO_TRUSTEDWID) && (s->trustedwid >= s->nworlds)) { + error_setg(errp, "Trusted WID must be less than the number of world."); + return; + } + + if ((s->nworlds != 2) && (s->tz_compat)) { + error_setg(errp, "Only 2 worlds system could use TrustZone compatible mode."); + return; + } + + /* Register WG global config */ + worldguard_config = s; + + /* Initialize global data for wgChecker */ + wgc_slot_perm_mask = MAKE_64BIT_MASK(0, 2 * worldguard_config->nworlds); +} + +static void riscv_worldguard_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + device_class_set_props(dc, riscv_worldguard_properties); + dc->user_creatable = true; + dc->realize = riscv_worldguard_realize; +} + +static const TypeInfo riscv_worldguard_info = { + .name = TYPE_RISCV_WORLDGUARD, + .parent = TYPE_DEVICE, + .instance_size = sizeof(RISCVWorldGuardState), + .class_init = 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 = 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_worldguard.h new file mode 100644 index 0000000000..8a533a0517 --- /dev/null +++ b/include/hw/misc/riscv_worldguard.h @@ -0,0 +1,55 @@ +/* + * 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 for + * 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); + +uint32_t mem_attrs_to_wid(MemTxAttrs attrs); +bool could_access_wgblocks(MemTxAttrs attrs, const char *wgblock); + +#endif From patchwork Tue Apr 15 08:12:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051671 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1D3FBC369B8 for ; Tue, 15 Apr 2025 08:17:05 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bQC-00084J-9m; Tue, 15 Apr 2025 04:13:32 -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 1u4bQ9-0007t7-Le for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:29 -0400 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQ5-0001yP-E5 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:28 -0400 Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-2240b4de12bso70875425ad.2 for ; Tue, 15 Apr 2025 01:13:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704802; x=1745309602; 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=Q73Ra6NhBnNXysABi6967YWRbV9gsBItuZ0tiWgYmXM=; b=MkWtanBdA+GKcKMIZ6hFY2LIIhqEQd3iHpDg80AwDnTXcSTOG8XuHJGWvEpl49LJOQ Q7J98MIY61Y7RD3GZFJw+i8av3rwiR1XvbZlF2ggW9O/veCHPUGoMoN00S35cl1GmeCm Kvt9uFHa0GkmUpBllfWIpU+4CBZHU5SE44VO5dW/M3dB0Cn43viQ7wWgqQouNlIBF+1L 2h+dHp/Z0Tr5RQ7HR/nVwkvF5s4bcCUCzGaO2A/VfzZ819/9lDqmmK0l9wx4C44t0I6U 6aDq2O54BG65uFjHGvfrdavO3/jcFVo7sMXKmnH+sHjtcdFc837/xzGdXVzYGWk3iMPE d9Ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704802; x=1745309602; 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=Q73Ra6NhBnNXysABi6967YWRbV9gsBItuZ0tiWgYmXM=; b=cfU17qRdcziXKsV8GxMVj/Q4C58hdQ8247cSNIdRpOMYOf8ERpiOEtYOIBhs0YSEhv VBi8AdU2h4ZcqPrHESQjzSQT1AHb3RHUitc3RtuUwsZO3dZd7ZVG9EBGFocLGQPgZPLL 2RXHryJGbg91b+f3C+M0zeQ5EiXm/cgeFRSkQJU0kipdWohCGkotgjz6dPHf/ZNOQhUe lNwpsRip5FmbhZq8pzpNf+7t7tcTpI+3IL+uqFcisnfE3Sp/8Iq/B5UNoh7/GF3R39cW W9LUyeKtYqpaE/+oBJrkia2oiu1aLTAkp4J8jjLCT+kR8mSVlXXRPOs80psm5T/vN1XJ ogkQ== X-Gm-Message-State: AOJu0YxBuPstfM+xrmowT2zBOJMqCP8zZ2WoAdTRLd48mB9zhU+zdoTh 8XwE+hZrKHC7dZ3z0TsN6MRYC02mH71etgBK0a8No0P688p/aoC8Dhv7ueTPdOjKY77R78t+dRj z4OT3Nx8CQ336uUy0BH6FV3YNu6OjgNWDCBn/U5wMMS/7v6LT/WfUhWysTcgbeHAG/sDqHhmgDf F//Fd4XjHj5GdMB8fwPip1emwShVYFVSCtC/9o X-Gm-Gg: ASbGncuYlenVwuz1GiGPP8giG+eMEU5bFWHacTALEIuihFmg+yQKsH7j7n5nuxKVT7b 7d9J7X3zDNjtMiVn4kxGzMht7gNueouMWaDAuluPxOe3yyIkju1KuhttDNBu3jsYG4uR9InVTbc kpye0mOOV6P89IPRInDzcN60gY9F/JRjO5iP/VSLGg/kxVPCM24TyhX3ID3zoYUgvmgLD0mpepP x+D369ZxsB8bHs6P3qRvlYVMGsPzI8wVsXSwlqwhbsCx3fhdbDC6dGQ/LxsFW/YiIBr9cU5tTx+ hbYxgzPPZeZS3YCEJYZzs+KRyqmjrtVZcnR5O7Hk+wwt+uB7vf03VF1g9kR1rbU= X-Google-Smtp-Source: AGHT+IFY+kcpFxFOZHPc6XkK9i/XWDOlT9N3HZYQv5GsAe8eibEW6UNlcFcker9hPQ8wlwpq6MXkgA== X-Received: by 2002:a17:902:dacc:b0:21f:7a8b:d675 with SMTP id d9443c01a7336-22bea4a1cf9mr225370105ad.4.1744704795481; Tue, 15 Apr 2025 01:13:15 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:15 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 05/17] target/riscv: Add CPU options of WorldGuard CPU extension Date: Tue, 15 Apr 2025 16:12:19 +0800 Message-Id: <20250415081231.21186-6-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::634; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x634.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org We define CPU options for WG CSR support in RISC-V CPUs which can be set by machine/device emulation. The RISC-V CSR emulation will also check this feature for emulating WG CSRs. Signed-off-by: Jim Shu --- target/riscv/cpu.c | 3 +++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/tcg/tcg-cpu.c | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 09ded6829a..a182e8c61f 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -236,6 +236,9 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair), ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync), ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps), + ISA_EXT_DATA_ENTRY(smwg, PRIV_VERSION_1_12_0, ext_smwg), + ISA_EXT_DATA_ENTRY(smwgd, PRIV_VERSION_1_12_0, ext_smwgd), + ISA_EXT_DATA_ENTRY(sswg, PRIV_VERSION_1_12_0, ext_sswg), { }, }; diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index 8a843482cc..a5b045aa2f 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -143,6 +143,9 @@ struct RISCVCPUConfig { bool ext_smmpm; bool ext_sspm; bool ext_supm; + bool ext_smwg; + bool ext_smwgd; + bool ext_sswg; bool rvv_ta_all_1s; bool rvv_ma_all_1s; bool rvv_vl_half_avl; diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 5aef9eef36..343e46e698 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -694,6 +694,17 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) cpu->cfg.ext_ssctr = false; } + /* RISC-V WorldGuard */ + if (cpu->cfg.ext_sswg && !cpu->cfg.ext_smwg) { + error_setg(errp, "Sswg extension requires Smwg extension"); + return; + } + + if (cpu->cfg.ext_smwgd != cpu->cfg.ext_sswg) { + error_setg(errp, "Smwgd/Sswg extensions should be enabled together"); + return; + } + /* * Disable isa extensions based on priv spec after we * validated and set everything we need. From patchwork Tue Apr 15 08:12:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051663 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 13C37C369AB for ; Tue, 15 Apr 2025 08:15:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bQE-0008CR-HX; Tue, 15 Apr 2025 04:13:34 -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 1u4bQA-0007y0-9o for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:31 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQ5-0001yJ-EG for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:29 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-227cf12df27so42209495ad.0 for ; Tue, 15 Apr 2025 01:13:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704802; x=1745309602; 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=nwKYDLJebV8nfrFMI0a6Dc+oBkaaAbOXeXeNO1BXXr4=; b=XEv8i/vA5KnGtlRWW+zSvY4uyu2VCSIVBF/yyW4kW7ExdPJUiLpfbzqUmEXE2ZIQrD HfMWgjd/MhyWN0libU4nBCfh37MaN9RS1lhJRiaTaZBN+GEgUUGUYrFnD8bOPDWzvGWY 2p9y8nn6QPmJlt8MoJrXbSdNNoCWfiz7FppzQo7IUeOoaG3FBOsBkdTWPZyIJkhLBZ2P I5mhirUMZ1CEXU7e6GACkLefTal/4Xar4ThoFSMSsb8CTRcsQuMcLuSLf4P56teJmQql IWnC50vm2q000smrHtUQA0HtrL07Yf5yTUwvlPE3544xdEA/bsBFx8sS65VOTz83uUJd poSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704802; x=1745309602; 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=nwKYDLJebV8nfrFMI0a6Dc+oBkaaAbOXeXeNO1BXXr4=; b=tDeuhg3ULP2ov11p4kK+dyy3ivaHxyDYasTZPcdB0f5lpQXWQb1s6lDwc/iITftPh3 CrNwzyGRMvfRi21U3pXe4B+nULuoDyY7ar0R1RaNkzYEns6j1CCMpHde1yJ3TCziTyns GqwTT9RoR6HJemfucCr2kKoDq8OMevtPYJYm06WYEcHrZAU64e4tENh1TCxYeIdn6187 kJj3LLIyBMkIBGPVFYh5iXdz0227hvljVDyi5FAwiNl6W0uC3s0+A711MEsaqI0yJ4Ul BV4ftSTWHcvLmR7f+Em0V+iQg/xa4raTKOJGxt+Fr0g8G1qIrf4DokYkBzHsGo8u+nhU HlxA== X-Gm-Message-State: AOJu0Yz/e2xjN6RtFh1MmH+WsmGyyshsKeOSUkWIeduPLwoa5wgy+rVQ G1YJK3Db490jrteJriwREtKXs9HF4KddG2y9XNR1D5qy5uFiSsewm1x+0ab5r7BACcJ0M8GNnw+ bWTOdA2XygK912VbaTx0QiGCnPcrvws9Xf+2+Yl21mJmtQT7pUkZ5NUy79Gq7J2/gIOrQSlIIuF qApmP/ropEuhgmCRNsQZ2MoKoX0huj4oLjbP5v X-Gm-Gg: ASbGncvqzlRJen7fHuehw4F1gdgs7SQ5cWtQ/GA4tJvMnOHu1cOfd/oMfJIO1Zbrecr MrkDCnEAtDsnJemLSQ5mjVT2tR7hLJ9atgBBLg9JYm5ws9oT36p0VI2fI2bJGiUR5cBx68m72fp be3/iVYfqE0ZUHN4+IZ3xYn3pMH7hSZVAruPScSURGLNEMMVSLobg1uXCS/BXd6u9yWP6KqcLRF DvqUOPg2trc3wJEQBdLFQ7Dfb/ThEIdQ49qKpzKsnzXCfVvtUBBigKBOpGBAqDGVLC5wKdAPcIs SOQcQzyqC+5KTDwr7peKbZauE7I6dp1YfK/0ZaE03XwKcRVIhed71qz8KtDQUas= X-Google-Smtp-Source: AGHT+IHhrvH9XlXhAvlkmB4dmg5rWUKj4tV7WNnPYMhXKUjnS7+SRsMCzgnSdbDAMF3pjBVcH54UxA== X-Received: by 2002:a17:902:d490:b0:226:3392:3704 with SMTP id d9443c01a7336-22c24984d71mr35601285ad.12.1744704801308; Tue, 15 Apr 2025 01:13:21 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:20 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 06/17] target/riscv: Add hard-coded CPU state of WG extension Date: Tue, 15 Apr 2025 16:12:20 +0800 Message-Id: <20250415081231.21186-7-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62c.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add hard-coded state of WG extension. 'mwid' is the M-mode WID of CPU. 'mwidlist' is the list of allowed WID value of 'mlwid' CSR. These CPU states can be set by CPU option, or can be set by machine code via newly added APIs. If we want different WG configs of CPUs, we should set it by machine code. Signed-off-by: Jim Shu --- target/riscv/cpu.h | 2 ++ target/riscv/cpu_cfg.h | 2 ++ target/riscv/cpu_helper.c | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 51e49e03de..ac50928b57 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -613,6 +613,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, void *rmw_fn_arg); RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit); +void riscv_cpu_set_wg_mwid(CPURISCVState *env, uint32_t mwid); +void riscv_cpu_set_wg_mwidlist(CPURISCVState *env, uint32_t mwidlist); #endif /* !CONFIG_USER_ONLY */ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en); diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index a5b045aa2f..86b6240989 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -196,6 +196,8 @@ struct RISCVCPUConfig { bool pmp; bool debug; bool misa_w; + uint32_t mwid; + uint32_t mwidlist; bool short_isa_string; diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index f4c4b69a3c..2c3a0d903b 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -231,6 +231,24 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +#ifndef CONFIG_USER_ONLY +void riscv_cpu_set_wg_mwid(CPURISCVState *env, uint32_t mwid) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + + cpu->cfg.mwid = mwid; +} + +void riscv_cpu_set_wg_mwidlist(CPURISCVState *env, uint32_t mwidlist) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + + cpu->cfg.mwidlist = mwidlist; +} +#endif /* CONFIG_USER_ONLY */ + RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) { #ifndef CONFIG_USER_ONLY From patchwork Tue Apr 15 08:12:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051659 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D2DA0C369AB for ; Tue, 15 Apr 2025 08:14:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bQK-0008Pl-Fl; Tue, 15 Apr 2025 04:13:41 -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 1u4bQB-00083a-U3 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:32 -0400 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQ9-0001z6-Af for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:31 -0400 Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-224341bbc1dso46532065ad.3 for ; Tue, 15 Apr 2025 01:13:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704807; x=1745309607; 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=31sA8ZoJNIVGckIUDC4jt2xxe297otB918AQ9sayA4k=; b=OVsaGVVET81oJmLFfdrhd0IamxYzr1PhdWstz5TOA5vb8HjERaApGMn8T/Pox+ki5F zK5ySesKkPLALxmw/zEIFiS0g5MAtxSTYe4GiL0tMLaks3HGGr1ANChZrSpebh0X7sMs gjDYYrKTIy/4T1TSIXJw3vdVhCS0o/fx4NzCf4Owr+120tfrel9N7uI+1FlObfbhTSvM YNlu5WFkDWaE7pykqBYLkhqCLJk9SObcZuRyyCpwwSLNz1fHuBCYjvIcBopYPvFcq+jP 6i6ipdLYwRZLffS525aEB/IY1hOqG5gOidaxKdHeMQMPfNDsBqWkAyz8SrKlhAvEqEdi /c7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704807; x=1745309607; 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=31sA8ZoJNIVGckIUDC4jt2xxe297otB918AQ9sayA4k=; b=SI1AL2k5+/fLlTjpo727Qp3nfpoqmb8NbMYdiyVJnd6rHLz6QnFl0WKv9ah60TDUR6 IP1J1jinWx91BCjQFA/VKKoOT6M3FDWZ9PcKOTOeSv9ANd9tbW75p/h173EYQU8lDifk zDxMIRJoXbgiw2La4zXTBjtKZFBntiE08JEJaYGRX2XDiArXPJ3mHY+ggs59n712Sf3s YmIqWmWVskagjIFk8pRgP2mnvadgBSIVW5N6gTg4nm6I6J4YBYwONOkOfhHET/c7mP9J bXoNB1cxooFQatLIC+AVRHHt+qrTqgGO0cc5dhO3fZwhw80Lyv+o657lz8ropDtC6p14 O9bQ== X-Gm-Message-State: AOJu0YyeTB/z2NCQvXld5i3sqKZOCXKoSBYH32MlxM/zeyGGOvBmzYPF RxKMZd/GvPIY01n9NMusJ1nDtZR3tFgb3MBO9OfGGh9w2sArSFKHIZ+bTQjS2lZWRofxynTJCMo XVBNfExWvOh5JxQ5jnDdosFWSW587oKurQhMThEI+Kpgxu6GP117JtH7CjhH8NQbXwmCRTrPTEz V/xyvaTFUChUVYaHoFLbPtEYmaNMSejoFeO6r1 X-Gm-Gg: ASbGncv0IrCEZWLkQIwHa6Xe3mdgJabERiztotdMnyVrKZ0CBz2PN0Ktla1RtIBDQ0O CsyBj3RdUQ+sf6F7gVbpRwQgq4RH9XVsVlFiVhH06W6HrO5Phd1R7j9VUxiNN00iR32p/R0S/Cj iK3MFzIm8Vw1FLONfndKV0pkZTu3iZgWMpSCNKbs8jQoPS/NsWJFhbqrt+Uns92Fp94agdl/IaB sFcC5GYq4HgB87LFb+3AXYrjKV0VH1c61QD1AzqKJpVPoguQer+XVNOok5el1TrNfSa9noxk/qY YiBlfkQkE267LEB+4VWrZF143CnrZuQqXaMo7r24WXpw0ke31SnbsBFnSgSX/Kc= X-Google-Smtp-Source: AGHT+IG1cDOvUSZkXXjAg0Xikt2bJZC7MEeIsa5oZbWEIVSLT/jrN+9koPPH1yIIfjHY2bCEAnzAxQ== X-Received: by 2002:a17:902:d550:b0:224:1ec0:8a0c with SMTP id d9443c01a7336-22bea4bd74dmr236155105ad.29.1744704806989; Tue, 15 Apr 2025 01:13:26 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:26 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 07/17] target/riscv: Add defines for WorldGuard CSRs Date: Tue, 15 Apr 2025 16:12:21 +0800 Message-Id: <20250415081231.21186-8-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::634; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x634.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add CSRs for 3 WG extensions: Smwg, Smwgd, and Sswg. Signed-off-by: Jim Shu --- target/riscv/cpu_bits.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index a30317c617..7705c6995e 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -408,6 +408,11 @@ #define CSR_DPC 0x7b1 #define CSR_DSCRATCH 0x7b2 +/* RISC-V WorldGuard */ +#define CSR_MLWID 0x390 +#define CSR_SLWID 0x190 +#define CSR_MWIDDELEG 0x748 + /* Performance Counters */ #define CSR_MHPMCOUNTER3 0xb03 #define CSR_MHPMCOUNTER4 0xb04 From patchwork Tue Apr 15 08:12:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051681 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 939CBC369B8 for ; Tue, 15 Apr 2025 08:20:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRA-0002qu-47; Tue, 15 Apr 2025 04:14:32 -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 1u4bQH-0008QJ-D6 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:38 -0400 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQE-00020s-R7 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:37 -0400 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-227c7e57da2so45835445ad.0 for ; Tue, 15 Apr 2025 01:13:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704813; x=1745309613; 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=Vz+7rJLKk52J8xcxBS8V6jPxUUQa+S+ay0i6P14+Mmc=; b=CsOnYW+9E+MbAkaWV9CNizlXk0fPPvr7lbF/H2Kn7VAHG5cCoFCHp/lX2feVI3X7ih JSzkHZEjoU44UEW2eMyGpASyDwO89qopZTUajKyccVsmfN/qGexIhpCsntCkZP/0stiG XNGI9R4oejGlPw15KdObrhEg4zSK0vGSSXtJx2Gku7ETVaob1+BRa+iDs7Vf1nBKaxkb ua8GcxWCmhTf7IPPbTRhhcbaGwqfnRrF6V1oOvgVIHTHj0uq6ic7JaDUgb+vjwZ+QRsW r8pW/o5Q73DqhOEQaqmnahtz5Y4Ajes1AqmA2Z0nG9uAzhrud84rq3vFC9TeVf4Xm8Zy +AJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704813; x=1745309613; 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=Vz+7rJLKk52J8xcxBS8V6jPxUUQa+S+ay0i6P14+Mmc=; b=GWeF1E/BOOgxS7Nxt1Py6jsGtxjtLpFgXyailmX86xalTXwGL8X4BOiWM6lzpPFVZk uJuZGavKkoX5yzUO38uoB1QrYph1+rV1BjeJQJeVqwl2ZTGqhaUiw86iQfOwnuhkke2F oknyZpJq0m9ZQByaGE7ZPvNsOZ67QROMmyksOp+xbeUEWa0/u2TjWkAgNOy3DPRUV18q BEIP3cgi8JJrWHeEC/TbiCOqHvRa/LekDfi8lQzZby9wxusRFd3GbIK6rWW954zPLWEr kMv1OlHXFCSWvyRJmnnkhGywk0FYYH5WPXl6pkWoY5qrKuwD8lSMlaE3J34W6iqLZlas Q5Zg== X-Gm-Message-State: AOJu0Yyrn6x2FF+pAfsT1TrjvVjzxSRDM7pAxQh0ONUS6RH0rb4qXSOh QGRs/HrTPt1g4DDWNjqFsK3R7UwpH8NYVwwkIm+orAwkOcyDQj9MVr8NjHGcCiIznUPQYRLyd5P 3RL5nYjoKRWI2uyF6A67ZBZXBzRAGf6eEQq62IVHUe5Bem2NZWB/nyidjauDK3/42XVpvL0B3il sVEZzyP4w3nzikEXRYltiFyHmqGG0nabWilyNC X-Gm-Gg: ASbGnctQenl/tnm1Lscq86ZjDMGFnk3fDJQBqT7gA4dioxK0ksNs0deA1z+7tpIBMDU EdemrCHENntnIz0+q3rpxU6MPSvdeKBsFRqkuW29KsFSRkalu6O+ak/3tZB/vhzUZvas7H093Nv Xsgxf/VhIadwMmwPj5S9jN3ZnX9zsXPQHslKrQACTmDtOJx6Nve67PUiU6kaZsp/U2QIDYcaUY4 FEABDcWheClC9kIJNhQaFX6VPEwFD051b2adwglMT8yltOVbu/fBXyk05fNgjTvT7upEPH580x6 Ibi3Ywzb1UQatePIitmbtCxJX1UcuUJvAZr5mgoqkrFcCaA0G9f4usjcMC3pLgA= X-Google-Smtp-Source: AGHT+IHHoPm4QQ9v0tOplwzjlpJQqhF8CoNoqXf2+aqmcGjlUFn1SmyfmdIGlkgop9tgFk3wJfZdHg== X-Received: by 2002:a17:902:f707:b0:224:2175:b0cd with SMTP id d9443c01a7336-22bea4c3baamr220686105ad.26.1744704812581; Tue, 15 Apr 2025 01:13:32 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:32 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 08/17] target/riscv: Allow global WG config to set WG CPU callbacks Date: Tue, 15 Apr 2025 16:12:22 +0800 Message-Id: <20250415081231.21186-9-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::635; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x635.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Some WG CPU functions depend on global WG config (like num-of-world), so we let the global WG config device to set callbacks of a RISC-V HART. Signed-off-by: Jim Shu --- target/riscv/cpu.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index ac50928b57..6dfc260a07 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -500,6 +500,10 @@ struct CPUArchState { target_ulong rnmip; uint64_t rnmi_irqvec; uint64_t rnmi_excpvec; + + /* machine specific WorldGuard callback */ + void (*wg_reset)(CPURISCVState *env); + void (*wid_to_mem_attrs)(MemTxAttrs *attrs, uint32_t wid); }; /* From patchwork Tue Apr 15 08:12:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051668 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B392CC369AB for ; Tue, 15 Apr 2025 08:16:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRE-0003JU-0c; Tue, 15 Apr 2025 04:14:36 -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 1u4bQU-0000h8-2U for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:59 -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 1u4bQM-00021v-It for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:45 -0400 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-227914acd20so49640895ad.1 for ; Tue, 15 Apr 2025 01:13:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704820; x=1745309620; 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=2ynf1dYmwbYGI8KiYXQBOC7joESopxPzlk7K7/NwSsw=; b=mBfQyhj2W4rUtoPHScJqJAxuiMbvmzpbFEt0MzcNYVrAxCZU4GtdLSt7PC5FqWvIZD 6bVnRVxHp4nh3cZR46FiDFlVIxEK69TxU1k7Hsbmk19o8IyiT4AAN8KF5xRw+hfGrZZZ CfgCdBCsbBc0sEKrAYhLfrHGPae8e4yOY2yJA2T8f8ODyFU3b20m4BYrUBJLos5yT1Pu dZQcHhMwgkwmU/8NFdHrSPOVba6uFh+Pb9NKfs5f4W7IVeM3osJN13c30yitu6NNaDrd XZSRvM1LQtUXYyY0FKiicVIIpANKWIa4sjDDOIuw1aZq773x4F8cqH3do20YrBVda+2o E6QA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704820; x=1745309620; 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=2ynf1dYmwbYGI8KiYXQBOC7joESopxPzlk7K7/NwSsw=; b=kCfitwLF3JEkqssTWnjoMJd+85YSoSWh45pi+SXKFe/jNHj5g4fghBuHcvvhBcOCzi oCBDECk9Z9hVbFkRct06ZyUnxIC9dWT8NwxiYzk6xP8L78dCG+3WzXLjkQfaeX2qxjpm X0BzHZ0tMsysPi1fWR7/dAnpQvIuhfgClkSZ7irKvHrntzf4wpbrd285tLajDZcV4+9S VMhneqoAwGn0TgnEngeP3x/YLpd17BtfzZcp4BGC+FyxqkbtKPmIJdFJKxUUeLR9a7Ai gQnWw3TPgVRxGpTkAkjBsdX3gUfydV9Rux8YiikYZ7Y1+5zZ8E0vYz/47zEsW3g8TAuM nqNQ== X-Gm-Message-State: AOJu0YzNfyw8xL8ydAUSJd+KzWaHfEuIEdGribdwQ6C/sf9bpwGfTlAF 0GWgrKOrRlgnONO4GHyByvaFfISFpYk6ZDuqnU8Z2QJmP+G7A19jaJzrdBAfuvKvkuJhHO/za/S n4UU+stKgposUrJxVVLZzo1/bSRE6rVSd4KpDegD2K7UGjkMF7eaPF/jABa4gR9a/w4VEhwD3kD fzxlo4h42OOH2GQfuZbDGEKixez3fZcygGtexc X-Gm-Gg: ASbGncu/uryLalSYX/+UYIkE/IrEbdTbPN32MbLWlGVWdJNbJoNYIiu5OOa6srK3xzZ UtkTyaMuvnal205tPhlLFOwyGJDmI8iyYDSGfGIL4SRWcykTgF8RoGPndIJiRhSSPkS+B5bGNPI 11x4xz1nJwYpT//EZVPki/EdMl/+ScSr/i/9MwlsZR1Ia+i/PzvkzEypCQNCDp/tqIevdCA6e5v jlOK8bDe7z7VLPTpg0PNLHTkRpmoUQvFdKejnyn1sYxA7sRDy7pu/pC6wnclvBLSe3YPstzZy3o cmGrO/GH7HIGQnp6noePZ23LY/Agg2QjpTrWnEKxvmje0sJkicaIoVMn1ud46K0= X-Google-Smtp-Source: AGHT+IGwlw+1pIMet0N5eLVT5rtEK1jCanVLMLapFehkzX4KFy3x+yK89L8pboYFgn5ElZEAiIl/vQ== X-Received: by 2002:a17:902:e94d:b0:21a:7e04:7021 with SMTP id d9443c01a7336-22c249c2952mr36994855ad.24.1744704818184; Tue, 15 Apr 2025 01:13:38 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:37 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 09/17] target/riscv: Implement WorldGuard CSRs Date: Tue, 15 Apr 2025 16:12:23 +0800 Message-Id: <20250415081231.21186-10-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> 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 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The WG v0.4 specification adds 3 CSRs to configure S/U/HS/VS-mode WIDs of CPUs in the higher privileged modes. The Smwg extension at least requires a RISC-V HART to have M/U-mode, and the Sswg/Smwgd extension at least requires a RISC-V HART to have M/S/U-mode. Signed-off-by: Jim Shu --- target/riscv/cpu.c | 4 ++ target/riscv/cpu.h | 5 +++ target/riscv/csr.c | 107 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index a182e8c61f..1dbeac0509 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1141,6 +1141,10 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type) env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false); } + if (riscv_cpu_cfg(env)->ext_smwg && env->wg_reset) { + env->wg_reset(env); + } + if (kvm_enabled()) { kvm_riscv_reset_vcpu(cpu); } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6dfc260a07..7bffe62f70 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -501,6 +501,11 @@ struct CPUArchState { uint64_t rnmi_irqvec; uint64_t rnmi_excpvec; + /* RISC-V WorldGuard */ + target_ulong mlwid; + target_ulong slwid; + target_ulong mwiddeleg; + /* machine specific WorldGuard callback */ void (*wg_reset)(CPURISCVState *env); void (*wid_to_mem_attrs)(MemTxAttrs *attrs, uint32_t wid); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 7948188356..614df37d00 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -5388,6 +5388,109 @@ static int write_mnstatus(CPURISCVState *env, int csrno, target_ulong val) return RISCV_EXCP_NONE; } +/* RISC-V Worldguard */ +static RISCVException worldguard_umode(CPURISCVState *env, int csrno) +{ + if (!riscv_cpu_cfg(env)->ext_smwg) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return umode(env, csrno); +} + +static RISCVException worldguard_sumode(CPURISCVState *env, int csrno) +{ + RISCVException ret; + + if (!riscv_cpu_cfg(env)->ext_sswg) { + return RISCV_EXCP_ILLEGAL_INST; + } + + ret = smode(env, csrno); + + if (ret != RISCV_EXCP_NONE) { + return ret; + } + + return umode(env, csrno); +} + +static RISCVException rmw_mlwid(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + target_ulong new_mlwid = (env->mlwid & ~wr_mask) | (new_val & wr_mask); + + if (ret_val) { + *ret_val = env->mlwid; + } + + g_assert(cpu->cfg.mwidlist); + if (!(BIT(new_mlwid) & cpu->cfg.mwidlist)) { + /* Set WID to lowest legal value if writing illegal value (WARL) */ + new_mlwid = find_first_bit((unsigned long *)&cpu->cfg.mwidlist, 32); + } + + if (env->mlwid != new_mlwid) { + env->mlwid = new_mlwid; + tlb_flush(cs); + } + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_slwid(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + target_ulong new_slwid = (env->slwid & ~wr_mask) | (new_val & wr_mask); + + if (!env->mwiddeleg) { + /* + * When mwiddeleg CSR is zero, access to slwid raises an illegal + * instruction exception. + */ + return RISCV_EXCP_ILLEGAL_INST; + } + + if (ret_val) { + *ret_val = env->slwid; + } + + if (!(BIT(new_slwid) & env->mwiddeleg)) { + /* Set WID to lowest legal value if writing illegal value (WARL) */ + new_slwid = find_first_bit( + (unsigned long *)&env->mwiddeleg, TARGET_LONG_BITS); + } + + if (env->slwid != new_slwid) { + env->slwid = new_slwid; + tlb_flush(env_cpu(env)); + } + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_mwiddeleg(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + + if (ret_val) { + *ret_val = env->mwiddeleg; + } + + env->mwiddeleg = (env->mwiddeleg & ~wr_mask) | (new_val & wr_mask); + + /* Core wgMarker can only have WID value in mwidlist. */ + env->mwiddeleg &= cpu->cfg.mwidlist; + + return RISCV_EXCP_NONE; +} #endif /* Crypto Extension */ @@ -6465,5 +6568,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_SCOUNTOVF] = { "scountovf", sscofpmf, read_scountovf, .min_priv_ver = PRIV_VERSION_1_12_0 }, + /* RISC-V WorldGuard */ + [CSR_MLWID] = { "mlwid", worldguard_umode, NULL, NULL, rmw_mlwid }, + [CSR_SLWID] = { "slwid", worldguard_sumode, NULL, NULL, rmw_slwid }, + [CSR_MWIDDELEG] = { "mwiddeleg", worldguard_sumode, NULL, NULL, rmw_mwiddeleg }, #endif /* !CONFIG_USER_ONLY */ }; From patchwork Tue Apr 15 08:12:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051664 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F13AAC369AB for ; Tue, 15 Apr 2025 08:15:59 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRF-0003SQ-Bc; Tue, 15 Apr 2025 04:14:37 -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 1u4bQo-0001dJ-B7 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:18 -0400 Received: from mail-pl1-x62e.google.com ([2607:f8b0:4864:20::62e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQT-00022W-PP for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:13:53 -0400 Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-224191d92e4so50379155ad.3 for ; Tue, 15 Apr 2025 01:13:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704824; x=1745309624; 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=byOo/KqqWXeR72ANJUzCRKebW2bLJp2ySZr8t52WqcA=; b=PezG+Q5z+ZJDIykrAzAVlQ0v7qYFBpKpACr/yHrq33MDgu0s8HFPj771YwShVL6s0Z ONcY2F38Tdh4dPjlii1IaKEOH+/vZUP/E6rsW2YDRDnTViYSAOJ0K8PR26spgK3HuZDQ vkxMHn9SsOYcEgDR1m+15Cyflq7uaF0qi7qblgNOA+nrwnZCU/vJGg8uBfhKcRGjdPwX pn7j8T6j0h1kOr/z0hG2H0ifLH9PzpjvP+2skqaEWncVXShJYW/Zy5t2k+L9H+LCqrDi cUrO0FbATbVqGSBVUa6srjiCyQviOJW4lMPK150Ind4dZQPPWs/5UFIghOq5/ZKGlKUJ Ikmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704824; x=1745309624; 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=byOo/KqqWXeR72ANJUzCRKebW2bLJp2ySZr8t52WqcA=; b=LHNQeOqASAFJK6kR8cP8HXeYOGTYcD+LjJjVix5NAwYzUlEnPp/iLkVFe1e2rOJu/C ZZs39ee+d0uueT5LE7kZWAYrbuLpK6umF+lfUsFrlZnorpB6OMTOGALMoUHO54rUfzWW Y8VrxEr7imA0RAFEaKx9eNibJCl2AY6OISs/rmq90Tb4VKxWoTdxMniSmQrTAdiiNFeV kW7+dTTStVDuQxxvtpNMTlaHOVrvQBcyyO5Flw5b5/kefIW/ODZNU8VZNKCHlqVV6ZSN MrJrTdSfyT2tUSmL2tykUjcxP/yGkDED3UThrWkHNAUXV74m4fwhZj+uCmx6IaYSLgjc yDRA== X-Gm-Message-State: AOJu0Yw8K06C56W71fP3hxPtJmdQBJ8ykYYOv6ZxPD4sWdWFmL2QjWMM o6hk0AnfuqayHg4Ol8AKZLTpW5y4UT/KpiEc+UbufEf5HeNW+JxZwbBV9Vt/73UswVUXVG2DYSR OWrP9k5727GWQXPINEDzbuiKUEeIzY3gPAJUr/qm3gtvKtASusvavHl98l6XbNVNkDThCe3u/zy NsVwCX07msEyfEUmBjriOLsm6yeqv1vXVYaUil X-Gm-Gg: ASbGncvhXhiIdexeKAgqcw+bibpwtt0sUceW4zqw8VJDvfUhusdv3Dmu24tqWGaGWcj yOWos2VFBSBskZVgxQ0g6IqhTWige3Ns+EkVRhZGN5MEANF9upABQ4mA0ATsbPsANlUlzVhber9 mbBDrz7unEFt4uyvh6UsE+teq74u+Py1GC8yQQXWlkEYoFdCfaniSrlSZN2pf8edvk1qi03fZjb ywo431icM6UKAscFhpcdRntIZmbKmWSjxDok3q3AwMpZdFQ2XE8G2Mx/oT/AE/Yry6rcBlHrSZv y9Gf1ANffo2tLBeelzJut0WKHQiICQfXbqg4s5AlWS62AdUzb9if6pHk1Nx1Nuqgd0XDAycfHA= = X-Google-Smtp-Source: AGHT+IGyx8GvBTfmVgXY2piG+6l11HV9bx2iR0uLFsFb3SZqWdv2RIXzDpAZu8eh+htZungiwJ98jw== X-Received: by 2002:a17:903:3c6d:b0:224:a74:28c2 with SMTP id d9443c01a7336-22bea4c3e94mr246673185ad.29.1744704823797; Tue, 15 Apr 2025 01:13:43 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:43 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 10/17] target/riscv: Add WID to MemTxAttrs of CPU memory transactions Date: Tue, 15 Apr 2025 16:12:24 +0800 Message-Id: <20250415081231.21186-11-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62e; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62e.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org When a RISC-V HART has WG extension, their memory transactions will contain WID. Support MemTxAttrs in RISC-V target and add WID inside if a HART has WG extension. Signed-off-by: Jim Shu --- target/riscv/cpu.c | 2 +- target/riscv/cpu.h | 1 + target/riscv/cpu_helper.c | 51 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1dbeac0509..1aba6dd853 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -3035,7 +3035,7 @@ static int64_t riscv_get_arch_id(CPUState *cs) static const struct SysemuCPUOps riscv_sysemu_ops = { .has_work = riscv_cpu_has_work, - .get_phys_page_debug = riscv_cpu_get_phys_page_debug, + .get_phys_page_attrs_debug = riscv_cpu_get_phys_page_attrs_debug, .write_elf64_note = riscv_cpu_write_elf64_note, .write_elf32_note = riscv_cpu_write_elf32_note, .legacy_vmsd = &vmstate_riscv_cpu, diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 7bffe62f70..1fdeee7708 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -584,6 +584,7 @@ int riscv_env_mmu_index(CPURISCVState *env, bool ifetch); bool cpu_get_fcfien(CPURISCVState *env); bool cpu_get_bcfien(CPURISCVState *env); bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt); +hwaddr riscv_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, MemTxAttrs *attrs); G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 2c3a0d903b..944a5b7ee1 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -232,6 +232,34 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, } #ifndef CONFIG_USER_ONLY +static uint32_t riscv_cpu_wg_get_wid(CPURISCVState *env, int mode) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + bool virt = env->virt_enabled; + + if (mode == PRV_M) { + return cpu->cfg.mwid; + } else if (mode == PRV_S) { + if (!virt || !env->mwiddeleg) { + /* HS-mode, S-mode w/o RVH, or VS-mode but mwiddeleg = 0 */ + return env->mlwid; + } else { + /* VS-mode */ + return env->slwid; + } + } else if (mode == PRV_U) { + if (!riscv_has_ext(env, RVS) || !env->mwiddeleg) { + /* M/U mode CPU or mwiddeleg = 0 */ + return env->mlwid; + } else { + return env->slwid; + } + } + + return cpu->cfg.mwid; +} + void riscv_cpu_set_wg_mwid(CPURISCVState *env, uint32_t mwid) { CPUState *cs = env_cpu(env); @@ -1768,13 +1796,22 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address, env->two_stage_indirect_lookup = two_stage_indirect; } -hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) +hwaddr riscv_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, MemTxAttrs *attrs) { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; hwaddr phys_addr; int prot; int mmu_idx = riscv_env_mmu_index(&cpu->env, false); + int mode = mmuidx_priv(mmu_idx); + uint32_t wid; + + if (riscv_cpu_cfg(env)->ext_smwg && env->wid_to_mem_attrs) { + wid = riscv_cpu_wg_get_wid(env, mode); + env->wid_to_mem_attrs(attrs, wid); + } else { + *attrs = MEMTXATTRS_UNSPECIFIED; + } if (get_physical_address(env, &phys_addr, &prot, addr, NULL, 0, mmu_idx, true, env->virt_enabled, true, false)) { @@ -1886,12 +1923,20 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, int mode = mmuidx_priv(mmu_idx); /* default TLB page size */ hwaddr tlb_size = TARGET_PAGE_SIZE; + uint32_t wid; + MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; env->guest_phys_fault_addr = 0; qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n", __func__, address, access_type, mmu_idx); + if (riscv_cpu_cfg(env)->ext_smwg && env->wid_to_mem_attrs) { + mode = mmuidx_priv(mmu_idx); + wid = riscv_cpu_wg_get_wid(env, mode); + env->wid_to_mem_attrs(&attrs, wid); + } + pmu_tlb_fill_incr_ctr(cpu, access_type); if (two_stage_lookup) { /* Two stage lookup */ @@ -1984,8 +2029,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } if (ret == TRANSLATE_SUCCESS) { - tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1), - prot, access_type, mmu_idx, tlb_size); + tlb_set_page_with_attrs(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1), + attrs, prot, access_type, mmu_idx, tlb_size); return true; } else if (probe) { return false; From patchwork Tue Apr 15 08:12:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051679 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 86344C369B8 for ; Tue, 15 Apr 2025 08:19:51 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRL-00043o-J3; Tue, 15 Apr 2025 04:14:43 -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 1u4bQq-0001j1-Au for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:19 -0400 Received: from mail-pl1-x632.google.com ([2607:f8b0:4864:20::632]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQm-00023E-Ko for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:11 -0400 Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-2279915e06eso55495275ad.1 for ; Tue, 15 Apr 2025 01:13:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704829; x=1745309629; 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=vQTsKrAn76+UasM8uqjd/nLkuCgMzLsX/xbV+gpdXKA=; b=Aev5kIMeBJjGbd9x5xnKZs6vbe9+zv8id7sa3gu5sI/5NtxkoqC56FNDWyb+rUkKHG CtaBBKTsSsQ2uvYtwKr6UdxLw87n3cWYuRpP+jAw+FE+xVfWorx5POi6xG4hkhDgC4L9 y8dvJ94lcXkyr+ozF5vQ8USPwAgx3TXs3gWqFG7pPjYCmUA8zHtb2nGjPTF+Z+SCYJfA Vk95kQpxS8uajGpnpF4bB9XV0YoBL7mPM/9eFfLCpZ8BSzsfqZi0NeJtf1idyLvEn7Mr w2/OvLTTD/0nE2OlloKNTi1oaQka729+KIyVUl5ZcaUq2olbZiKj2RMmT6HPf9mTMPZ8 Ks7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704829; x=1745309629; 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=vQTsKrAn76+UasM8uqjd/nLkuCgMzLsX/xbV+gpdXKA=; b=Q2fs5JqlB0gku6LZ/vm3c2N5DZUMVw2OBPbWzMHkL3xXmFOebjsItC2Mpu1DSBixJ5 w+zlP/NF2Mp6fcpsG2+exaKm9avsrh2y5HK4c299b/UzOjCynKk63QCURFQuJqFXgux4 iKFtWv6TnZByXTfXI4++cAuCpVUkOlaSWiqDxyDW3/nXREChJy/vjxNoJ1CCeyDOWatw rvwQpm1gy4ZEZpJHHkUtE+9A5olioiy4fpm48rLflLyjXjDoZAIg46toliNI42jsuNNB lmo0wOHwvNwGIfxaAuNydnYSqV9pjcoDpEfYLqRqeqewjjX+MKPLVM/5m5BhoNu8d6x/ Oe4Q== X-Gm-Message-State: AOJu0YwaLSFZ8s2xiwuyBKgi+3Jlp3N+iJF8vQCNHcx/6h6kYOwIhHVs ZB7/oaAyLvmto5EkeTknhj0L6x1iXT2XFK+3x/ydoAsKOc5k9mgKpyJ4BRQJ88E79Qy5PGLK5Pb eLg1NczwWtIKNZo6lXHQ7CEmm3nv3KUaVOSWd9CtQhOAt8Nnls0YbTNwzduAarNtdFuyu0smaoA oE1RxiYgw23I/aNEabOJXarXnyIIOZFDgJiA== X-Gm-Gg: ASbGncuAy7MF55WAPMeksaFydC/Ns43xc+KItuV8e6Txld9q7TT4GtIHuSIUy7hD6dY 8JlZPKAarCJjCdpQWeLSnnTgmf7DTp61mCkE8Jxf+Kg30VhKMO2soMq1I6uA2lomydE3G7iPbq2 BtmAmRfOPIS3GKf/rjvhL9EYZ8rZy7kCzDbS5mUqelsVi+6AycJAaZasyZ1qiSExBgsI1McgUd0 69bPYp5mTUL1K+OyxV1/nafh1ACEAo+xVEI03mmEFsdAv2Ctkh+Cx69Co81xDjCjPNoUfRwY+Q4 C54RQm1FprUuJj1ab7KiGHT0cWZxAPZwmD+ICPWqqBOw0zQikxFmtczvs1hu/V9WcgDh9XVIpw= = X-Google-Smtp-Source: AGHT+IHSKmtUmM0cx77bUlNhCVJTM5OCuq0sLiB+4Qtfpk2UnOWoC52+bpicZUzaIloz0hmGRdKKXQ== X-Received: by 2002:a17:903:120b:b0:223:619e:71e9 with SMTP id d9443c01a7336-22bea4958ffmr199862585ad.11.1744704829434; Tue, 15 Apr 2025 01:13:49 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:48 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 11/17] target/riscv: Expose CPU options of WorldGuard Date: Tue, 15 Apr 2025 16:12:25 +0800 Message-Id: <20250415081231.21186-12-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::632; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x632.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=ham 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Expose WG CPU extensions (Smwg, Sswg, Smwgd) and WG CPU configs (mwid, mwidlist). Signed-off-by: Jim Shu --- target/riscv/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 1aba6dd853..46df970fe3 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1742,6 +1742,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = { const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { MULTI_EXT_CFG_BOOL("x-svukte", ext_svukte, false), + /* RISC-V WorldGuard v0.4 */ + MULTI_EXT_CFG_BOOL("x-smwg", ext_smwg, false), + MULTI_EXT_CFG_BOOL("x-smwgd", ext_smwgd, false), + MULTI_EXT_CFG_BOOL("x-sswg", ext_sswg, false), + { }, }; @@ -2975,6 +2980,9 @@ static const Property riscv_cpu_properties[] = { * it with -x and default to 'false'. */ DEFINE_PROP_BOOL("x-misa-w", RISCVCPU, cfg.misa_w, false), + + DEFINE_PROP_UINT32("x-mwid", RISCVCPU, cfg.mwid, UINT32_MAX), + DEFINE_PROP_UINT32("x-mwidlist", RISCVCPU, cfg.mwidlist, UINT32_MAX), }; #if defined(TARGET_RISCV64) From patchwork Tue Apr 15 08:12:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051670 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CC770C369B8 for ; Tue, 15 Apr 2025 08:16:50 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRK-0003zK-Ff; Tue, 15 Apr 2025 04:14: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 1u4bQx-00020C-3e for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:20 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQo-00023n-64 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:14 -0400 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-30155bbbed9so4113481a91.1 for ; Tue, 15 Apr 2025 01:13:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704835; x=1745309635; 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=wmWgl0GHsRaxiJyu5Hk62jxV2+HXDxpJgBZBEMvOZO8=; b=iXLYWzA6792SY49MRyEfTec2A3kfaXFNsS6d2Hu5rzlB+gqS7uurrtV86ufDOhH3Js QB9ErESFWZqCx/uICqRJLh9wewtmoBgMI/eZkagFsdxBnsjDjU6tGUK99OmDJeKgt4xS +QQbYx4/BR1PSYEri5CWXoz+Wk4AbV4bwzLaaKhemPHmvxNovfIhQIwdaBBXkAiO31nZ 3Ge/h6OMX8ZIs3SmrKg3FnlRIKAAVaEKI4QjFPhMMJSE6OZUYEwpsUyKLFScbt6vaLOE 5tlevSL8baVTDNgg+vEwHiq2k5Z9tiKKarHOD3LZol4Nv/xmxvhbfYslLKCUXgL5rdox fqZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704835; x=1745309635; 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=wmWgl0GHsRaxiJyu5Hk62jxV2+HXDxpJgBZBEMvOZO8=; b=QTD4R716pyvEabp4pizK+3tBZq7gkX9KjdMj5NGHijLiVgs/EpbEAvIMIX/FLkfKNp ZPBpdNhXXGipDwxf3FU9QvsxTnoce7F1fdv8nu4VFTE4hIxuJQP/8SjnX9/kUJvUXN7k 9RA8LlWVE3PjrI2XpPok9niAAPEQwKtIvp7FlZ+x4ofX9jZn/oT51eUuOjsDMGLwBqFb ZLPdmUlM5X+WZRxDI1505qfO1wuypC9WW0a9X7EGpgOUh6MV1OprDOp8VdijgXEXiW3j UG3Zy5byWBGoBgHWczLvsB2ikwmRb0G7t7D8AT6+bycSzrrfZWKXazLtuBdJlIrAOC5d N+pg== X-Gm-Message-State: AOJu0Yz+oDsWCx0HCFbR+6kpe8ljmhkpxoa4TiBf2iNEQQSxsPxuiDN4 kRxhOTrmxaQEgYqGELyjsCt1RDbTZNzujFaJtAWbSWkMgdR8uuBOLHojVDq4MU3n+8bp2Wa1CDd s6PUrfQyQqQCR0vRGRNyRIwPY23aB0Jl00M+JP4S1yC6cDHSkPc5IbYCKTFglCb3PSZqwShNx1k wHFKMlHBhhZkXUQGDQP5r73gImhzPyDkEkmQ== X-Gm-Gg: ASbGnct9DGOCjj97a30+hPOuG/shVxxRSeuVI1n9r4/KfSnbwpDK7ffNhRx3dPxf6u8 vmGzCjgxNkgqxQrMnMGo59MsRhtDA+jP5NW6K1M5LsMC93Q9XIVI8CFaA+9oVL/x/jg0CRoB6/f wsYtROplSp8MUlfC49FOSF1c3tH8Mw3CAVLtfNUU+aMxS5McgDX9hMd3HZ3iBnZS6VrS6WWEWny YCyMA7oqQ2HAO9vVFhtp+7FlhwVUO/O/+3C1KrtJsE2v5JwtZKC3TvUs7/mZOhavtX6XX7/Ng+T U0P1X3jXqGac8uK8UjyQ32SRqpRGFqxd8HdOgYYlsceHUnGEJ8Hk4+X3zQkfILI= X-Google-Smtp-Source: AGHT+IHSpqT4tx13aUU5XeEODDNE5dFjkjHSEONowjSmSoGirw4UK9mUPEpqy1GqDoWIotSmwM7oHA== X-Received: by 2002:a17:90b:5407:b0:2fe:99cf:f579 with SMTP id 98e67ed59e1d1-3082366038bmr22498415a91.4.1744704835012; Tue, 15 Apr 2025 01:13:55 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:13:54 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 12/17] hw/misc: riscv_worldguard: Add API to enable WG extension of CPU Date: Tue, 15 Apr 2025 16:12:26 +0800 Message-Id: <20250415081231.21186-13-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=jim.shu@sifive.com; helo=mail-pj1-x1033.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org riscv_worldguard_apply_cpu() could enable WG CPU extension and set WG callback to CPUs. It is used by machine code after realizing global WG device. Signed-off-by: Jim Shu --- hw/misc/riscv_worldguard.c | 87 ++++++++++++++++++++++++++++++ include/hw/misc/riscv_worldguard.h | 1 + 2 files changed, 88 insertions(+) diff --git a/hw/misc/riscv_worldguard.c b/hw/misc/riscv_worldguard.c index b02bd28d02..1a910f4cf3 100644 --- a/hw/misc/riscv_worldguard.c +++ b/hw/misc/riscv_worldguard.c @@ -92,6 +92,93 @@ uint32_t mem_attrs_to_wid(MemTxAttrs attrs) } } +static void riscv_cpu_wg_reset(CPURISCVState *env) +{ + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + uint32_t mlwid, slwid, mwiddeleg; + uint32_t trustedwid; + + if (!riscv_cpu_cfg(env)->ext_smwg) { + return; + } + + if (worldguard_config == NULL) { + /* + * Note: This reset is dummy now and WG CSRs will be reset again + * after worldguard_config is realized. + */ + return; + } + + trustedwid = worldguard_config->trustedwid; + if (trustedwid == NO_TRUSTEDWID) { + trustedwid = worldguard_config->nworlds - 1; + } + + /* Reset mlwid, slwid, mwiddeleg CSRs */ + if (worldguard_config->hw_bypass) { + /* HW bypass mode */ + mlwid = trustedwid; + } else { + mlwid = 0; + } + slwid = 0; + mwiddeleg = 0; + + env->mlwid = mlwid; + if (riscv_cpu_cfg(env)->ext_sswg) { + env->slwid = slwid; + env->mwiddeleg = mwiddeleg; + } + + /* Check mwid, mwidlist config */ + if (worldguard_config != NULL) { + uint32_t valid_widlist = MAKE_64BIT_MASK(0, worldguard_config->nworlds); + + /* CPU use default mwid / mwidlist config if not set */ + if (cpu->cfg.mwidlist == UINT32_MAX) { + /* mwidlist contains all WIDs */ + cpu->cfg.mwidlist = valid_widlist; + } + if (cpu->cfg.mwid == UINT32_MAX) { + cpu->cfg.mwid = trustedwid; + } + + /* Check if mwid/mwidlist HW config is valid in NWorld. */ + g_assert((cpu->cfg.mwidlist & ~valid_widlist) == 0); + g_assert(cpu->cfg.mwid < worldguard_config->nworlds); + } +} + +/* + * riscv_worldguard_apply_cpu - Enable WG extension of CPU + * + * Note: This API should be used after global WG device is created + * (riscv_worldguard_realize()). + */ +void riscv_worldguard_apply_cpu(uint32_t hartid) +{ + /* WG global config should exist */ + g_assert(worldguard_config); + + CPUState *cpu = qemu_get_cpu(hartid); + RISCVCPU *rcpu = RISCV_CPU(cpu); + CPURISCVState *env = cpu ? cpu_env(cpu) : NULL; + + rcpu->cfg.ext_smwg = true; + if (riscv_has_ext(env, RVS) && riscv_has_ext(env, RVU)) { + rcpu->cfg.ext_sswg = true; + } + + /* Set machine specific WorldGuard callback */ + env->wg_reset = riscv_cpu_wg_reset; + env->wid_to_mem_attrs = wid_to_mem_attrs; + + /* Reset WG CSRs in CPU */ + env->wg_reset(env); +} + bool could_access_wgblocks(MemTxAttrs attrs, const char *wgblock) { uint32_t wid = mem_attrs_to_wid(attrs); diff --git a/include/hw/misc/riscv_worldguard.h b/include/hw/misc/riscv_worldguard.h index 8a533a0517..211a72e438 100644 --- a/include/hw/misc/riscv_worldguard.h +++ b/include/hw/misc/riscv_worldguard.h @@ -48,6 +48,7 @@ extern struct RISCVWorldGuardState *worldguard_config; DeviceState *riscv_worldguard_create(uint32_t nworlds, uint32_t trustedwid, bool hw_bypass, bool tz_compat); +void riscv_worldguard_apply_cpu(uint32_t hartid); uint32_t mem_attrs_to_wid(MemTxAttrs attrs); bool could_access_wgblocks(MemTxAttrs attrs, const char *wgblock); From patchwork Tue Apr 15 08:12:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051678 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F108CC369B9 for ; Tue, 15 Apr 2025 08:19:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRh-00060V-LU; Tue, 15 Apr 2025 04:15:05 -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 1u4bQx-0001zx-3E for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:20 -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 1u4bQo-000248-5F for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:16 -0400 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-22409077c06so68619745ad.1 for ; Tue, 15 Apr 2025 01:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704841; x=1745309641; 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=tIJ3izDwhM7rqWWbObHdV4Xt43nkxUxukpA0UtZRKQU=; b=PekJSOfMd/kyLB8Q3m2sU8/8eGidVs5ihCYBHWC156oN6Wopotcb4Ya5kAxkNO3KGH KUDgwITVFjooYxXfcjjoWoRzCfB9gpShORctjwmLwB2xgrRoXrk8K2F3xt8Fny/LZ6GQ RkxqDBPFZAxg26gxEIvCYGmAr/6WhjFO9aeybe/tbbEyzKH2CP+fapexo7xDItQ4/CjN 9amk7r8epV3o3I8GN0k4zA5wc8LT+NcvNEwHitsdyYse12tc72/WqG23kaRoRuvveICr z43t1WzHmUzVasHDEQEY1cNiAUtUawicC7++sGU9G0/GHLncVwpyVoKX39IS6++N1R6t RXMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704841; x=1745309641; 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=tIJ3izDwhM7rqWWbObHdV4Xt43nkxUxukpA0UtZRKQU=; b=uTCuFhrnQaEqD+K5G0iwV3+hg1ORudvdunp7Khjnwd7Xh1K9627//80DU/u+D3FzmL T7WRVEV+HQ0OPUYm9BkkIe+2w7QLdUlFf+hIh8371VvEVGwLHulCUWuW53aI9ppK1VmN L5tB6dmghEYBEBieBb+NK1mOcegMlAmY/J2kKafN1I+GoxPfqClHdq3QAQj95FP6Z0FJ 6OlHnzCZCLtHAgbXktE8aB4zWHPq/GNvDGGiOEZA3a72c6oOaEojLiV9TPF1TtNIIi9f J62KyMWCOFomTSmZc0VS+/qCJTtKHgetgZzHjbOCTQGxjjNZ8w/udPKXm+vv1r5LkmXo UViQ== X-Gm-Message-State: AOJu0YxMsam8F1FGU4Dr1Vd3NNSZsubxrprRnQ3jY+zd/UHfTpG5icnP FLOWc53tZRGujKXb4KwLN7ueNjZEzxjYveaVLVoQV5QdMTgS8b8mbKm3MBAxXFl2FTvLqlq9oUy +u+dfwHpiSlqmk9Y1jFYQdMb5tL53md3AnxqctJxsGlLlKmrFjpux4qfYMFDfcgTtDSqCZW84LY 5kP/mnUviGA7sjAGzwJqqjoH8NJXIDRBJ4Mw== X-Gm-Gg: ASbGncsIr0OL621hg9ijSmLolS1UziTTPq1kchJyUjinAC1i5Z9FW1gKXwfIul3fRff R1bu9EYtRq4JqVRs8jhXviSNGaidGWsCbaU8BWHsskuk6edqVJBupWT1H5Snqx2o5zjW7DVhj9n EdruAysXd42U7h1VWqgMO9ppT0rz0fNee/hfGzVNr0QTBud7WV+GjHgHDoXhymV7ldWnSL3AnZi 5VP8nLbgnOzc/JUBXWprZZvt4Y8MY5+HTggz8ZGsALkg7tXbDnG4hvK95k2HOFfAh0aCuiFbBg0 IIOUjdhEXJ+F39EclZPvkmUi1NX7m+9SW5DrYWBdXZCTZIf8XyrtlcW8Hx7WXgs= X-Google-Smtp-Source: AGHT+IG425OyFrl53O+meDfAi876+qS9LMFgjuJjRzBY5VT4OuYk4d3zjDoEmsc6f/h1ub98M3DaNg== X-Received: by 2002:a17:903:244d:b0:223:8256:533d with SMTP id d9443c01a7336-22bea4fdffdmr201958115ad.46.1744704840690; Tue, 15 Apr 2025 01:14:00 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.13.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:14:00 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 13/17] hw/misc: riscv_wgchecker: Implement RISC-V WorldGuard Checker Date: Tue, 15 Apr 2025 16:12:27 +0800 Message-Id: <20250415081231.21186-14-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> 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 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Implement the RISC-V WorldGuard Checker, which sits in front of RAM or device MMIO and allow software to configure it to either pass through or reject transactions. We implement the wgChecker as a QEMU IOMMU, which will direct transactions either through to the devices and memory behind it or to a special "never works" AddressSpace if they are blocked. This initial commit implements the skeleton of the device: * it always permits accesses * it doesn't implement wgChecker's slot registers * it doesn't implement the interrupt or other behaviour for blocked transactions Signed-off-by: Jim Shu --- hw/misc/meson.build | 2 +- hw/misc/riscv_wgchecker.c | 603 +++++++++++++++++++++++++++++ hw/misc/trace-events | 8 + include/hw/misc/riscv_worldguard.h | 63 +++ 4 files changed, 675 insertions(+), 1 deletion(-) create mode 100644 hw/misc/riscv_wgchecker.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 3d2f4bb6a3..73c11bc7c9 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -34,7 +34,7 @@ system_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: files('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_worldguard.c')) +specific_ss.add(when: 'CONFIG_RISCV_WORLDGUARD', if_true: files('riscv_worldguard.c', 'riscv_wgchecker.c')) subdir('macio') diff --git a/hw/misc/riscv_wgchecker.c b/hw/misc/riscv_wgchecker.c new file mode 100644 index 0000000000..ea50f4f53a --- /dev/null +++ b/hw/misc/riscv_wgchecker.c @@ -0,0 +1,603 @@ +/* + * RISC-V WorldGuard Checker Device + * + * Copyright (c) 2022 SiFive, Inc. + * + * This provides WorldGuard Checker model. + * + * 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 for + * 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 "exec/exec-all.h" +#include "hw/irq.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 "target/riscv/cpu.h" +#include "trace.h" + +/* Common */ +REG32(VENDOR, 0x000) +REG32(IMPID, 0x004) + +/* wgChecker */ +REG32(NSLOTS, 0x008) +REG64(ERRCAUSE, 0x010) + FIELD(ERRCAUSE, WID, 0, 8) + FIELD(ERRCAUSE, R, 8, 1) + FIELD(ERRCAUSE, W, 9, 1) + FIELD(ERRCAUSE, BE, 62, 1) + FIELD(ERRCAUSE, IP, 63, 1) + +#define ERRCAUSE_MASK \ + (R_ERRCAUSE_WID_MASK | \ + R_ERRCAUSE_R_MASK | \ + R_ERRCAUSE_W_MASK | \ + R_ERRCAUSE_BE_MASK | \ + R_ERRCAUSE_IP_MASK) + +REG64(ERRADDR, 0x018) + +/* + * Accesses only reach these read and write functions if the wgChecker + * is blocking them; non-blocked accesses go directly to the downstream + * memory region without passing through this code. + */ +static MemTxResult riscv_wgc_mem_blocked_read(void *opaque, hwaddr addr, + uint64_t *pdata, + unsigned size, MemTxAttrs attrs) +{ + uint32_t wid = mem_attrs_to_wid(attrs); + + trace_riscv_wgc_mem_blocked_read(addr, size, wid); + + *pdata = 0; + return MEMTX_OK; +} + +static MemTxResult riscv_wgc_mem_blocked_write(void *opaque, hwaddr addr, + uint64_t value, + unsigned size, MemTxAttrs attrs) +{ + uint32_t wid = mem_attrs_to_wid(attrs); + + trace_riscv_wgc_mem_blocked_write(addr, value, size, wid); + + return MEMTX_OK; +} + +static const MemoryRegionOps riscv_wgc_mem_blocked_ops = { + .read_with_attrs = riscv_wgc_mem_blocked_read, + .write_with_attrs = riscv_wgc_mem_blocked_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid.min_access_size = 1, + .valid.max_access_size = 8, + .impl.min_access_size = 1, + .impl.max_access_size = 8, +}; + +static IOMMUTLBEntry riscv_wgc_translate(IOMMUMemoryRegion *iommu, + hwaddr addr, IOMMUAccessFlags flags, + int iommu_idx) +{ + WgCheckerRegion *region = container_of(iommu, WgCheckerRegion, upstream); + RISCVWgCheckerState *s = RISCV_WGCHECKER(region->wgchecker); + hwaddr phys_addr; + uint64_t region_size; + + IOMMUTLBEntry ret = { + .iova = addr & ~WG_ALIGNED_MASK, + .translated_addr = addr & ~WG_ALIGNED_MASK, + .addr_mask = WG_ALIGNED_MASK, + .perm = IOMMU_RW, + }; + + /* addr shouldn't exceed region size of down/upstream. */ + region_size = memory_region_size(region->downstream); + g_assert(addr < region_size); + + /* + * Look at the wgChecker configuration for this address, and + * return a TLB entry directing the transaction at either + * downstream_as or blocked_io_as, as appropriate. + * For the moment, always permit accesses. + */ + + /* Use physical address instead of offset */ + phys_addr = addr + region->region_offset; + + is_success = true; + + trace_riscv_wgc_translate(phys_addr, flags, + iommu_idx, is_success ? "pass" : "block"); + + ret.target_as = is_success ? ®ion->downstream_as : ®ion->blocked_io_as; + return ret; +} + +static int riscv_wgc_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attrs) +{ + return mem_attrs_to_wid(attrs); +} + +static int riscv_wgc_num_indexes(IOMMUMemoryRegion *iommu) +{ + return worldguard_config->nworlds; +} + +static uint64_t riscv_wgchecker_readq(void *opaque, hwaddr addr) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + uint64_t val = 0; + + switch (addr) { + case A_ERRCAUSE: + val = s->errcause & ERRCAUSE_MASK; + break; + case A_ERRADDR: + val = s->erraddr; + break; + case A_NSLOTS: + val = s->slot_count; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 8); + break; + } + + return val; +} + +static uint64_t riscv_wgchecker_readl(void *opaque, hwaddr addr) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + uint64_t val = 0; + + switch (addr) { + case A_VENDOR: + val = 0; + break; + case A_IMPID: + val = 0; + break; + case A_NSLOTS: + val = extract64(s->slot_count, 0, 32); + break; + case A_NSLOTS + 4: + val = extract64(s->slot_count, 0, 32); + break; + case A_ERRCAUSE: + val = s->errcause & ERRCAUSE_MASK; + val = extract64(val, 0, 32); + break; + case A_ERRCAUSE + 4: + val = s->errcause & ERRCAUSE_MASK; + val = extract64(val, 32, 32); + break; + case A_ERRADDR: + val = extract64(s->erraddr, 0, 32); + break; + case A_ERRADDR + 4: + val = extract64(s->erraddr, 32, 32); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 4); + break; + } + + return val; +} + +static uint64_t riscv_wgchecker_read(void *opaque, hwaddr addr, unsigned size) +{ + uint64_t val = 0; + + switch (size) { + case 8: + val = riscv_wgchecker_readq(opaque, addr); + break; + case 4: + val = riscv_wgchecker_readl(opaque, addr); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid read size %u to wgChecker\n", + __func__, size); + return 0; + } + + return val; +} + +static void riscv_wgchecker_writeq(void *opaque, hwaddr addr, + uint64_t value) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + + switch (addr) { + case A_ERRCAUSE: + s->errcause = value & ERRCAUSE_MASK; + break; + case A_ERRADDR: + s->erraddr = value; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 8); + break; + } +} + +static void riscv_wgchecker_writel(void *opaque, hwaddr addr, + uint64_t value) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + + switch (addr) { + case A_ERRCAUSE: + value &= extract64(ERRCAUSE_MASK, 0, 32); + s->errcause = deposit64(s->errcause, 0, 32, value); + break; + case A_ERRCAUSE + 4: + value &= extract64(ERRCAUSE_MASK, 32, 32); + s->errcause = deposit64(s->errcause, 32, 32, value); + break; + case A_ERRADDR: + s->erraddr = deposit64(s->erraddr, 0, 32, value); + break; + case A_ERRADDR + 4: + s->erraddr = deposit64(s->erraddr, 32, 32, value); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 4); + break; + } +} + +static void riscv_wgchecker_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + switch (size) { + case 8: + riscv_wgchecker_writeq(opaque, addr, value); + break; + case 4: + riscv_wgchecker_writel(opaque, addr, value); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid write size %u to wgChecker\n", + __func__, size); + break; + } +} + +static MemTxResult riscv_wgchecker_read_with_attrs( + void *opaque, hwaddr addr, uint64_t *pdata, unsigned size, + MemTxAttrs attrs) +{ + SysBusDevice *dev = SYS_BUS_DEVICE(opaque); + + trace_riscv_wgchecker_mmio_read(dev->mmio[0].addr, addr, size); + + *pdata = 0; + if (could_access_wgblocks(attrs, "wgChecker")) { + *pdata = riscv_wgchecker_read(opaque, addr, size); + } + + return MEMTX_OK; +} + +static MemTxResult riscv_wgchecker_write_with_attrs( + void *opaque, hwaddr addr, uint64_t data, unsigned size, + MemTxAttrs attrs) +{ + SysBusDevice *dev = SYS_BUS_DEVICE(opaque); + + trace_riscv_wgchecker_mmio_write(dev->mmio[0].addr, addr, size, data); + + if (could_access_wgblocks(attrs, "wgChecker")) { + riscv_wgchecker_write(opaque, addr, data, size); + } + + return MEMTX_OK; +} + +static const MemoryRegionOps riscv_wgchecker_ops = { + .read_with_attrs = riscv_wgchecker_read_with_attrs, + .write_with_attrs = riscv_wgchecker_write_with_attrs, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8 + }, + .impl = { + .min_access_size = 4, + .max_access_size = 8 + } +}; + +static void riscv_wgc_iommu_memory_region_class_init(ObjectClass *klass, + void *data) +{ + IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); + + imrc->translate = riscv_wgc_translate; + imrc->attrs_to_index = riscv_wgc_attrs_to_index; + imrc->num_indexes = riscv_wgc_num_indexes; +} + +static const TypeInfo riscv_wgc_iommu_memory_region_info = { + .name = TYPE_RISCV_WGC_IOMMU_MEMORY_REGION, + .parent = TYPE_IOMMU_MEMORY_REGION, + .class_init = riscv_wgc_iommu_memory_region_class_init, +}; + + +#define DEFINE_REGION(N) \ + DEFINE_PROP_LINK("downstream-mr[" #N "]", RISCVWgCheckerState, \ + mem_regions[N].downstream, \ + TYPE_MEMORY_REGION, MemoryRegion *), \ + DEFINE_PROP_UINT64("region-offset[" #N "]", RISCVWgCheckerState, \ + mem_regions[N].region_offset, 0) \ + +static Property riscv_wgchecker_properties[] = { + DEFINE_PROP_UINT32("slot-count", RISCVWgCheckerState, slot_count, 0x1), + DEFINE_PROP_UINT32("mmio-size", RISCVWgCheckerState, mmio_size, 0x1000), + + /* Assume 1 wgChecker has 16 regions at maximum (WGC_NUM_REGIONS). */ + DEFINE_REGION(0), DEFINE_REGION(1), DEFINE_REGION(2), DEFINE_REGION(3), + DEFINE_REGION(4), DEFINE_REGION(5), DEFINE_REGION(6), DEFINE_REGION(7), + DEFINE_REGION(8), DEFINE_REGION(9), DEFINE_REGION(10), DEFINE_REGION(11), + DEFINE_REGION(12), DEFINE_REGION(13), DEFINE_REGION(14), DEFINE_REGION(15), + + DEFINE_PROP_UINT64("addr-range-start", RISCVWgCheckerState, addr_range_start, 0), + DEFINE_PROP_UINT64("addr-range-size", RISCVWgCheckerState, addr_range_size, UINT64_MAX), + + /* + * We could only set individual wgChecker to hw-bypass mode. It is + * usually used in wgChecker of BootROM, since SW has no way to enable + * the permission of it. + */ + DEFINE_PROP_BOOL("hw-bypass", RISCVWgCheckerState, hw_bypass, false), +}; + +static int int_log2_down(int n) +{ + int i = 0; + + n >>= 1; + + while (n) { + i++; + n >>= 1; + } + + return i; +} + +static int int_log2_up(int n) +{ + return int_log2_down(n - 1) + 1; +} + +/* + * Change the address range to be NAPOT alignment. + * + * New address range should totally cover the origin range, but new range + * should be configured by 1 NAPOT region (slot). + */ +static void address_range_align_napot(RISCVWgCheckerState *s) +{ + uint64_t start, end, size, new_size; + + start = s->addr_range_start; + end = s->addr_range_start + s->addr_range_size; + size = s->addr_range_size; + + if (size == UINT64_MAX) { + /* Full address range. No need of NAPOT alignment. */ + return; + } + + /* Size is the next power-of-2 number. */ + size = 1 << (int_log2_up(size)); + start = QEMU_ALIGN_DOWN(start, size); + end = QEMU_ALIGN_UP(end, size); + new_size = end - start; + + /* + * If base is not aligned to region size (new_size), + * double the region size and try it again. + */ + while ((new_size != size) && (size != 1ULL << 63)) { + size *= 2; + start = QEMU_ALIGN_DOWN(start, size); + end = QEMU_ALIGN_UP(end, size); + new_size = end - start; + } + + s->addr_range_start = start; + s->addr_range_size = size; +} + +static void riscv_wgchecker_realize(DeviceState *dev, Error **errp) +{ + Object *obj = OBJECT(dev); + RISCVWgCheckerState *s = RISCV_WGCHECKER(dev); + uint64_t size; + + if (worldguard_config == NULL) { + error_setg(errp, "Couldn't find global WorldGuard configs. " + "Please realize %s device at first.", + TYPE_RISCV_WORLDGUARD); + return; + } + + if (s->slot_count == 0) { + error_setg(errp, "wgChecker slot-count couldn't be zero."); + return; + } + + memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_wgchecker_ops, s, + TYPE_RISCV_WGCHECKER, s->mmio_size); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); + sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); + + /* Address range should be NAPOT alignment */ + address_range_align_napot(s); + + for (int i=0; imem_regions[i]; + + if (!region->downstream) { + continue; + } + region->wgchecker = s; + + const char *upstream_name = g_strdup_printf( + "wgchecker-upstream-%"HWADDR_PRIx, region->region_offset); + const char *downstream_name = g_strdup_printf( + "wgchecker-downstream-%"HWADDR_PRIx, region->region_offset); + + size = memory_region_size(region->downstream); + memory_region_init_iommu(®ion->upstream, sizeof(region->upstream), + TYPE_RISCV_WGC_IOMMU_MEMORY_REGION, + obj, upstream_name, size); + + /* upstream MRs are 2nd ~ (n+1)th MemoryRegion. */ + sysbus_init_mmio(SYS_BUS_DEVICE(dev), MEMORY_REGION(®ion->upstream)); + + /* + * This memory region is not exposed to users of this device as a + * sysbus MMIO region, but is instead used internally as something + * that our IOMMU translate function might direct accesses to. + */ + memory_region_init_io(®ion->blocked_io, obj, &riscv_wgc_mem_blocked_ops, + region, "wgchecker-blocked-io", size); + + address_space_init(®ion->downstream_as, region->downstream, + downstream_name); + address_space_init(®ion->blocked_io_as, ®ion->blocked_io, + "wgchecker-blocked-io"); + } +} + +static void riscv_wgchecker_unrealize(DeviceState *dev) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(dev); + + g_free(s->slots); + if (s->num_default_slots && s->default_slots) { + g_free(s->default_slots); + } +} + +static void riscv_wgchecker_reset_enter(Object *obj, ResetType type) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(obj); + uint64_t start = s->addr_range_start; + uint64_t end = s->addr_range_start + s->addr_range_size; + int nslots = s->slot_count; + + s->errcause = 0; + s->erraddr = 0; +} + +static void riscv_wgchecker_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + device_class_set_props(dc, riscv_wgchecker_properties); + dc->user_creatable = true; + dc->realize = riscv_wgchecker_realize; + dc->unrealize = riscv_wgchecker_unrealize; + ResettableClass *rc = RESETTABLE_CLASS(klass); + rc->phases.enter = riscv_wgchecker_reset_enter; +} + +static void riscv_wgchecker_instance_init(Object *obj) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(obj); + + s->num_default_slots = 0; +} + +static const TypeInfo riscv_wgchecker_info = { + .name = TYPE_RISCV_WGCHECKER, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = riscv_wgchecker_instance_init, + .instance_size = sizeof(RISCVWgCheckerState), + .class_init = riscv_wgchecker_class_init, +}; + +static void riscv_wgchecker_register_types(void) +{ + type_register_static(&riscv_wgchecker_info); + type_register_static(&riscv_wgc_iommu_memory_region_info); +} + +type_init(riscv_wgchecker_register_types) + +/* + * Create WgChecker device + */ +DeviceState *riscv_wgchecker_create(hwaddr addr, uint32_t size, + qemu_irq irq, uint32_t slot_count, + uint64_t addr_range_start, + uint64_t addr_range_size, + uint32_t num_of_region, + MemoryRegion **downstream, + uint64_t *region_offset, + uint32_t num_default_slots, + WgCheckerSlot *default_slots) +{ + DeviceState *dev = qdev_new(TYPE_RISCV_WGCHECKER); + RISCVWgCheckerState *s = RISCV_WGCHECKER(dev); + char name_mr[32]; + char name_offset[32]; + int i; + + qdev_prop_set_uint32(dev, "slot-count", slot_count); + qdev_prop_set_uint32(dev, "mmio-size", size); + qdev_prop_set_uint64(dev, "addr-range-start", addr_range_start); + if (addr_range_size) { + qdev_prop_set_uint64(dev, "addr-range-size", addr_range_size); + } + + g_assert(num_of_region <= WGC_NUM_REGIONS); + for (i=0; i*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion mmio; + qemu_irq irq; + + /* error reg */ + uint64_t errcause; + uint64_t erraddr; + + /* Memory regions protected by wgChecker */ + WgCheckerRegion mem_regions[WGC_NUM_REGIONS]; + + /* Property */ + uint32_t slot_count; /* nslots */ + uint32_t mmio_size; + uint64_t addr_range_start; + uint64_t addr_range_size; + bool hw_bypass; +}; + +DeviceState *riscv_wgchecker_create(hwaddr addr, uint32_t size, + qemu_irq irq, uint32_t slot_count, + uint64_t addr_range_start, + uint64_t addr_range_size, + uint32_t num_of_region, + MemoryRegion **downstream, + uint64_t *region_offset, + uint32_t num_default_slots, + WgCheckerSlot *default_slots); + #endif From patchwork Tue Apr 15 08:12:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051661 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 36E86C369AB for ; Tue, 15 Apr 2025 08:14:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRG-0003c1-R2; Tue, 15 Apr 2025 04:14:39 -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 1u4bQx-00020I-3h for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:20 -0400 Received: from mail-pf1-x434.google.com ([2607:f8b0:4864:20::434]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQo-00024S-2a for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:13 -0400 Received: by mail-pf1-x434.google.com with SMTP id d2e1a72fcca58-736c277331eso5701031b3a.1 for ; Tue, 15 Apr 2025 01:14:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704847; x=1745309647; 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=PalTCHeL3ElxHt3CezuVo/2+iw/lympwyWxiua7uelw=; b=mZktcG2IW+YVwWVx26wRhmpOJhdGh+uTGT6UZTkdoS3VU/PI4vlQlnrVo1+MElZRlG sJRN9LVUyM5M0yZOd9iZGbOMYV+GOVzbc0nlLHZnt8GMwrb0kzHBKrWwclfwXEgf/Oj6 zMTGyQW+C57JRN4RPiILx83/WkftSg79vpG4JAEf0ZgHnes7dqIY4zHf1gax2dM+iPWH yKYSCwtu12nnMyPh5l2NPeXOsBkL+agxyi1VbYpJpZ7IXWkOTyI+3M6afdYMwFqEbQ2a RGDD3hRyWK7Oxk/pgKj2J838Aio0QfoG3Ha2VaVe658vcuuHhC4e+DjnpNU/tTiGPeYs MoLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704847; x=1745309647; 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=PalTCHeL3ElxHt3CezuVo/2+iw/lympwyWxiua7uelw=; b=i2wkWnfkV9cUxSiIk8nM+oaTPKnF6Gtx3zaiBbhs5q29BL6BmIzMXnsm1hTVT51rkI c/g77nL1KbxvZa1utETTq6Hz/7alcPTHCTb4hAgKIuo9whlgzvYjqmml7OijinNQzipe TA6Yz7q63rlY3q1PnEHR2jAOIa+ezwkH/DeOG9KWOw6wchwmNqEfQUlBs8jV4TayIu09 TqPgaYmbLG7cFUlJ4L16O2JjYdSRVkQbqd3o8zSLeHXrhrAEMYTaEkN/8pAnYw3+oDKo X387rUJP7VA/1Lh+bwNDMech8Hff95/A3xGkBo9PpAZFfDaUYpXea4/y/ruKoAU8jXa/ uVVw== X-Gm-Message-State: AOJu0YzCoT7A6ztcoHvSB4wJjg35qrMzvcEHEAbfq3m1jSupTPBoFP3s Ol51t8+QLK/20eDT6nf+5sGagAQmrgDpkx0J2G7HqMFVAweG3WPX2bduksOhKeAU4Wh88Tcn2jc A25aa3gqUrMhH/f2Rqf03uXm44gZAJe83x0KLTWFEIFaIDOj29b7hRQsWJCDJXK7fSmaWRT8kox Ivc5GNYVlVbfGxy5+NvoTs+F+19Ajvx2tfwQ== X-Gm-Gg: ASbGncvkoOwR/rAlmSB3/Ooa+Nk5c4z6fFDmm9SyqSkBq0m/ynpXFCJTPgx76ddAtXA BLEKrKbYyFUgm8+K6xiY0/WSmd0zsqCmrCH81mDZLJXkJlyxDcFt4TPpYxTVW/4r2mY2WEl2/8i o4q1c4gext6JbZHfiszwAcMd2AIVnTwqOLOyqzJV0G0dd7EBeBdwRKOWz/4g+JydDx+pSdTunzM VkO4+tPXUkXi1XV0evFIlu0ooZxx9w7men/1CnP8nHWialNE0JQmrKcrEviN7rZ7DuG8nAYIksO ehzsNBLbym//gRbT7hXwJzzX0IL5VIjLhXpeEPhXbew5bTRtXF5PYBxs5VzbjzdP06f2xvJnfw= = X-Google-Smtp-Source: AGHT+IFOMJMQubsTktnEegMjgsK061VvHoYudBDYcAPUpxoCzp+Ylb/c9w+bk4hn5PnOUM/T1WMoDQ== X-Received: by 2002:a17:90b:3bce:b0:2ff:71d2:ee8f with SMTP id 98e67ed59e1d1-3084f36ecf4mr3841023a91.13.1744704846368; Tue, 15 Apr 2025 01:14:06 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.14.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:14:05 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 14/17] hw/misc: riscv_wgchecker: Implement wgchecker slot registers Date: Tue, 15 Apr 2025 16:12:28 +0800 Message-Id: <20250415081231.21186-15-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::434; envelope-from=jim.shu@sifive.com; helo=mail-pf1-x434.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=ham 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org wgChecker slot is similar to PMP region. SW could program each slot to configure the permission of address range. Signed-off-by: Jim Shu --- hw/misc/riscv_wgchecker.c | 330 +++++++++++++++++++++++++++++ hw/misc/riscv_worldguard.c | 3 + include/hw/misc/riscv_worldguard.h | 4 + 3 files changed, 337 insertions(+) diff --git a/hw/misc/riscv_wgchecker.c b/hw/misc/riscv_wgchecker.c index ea50f4f53a..8839d898c9 100644 --- a/hw/misc/riscv_wgchecker.c +++ b/hw/misc/riscv_wgchecker.c @@ -53,6 +53,52 @@ REG64(ERRCAUSE, 0x010) R_ERRCAUSE_IP_MASK) REG64(ERRADDR, 0x018) +REG64(WGC_SLOT, 0x020) + +/* wgChecker slots */ +REG64(SLOT_ADDR, 0x000) +REG64(SLOT_PERM, 0x008) +REG32(SLOT_CFG, 0x010) + FIELD(SLOT_CFG, A, 0, 2) + FIELD(SLOT_CFG, ER, 8, 1) + FIELD(SLOT_CFG, EW, 9, 1) + FIELD(SLOT_CFG, IR, 10, 1) + FIELD(SLOT_CFG, IW, 11, 1) + FIELD(SLOT_CFG, LOCK, 31, 1) + +#define SLOT_SIZE 0x020 + +#define SLOT0_CFG_MASK \ + (R_SLOT_CFG_ER_MASK | \ + R_SLOT_CFG_EW_MASK | \ + R_SLOT_CFG_IR_MASK | \ + R_SLOT_CFG_IW_MASK | \ + R_SLOT_CFG_LOCK_MASK) + +#define SLOT_CFG_MASK \ + (R_SLOT_CFG_A_MASK | (SLOT0_CFG_MASK)) + +#define WGC_SLOT_END(nslots) \ + (A_WGC_SLOT + SLOT_SIZE * (nslots + 1)) + +/* wgChecker slot is 4K alignment */ +#define WG_ALIGNED_SIZE (1 << 12) +#define WG_ALIGNED_MASK MAKE_64BIT_MASK(0, 12) + +/* wgChecker slot address is (addr / 4). */ +#define TO_SLOT_ADDR(addr) ((addr) >> 2) +#define FROM_SLOT_ADDR(addr) ((addr) << 2) + +/* wgChecker slot cfg.A[1:0] */ +#define A_OFF 0 +#define A_TOR 1 +#define A_NA4 2 +#define A_NAPOT 3 + +/* wgChecker slot perm */ +#define WGC_PERM(wid, perm) ((uint64_t)(perm) << (2 * (wid))) +#define P_READ (1 << 0) +#define P_WRITE (1 << 1) /* * Accesses only reach these read and write functions if the wgChecker @@ -146,6 +192,28 @@ static uint64_t riscv_wgchecker_readq(void *opaque, hwaddr addr) RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); uint64_t val = 0; + if ((addr >= A_WGC_SLOT) && (addr < WGC_SLOT_END(s->slot_count))) { + /* Read from WGC slot */ + int slot_id = (addr - A_WGC_SLOT) / SLOT_SIZE; + int slot_offset = (addr - A_WGC_SLOT) % SLOT_SIZE; + + switch (slot_offset) { + case A_SLOT_ADDR: + val = s->slots[slot_id].addr; + break; + case A_SLOT_PERM: + val = s->slots[slot_id].perm; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 8); + break; + } + + return val; + } + switch (addr) { case A_ERRCAUSE: val = s->errcause & ERRCAUSE_MASK; @@ -171,6 +239,37 @@ static uint64_t riscv_wgchecker_readl(void *opaque, hwaddr addr) RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); uint64_t val = 0; + if ((addr >= A_WGC_SLOT) && (addr < WGC_SLOT_END(s->slot_count))) { + /* Read from WGC slot */ + int slot_id = (addr - A_WGC_SLOT) / SLOT_SIZE; + int slot_offset = (addr - A_WGC_SLOT) % SLOT_SIZE; + + switch (slot_offset) { + case A_SLOT_ADDR: + val = extract64(s->slots[slot_id].addr, 0, 32); + break; + case A_SLOT_ADDR + 4: + val = extract64(s->slots[slot_id].addr, 32, 32); + break; + case A_SLOT_PERM: + val = extract64(s->slots[slot_id].perm, 0, 32); + break; + case A_SLOT_PERM + 4: + val = extract64(s->slots[slot_id].perm, 32, 32); + break; + case A_SLOT_CFG: + val = s->slots[slot_id].cfg & SLOT_CFG_MASK; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 4); + break; + } + + return val; + } + switch (addr) { case A_VENDOR: val = 0; @@ -228,11 +327,121 @@ static uint64_t riscv_wgchecker_read(void *opaque, hwaddr addr, unsigned size) return val; } +/* + * Validate the WGC slot address is between address range. + * + * Fix the slot address to the start address if it's not within the address range. + * We need validation when changing "slot address" or "TOR/NAPOT mode (cfg.A)" + */ +static void validate_slot_address(void *opaque, int slot_id) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + uint64_t start = TO_SLOT_ADDR(s->addr_range_start); + uint64_t end = TO_SLOT_ADDR(s->addr_range_start + s->addr_range_size); + uint32_t cfg_a = FIELD_EX32(s->slots[slot_id].cfg, SLOT_CFG, A); + + /* First and last slot address are hard-coded. */ + if ((slot_id == 0) || (slot_id == s->slot_count)) { + return; + } + + /* Check WGC slot address is between address range. */ + if ((s->slots[slot_id].addr < start) || (s->slots[slot_id].addr >= end)) { + s->slots[slot_id].addr = start; + } + + /* Check WGC slot is 4k-aligned. */ + if (cfg_a == A_TOR) { + s->slots[slot_id].addr &= ~TO_SLOT_ADDR(WG_ALIGNED_MASK); + } else if (cfg_a == A_NAPOT) { + s->slots[slot_id].addr |= TO_SLOT_ADDR(WG_ALIGNED_MASK >> 1); + } else if (cfg_a == A_NA4) { + /* Forcely replace NA4 slot with 4K-aligned NAPOT slot. */ + FIELD_DP32(s->slots[slot_id].cfg, SLOT_CFG, A, A_NAPOT); + s->slots[slot_id].addr |= TO_SLOT_ADDR(WG_ALIGNED_MASK >> 1); + } +} + +static bool slots_reg_is_ro(int slot_id, int slot_offset, uint32_t nslots) +{ + /* + * Special slots: + * - slot[0]: + * - addr is RO + * - perm is RO + * - cfg.A is OFF + * + * - slot[nslots]: + * - addr is RO + * - cfg.A is OFF or TOR + */ + if (slot_id == 0) { + switch (slot_offset) { + case A_SLOT_ADDR: + case A_SLOT_ADDR + 4: + case A_SLOT_PERM: + case A_SLOT_PERM + 4: + return true; + default: + break; + } + } else if (slot_id == nslots) { + switch (slot_offset) { + case A_SLOT_ADDR: + case A_SLOT_ADDR + 4: + return true; + default: + break; + } + } + + return false; +} + static void riscv_wgchecker_writeq(void *opaque, hwaddr addr, uint64_t value) { RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + if ((addr >= A_WGC_SLOT) && (addr < WGC_SLOT_END(s->slot_count))) { + /* Read from WGC slot */ + int slot_id = (addr - A_WGC_SLOT) / SLOT_SIZE; + int slot_offset = (addr - A_WGC_SLOT) % SLOT_SIZE; + bool locked = FIELD_EX32(s->slots[slot_id].cfg, SLOT_CFG, LOCK); + + if (locked) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Couldn't write access to locked wgChecker Slot: " + "slot = %d, offset = %d\n", __func__, slot_id, + slot_offset); + return; + } + + if (slots_reg_is_ro(slot_id, slot_offset, s->slot_count)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 8); + } + + switch (slot_offset) { + case A_SLOT_ADDR: + s->slots[slot_id].addr = value; + validate_slot_address(s, slot_id); + break; + case A_SLOT_PERM: + value &= wgc_slot_perm_mask; + s->slots[slot_id].perm = value; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 8); + break; + } + + return; + } + switch (addr) { case A_ERRCAUSE: s->errcause = value & ERRCAUSE_MASK; @@ -253,6 +462,81 @@ static void riscv_wgchecker_writel(void *opaque, hwaddr addr, { RISCVWgCheckerState *s = RISCV_WGCHECKER(opaque); + if ((addr >= A_WGC_SLOT) && (addr < WGC_SLOT_END(s->slot_count))) { + /* Write to WGC slot */ + int slot_id = (addr - A_WGC_SLOT) / SLOT_SIZE; + int slot_offset = (addr - A_WGC_SLOT) % SLOT_SIZE; + bool locked = FIELD_EX32(s->slots[slot_id].cfg, SLOT_CFG, LOCK); + int cfg_a, old_cfg_a; + + if (locked) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Couldn't write access to locked wgChecker Slot: " + "slot = %d, offset = %d\n", __func__, slot_id, + slot_offset); + return; + } + + if (slots_reg_is_ro(slot_id, slot_offset, s->slot_count)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 4); + } + + switch (slot_offset) { + case A_SLOT_ADDR: + s->slots[slot_id].addr = deposit64( + s->slots[slot_id].addr, 0, 32, value); + validate_slot_address(s, slot_id); + break; + case A_SLOT_ADDR + 4: + s->slots[slot_id].addr = deposit64( + s->slots[slot_id].addr, 32, 32, value); + validate_slot_address(s, slot_id); + break; + case A_SLOT_PERM: + value &= wgc_slot_perm_mask; + s->slots[slot_id].perm = deposit64( + s->slots[slot_id].perm, 0, 32, value); + break; + case A_SLOT_PERM + 4: + value &= extract64(wgc_slot_perm_mask, 32, 32); + s->slots[slot_id].perm = deposit64( + s->slots[slot_id].perm, 32, 32, value); + break; + case A_SLOT_CFG: + if (slot_id == 0) { + value &= SLOT0_CFG_MASK; + s->slots[0].cfg = value; + } else if (slot_id == s->slot_count) { + old_cfg_a = FIELD_EX32(s->slots[s->slot_count].cfg, SLOT_CFG, A); + cfg_a = FIELD_EX32(value, SLOT_CFG, A); + + value &= SLOT0_CFG_MASK; + if ((cfg_a == A_OFF) || (cfg_a == A_TOR)) { + value |= cfg_a; + } else { + /* slot[nslots] could only use OFF or TOR config. */ + value |= old_cfg_a; + } + s->slots[s->slot_count].cfg = value; + + validate_slot_address(s, slot_id); + } else { + value &= SLOT_CFG_MASK; + s->slots[slot_id].cfg = value; + } + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unexpected memory access to (0x%" HWADDR_PRIX ", %u) \n", + __func__, addr, 4); + break; + } + + return; + } + switch (addr) { case A_ERRCAUSE: value &= extract64(ERRCAUSE_MASK, 0, 32); @@ -460,6 +744,8 @@ static void riscv_wgchecker_realize(DeviceState *dev, Error **errp) return; } + s->slots = g_new0(WgCheckerSlot, s->slot_count + 1); + memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_wgchecker_ops, s, TYPE_RISCV_WGCHECKER, s->mmio_size); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); @@ -523,6 +809,37 @@ static void riscv_wgchecker_reset_enter(Object *obj, ResetType type) s->errcause = 0; s->erraddr = 0; + + for (int i = 0; i < nslots; i++) { + s->slots[i].addr = TO_SLOT_ADDR(start); + s->slots[i].perm = 0; + s->slots[i].cfg = 0; + } + s->slots[nslots].addr = TO_SLOT_ADDR(end); + s->slots[nslots].perm = 0; + s->slots[nslots].cfg = 0; + + if (s->num_default_slots != 0) { + /* + * Use default slots: + * slot[0] is hard-coded to start address, so the default slots + * start from slot[1]. + */ + memcpy(&s->slots[1], s->default_slots, + sizeof(WgCheckerSlot) * s->num_default_slots); + } else if ((s->hw_bypass) || + ((worldguard_config != NULL) && worldguard_config->hw_bypass)) { + /* HW bypass mode */ + uint32_t trustedwid = worldguard_config->trustedwid; + + if (trustedwid == NO_TRUSTEDWID) { + trustedwid = worldguard_config->nworlds - 1; + } + + s->slots[nslots].perm = WGC_PERM(trustedwid, P_READ | P_WRITE); + s->slots[nslots].perm &= wgc_slot_perm_mask; + s->slots[nslots].cfg = A_TOR; + } } static void riscv_wgchecker_class_init(ObjectClass *klass, void *data) @@ -596,6 +913,19 @@ DeviceState *riscv_wgchecker_create(hwaddr addr, uint32_t size, qdev_prop_set_uint64(dev, name_offset, region_offset[i]); } + if (num_default_slots > slot_count) { + num_default_slots = slot_count; + } + + s->num_default_slots = num_default_slots; + if (s->num_default_slots) { + s->default_slots = g_new0(WgCheckerSlot, s->num_default_slots); + memcpy(s->default_slots, default_slots, + sizeof(WgCheckerSlot) * s->num_default_slots); + } else { + s->default_slots = NULL; + } + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); diff --git a/hw/misc/riscv_worldguard.c b/hw/misc/riscv_worldguard.c index 1a910f4cf3..59ca6d16e7 100644 --- a/hw/misc/riscv_worldguard.c +++ b/hw/misc/riscv_worldguard.c @@ -38,6 +38,9 @@ */ struct RISCVWorldGuardState *worldguard_config = NULL; +/* perm field bitmask of wgChecker slot, it's depends on NWorld. */ +uint64_t wgc_slot_perm_mask = 0; + static Property riscv_worldguard_properties[] = { DEFINE_PROP_UINT32("nworlds", RISCVWorldGuardState, nworlds, 0), diff --git a/include/hw/misc/riscv_worldguard.h b/include/hw/misc/riscv_worldguard.h index 7b5aae866a..f53202524c 100644 --- a/include/hw/misc/riscv_worldguard.h +++ b/include/hw/misc/riscv_worldguard.h @@ -45,6 +45,7 @@ struct RISCVWorldGuardState { }; extern struct RISCVWorldGuardState *worldguard_config; +extern uint64_t wgc_slot_perm_mask; DeviceState *riscv_worldguard_create(uint32_t nworlds, uint32_t trustedwid, bool hw_bypass, bool tz_compat); @@ -86,9 +87,12 @@ struct WgCheckerRegion { struct RISCVWgCheckerState { /*< private >*/ SysBusDevice parent_obj; + uint32_t num_default_slots; + WgCheckerSlot *default_slots; /*< public >*/ MemoryRegion mmio; + WgCheckerSlot *slots; qemu_irq irq; /* error reg */ From patchwork Tue Apr 15 08:12:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051665 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0AB2DC369AB for ; Tue, 15 Apr 2025 08:16:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bRu-00072y-Bg; Tue, 15 Apr 2025 04:15:20 -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 1u4bR2-0002Fh-5M for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:26 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQx-00025r-V5 for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:23 -0400 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-227aaa82fafso41444225ad.2 for ; Tue, 15 Apr 2025 01:14:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704852; x=1745309652; 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=r8MkLirfRd+1eYBUne8MUcSIMDu4+B+icN4ZLFGI96k=; b=gxIlBtTWEFYL7lEQ0Utx/NB+sqqjEwH4QDA3ht1YuJFpOPZCQpfQDBtCTyh8Hs9VTe A6+gqhtI2TsRNB4CTWP2GRYEzpO2SxyOP8fqj0nfYhkIE03JEKHgGldscXFDhKgtt1dp +IICnRTyga2V1UTYlby+aJXR5SVQ8iYTCcdnHy+BmhQNYtNzuDotWQZQp0w8mGR/HZFg ChqeO1t1kNQIjU/Y0T3OMLgfQ8HAAGmFqO+VCYGIGJ3Z99t+4jiAZ5rizVlUwgrONDsR 5Mitm3tJE8NW32PrwbEs7FzlqAxg7QxPNCzNSO8fe947gQg4hqeQLiJ3e8yjE2b0Mofk FTYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704852; x=1745309652; 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=r8MkLirfRd+1eYBUne8MUcSIMDu4+B+icN4ZLFGI96k=; b=PaVsi37dsORIFtSOggnLaKySLfjVa+dDU2Xklerb2tvytaWOWv0P7CrEY3FYrnvQ00 Vc6A2mAHLxWyZY+QSLyS6/LlFzea8Z08ZMRXyc9gCifIEIbP+TnsPfEP7YwdaAH/MKsI 8Zpd4eJuCsVxImqy4O5BycGGKC8RoRyB1BbNwRtH+/SNnYhhGaIz9Soxgj1g+xIxh2SZ FLa9n6Q/dK1/BvPWSnfiq7Sp/PdHVfIPU/+ULaeTGiqmiyKB5ILA+YGHowB7Pjwwl8zB EESyMrRasfwDlKUybF3UuH82VXpUd1i+LSoNa8Ulvj10z8vO7DXFABCL56bqxFKxIpRQ ZNlQ== X-Gm-Message-State: AOJu0YwL8cRbdeVKfZ5wt0xW2bdCtXvAY1wih4PmFaFsawuSH/64jxah 2LH0Nz6S2C0kWqIU/ebZT3g+sLPAv2GWqs3yCHS9drTdB4x7rz4wSVLFTcpcem/dd+H1JXnBC9S k79OK3JSc3BDupGqo8KYZlIlsS/vxSKsnKHNOnT+sGURzZ9fD68WG/XBf9KzRqhCLB1QekLugu0 bOhPoYxZafRsUiTvRotbYXphCmeo+8L8QDjA== X-Gm-Gg: ASbGncs5TTlzkNYCHB8jSACB2VnYvKwQ0vhhocRxhDeA8HHkpSw7WnsA6KblCNyAZ+L kxh3AuEyATtgR570LsH/QwVSdGeNk1SCXkh7DRcf33yaa7fqm+ukWpC8eeCAVI1MwqK3b8cw7f1 TZFkL8hjtoZ+6ZWmI1+YTwMz/S6M5di9gYAzXxe3fJigcb6R6WC6Wo1Al9pTJkhRmreaYN9WosJ NsNi1+i7t10NOaSLp/XZjcsvNgjCPS8Vwkq9NtNWmqVKwh1ivMIXr+GCly6R61YOGyElf2tu64E ijesyMq9pC7vCOv/S4xbY68mQLczBcSl6UKjczndHYzMODO/UxERyARdm+0Y4uc= X-Google-Smtp-Source: AGHT+IHxw7teXwFJ4+Xorx5jZKi3l2qB+ap0ikCAJQv72KwcfUzrub4eg69qzmdmh8H2UK4tWBzqJw== X-Received: by 2002:a17:902:f64e:b0:220:ca08:8986 with SMTP id d9443c01a7336-22bea4adf58mr246190645ad.22.1744704852067; Tue, 15 Apr 2025 01:14:12 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.14.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:14:11 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 15/17] hw/misc: riscv_wgchecker: Implement correct block-access behavior Date: Tue, 15 Apr 2025 16:12:29 +0800 Message-Id: <20250415081231.21186-16-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62c.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The wgChecker is configurable for whether blocked accesses: * should cause a bus error or just read return zero and write ignore * should generate the interrupt or not Signed-off-by: Jim Shu --- hw/misc/riscv_wgchecker.c | 169 +++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 2 deletions(-) diff --git a/hw/misc/riscv_wgchecker.c b/hw/misc/riscv_wgchecker.c index 8839d898c9..5d2af7946f 100644 --- a/hw/misc/riscv_wgchecker.c +++ b/hw/misc/riscv_wgchecker.c @@ -100,6 +100,169 @@ REG32(SLOT_CFG, 0x010) #define P_READ (1 << 0) #define P_WRITE (1 << 1) +static void decode_napot(hwaddr a, hwaddr *sa, hwaddr *ea) +{ + /* + * aaaa...aaa0 8-byte NAPOT range + * aaaa...aa01 16-byte NAPOT range + * aaaa...a011 32-byte NAPOT range + * ... + * aa01...1111 2^XLEN-byte NAPOT range + * a011...1111 2^(XLEN+1)-byte NAPOT range + * 0111...1111 2^(XLEN+2)-byte NAPOT range + * 1111...1111 Reserved + */ + + a = FROM_SLOT_ADDR(a) | 0x3; + + if (sa) { + *sa = a & (a + 1); + } + if (ea) { + *ea = a | (a + 1); + } +} + +typedef struct WgAccessResult WgAccessResult; +struct WgAccessResult { + bool is_success; + bool has_bus_error; + bool has_interrupt; + uint8_t perm:2; +}; + +static WgAccessResult wgc_check_access( + RISCVWgCheckerState *s, hwaddr phys_addr, uint32_t wid, bool is_write) +{ + WgCheckerSlot *slot, *prev_slot; + uint32_t cfg_a, prev_cfg_a; + uint64_t start, end; + int slot_id, wgc_perm = 0; + WgAccessResult result = { 0 }; + + bool is_matching = false; + bool slot0_be, slot0_ip; + bool matched_slot_be = false, matched_slot_ip = false; + + for (slot_id = 0; slot_id < s->slot_count; slot_id++) { + slot = &s->slots[slot_id + 1]; + cfg_a = FIELD_EX32(slot->cfg, SLOT_CFG, A); + + if (cfg_a == A_TOR) { + prev_slot = &s->slots[slot_id]; + + prev_cfg_a = FIELD_EX32(prev_slot->cfg, SLOT_CFG, A); + if (prev_cfg_a == A_NA4) { + start = FROM_SLOT_ADDR(prev_slot->addr) + 4; + } else if (prev_cfg_a == A_NAPOT) { + decode_napot(prev_slot->addr, NULL, &start); + start += 1; + } else { /* A_TOR or A_OFF */ + start = FROM_SLOT_ADDR(prev_slot->addr); + } + end = FROM_SLOT_ADDR(slot->addr); + } else if (cfg_a == A_NA4) { + start = FROM_SLOT_ADDR(slot->addr); + end = start + 4; + } else if (cfg_a == A_NAPOT) { + decode_napot(slot->addr, &start, &end); + end += 1; + } else { + /* A_OFF: not in slot range. */ + continue; + } + + /* wgChecker slot range is between start to (end - 1). */ + if ((start <= phys_addr) && (phys_addr < end)) { + /* Match the wgC slot */ + int perm = ((slot->perm >> (wid * 2)) & 0x3); + + /* If any matching rule permits access, the access is permitted. */ + wgc_perm |= perm; + + /* + * If any matching rule wants to report error (IRQ or Bus Error), + * the denied access should report error. + */ + is_matching = true; + if (is_write) { + matched_slot_be |= FIELD_EX64(slot->cfg, SLOT_CFG, EW); + matched_slot_ip |= FIELD_EX64(slot->cfg, SLOT_CFG, IW); + } else { + matched_slot_be |= FIELD_EX64(slot->cfg, SLOT_CFG, ER); + matched_slot_ip |= FIELD_EX64(slot->cfg, SLOT_CFG, IR); + } + } + } + + /* If no matching rule, error reporting depends on the slot0's config. */ + if (is_write) { + slot0_be = FIELD_EX64(s->slots[0].cfg, SLOT_CFG, EW); + slot0_ip = FIELD_EX64(s->slots[0].cfg, SLOT_CFG, IW); + } else { + slot0_be = FIELD_EX64(s->slots[0].cfg, SLOT_CFG, ER); + slot0_ip = FIELD_EX64(s->slots[0].cfg, SLOT_CFG, IR); + } + + result.is_success = is_write ? (wgc_perm & P_WRITE) : (wgc_perm & P_READ); + result.perm = wgc_perm; + if (!result.is_success) { + if (is_matching) { + result.has_bus_error = matched_slot_be; + result.has_interrupt = matched_slot_ip; + } else { + result.has_bus_error = slot0_be; + result.has_interrupt = slot0_ip; + } + } + + return result; +} + +static MemTxResult riscv_wgc_handle_blocked_access( + WgCheckerRegion *region, hwaddr addr, uint32_t wid, bool is_write) +{ + RISCVWgCheckerState *s = RISCV_WGCHECKER(region->wgchecker); + bool be, ip; + WgAccessResult result; + hwaddr phys_addr; + + be = FIELD_EX64(s->errcause, ERRCAUSE, BE); + ip = FIELD_EX64(s->errcause, ERRCAUSE, IP); + phys_addr = addr + region->region_offset; + + /* + * Check if this blocked access trigger IRQ (Bus Error) or not. + * It depends on wgChecker slot config (cfg.IR/IW/ER/EW bits). + */ + result = wgc_check_access(s, phys_addr, wid, is_write); + + if (!be && !ip) { + /* + * With either of the be or ip bits is set, further violations do not + * update the errcause or erraddr registers. Also, new interrupts + * cannot be generated until the be and ip fields are cleared. + */ + if (result.has_interrupt || result.has_bus_error) { + s->errcause = FIELD_DP64(s->errcause, ERRCAUSE, WID, wid); + s->errcause = FIELD_DP64(s->errcause, ERRCAUSE, R, !is_write); + s->errcause = FIELD_DP64(s->errcause, ERRCAUSE, W, is_write); + s->erraddr = TO_SLOT_ADDR(phys_addr); + } + + if (result.has_interrupt) { + s->errcause = FIELD_DP64(s->errcause, ERRCAUSE, IP, 1); + qemu_irq_raise(s->irq); + } + + if (result.has_bus_error) { + s->errcause = FIELD_DP64(s->errcause, ERRCAUSE, BE, 1); + } + } + + return result.has_bus_error ? MEMTX_ERROR : MEMTX_OK; +} + /* * Accesses only reach these read and write functions if the wgChecker * is blocking them; non-blocked accesses go directly to the downstream @@ -109,23 +272,25 @@ static MemTxResult riscv_wgc_mem_blocked_read(void *opaque, hwaddr addr, uint64_t *pdata, unsigned size, MemTxAttrs attrs) { + WgCheckerRegion *region = opaque; uint32_t wid = mem_attrs_to_wid(attrs); trace_riscv_wgc_mem_blocked_read(addr, size, wid); *pdata = 0; - return MEMTX_OK; + return riscv_wgc_handle_blocked_access(region, addr, wid, false); } static MemTxResult riscv_wgc_mem_blocked_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, MemTxAttrs attrs) { + WgCheckerRegion *region = opaque; uint32_t wid = mem_attrs_to_wid(attrs); trace_riscv_wgc_mem_blocked_write(addr, value, size, wid); - return MEMTX_OK; + return riscv_wgc_handle_blocked_access(region, addr, wid, true); } static const MemoryRegionOps riscv_wgc_mem_blocked_ops = { From patchwork Tue Apr 15 08:12:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051682 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E35C1C369AB for ; Tue, 15 Apr 2025 08:20:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bSn-00027y-9d; Tue, 15 Apr 2025 04:16:13 -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 1u4bR3-0002KD-Og for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:27 -0400 Received: from mail-pg1-x52e.google.com ([2607:f8b0:4864:20::52e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u4bQy-00026q-DY for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:25 -0400 Received: by mail-pg1-x52e.google.com with SMTP id 41be03b00d2f7-aee773df955so5009712a12.1 for ; Tue, 15 Apr 2025 01:14:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704858; x=1745309658; 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=zQPqjXYVy2MZpkzlsyhoG+MQg9fKVsZKI/VvPlBGP+g=; b=N7mMyMdRGPQf0dIpQU/OVlwAMYxUxcV1n/OGIz+wrFwK93dW9069jOjTaaS0n52t+h LEjVirUYggSviMMPEeijTH78VlXE0qJCQ9JxA1q5igSHUFyxJiUA63OsHooWQ1zXrh5r QmiZlAgcbdEkdubWsYz5F9zLURccAig6GU4Q/oU2F2q3/WtJL7w/j2kdeCikpWI9q5NA 7JN/mBTws5jlSqUZd2LspUskU25JGFcsRwJLAsRqFx/ZIq1Sv2h3fTZ4D72ExxiHbIRL HD/xMib3x8kHW/EgOnxfz6EeYUToQuzNIIPxvvsTUJuFnw2BMXfuITXXccwHEahfaIou NbdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704858; x=1745309658; 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=zQPqjXYVy2MZpkzlsyhoG+MQg9fKVsZKI/VvPlBGP+g=; b=WW9VvT3uHov0Vw1NVeCBE2F8zgtbAWOiKg2hd84LQgGcysJk6dYfDnsoKObO3Rpdmp 4OAtpvoTZqphkbXBGqWqvuXWPbgJLI3i7NOZReFf79b1VcZ+o2Ck31XUMcp2WB/Y2esm U+UReo51BacTfvS0PStB0spYLdiHjCtk9tAJ6J279vpr1lKWlnlPSwyaypGOqmtjpeGM ioFb0fOmkttP2HFtPRAQhnDRmxTMh+zAWcLxIOfq0mPPSZWPez/MPRhXRjiC/dXI+onP ocAJJ45k4Eo1x+4SR4by2EIaDnYidJx9blzITJ3ocP5mXQdYWDr+6cjClq/v8ssSCOZ3 oylA== X-Gm-Message-State: AOJu0YyIheavehUiDefcgmoRnU3kJTYy2YtorD+Og33sad5rTuTkoUdC Ujl0it/7wg3olQWbzAJDWXYtJcwwc5MAV00XVnIswbCfonF6l21JxODKsHhZ04uM2N6uAlwnyQE /vZsaHRc/fODVihqHPgAI7Tou6wilXfGA6DEFapkX2xO7/+FcEMPa7N62BXOEuEVO2k8DWMgOx2 iDK0idHmgmVRzQ7rHk4g0ACffCPiHnSfT5KQ== X-Gm-Gg: ASbGncuUSMSg9a8Axd8pjXKf6gpQr8e73mCHYEPECEkcWfDN0fNAUzgw3kXOViSQ1bv QIzKH0vkhVv7B9/SwRXyFhjWZc10h4xocpMynqJ+KGymyyQbnEhu02b1xqHaSJU3/G7jSxt6i+v NQIv1wlOVvbjWIJEN3vfvN3nd3V04zjdYaYfJ4DwwUpRh+XFkmBRAFCnJqHDscWPiF0esm66Ilp SIhN6NUM6Bw0DDWqvrIN3oG6MMq7N2XXMQCd6mQgmEY4GpsLk0wMqyHW4/U7jxfxoIfkb2e8Cjs 25AP91xvu40bkkIKodXkACJJavEm3Uux4P5F/FrUqhsLNTqY/4fgc8AnmSWNN8o= X-Google-Smtp-Source: AGHT+IEJg5jW4QGqUiG5bxHCIDAmrdq674y5ICzayPjEgScWyAIJNmh/JIegAJbkrErhimbC448xmA== X-Received: by 2002:a17:902:fc8d:b0:220:cfb7:56eb with SMTP id d9443c01a7336-22c249da9a8mr33204635ad.26.1744704857666; Tue, 15 Apr 2025 01:14:17 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.14.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:14:17 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 16/17] hw/misc: riscv_wgchecker: Check the slot settings in translate Date: Tue, 15 Apr 2025 16:12:30 +0800 Message-Id: <20250415081231.21186-17-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::52e; envelope-from=jim.shu@sifive.com; helo=mail-pg1-x52e.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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The final part of wgChecker we need to implement is actually using the wgChecker slots programmed by guest to determine whether to block the transaction or not. Since this means we now change transaction mappings when the guest writes to wgChecker slots, we must also call the IOMMU notifiers at that point. One tricky part here is that the perm of 'blocked_io_as' is the condition of deny access. For example, if wgChecker only permits RO access, the perm of 'downstream_as' will be IOMMU_RO and the perm of 'blocked_io_as' will be IOMMU_WO. Signed-off-by: Jim Shu --- hw/misc/riscv_wgchecker.c | 70 ++++++++++++++++++++++++++++++++++++--- hw/misc/trace-events | 1 + 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/hw/misc/riscv_wgchecker.c b/hw/misc/riscv_wgchecker.c index 5d2af7946f..5a70231837 100644 --- a/hw/misc/riscv_wgchecker.c +++ b/hw/misc/riscv_wgchecker.c @@ -100,6 +100,52 @@ REG32(SLOT_CFG, 0x010) #define P_READ (1 << 0) #define P_WRITE (1 << 1) +static IOMMUAccessFlags wgc_perm_to_iommu_flags(int wgc_perm) +{ + if (wgc_perm == (P_READ | P_WRITE)) { + return IOMMU_RW; + } else if (wgc_perm & P_WRITE) { + return IOMMU_WO; + } else if (wgc_perm & P_READ) { + return IOMMU_RO; + } else { + return IOMMU_NONE; + } +} + +static void wgchecker_iommu_notify_all(RISCVWgCheckerState *s) +{ + /* + * Do tlb_flush() to whole address space via memory_region_notify_iommu() + * when wgChecker changes it's config. + */ + + IOMMUTLBEvent event = { + .entry = { + .addr_mask = -1ULL, + } + }; + + trace_riscv_wgc_iommu_notify_all(); + + for (int i=0; imem_regions[i]; + uint32_t nworlds = worldguard_config->nworlds; + + if (!region->downstream) { + continue; + } + event.entry.iova = 0; + event.entry.translated_addr = 0; + event.type = IOMMU_NOTIFIER_UNMAP; + event.entry.perm = IOMMU_NONE; + + for (int wid=0; widupstream, wid, event); + } + } +} + static void decode_napot(hwaddr a, hwaddr *sa, hwaddr *ea) { /* @@ -309,6 +355,9 @@ static IOMMUTLBEntry riscv_wgc_translate(IOMMUMemoryRegion *iommu, { WgCheckerRegion *region = container_of(iommu, WgCheckerRegion, upstream); RISCVWgCheckerState *s = RISCV_WGCHECKER(region->wgchecker); + bool is_write; + WgAccessResult result; + int wgc_perm; hwaddr phys_addr; uint64_t region_size; @@ -327,18 +376,25 @@ static IOMMUTLBEntry riscv_wgc_translate(IOMMUMemoryRegion *iommu, * Look at the wgChecker configuration for this address, and * return a TLB entry directing the transaction at either * downstream_as or blocked_io_as, as appropriate. - * For the moment, always permit accesses. */ /* Use physical address instead of offset */ phys_addr = addr + region->region_offset; + is_write = (flags == IOMMU_WO); - is_success = true; + result = wgc_check_access(s, phys_addr, iommu_idx, is_write); trace_riscv_wgc_translate(phys_addr, flags, - iommu_idx, is_success ? "pass" : "block"); + iommu_idx, result.is_success ? "pass" : "block"); - ret.target_as = is_success ? ®ion->downstream_as : ®ion->blocked_io_as; + wgc_perm = result.perm; + if (!result.is_success) { + /* if target_as is blocked_io_as, the perm is the condition of deny access. */ + wgc_perm ^= (P_READ | P_WRITE); + } + ret.perm = wgc_perm_to_iommu_flags(wgc_perm); + + ret.target_as = result.is_success ? ®ion->downstream_as : ®ion->blocked_io_as; return ret; } @@ -604,6 +660,9 @@ static void riscv_wgchecker_writeq(void *opaque, hwaddr addr, break; } + /* Flush softmmu TLB when wgChecker changes config. */ + wgchecker_iommu_notify_all(s); + return; } @@ -699,6 +758,9 @@ static void riscv_wgchecker_writel(void *opaque, hwaddr addr, break; } + /* Flush softmmu TLB when wgChecker changes config. */ + wgchecker_iommu_notify_all(s); + return; } diff --git a/hw/misc/trace-events b/hw/misc/trace-events index b1d8538220..54dfcd50a1 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -403,3 +403,4 @@ riscv_wgchecker_mmio_write(uint64_t base, uint64_t offset, unsigned int size, ui riscv_wgc_mem_blocked_read(uint64_t addr, unsigned size, uint32_t wid) "wgChecker blocked read: offset 0x%" PRIx64 " size %u wid %" PRIu32 riscv_wgc_mem_blocked_write(uint64_t addr, uint64_t data, unsigned size, uint32_t wid) "wgChecker blocked write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u wid %" PRIu32 riscv_wgc_translate(uint64_t addr, int flags, int wid, const char *res) "wgChecker translate: addr 0x%016" PRIx64 " flags 0x%x wid %d: %s" +riscv_wgc_iommu_notify_all(void) "wgChecker iommu: notifying UNMAP for all" From patchwork Tue Apr 15 08:12:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 14051684 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A5E50C369AB for ; Tue, 15 Apr 2025 08:21:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u4bSr-0002WY-BN; Tue, 15 Apr 2025 04:16:18 -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 1u4bR5-0002Sm-Un for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:29 -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 1u4bR3-00028S-Dr for qemu-devel@nongnu.org; Tue, 15 Apr 2025 04:14:27 -0400 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-224191d92e4so50382805ad.3 for ; Tue, 15 Apr 2025 01:14:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1744704864; x=1745309664; 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=mEHD4jqnQyx5yEVuX/6t/quqlcTWATx7qTJMr+KrQBg=; b=b/2/dB8tns3EJp8BQ+NbOSBaMobiTtQDmOFMzasQGpG3yCcvZNcwQ0kcqcHSQft4EL v6Qa2ThaC+Be51kEUWXZpzOLyjwulLqrTyEGWtfaWhc8+lfCwQkP1iMP7qKEVhPDzmIY MS0GavGgcoECumTL/sDOBpBsKNDyAq6qlNqmk5DJr682emOpoFM8EczN44bUYEcbCT2K 9GjriDDf22nUDbg6V1F0ZwSH8vXvvc40wuLgj59rOTUG/6AkgALROlk2OudWYUaAKTkS g/r9ukNG9iygC7nxG8U3od7PoAYHqD5+B0kxRqjMnKmiv6IkVsThhDpn3F9VkQbmQZ62 Pxbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744704864; x=1745309664; 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=mEHD4jqnQyx5yEVuX/6t/quqlcTWATx7qTJMr+KrQBg=; b=buJXNVwVWV8bUmJvPz57vXkPnzrLrDdpG1GSYidTrWuDj+5tutL9kGGDHBCTxwI5vU h6Yz1l9RMNvtYYkcQC3ln3xg4CtSf92GXo+Hz65qIg9zjkQ59WULho7nJfnDx+hXcVvR 5L+bipel+KH7oqyLQsregB3xmyYUI0AMboe7l17B2fn5y6LfkggPkLQjYEqGNeS657OT MO7f878cJtmgX1vBR5VPj8AMeCcoRpZ6LUXmY3V/5yHT1msW5eHYLonIJEvtUUvMDExz +rovVEET3lOX0pn15lxqjOslEd1s+pzn8t146mtSotr/FT/m9VGzlfl1IRQNCOp92RF7 gDaw== X-Gm-Message-State: AOJu0YwLtN7XnTXAHbg6CtgCb0IxZOTPFf3E8vNXoheixruGhEhueS+E xXgNM+wXGbLpKF6QmLS+qLd76krtKOSSAfQBYKfTItPr/Q5QQUBgy3G8lYI/OajDgFXxDvGf7+X l3/UwpOE3P8Gqe23OH+Lw7kFpmnYst4g6ghcUwhW93pY4mzPmChZWTRn5ONB3Paql9kvxT1htEj agQCLv3AnLvDGWTcFxME/xmFN9oKTKe8Q6Wg== X-Gm-Gg: ASbGncsnsl7GaoSInMc/JuIXBYZqlmjdXV4SzxUGeeLHj4SQqmB23OX+xA9gCoxpvcF kQcn4naKzKe1wkGPY24NQ/RsHm1zoilU6q1Bk9pt689hdNk60Nkxg1q/wYr9gYW6d5U1AT3Gh0b MhPRF4NOmspTqaWdqjRZpfA/ncDT2vshMXF7jDHh09wUx6b5ubzq+J8WB2MyHEUOT/ALRgSwKVr diLgCpkI6XO2DjjMuGW8vNaCNkqAokhn58ZtOvBnYbV6/kA6w4A5W5wAxqOwyeN+Uzrb0ekTQg8 gX9I0zimgBOPVRAucBxyRIUvm7gFvM5jFuwfKiV8UK+je0lT0jVx021O/5JbfU0= X-Google-Smtp-Source: AGHT+IG/dypEZsLi0EK8J0/rvTSc+51CbkW3LoLi14+8Tu+6+xVO7qZnxOuuvb9SniROnu+2mc+AUg== X-Received: by 2002:a17:902:c40b:b0:223:88af:2c30 with SMTP id d9443c01a7336-22bea4b3c03mr172146135ad.16.1744704863348; Tue, 15 Apr 2025 01:14:23 -0700 (PDT) Received: from hsinchu26.internal.sifive.com ([210.176.154.34]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7c95cd1sm111082335ad.150.2025.04.15.01.14.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Apr 2025 01:14:22 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , 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 , 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 17/17] hw/riscv: virt: Add WorldGuard support Date: Tue, 15 Apr 2025 16:12:31 +0800 Message-Id: <20250415081231.21186-18-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20250415081231.21186-1-jim.shu@sifive.com> References: <20250415081231.21186-1-jim.shu@sifive.com> 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 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org * Add 'wg=on' 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 | 20 +++++ hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 163 ++++++++++++++++++++++++++++++++++++- include/hw/riscv/virt.h | 15 +++- 4 files changed, 195 insertions(+), 4 deletions(-) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index 60850970ce..d2bc65f71c 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -146,6 +146,26 @@ The following machine-specific options are supported: Enables the riscv-iommu-sys platform device. Defaults to 'off'. +- wg=[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 resources + if the transaction contains WID. When not specified, this option is assumed + to be "off". + + The WG configuration of virt machine includes 4 worlds. For WG configuration + of CPUs, the M-mode WID of CPU (`mwid`) is set to the largest WID number, + and the authorized WID list of CPU (`mwidlist`) includes all WIDs. We can + modify the configuration of all CPUs via `x-mwid` and `x-mwidlist` + CPU options. There are 3 wgCheckers in the virt machine, which seperately + protects DRAM, FLASH, and UART. Default WG configuration on the virt machine + is enough to run the demo of dual OSes in the different worlds. For example, + running both Linux kernel and Secure OS (e.g. OP-TEE) in it's own world. + + This option is restricted to the TCG accelerator. + Running Linux kernel -------------------- diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index e6a0ac1fa1..5c3e7b3479 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -68,6 +68,7 @@ config RISCV_VIRT select PLATFORM_BUS select ACPI select ACPI_PCI + select RISCV_WORLDGUARD config SHAKTI_C bool diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index e517002fdf..da873bc8b8 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -58,6 +58,7 @@ #include "qapi/qapi-visit-common.h" #include "hw/virtio/virtio-iommu.h" #include "hw/uefi/var-service-api.h" +#include "hw/misc/riscv_worldguard.h" /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */ static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type) @@ -89,6 +90,9 @@ static const MemMapEntry virt_memmap[] = { [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, [VIRT_IOMMU_SYS] = { 0x3010000, 0x1000 }, [VIRT_PLATFORM_BUS] = { 0x4000000, 0x2000000 }, + [VIRT_WGC_DRAM] = { 0x6000000, 0x1000 }, + [VIRT_WGC_FLASH] = { 0x6001000, 0x1000 }, + [VIRT_WGC_UART] = { 0x6002000, 0x1000 }, [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) }, [VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) }, [VIRT_APLIC_S] = { 0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) }, @@ -114,6 +118,38 @@ static MemMapEntry virt_high_pcie_memmap; #define VIRT_FLASH_SECTOR_SIZE (256 * KiB) +/* 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[] = { + [WGC_DRAM] = { VIRT_WGC_DRAM, WGC_DRAM_IRQ, 16 }, + [WGC_FLASH] = { VIRT_WGC_FLASH, WGC_FLASH_IRQ, 16 }, + [WGC_UART] = { 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] = region; + info->c_offset[info->num_of_child] = offset; + info->num_of_child += 1; +} + static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s, const char *name, const char *alias_prop_name) @@ -164,7 +200,8 @@ static void virt_flash_map1(PFlashCFI01 *flash, } static void virt_flash_map(RISCVVirtState *s, - MemoryRegion *sysmem) + MemoryRegion *sysmem, + WGCInfo *info) { hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; hwaddr flashbase = virt_memmap[VIRT_FLASH].base; @@ -173,6 +210,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); + } } static void create_pcie_irq_map(RISCVVirtState *s, void *fdt, char *nodename, @@ -1426,6 +1472,71 @@ static void virt_build_smbios(RISCVVirtState *s) } } +static DeviceState *create_wgc(WGCInfo *info, DeviceState *irqchip) +{ + MemoryRegion *system_memory = get_system_memory(); + DeviceState *wgc; + MemoryRegion *upstream_mr, *downstream_mr; + qemu_irq irq = 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=0; inum_of_child; i++) { + downstream_mr = info->c_region[i]; + + g_assert(downstream_mr); + if (downstream_mr->container == 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 = virt_memmap[info->memmap_idx].base; + size = virt_memmap[info->memmap_idx].size; + + wgc = 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=0; inum_of_child; i++) { + upstream_mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(wgc), i+1); + g_assert(upstream_mr); + memory_region_add_subregion(system_memory, info->c_offset[i], upstream_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 = cpu ? cpu_env(cpu) : NULL; + + riscv_worldguard_apply_cpu(env->mhartid); + } + + /* Create all wgChecker devices */ + for (int i=0; ihave_wg) { + error_report("'wg' is only available with TCG acceleration"); + exit(1); + } + /* Initialize sockets */ mmio_irqchip = virtio_irqchip = pcie_irqchip = NULL; for (i = 0; i < socket_count; i++) { @@ -1673,6 +1791,10 @@ static void virt_machine_init(MachineState *machine) memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base, machine->ram); + if (tcg_enabled() && s->have_wg) { + wgc_append_child(&wgcinfo[WGC_DRAM], machine->ram, memmap[VIRT_DRAM].base); + } + /* boot rom */ memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom", memmap[VIRT_MROM].size, &error_fatal); @@ -1700,10 +1822,16 @@ static void virt_machine_init(MachineState *machine) create_platform_bus(s, mmio_irqchip); - serial_mm_init(system_memory, memmap[VIRT_UART0].base, + uart = 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); + 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)); @@ -1712,7 +1840,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); + } /* load/create device tree */ if (machine->dtb) { @@ -1757,6 +1894,20 @@ static void virt_machine_instance_init(Object *obj) s->iommu_sys = ON_OFF_AUTO_AUTO; } +static bool virt_get_wg(Object *obj, Error **errp) +{ + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + + return s->have_wg; +} + +static void virt_set_wg(Object *obj, bool value, Error **errp) +{ + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + + s->have_wg = value; +} + static char *virt_get_aia_guests(Object *obj, Error **errp) { RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); @@ -1977,6 +2128,12 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) NULL, NULL); object_class_property_set_description(oc, "iommu-sys", "Enable IOMMU platform device"); + + 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/disable the " + "RISC-V WorldGuard."); } static const TypeInfo virt_machine_typeinfo = { diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 48a14bea2e..3a631a6a23 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; @@ -87,11 +88,17 @@ enum { VIRT_PLATFORM_BUS, VIRT_PCIE_ECAM, VIRT_IOMMU_SYS, + VIRT_WGC_DRAM, + VIRT_WGC_FLASH, + VIRT_WGC_UART }; enum { UART0_IRQ = 10, RTC_IRQ = 11, + WGC_DRAM_IRQ = 15, + WGC_FLASH_IRQ = 16, + WGC_UART_IRQ = 17, VIRTIO_IRQ = 1, /* 1 to 8 */ VIRTIO_COUNT = 8, PCIE_IRQ = 0x20, /* 32 to 35 */ @@ -102,7 +109,7 @@ enum { #define VIRT_PLATFORM_BUS_NUM_IRQS 32 #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) @@ -158,4 +165,10 @@ uint32_t imsic_num_bits(uint32_t count); #error "Can't accommodate all IMSIC groups in address space" #endif +/* WorldGuard */ +#define VIRT_WG_NWORLDS 4 +#define VIRT_WG_TRUSTEDWID 3 +#define VIRT_WG_HWBYPASS true +#define VIRT_WG_TZCOMPAT false + #endif