From patchwork Wed Jun 12 08:14:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694613 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 D8DF7C27C53 for ; Wed, 12 Jun 2024 08:16:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ80-00029M-88; Wed, 12 Jun 2024 04:14:44 -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 1sHJ7y-00026I-9o for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:14:42 -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 1sHJ7v-0006HM-V5 for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:14:42 -0400 Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-1f6fada63a6so29662205ad.3 for ; Wed, 12 Jun 2024 01:14:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180077; x=1718784877; 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=XwMwVBT0fP270rWsEHSo2631M0ztS9piF83iSzYOuzw=; b=N8bpuZp7gD6N3q70+D4kOG9fzrpjMjZT5hjOOWEXGHc4/lMrxDAfg9lokzwOR/Sbhi MxO/uAJVrfkSTaHtN6XVLBn3i7JcY2LO/ijoT6xNDwZm4Tiox79vPDyLaNq7hWamb3J4 X9sJ3cQLkvk0fP44T6LKwxJ1T0obyMWdtg8fFKcBJTgMDAAcu3wbn9j5/emZWkW32b/+ e6oN0sKMtJiIZ11rtlKjsSTDAHcwoCcefpK3Vo6brAvbG+WbBeOxgyAO3ZuQfA4cIzyN P5cEk5DhdsbdJF2/ZEVQ+rvf0cBjJ7XMyHLdEN6WdWr09HpjM6uCTFVkgYgbmfO2mGBp SGpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180077; x=1718784877; 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=XwMwVBT0fP270rWsEHSo2631M0ztS9piF83iSzYOuzw=; b=oVqRJvsJNBjGGD+RIOcAEPQckeH1r6Yh0ubA8+dqRKgqRklH77U4mNc55Bdd9AOW61 seuLf1miMxfhfoORbOLKAr7sY2sUfx5FNshan1vABLiHih9jB85pMIdrDiEavsk9o37G GR19/pZ8hMxMA2E53UmUVeUIpY11+McgxwxRT1v79XO5WoG0Xo1+eoOknXS6nuiwhCi2 9dBdC7xvp2Ld/nphrxmMlmri8YTkAT/JoooyhxbWimrCLXgVqEwMFBc9yupToBnEZBB+ Si+5YFe6+JgV8CD9LflJ/ynFPLiKBH/NG1w/4uUCPdiOIszcafrFtm13t3MdZlCUcDia 8N2A== X-Gm-Message-State: AOJu0YxNQ9BvAfmVZkLm5D7EeLQh0MUScoEXauR1QqWw/b5q+K4ABAXj AuWqtSMXydXkF7SYbIzF/lKH5lcOc1TXzUlFS6pENQR3ijvSs3FQFr16t8WnQb9v1s6CEy2J5Vt oDn8+p4q1vgWIU2ihe7xtx8DNYkBFETecEmHPImM6Uq6UkI9ZWWtzwwpmQPIYRxdGTglL7MXwu8 esf9jnenriciRlDOlevJqAfBJHKU7Oq1VgWDoWBTG4Eg== X-Google-Smtp-Source: AGHT+IEo1bK99dcUiJWk+0Vs1vbfw/dSUmok49xRm+S/vMWu5IGnR7xF0K7Wa7r8B36J57d42xYrsw== X-Received: by 2002:a17:902:dacf:b0:1f7:9fb:9d0c with SMTP id d9443c01a7336-1f83b74260emr11841995ad.56.1718180077162; Wed, 12 Jun 2024 01:14:37 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.14.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:14:36 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 01/16] accel/tcg: Store section pointer in CPUTLBEntryFull Date: Wed, 12 Jun 2024 16:14:01 +0800 Message-Id: <20240612081416.29704-2-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 117b516739..8cf124b760 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1169,6 +1169,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 */ @@ -1248,14 +1249,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); @@ -1571,9 +1572,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 { @@ -1972,7 +1971,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(); @@ -1993,7 +1992,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(); @@ -2513,7 +2512,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(); @@ -2533,7 +2532,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 a2c8536943..3f6c10897b 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -217,6 +217,9 @@ typedef 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 Wed Jun 12 08:14:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694614 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 DC37FC41513 for ; Wed, 12 Jun 2024 08:16:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8B-0002CL-3B; Wed, 12 Jun 2024 04:14:55 -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 1sHJ89-0002BH-UM for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:14:53 -0400 Received: from mail-pf1-x432.google.com ([2607:f8b0:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ86-0006IT-9O for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:14:53 -0400 Received: by mail-pf1-x432.google.com with SMTP id d2e1a72fcca58-70435f4c330so1635886b3a.1 for ; Wed, 12 Jun 2024 01:14:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180087; x=1718784887; 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=EnRKmLCd3tTTNF000mNJdg96ExcPAjbIehkU3yaHeR4=; b=LlhhuXhXzzSXpCQ0/ksG9Sa7Vm9NIuhbwIkb/xcuX/K9EIry5vzHFD9cA+bAkMGuNm 04mKWDtpVEFKsMFB6FLl5IAtXueWga/46L+WrfmPBSCp2E6mYUCLUxVASjcx4cZiWSbE 928fRli9enZQVz1FK3qJkz0eFc2vyJ9oIXxGJx9rdRX++Jbd2nvt359R0S14H5HL8HVs oogHtN20C4LSsx3xyoz+rjSErk/ZBIpcX6K2FZEiFrpCpCq6rJVNP6B7j6w/HP00CDfz pHyrYF07QTgvLogwY7w5s0N7Cm7IZqmRSraF5B5ZHIx16wq+gkKDtpP1UsD0K4fdntqQ EM9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180087; x=1718784887; 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=EnRKmLCd3tTTNF000mNJdg96ExcPAjbIehkU3yaHeR4=; b=nJPwnVBDCZj8Bc2CW0qNeC8kwIKW73jaTVPuMeVU2wPor4cxFrtgLgPhGwu4wWe30r j0TewNh7PE1Q6bOk/TelTPigVXKPpOMxV83YHpukp7ooUC9XzpPL+RIO6m7gwXR+tzKh iQ676fUeW3xQTdWs1c6uQ0Oy9TvUs2xrr9s+4YGaYA4k054wvRhLzAC/COcXbg9v7l4+ D+cWNPIIxKht8VnS/2/N0LYAgxhawxOHoJ/laGA3RHUvCyTNSrF5AVlO1oGe2uD08aPD n55haP4058RzOn8lyZN0RUiiwKoi2Z0Irr4srRgWW95Ectb1/5hWS2E6qmddzUXXozqI 09ag== X-Gm-Message-State: AOJu0YxNYIUzr0Dd+hCHMH1KqLzHP8D8iNK0/L5YBnk+g+wpjpFEZdF2 BsRWpoiwxYOUfpFjPjsVS3mlBFRlrJioM5F/cJEeFs4q7pYrsJrCMfCgehYUTlYrg3GgB6cUen8 ST9+kzzalJ2ZIrcPs7Zaew4WwYuxCiD5uhzqCLWPkt5uRbSm0ocEBdLWNi9tQxw77aBuOA33pun jvUSSoH2phjpXImLE8L5//PAIsOqCCA3t2k2vKNZQDMw== X-Google-Smtp-Source: AGHT+IGWlon/ISFN4i9A53CaDMMAPipk99P9n7vrPkOWhZGMNrV4ht77HI7oB5plpt7aCs8z+SBucg== X-Received: by 2002:a05:6a20:bc9b:b0:1b1:ed9d:f92e with SMTP id adf61e73a8af0-1b8a9c2c72bmr946171637.38.1718180087187; Wed, 12 Jun 2024 01:14:47 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.14.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:14:46 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 02/16] accel/tcg: memory access from CPU will pass access_type to IOMMU Date: Wed, 12 Jun 2024 16:14:02 +0800 Message-Id: <20240612081416.29704-3-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::432; envelope-from=jim.shu@sifive.com; helo=mail-pf1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 | 15 +++++++++------ include/exec/exec-all.h | 11 +++++++---- system/physmem.c | 16 +++++++++++----- target/alpha/helper.c | 2 +- target/arm/tcg/tlb_helper.c | 2 +- target/avr/helper.c | 2 +- target/cris/helper.c | 2 +- target/hppa/mem_helper.c | 2 +- target/i386/tcg/sysemu/excp_helper.c | 3 ++- target/loongarch/tcg/tlb_helper.c | 2 +- target/m68k/helper.c | 10 +++++++--- target/microblaze/helper.c | 8 ++++---- target/mips/tcg/sysemu/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 ++- 22 files changed, 61 insertions(+), 42 deletions(-) diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 8cf124b760..f1b07f6926 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1036,7 +1036,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]; @@ -1063,7 +1064,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 @@ -1200,7 +1202,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, uint64_t size) + MMUAccessType access_type, int mmu_idx, + uint64_t size) { CPUTLBEntryFull full = { .phys_addr = paddr, @@ -1210,15 +1213,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, uint64_t size) { tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED, - prot, mmu_idx, size); + prot, access_type, mmu_idx, size); } /* diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index b6b46ad13c..0d5363ac02 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -205,7 +205,7 @@ void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu, * used by tlb_flush_page. */ void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr, - CPUTLBEntryFull *full); + MMUAccessType access_type, CPUTLBEntryFull *full); /** * tlb_set_page_with_attrs: @@ -231,7 +231,8 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr, */ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr, hwaddr paddr, MemTxAttrs attrs, - int prot, int mmu_idx, vaddr size); + int prot, MMUAccessType access_type, int mmu_idx, + vaddr size); /* tlb_set_page: * * This function is equivalent to calling tlb_set_page_with_attrs() @@ -240,7 +241,8 @@ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr, */ void tlb_set_page(CPUState *cpu, vaddr addr, hwaddr paddr, int prot, - int mmu_idx, vaddr size); + MMUAccessType access_type, int mmu_idx, + vaddr size); #else static inline void tlb_init(CPUState *cpu) { @@ -591,7 +593,8 @@ void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length); 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 b7847db1a2..a5a0ea77bd 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -674,12 +674,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; @@ -696,10 +698,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 2f1000c99f..7ea548f1d0 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/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index 885bf4ec14..186c612957 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -361,7 +361,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, res.f.extra.arm.pte_attrs = res.cacheattrs.attrs; res.f.extra.arm.shareability = res.cacheattrs.shareability; - tlb_set_page_full(cs, mmu_idx, address, &res.f); + tlb_set_page_full(cs, mmu_idx, address, access_type, &res.f); return true; } else if (probe) { return false; diff --git a/target/avr/helper.c b/target/avr/helper.c index 345708a1b3..07d795848e 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/cris/helper.c b/target/cris/helper.c index 1c3f86876f..644244312c 100644 --- a/target/cris/helper.c +++ b/target/cris/helper.c @@ -68,7 +68,7 @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size, phy = res.phy & ~0x80000000; prot = res.prot; tlb_set_page(cs, address & TARGET_PAGE_MASK, phy, - prot, mmu_idx, TARGET_PAGE_SIZE); + prot, access_type, mmu_idx, TARGET_PAGE_SIZE); return true; } diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c index b984f730aa..0a42d47ce9 100644 --- a/target/hppa/mem_helper.c +++ b/target/hppa/mem_helper.c @@ -461,7 +461,7 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, * because we record the large page here in the hppa tlb. */ tlb_set_page(cs, addr & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, - prot, mmu_idx, TARGET_PAGE_SIZE); + prot, type, mmu_idx, TARGET_PAGE_SIZE); return true; } diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c index 8fb05b1f53..c7a53a1179 100644 --- a/target/i386/tcg/sysemu/excp_helper.c +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -610,7 +610,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 d6331f9b0b..7f9a44128a 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -490,7 +490,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 7967ad13cb..e63ebe4e18 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -967,7 +967,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; } @@ -987,7 +987,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; } @@ -1459,6 +1460,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) { @@ -1466,9 +1468,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; @@ -1478,7 +1482,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 5d3259ce31..5229daf1d5 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/sysemu/tlb_helper.c b/target/mips/tcg/sysemu/tlb_helper.c index 3ba6d369a6..90b9668bd0 100644 --- a/target/mips/tcg/sysemu/tlb_helper.c +++ b/target/mips/tcg/sysemu/tlb_helper.c @@ -931,7 +931,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) @@ -949,7 +949,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 c632d5230b..a04003c37e 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 b0a0676beb..dd264ac335 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -1368,7 +1368,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 6709622dd3..161df34626 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1419,7 +1419,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 8a584f0a11..2e0fd20aef 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -163,7 +163,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 4c0b692c9e..bcd9f80474 100644 --- a/target/s390x/tcg/excp_helper.c +++ b/target/s390x/tcg/excp_helper.c @@ -178,7 +178,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 6702910627..00b06898b7 100644 --- a/target/sh4/helper.c +++ b/target/sh4/helper.c @@ -807,7 +807,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 9ff06026b8..1dade2eef8 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 7014255f77..295f515772 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 ca214b948a..3a155638c5 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -280,7 +280,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 Wed Jun 12 08:14:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694617 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 086B3C27C77 for ; Wed, 12 Jun 2024 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 1sHJ8E-0002Fu-M8; Wed, 12 Jun 2024 04:14:58 -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 1sHJ8D-0002Es-BF for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:14:57 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ8B-0006JY-Fi for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:14:57 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1f64ecb1766so50546675ad.1 for ; Wed, 12 Jun 2024 01:14:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180093; x=1718784893; 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=N1D0EBwsV6VQtcv780/DUEjjt7vhGVA63Te3ctWhZfA=; b=mti9qCRsNJmelYIZR/D/m3ezfW3mxqAD7hGR4vnie+B3dDRqxjcd0XSWdzAPcAjl8h /ALR2RQHk3Oaxb7nqqmovjpBQw5GfCAd8Xchpn+SRwNFY+uc9IlnaSvDi0eM11N14vZN j23lYgRUCgci6ihTZS3lRHmmfRWDLYP/F8I7/mMT2BZVYm7JtPID2TEMUJ42aa0T0g56 88KnZMyspzaDVC+Nf7ZTHp1dqBZVOf/w4fxoAgqEACVQm6F2CLCwkN8GHJs4FCqEWgVc Crj5WOC3cJMb7nduWEGSrGUiUoCyvQ7lTHKlRC+xjzj6yd6pW7d7k/Xn85PDHu8AfS22 LbRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180093; x=1718784893; 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=N1D0EBwsV6VQtcv780/DUEjjt7vhGVA63Te3ctWhZfA=; b=wmO8+I0EszqRm61dL8VvULxMc+3xjfVoJxc//77maJVKPAQNAAWF01MTBBeyh+iN3I aL7avKYWbt5vBvaPTkV+htgt8AHhokUAM4Dhh85PQt5yPGb61+sQUMoRg+PJS/xdcYBg 4xT8KGHIHRBQgfYRz8DiF7ugjDsfGzdRsbaHw0gAkwqMawgvGBCJRAmdqjtOw/dLP/+M g8246ofP4cIvNwgplHGXZNy/Wx210jzlEN/6sEbvBYEuvGl+rMxdEUW1MWD5fxy9CADC ZPf8sOdpwFVbDBHQtyaJsi+9IoIsTPLKF6lAAn6mCaY+Gv37hVT3nR8KBiNCaWGm5LwM gQ2g== X-Gm-Message-State: AOJu0YznfUOTxWVMAzgF7VJio5+ijKAhIxNKbmhBdsWL89x15Hx+V5GZ oa9kPfMAWQrCzDDx9LKZN5/qxd7T6PihzRtXbMM50S18CB/AtIfLaNOLTPFZIgNjafzueVCfi8m 0mBzFFWruqV1osFqwMurxN1raWkscLbmRdJfMtULE3mDtJuiJLA5y1LA3oVdTvf2oNl+AMKemTk qivU+AGf61s7Ucs8aRu+W4pCqBfh3LPVYGNeLPDy37xA== X-Google-Smtp-Source: AGHT+IHAWHsJkZE4953kpysrVK4yCFesw23yF64Dnflq1Ntro1lAaQJsWtSgpvQzgG6J5tDpW9DiUA== X-Received: by 2002:a17:902:cf08:b0:1f4:71ef:98f8 with SMTP id d9443c01a7336-1f83b6990aemr11303805ad.16.1718180093024; Wed, 12 Jun 2024 01:14:53 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.14.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:14:52 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 03/16] exec: Add RISC-V WorldGuard WID to MemTxAttrs Date: Wed, 12 Jun 2024 16:14:03 +0800 Message-Id: <20240612081416.29704-4-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h index 14cdd8d582..d00f3c5500 100644 --- a/include/exec/memattrs.h +++ b/include/exec/memattrs.h @@ -52,6 +52,11 @@ typedef struct MemTxAttrs { unsigned int memory:1; /* Requester ID (for MSI for example) */ unsigned int requester_id:16; + + /* + * RISC-V WorldGuard: the 5-bit WID of memory access. + */ + uint8_t world_id; } MemTxAttrs; /* Bus masters which don't specify any attributes will get this, From patchwork Wed Jun 12 08:14:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694634 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 437EDC27C75 for ; Wed, 12 Jun 2024 08:18:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8N-0002JO-1k; Wed, 12 Jun 2024 04:15:07 -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 1sHJ8L-0002Iv-HI for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:05 -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 1sHJ8I-0006Le-SU for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:05 -0400 Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1f6e183f084so34065145ad.1 for ; Wed, 12 Jun 2024 01:15:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180099; x=1718784899; 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=htuMZxd9RVqlZETMagy8fsRybQcg5cD/2wiawbgeZIg=; b=FRUfg/gVw3Oxt4TX8NWhjtqz9ZanX2FS0qSuk0kaAJpUjfccp2JsTW/zkargcP17jv GJjF3/77nsPUBWpHFB+2PZp1AL3M1Okn+0zzaW0OTj3PZKTlpdkntUYcbu1Gji80pzIX TMSVF1PzrIiWSxDLzKHyWTmvdz7CzDOUt2Bjwar66M/OLoac5pVZ7kb4o2NQckLiOgzS N6aakZ/7YuwpGzEiWMHukcLSBxLL6/qA10b0Qqn3GwGqw6lRd40DvOkb/XACOQP4ulEM a6vS5/0avLB6jwidtaUj2brawpJBEdFyY+RDOcsVg/FUCEZ2JK2t0iK/gIXntM9sk3+O 0HJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180099; x=1718784899; 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=htuMZxd9RVqlZETMagy8fsRybQcg5cD/2wiawbgeZIg=; b=krKMQ/9ClJBacn3M2oyLZ4i3m72LZbyTVJUJlP0YjctwZDXcCY5Nkj3oAQdX1oyoX5 Qc0M0O/a7AoQcRdEVGlH0xab8jiFPi9T4sDath616viPEs/bDKi5yB7E1M8oMu1j3Agx PaxR7Z2SZ9qlaxfiVCzzVEwPWJyPnsrHT4HKMjyY59Sy8kvxMU8/wR9Q1zjYi4jZJUZi jzfXpphsGaDOkLN0n4Tc/l9topr5cTrYDI2f/5+OAzmCjTtgDtqv/lyWXheZv88nCgBM EE/2+Xjc7zIDDZF5x0LQvd13NmlxvLgLwdITSStloArGJKXG5FxUv4X/cViXmLM9rEFZ K5vg== X-Gm-Message-State: AOJu0Yw3zDXyJ0UjBTzl3Pov0nodDiwnsI0UYbldLXqkaY0m11LBMGsY jQA/G+fTjAQZc/0nsDawkkXEK1zJFNARdEiVXFQZfwcO6RFCv0K2Nr5tMOU9yIbtsRa3ZD4+AIC g7L+OXvDUG5/7Ai5EYuKmRJjzmJTLQOp1Fp0/HOo8KEitAVqdlspWoTl1qvDV+MtnS+itM2wmg3 +Rh6+LEdWBO3UeA7zjwXfCrrJR6p9ZcykWoh73CVRRGw== X-Google-Smtp-Source: AGHT+IH0NPHsJ9joimlSunHKOZrAbuxsmWvanZHC0tGwoZHwOCxvzYU4tYx3PvGFmGYZRHsKj9LYOQ== X-Received: by 2002:a17:902:6546:b0:1f7:1931:7a8f with SMTP id d9443c01a7336-1f83b709a39mr10224655ad.64.1718180098732; Wed, 12 Jun 2024 01:14:58 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.14.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:14:58 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 04/16] hw/misc: riscv_worldguard: Add RISC-V WorldGuard global config Date: Wed, 12 Jun 2024 16:14:04 +0800 Message-Id: <20240612081416.29704-5-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 | 183 +++++++++++++++++++++++++++++ include/hw/misc/riscv_worldguard.h | 55 +++++++++ 4 files changed, 242 insertions(+) create mode 100644 hw/misc/riscv_worldguard.c create mode 100644 include/hw/misc/riscv_worldguard.h diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 1e08785b83..08fc0f2b8c 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -213,4 +213,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 86596a3888..a75668ff86 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..c839cc4e87 --- /dev/null +++ b/hw/misc/riscv_worldguard.c @@ -0,0 +1,183 @@ +/* + * 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), + DEFINE_PROP_END_OF_LIST(), +}; + +/* 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 Wed Jun 12 08:14:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694629 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 DF4BDC27C75 for ; Wed, 12 Jun 2024 08:17:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8Q-0002QT-DN; Wed, 12 Jun 2024 04:15:10 -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 1sHJ8P-0002Q3-I1 for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:09 -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 1sHJ8N-0006Mr-8p for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:09 -0400 Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1f68834bfdfso48623545ad.3 for ; Wed, 12 Jun 2024 01:15:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180105; x=1718784905; 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=t/AUOAInjkFfC7EhRiJBRMiTPdQ2lCm4ch6BlghBPuU=; b=aX6MP6oDirKKIplRDKeNZtxcVMIAo9p5Z1/F6DMVPKMte12z8pyX5h5YXaawEhAOnB NELYJRlkQy0sscSUAvsggWIdTD6pOANS2/+Tf6xwH3Vtu0oLmPvPieAvP0QHoDTcDMK6 kfjJcxpENdHZ9Xcw2SxjvrqIz2caErFVNyQkVVUJnx3lcQP9hooU55OGGbtGsAOJ3Of8 0SwJIrmLnByEUhCI+hqizlSemZrJLl0ZlhBSjK2Eh/KfPSLIX2AS7l2UGqgx9r8GC2LG mgRUN6k6BVWgPkpj2LXDZfOHOnYtnNCjWjXCp5Z0vdJDXkftyr9YdIBmW5FTKlx/cMhx nxtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180105; x=1718784905; 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=t/AUOAInjkFfC7EhRiJBRMiTPdQ2lCm4ch6BlghBPuU=; b=kbS0tTgadsgjiHizjkkwSyYKmcpl5zlxpStZMR1iPotILSMJV+GqNpQJyu2ZgUWvo/ jm6gVP4BZLG9bwelCkeY8SrIByEnUMmmyhIycIk7OFkYAQllahCmRJw4nEA8Mi6VZqcl GZ8YBVUErbrV3DEySbklAShXe4Fke/kQdA1orR+I0FZnYoSUZKEDJOZFxG/uXAHRLcQz 0jjKJRnrNxd7tSw+HtnmCbarFfn9yCbHDVWLh5FwVWlCeL4q4VHN/iw7a1AqZfDOz/10 CjVyTrzOohjnWM88MztfYj0ma3Bmd6kexExf3NO4hvoFnph7yop2LrPR4YwwCOdsutWa 9Lug== X-Gm-Message-State: AOJu0YwtWeQGOMKJTgTbi64GFy4Od5nD6D0h0BqTN9QHvk8QM7o1GuBk NjAzhy5HYkH9x5+qLQd2Z8SS1JIvByNnScV0PJdE06rNjLbya+Wd6FMjATDEwlivfkPS87NB+Vu hahiuwqtt6LhFZjrv2FIHNQh76dbBlig+dVhc+y/5DPRHzOQ9mCfnY4ycvPSqJGg6izErm8ZQs3 KTYL5btVNMvBxRQ6EICFdpwUNJVroqnI+ARZ/tbJsaGQ== X-Google-Smtp-Source: AGHT+IG5wJthYOfktPwpbknyCYAna1CFTxUI/ODaFFZ95fOwIwfQ0NUj0LE3JyOUAyDJz83FyZgtZw== X-Received: by 2002:a17:902:d48b:b0:1f7:345a:e23d with SMTP id d9443c01a7336-1f83b6f6b61mr11145425ad.31.1718180104409; Wed, 12 Jun 2024 01:15:04 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.14.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:04 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 05/16] target/riscv: Add CPU options of WorldGuard CPU extension Date: Wed, 12 Jun 2024 16:14:05 +0800 Message-Id: <20240612081416.29704-6-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 | 8 ++++++++ target/riscv/cpu_cfg.h | 3 +++ target/riscv/tcg/tcg-cpu.c | 11 +++++++++++ 3 files changed, 22 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 69a08e8c2c..d70eedf957 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -204,6 +204,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), DEFINE_PROP_END_OF_LIST(), }; @@ -1595,6 +1598,11 @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = { MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true), + /* 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), + DEFINE_PROP_END_OF_LIST(), }; diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index e1e4f32698..23e779ae08 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -120,6 +120,9 @@ struct RISCVCPUConfig { bool ext_ssaia; bool ext_sscofpmf; bool ext_smepmp; + bool ext_smwg; + bool ext_smwgd; + bool ext_sswg; bool rvv_ta_all_1s; bool rvv_ma_all_1s; diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 683f604d9f..dc86e6e1d5 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -726,6 +726,17 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) cpu->pmu_avail_ctrs = 0; } + /* 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 Wed Jun 12 08:14:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694626 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 7241AC27C53 for ; Wed, 12 Jun 2024 08:16:42 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8W-0002YJ-1V; Wed, 12 Jun 2024 04:15:16 -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 1sHJ8U-0002TN-Lm for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:14 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ8R-0006Oq-V8 for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:14 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-1f6b0a40721so47263005ad.2 for ; Wed, 12 Jun 2024 01:15:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180110; x=1718784910; 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=el4zPCh6MA7yt0wMvmZSek8pCRQ+TGyMHlmrAHD52rE=; b=IyjLIFnLWBqQEQf0CjX9WVC+1vXR0OLkkwm45PpzJnTG/iMacunwHpv+GTV9Y7VXoj H3SXzR2zfJp03hd7ZayRWZmJrGJkWAJfprb0FQSWBcyzNF2qw/tfd6xSLaMdMIziEWt0 Bzfy/7Y3IRbUBj7/6A4fa+aZE42kP74izi88UGUrClJ7d/7RhPJ5DteHGOhsFSyvyLH0 XysDDdbcvlFCODE4cH8mHHAaT4TKHJlX6ylaOYwSbVNUyydtQNn+b7RPmkBMJpNF3PGO R01+n7lKu5UmTvLBP+mE51DpEFW/yrschOtSJBL19lJUQu7iXbrtYAVFnyHP5DBXtV+a UnIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180110; x=1718784910; 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=el4zPCh6MA7yt0wMvmZSek8pCRQ+TGyMHlmrAHD52rE=; b=rYrhayyx3NcQZZUsGbk3/hRq64WHUvVO+0v9wFYUW/dKOTOr5C+T+jmyEKpob2eEsQ n3r5B6+d3Il/Fsp8zDmUE+gARiRzZAmiR1aUtGYBWJ64hxZRxrueEIU4fXsOwyA+3/dG q4aXufMqxBU2wYp3gzC2CitTcpNxyabhzr8gfMX0+tJ2v5R5ELkR7/qpxW09SzP3DZcI QnxaH3ERbbZ3dDad8cOTWyv8RwHaD0qBs9nXtXGO596QaGFFKmDL3j9TnQdZv1T387H0 wXTviC4XIwewb/15rS0vxzIMpMHig1BSo6vvYIArG3BSNGrZaZZq3pRDjYlzcFKrMFSr 2/iw== X-Gm-Message-State: AOJu0YyQ5US3plRfQ9c06SHuCiFC8jfnjFSrK0zlldgmd3HXK7/Hsu2G qFP/qACurIjwHpA0cyZKi5vF5jIqveQRd25DLTF72WPeFCJldwi50qbKjMVAnoJbQbRAWR+mPPT /XhweKbNRD+Q5/zYQDeI6bATPTJcdMJOFT3NWNnGymyBGxJ9oUSJJcRIlZ1WrRpNLHrcHEl5Y4R /0KH5zqJn9VkRYIdZo1J0xtDRoE3dR8y1FdWAIgx6AWA== X-Google-Smtp-Source: AGHT+IFnhn4/AVuIA7BK0PPox1Lg0y+LEUdi4+TqzWjD8p+wIF7opIsUWNHMprWx0xcNxlpH593RHg== X-Received: by 2002:a17:903:983:b0:1f6:39d8:dc4f with SMTP id d9443c01a7336-1f83b55f8ccmr14197785ad.10.1718180110071; Wed, 12 Jun 2024 01:15:10 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:09 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 06/16] target/riscv: Add hard-coded CPU state of WG extension Date: Wed, 12 Jun 2024 16:14:06 +0800 Message-Id: <20240612081416.29704-7-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62d; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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.c | 2 ++ target/riscv/cpu.h | 2 ++ target/riscv/cpu_cfg.h | 2 ++ target/riscv/cpu_helper.c | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index d70eedf957..4e87fa4d5b 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -2291,6 +2291,8 @@ static 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("mwid", RISCVCPU, cfg.mwid, UINT32_MAX), + DEFINE_PROP_UINT32("mwidlist", RISCVCPU, cfg.mwidlist, UINT32_MAX), DEFINE_PROP_END_OF_LIST(), }; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6fe0d712b4..2d3bfedbba 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -540,6 +540,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); diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index 23e779ae08..de9c134b15 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -166,6 +166,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 161df34626..ff20ab6ab8 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -149,6 +149,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 */ + void riscv_cpu_update_mask(CPURISCVState *env) { target_ulong mask = 0, base = 0; From patchwork Wed Jun 12 08:14:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694631 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 B54BBC27C77 for ; Wed, 12 Jun 2024 08:17:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8c-0002iu-3q; Wed, 12 Jun 2024 04:15:22 -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 1sHJ8a-0002hO-LG for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:20 -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 1sHJ8X-0006Pm-Um for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:20 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-1f44b45d6abso52242005ad.0 for ; Wed, 12 Jun 2024 01:15:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180116; x=1718784916; 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=UcDgwLrJ/vJ0LXvTIFwEowSYV1ch13n/xdEVQi7gzwg=; b=V7dqK03Yx9eDJ3inOzyA/GRofWPe86ycGZze/x7o1MqaYfSnRQ27RosOKXOm7X8w61 kL82GgTUK2R/E4OWvIKDjWS96Jdsd1zASo1DYLJHF9uJIhS2ImYvPEMHc663zFovoQgo rkse+eQbcAgM7WJCFkTopP5Gt8cKm68U+ddhJI+LyEp3fStn6HAk5mj3SVMwSkPmG4EL YSk2JOQ0y8Zs5zfQd6O69xE9lner7k+6MkT3lBRZI1pJIVmiGry9FBdMW44wohXtRs26 qA8fkLSWXZIdd2ouL3axajUpPW1NfQdHqs1Uhl6nChoCqw1Zvoo/KV7oX57Hg52bxxML YA2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180116; x=1718784916; 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=UcDgwLrJ/vJ0LXvTIFwEowSYV1ch13n/xdEVQi7gzwg=; b=aRfywJf4jueamut6o6HFj18OeIRZqmWdA33dZFdA1FAPTfzlKs5Q8vlBqIdiGWZEEJ LKo2A3Pz7j99ogjD1lvGrq+NKCH9NLpL31Yd4oD/puGf6agn/Lma2NzOwvwS709Zh4vJ RFsB3AKFKPGDg4CVxrksnKNhnKro65YD0MMkq0tKsEgLzooJNoueYFXvHbjZfyE91nbs cc2z8sp8EYtovajv9qckd6oqJ/+SQh8hdvoiy83ZA2jg8rVEYviJIB4DhC6F2q5PEWD+ QdE4gdEnC2dghD6oRrtaSYNZDyZfBSEUPGCQ2ztCIg1F+tvoF3JDiLejHTrBtqwD+Fsm J9qg== X-Gm-Message-State: AOJu0Yzj991Oh9EzAkoEvA6Y84h5EdThUubKJ2N0j7qGmk5dvwOIOjVI 5rCXrx+KXzh5UC7xJEcd2wxiRZnrdGmhi4WVrCGRmVaWYMZEkIMIcVEnpbHP2CIzuC53I4BDJ+0 vUsVCZkf9Y1xRaJjhe7h3wnSWiWfOxWyVXQ4p2IXIGXZ83aR+q8BnT6Q/GHpMOO4L7sub3jfGEH SX6urmogj08+kJKVv1JN2AWWHfhThvGBBelC4BNnGgGw== X-Google-Smtp-Source: AGHT+IFJgYDmFtlEPz+ZdnPNMvTRVXP2I6U3BKMOCznksrq2qjqXVGEPeamRrREJOhgaIl3R3IbUDA== X-Received: by 2002:a17:902:db04:b0:1f7:17e4:b57b with SMTP id d9443c01a7336-1f83b6abc85mr13533535ad.23.1718180115817; Wed, 12 Jun 2024 01:15:15 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:15 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 07/16] target/riscv: Add defines for WorldGuard CSRs Date: Wed, 12 Jun 2024 16:14:07 +0800 Message-Id: <20240612081416.29704-8-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 74318a925c..3ea8a8e9a0 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -360,6 +360,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 Wed Jun 12 08:14:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694616 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 A0877C27C75 for ; Wed, 12 Jun 2024 08:16:23 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8h-0002rJ-H1; Wed, 12 Jun 2024 04:15:27 -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 1sHJ8f-0002l5-Np for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:25 -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 1sHJ8d-0006RE-No for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:25 -0400 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1f692d6e990so61548725ad.3 for ; Wed, 12 Jun 2024 01:15:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180122; x=1718784922; 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=cAY0jW33Nj782SxENctmS4bNW7VRXFYMi+Au2pU8GGg=; b=AkFChHSRi9FuDXAqDe2qDD5ieYTd44LLsZ5Sml08XQezQoyaBUBucwFB5kYOVyCinF bHk7o90d9ajMeiWFAdegIg4F3OVxHCCZZQT1vE/YEUk+tTOzjPmtvT4GqmyoROlWU6+W L76ORVFZPlULW46bopTc8Pbh5wKATpSbMHHUBLT6cl+p4CzsaQEWcD+JF9tGcsHw8P4o 6psMSWgAt6tvs4PRsiLhlFKz30tWPnfyia2B6VTIHei9ZVAYtv8Dsseop2BiJ5gT0DGQ llCdAKZtVQ6XlCw562lBX6A2mUgobCptAkuE5cLAVA7WAzwOmh/amDqkn1BeN3gS9UPm ypIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180122; x=1718784922; 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=cAY0jW33Nj782SxENctmS4bNW7VRXFYMi+Au2pU8GGg=; b=oUnILmrIBBWKAEMIOK2txPDz4RrekqPTRZmRFc/kaRg2SQzq6vZh1j1xt0DB5jCZbJ q2q6/rffW1136/qEGf6SywHio93uxELihT2rqC5C9D77b1p/T1jaaPj74dZp3XVk96qS H/pIEPFsLfpPuIxeaRVVY9/AYtM2D4CIlT9unMlkjqozA8XYFTWwXzENm8//wmAcz1td K84IWtOgAxh7ktHalDsiAvKGkQYcVaTtjaFunYQHl9OMNjzO4NsSeDh4oZunCqMb8fUs AjZ/K6GfsaJ7BJgxRuTJahLisXQ4xPHlSZ1kT1c7XYDRMx6Y/gp4GVPyB8ZzSjgZ973M VK2Q== X-Gm-Message-State: AOJu0YzJwyEAHv8NRH5Za/6h0hnTvmsws4P7vuo4E6L0iy4ETAAo14OI go6FEfoNcWon9woNWkJyPMYabB8gBxzF0RS7XpzIU6rkP2Htr+0trSFhFCdfjX784A7opWxQ9XG qRkMqyc/XRWReAchQzH1SqWS3giwjabypaPfRoAN95sxNmYJ1oMhjRS8LaaHdzcLbuDl/ijV2d6 p0589C6K4ak2rxXypUcte+XaKgaUaTvlvKzEyjsgg8rg== X-Google-Smtp-Source: AGHT+IHUiZ6yRJPovFi3wuSKb1lIaXMYW52Ig2N+KD3BR2hpJOErLSMsS3A/wsHOygy4d4Z3kX5hNg== X-Received: by 2002:a17:903:234b:b0:1f7:13b1:753f with SMTP id d9443c01a7336-1f83b5e1de8mr13440535ad.22.1718180121827; Wed, 12 Jun 2024 01:15:21 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:21 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 08/16] target/riscv: Allow global WG config to set WG CPU callbacks Date: Wed, 12 Jun 2024 16:14:08 +0800 Message-Id: <20240612081416.29704-9-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 2d3bfedbba..50a0fba127 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -431,6 +431,10 @@ struct CPUArchState { uint64_t kvm_timer_state; uint64_t kvm_timer_frequency; #endif /* CONFIG_KVM */ + + /* machine specific WorldGuard callback */ + void (*wg_reset)(CPURISCVState *env); + void (*wid_to_mem_attrs)(MemTxAttrs *attrs, uint32_t wid); }; /* From patchwork Wed Jun 12 08:14:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694618 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 F29EFC27C53 for ; Wed, 12 Jun 2024 08:16:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8v-0003Ob-J1; Wed, 12 Jun 2024 04:15: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 1sHJ8n-00035B-6F for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:38 -0400 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ8k-0006TC-NS for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:32 -0400 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1f6da06ba24so40419335ad.2 for ; Wed, 12 Jun 2024 01:15:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180128; x=1718784928; 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=h0z/gLbV7H1AqreyjOU1SY6iFOr0/svp6XKbzOXxi3c=; b=fZpfN0rHuApg4517dvvFDaqtyc2VL/WAYAVrGBUz1VY1pYp5M/JXPz1hBRHOP4ho3E uwggaaHmfWYx6ElduZ/7VpurwzLvN/eXe0MEqBwtgCAhh7Upt6zajTIcDME800Y4OnFg 6jOgbPqOm54xENl3cNCPv+gXqsh8HpHnNnTB/XswzOOMcytGxCLNo3bH2fG0dhGR225f hJF2LKysnl7klEFx8+9gJowyBnb2CcQUA9LMBVBSd8G6MINMAAbagAFI6zRcjMqIcEDa X6wDGCjkypXzOfNa93iHwN/ahnhiQ1X6bSpr/tlPTpRE3S21HwOQtxdXOGv3nrKcERic tJvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180128; x=1718784928; 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=h0z/gLbV7H1AqreyjOU1SY6iFOr0/svp6XKbzOXxi3c=; b=aItvzi3rbcVnEwMcy54Ukaf14pHWEodac1i+7BcmRDq8Q73aZXJRe2up6yc/rL1AcX XD8XqfFpIhGmlV5Whea4ZNRy33G2xLZMQwjarEvUko8GQynLsQJ7ZdDEX65iyZn51UpH 1abU7E82GA2OM/vDiQHFKV1PF+af6pbhzrE5o47tf6rT8DEI9ZnVNQqaf/j/210fP+D9 E3VBVYoXjkFVJDpQ9xWI5iYCsMkwCQE1T44KZlYkSMFdEMLjLlBcPWri3JPuXI6Lp2aH 2WERYgM3cO8nQ94YloG6zUXtw8jUdmBOd7wjPW5whUahxCCosv6ojW1Xzjtk2ya1oFlA qK0w== X-Gm-Message-State: AOJu0YxpMLENpl91q6MmdJxSSyqFKwujqqTA/NgZwIvIK/aBEaIlPQZk 4vVq4bU+Z/AI307/2eJAee0fpo00Ad4hbhFjMRjsIGXbanD1tpYTTXj58UC6q2ZGmrcJYKpD3FV YWSDPk+D8IQTPPLedYvgA6uYz0NaBqtniv7fUPSlJ+iX2zeXLkLvpTsMuJ6kJD8FSSUgtIvmZI7 eooL5aVD5BNotJloU4D57WIt1bp5Cy4Lf1LkiH22ZGlw== X-Google-Smtp-Source: AGHT+IElBXpniJAtgpcO8h7wvvvpFvELLrYUqd6ldIz07LJ9f8BCphhJY5JR+yJoS8Eo7TnfJ1dFrA== X-Received: by 2002:a17:902:e80a:b0:1f7:1931:7a9c with SMTP id d9443c01a7336-1f83b5df346mr14898975ad.15.1718180127879; Wed, 12 Jun 2024 01:15:27 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:27 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 09/16] target/riscv: Implement WorldGuard CSRs Date: Wed, 12 Jun 2024 16:14:09 +0800 Message-Id: <20240612081416.29704-10-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::633; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x633.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 4e87fa4d5b..ff1c22c71c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1022,6 +1022,10 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type) riscv_trigger_reset_hold(env); } + 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 50a0fba127..43ab558111 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -432,6 +432,11 @@ struct CPUArchState { uint64_t kvm_timer_frequency; #endif /* CONFIG_KVM */ + /* 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 58ef7079dc..f3536e9e5d 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -4264,6 +4264,109 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, 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 */ @@ -5230,5 +5333,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 Wed Jun 12 08:14:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694628 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 8BE21C27C77 for ; Wed, 12 Jun 2024 08:17:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ8x-0003Uu-2u; Wed, 12 Jun 2024 04:15: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 1sHJ8s-00037V-PC for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:38 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ8p-0006Va-Q8 for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:38 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1f70131063cso16957485ad.2 for ; Wed, 12 Jun 2024 01:15:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180134; x=1718784934; 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=6oKmkxCufFR9XMY0JlGHXgLRvtGXtLT9oX2X0hjPKqA=; b=gMteCJB8dR+rodlZp4gDWzHDxC0ahE0Oz5DtNKvQQjWa4xbnd1el/i7oDudVHgVYY5 GlMKc8Nh1F0DodV+Ge7nw6mT0VXMKC3yA/Tkq9DyabObtckU+IrVJ+smvNauVORR/Zlq PqoSWH+NvBKJc+ODCsNkGarYo4NVsUrKKvUKlCTBKdqki2xZYbtq5+mEeXwi3hh2P67d uKfiuFHuP7GFlj0AKydOUlJDVWFdGi5q+z8FciyJcrOMIJdmz9RAgrYibQaa/FpfhpdS R+lPx6mOYcd9X1VFRk/FLb0DdubOEVDdSxbp8JC37h4KGWroI8Yx1TuB1bWGN5PpqEjL xVVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180134; x=1718784934; 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=6oKmkxCufFR9XMY0JlGHXgLRvtGXtLT9oX2X0hjPKqA=; b=iZyBPMFQu7+4MGw1kzoV6MCdQuBJ8mXFXwAyfQ2j8BttjiToSPRPsq4/XkMwt9MTM1 BKiOB3mFCkHRGGSCey9mTAx4ipnLlY+bcLh/dQrkas7ijGKk1issWrLhFFcfMz7sFAB3 XqAWRlZbg0YcHtRW/e+LPmcBXom7HutyyfMweUBkFEkix8zugUM9f53p7f4QCN+z8LkJ RUijaEwkNpOaAbpsZeJQXZU3/WeNC+PwTtiwT+HFEETBy8IfnIfZOOsMei2/MJaWR+/z ZEY4Oyhol6Lg0Yoe2MXFg0PXhNaGexE4R/eZdxPm3hjQLuKY3nsA7LwcKok3k96eB/8c LWlg== X-Gm-Message-State: AOJu0YwlVOSMklRyR9tUF1g8rbT+1+clpZeIB+2Oz+tpCc+xvgHzMZqL wvNOssBMsfAvOK1/WvKTweWDYPzlBoLWIfuh6hvOo4OaqhurPATRE+2ExGX3pj9y19BbgzBCGHt QOTPaRy3iok+XAdtaTy0zLQ0bWz4YIb4oxlHtDLUnK8AZsozl000C8bhoqirzSmSVTrN3xbKnM5 A1eqyHCGfolCaggZQreOu6UMTp58EQOHyuomfFtye2fQ== X-Google-Smtp-Source: AGHT+IFcBMkrmaVMmlAZ6KNUw/nrjfXog9dmzxGNuZ94hP0C/vFGMp/6JrjpvmX5ycJgAapkG3mqPA== X-Received: by 2002:a17:903:40c1:b0:1f4:aa72:1db with SMTP id d9443c01a7336-1f83b5e4b50mr14099615ad.22.1718180133624; Wed, 12 Jun 2024 01:15:33 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:33 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 10/16] target/riscv: Add WID to MemTxAttrs of CPU memory transactions Date: Wed, 12 Jun 2024 16:14:10 +0800 Message-Id: <20240612081416.29704-11-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 ff1c22c71c..55d980ff4b 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -2343,7 +2343,7 @@ static int64_t riscv_get_arch_id(CPUState *cs) #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps riscv_sysemu_ops = { - .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 43ab558111..588f5de7f7 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -512,6 +512,7 @@ void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen); bool riscv_cpu_vector_enabled(CPURISCVState *env); void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); int riscv_env_mmu_index(CPURISCVState *env, bool ifetch); +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 ff20ab6ab8..afdccdd672 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -150,6 +150,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); @@ -1229,13 +1257,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)) { @@ -1339,12 +1376,20 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, int mode = mmuidx_priv(mmu_idx); /* default TLB page size */ target_ulong 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 */ @@ -1436,8 +1481,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 Wed Jun 12 08:14:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694630 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 8C2F8C27C53 for ; Wed, 12 Jun 2024 08:17:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ92-000438-9k; Wed, 12 Jun 2024 04:15:48 -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 1sHJ90-0003r5-4I for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:46 -0400 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ8w-0006Wz-2W for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:45 -0400 Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-7046e87e9afso1671708b3a.0 for ; Wed, 12 Jun 2024 01:15:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180140; x=1718784940; 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=qTKcjK5EXlwx4nqxpoQ63FtP6DiDpTwQjxOyBCiDETw=; b=lFfMiJnuRSMxvcN3y146qLzn0zh54CU578qa5ae8Cti7/Ev38ZnO/UOGTa0if9+1pv AiPTEQtRksTFdwSXLV++uEw7r4m/po4RPXwb+tFPQYT5D4+dMloh59j2MaDmUte71I2e gDfgmAiflIF6itrDeN3qsK58iRp9a7JYnLuJKDwv2UugAsX+d6WoJRnQxvrrQX6wa8T7 udy/uJb+fk2hcfRqYeg0jrXOY22pxZJuYd66C2q/+5r6CdicpxOUpUdXHGs4eUtREumE FOVKYF5GhL76n0IkFtwwnrOpl7+m7p1i8/mFLHlsC20/P1CkUcOKPjDzxSneffo048Dc GgbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180140; x=1718784940; 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=qTKcjK5EXlwx4nqxpoQ63FtP6DiDpTwQjxOyBCiDETw=; b=f1fBrogoAt4j9ZFG1LlAC+wuzVLqRR0Lvw8m1/k1lAD6AemzvkPk+oIwy8Cp1+eF8O OVIRI+wdda/KMCS5Z31wDLg2oxcZ3dXftFeAuCBlj0kRlqSJjUnJxe1h/u/HD55Qq0SW 1eYCL+3CYLRp/PlAYQR9dPL00voFTYiBcXvk2FU7aG5Ps7dlEaH6OOSkZiRs8WoR9Idv Rc1EATXLU9x/McRVAiHH891BU4rZXgDmphu1MnZKUA76Lf9088nWOKR9aGwtcl9WOD6s Xr3lLlPJiEyiGdL6VId7L24Izu1qtLl4Sp7D+72n0LyIVtLyIywwCONmdMC2bjxRp2y1 xG/g== X-Gm-Message-State: AOJu0YylD9QNPx2HuQZJ6d7/CIrYvoigoMFVOKbYJwQ3MxG4yQ4wMEbk MNwjKoT85bVYZ/g891223Cl/QJT1mQfd2BjDLZHGGlTAVd1W/ytfqHXRzBzM2bZZRu7rob1WocX Or2qGUPxAPTuFO1ICZk3PI0yuS8gPRmBqYRJmDMQQCoScJ8ITJ+9bN6h7ZofAceqd4bZzpYjHr4 H1lG5uB3Ss2xHBRFkRp/BeUzonQJ9S3w2x3h8EY7zWug== X-Google-Smtp-Source: AGHT+IF/M2n8DqJvULKMMitCPhVPOFUwXB80CobMLfkGQhNAASkvBjBQM8JQ6otDp4pxad3wPRyQfg== X-Received: by 2002:a05:6a20:914c:b0:1b5:d063:3396 with SMTP id adf61e73a8af0-1b8a9c4e255mr1276925637.59.1718180139441; Wed, 12 Jun 2024 01:15:39 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:39 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 11/16] hw/misc: riscv_worldguard: Add API to enable WG extension of CPU Date: Wed, 12 Jun 2024 16:14:11 +0800 Message-Id: <20240612081416.29704-12-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::430; envelope-from=jim.shu@sifive.com; helo=mail-pf1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 c839cc4e87..836ba43239 100644 --- a/hw/misc/riscv_worldguard.c +++ b/hw/misc/riscv_worldguard.c @@ -93,6 +93,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 Wed Jun 12 08:14:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694615 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 7FB9EC27C53 for ; Wed, 12 Jun 2024 08:16:20 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ99-0004bV-GU; Wed, 12 Jun 2024 04:15:55 -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 1sHJ97-0004Qz-3S for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:53 -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 1sHJ92-0006Z4-3m for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:52 -0400 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-1f480624d0fso16641775ad.1 for ; Wed, 12 Jun 2024 01:15:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180146; x=1718784946; 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=6SDWdEji79jZuEfxYlRwhHJyOygZmGzZyl21bKBD6lI=; b=ephY/oG5/TyYFT0AghH/uXuv1mMIRr3MaXAISFHntDtE3JzgBO5NGwB3ExM0iD35TE AaSz2MJY3cH79jinsT6Yu/zfunoD3WRKW1pP6VCb6H04uGyMcKkt1ewPmgBQ9Wvo4Fgp QDA4OGIO+LAMN07mzefCS45D9ZAp/AUveGH+yg9xc2Kn/rrwIBercd5HEt0DQgxKB6h3 J79ZqjDlta++Lwr+978x5iP9/ntkzF66qofaeAkBprcCOu17bx01kuqFlQOCO1/htuPO cTZmA3v8kofw2WXhoeFQGbtdknqjlhi3hi13u3Plq4PYQPySkDWZ5I97Cv93R8jJU2w0 58Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180146; x=1718784946; 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=6SDWdEji79jZuEfxYlRwhHJyOygZmGzZyl21bKBD6lI=; b=IYDDl1KA7wzSFvka+icGe2Fo2EZc4Zzyu6vJo7+JmRpE4H2FeclT4FutrpzV46U5Nh tBlq0iG4IKDUCRwDm4Cc6ZDIvXrOA0F54jV3fbzWOHM/zVp7rQDRgRiMr/WejIaJxs0M GIBkzI0r47e4+KDDs+pkLe39weSS4otqJjZDGsoiZNHAN82MXZpgQqju4q5zVkLhZQoB fefshrzvTT52Tx9NQGuVMqLfBSKpXy0v5vabgM+G/qfjZWnWio0TefA+HCuLKuhHdKla goqZjptKG30p2EsUCeWnbuHznI0uKSNr1tzsrCNRPll3CAvkeaqNF4MALmxGW3qQsESU ZxUA== X-Gm-Message-State: AOJu0YwOZrTaLFryd+sAlJtC+y8lEtZf+r1S1yZLIiw9zusGppsC1Jy2 WwcAfryxEfk7OC28XwthWo4E2t8tOKitFUBopPgSCSdl9+Giy3v/oyP3+BjPh43tq/N3KNp4bBE P+fJwmqLIPTczgRzJ7BrWE69crIq28E31ngCu34LnoEMS7ZkaqD6WndDzPhxBDu0vljRgwMHcHs ZAxI3Lrh43B5gWCUQro3hkUWWMyeBfqF18y1ETfYRBew== X-Google-Smtp-Source: AGHT+IGWuiw4qN6215AIuz3B82UrjcAr18BITHC04BrN6BSLgSVO+wOv8vv9zRqeYywcoxF4Y1/pug== X-Received: by 2002:a17:903:18a:b0:1f4:64d9:5cfd with SMTP id d9443c01a7336-1f83b6ed60dmr12725245ad.42.1718180145210; Wed, 12 Jun 2024 01:15:45 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:44 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 12/16] hw/misc: riscv_wgchecker: Implement RISC-V WorldGuard Checker Date: Wed, 12 Jun 2024 16:14:12 +0800 Message-Id: <20240612081416.29704-13-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 | 604 +++++++++++++++++++++++++++++ hw/misc/trace-events | 8 + include/hw/misc/riscv_worldguard.h | 63 +++ 4 files changed, 676 insertions(+), 1 deletion(-) create mode 100644 hw/misc/riscv_wgchecker.c diff --git a/hw/misc/meson.build b/hw/misc/meson.build index a75668ff86..c5cb3bf4ee 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..2421b1438c --- /dev/null +++ b/hw/misc/riscv_wgchecker.c @@ -0,0 +1,604 @@ +/* + * 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), + DEFINE_PROP_END_OF_LIST(), +}; + +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 Wed Jun 12 08:14:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694632 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 4EE43C27C77 for ; Wed, 12 Jun 2024 08:17:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ9C-0004jv-CX; Wed, 12 Jun 2024 04:15:58 -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 1sHJ9A-0004eY-EX for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:56 -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 1sHJ97-0006b4-6d for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:15:55 -0400 Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1f70fdc9644so5366015ad.0 for ; Wed, 12 Jun 2024 01:15:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180151; x=1718784951; 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=jYeeLmPdyr50rNmzKWawNIJPiKXGVFWI+GFbsjjtyoU=; b=JXxyEB4mvDeHcNIraBpzFnpsTVRCeQ0HA0qgJLS8JfDllSEcqox0xFtlOt4uy4aUzy R2I8u8ymwu5tJGmebYpVzMujpsBoI0QJ2SAp5mz8EUStzTQyG5X22Xui7wixU5xP0FLS hQwvQn5v2R7Wt3tAxjHBBRDNjQDOxJtLnbgvUgfQP0vN1jd30wFe3UcBkHbQNLEqpfId yUD0vQSLWbRNE1DR0DyQLIAhQkldxOstmfJJmDEq303TIAOjaj8aIaAlrKJ2EMaRbP0k QgEkUlShe/3mtcYJuYYHwdCT10rrfIliTzGRoKXLiLBuerr4FXtUY97KN2/7s1f6ixEZ GH6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180151; x=1718784951; 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=jYeeLmPdyr50rNmzKWawNIJPiKXGVFWI+GFbsjjtyoU=; b=u26lRNBCco1S08gWejzTPZGd6ifBMw6tf51yTuAuT5Ssq8oDzmlU2s9Melv75zh9+i /vPLow7LxalaJmfPrqidvV/FzLGcyONVkTCaIgm7PokPE+7vBVQpc96Eobx2GFMl6MID Bmc2VSsKuTKUjxxJ/LmdhTxvGTV9rcpy9/R0Xa/Om0VfHFlRXkwNb0Ypxdwwl+HFQG/6 57cjpqi9EAfMQSzWjqxFD9XiwwzjnCZrrKbAvj9VouJmeuAkubzEjHEJvGQCNjQgNG14 9z/PIAulF2kdTljlYIHCLodMP9pBrVwO7cnncp3HqMUSYcMGRmhxQZhvX4vRsW/7rdAG nahQ== X-Gm-Message-State: AOJu0YzZYvsoOs6g5Vh+cd+MWCwuUInP3EZEvKYvFtKfag/8uFBQSmlP Y9nrdQHvR3PPJ6GV7HEJkdC4BZadS9SWgf44SxDVLS+9gzYw96Xxc07JJ9fg0ueeOq6n73f+4pl VSa3RjypLzOGniSzKRd/Kl22nvjqck/QqDyp1s6T6mO+0EPS4d6mVBHVj5HMSamrGChryzXThpc JQ/KYOOwGnCDZr7xn5GE1FmQXKHgNwptXQY6rYW8jHCw== X-Google-Smtp-Source: AGHT+IFm+FAU4+aHW/gmxVcFuim3vQHDOe0Yw75lv5loukaVymKlXe5Qw07gGHClyl1ak5dZ640tGQ== X-Received: by 2002:a17:902:e80e:b0:1f6:1a86:37ba with SMTP id d9443c01a7336-1f83ae5eccemr21552635ad.2.1718180150977; Wed, 12 Jun 2024 01:15:50 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:50 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 13/16] hw/misc: riscv_wgchecker: Implement wgchecker slot registers Date: Wed, 12 Jun 2024 16:14:13 +0800 Message-Id: <20240612081416.29704-14-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 2421b1438c..ab03fd671f 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); @@ -461,6 +745,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); @@ -524,6 +810,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) @@ -597,6 +914,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 836ba43239..d3a4b23dae 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 Wed Jun 12 08:14:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694619 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 C9E20C27C75 for ; Wed, 12 Jun 2024 08:16:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ9I-000531-GR; Wed, 12 Jun 2024 04:16:04 -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 1sHJ9G-0004xO-99 for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:02 -0400 Received: from mail-pf1-x431.google.com ([2607:f8b0:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ9C-0006ns-Ud for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:01 -0400 Received: by mail-pf1-x431.google.com with SMTP id d2e1a72fcca58-6ff6fe215c6so5783297b3a.3 for ; Wed, 12 Jun 2024 01:15:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180157; x=1718784957; 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=TqErKBJ8Vh4RlMrfEtbYlUxbkO7H6dBIl2WlaEw920Y=; b=iz9JaB2W2WiNUN/e/jKLOGxrTc63KGmEhpvAVgwkGRM40dq5MAWLV5c7cu3c0D5jWb pB1lps0zPtqbyMPe5bjNuq8+1x6BIgrAXt5L6Hsg7ePYrYNeUhlF8KmoIyTrJ12MlDgm CF7HRNzehr9a/xUM+fUi6WGZobVCeUGml+4nJVvy+IZ6YaTyJ+KUKhiS/lV2pM3kabFz 7lRn442kSZEtJaTFpXeQD4wCHtyb5ZRTeeV7qUNjjPfJ49GDS/rZIyYX/1hOw73rjbpw SUH+0A1oYLJsMwN26UxQn5j2oPkiW8gyhodcaND2k/05V0Jx1DFV7Tpl8nzKKtkuhsmY n4ug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180157; x=1718784957; 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=TqErKBJ8Vh4RlMrfEtbYlUxbkO7H6dBIl2WlaEw920Y=; b=TfA0XVvh3WKX3fHxYA6xfoq6VB0a1DzcwadyVVWXuxCQmSUkpYwq3QVc83YwNJNFrg kroutUuLjjGel3JrS4HQ1+okLp4BGWgWZl5sqgphlASvp6Td4OXtZU61iDalhzTjkz9S Q0Yp1LNu4vEZOMqnxEp3m8VreR2MYSfLsXhB8NcFrv6DgvZovCUWUeQ+5kgTsLXCzZQu hX5dhTBE5Cd2k1Rdnqs5kSLFOQxfmo7Uk9gehd3cFemGvNyazU6LRa8YejTNYyiJxmAx j51xK9VJW27bRMmHhBRRkGfHBDPfbJ0s636zLDPnVg3GKOdReRfw316x/jRSX1P8/PTL 2qgQ== X-Gm-Message-State: AOJu0YxhiFwXINg+yau/ghAhXpaUKO83iRir7Jp+l0UiG5XDGvyTgPQJ +TbCcLwk4J6lJIGrYsiuoWZDgMexcBNeIJI0RN8z42eMIei4Tes+1RppxKjTlBcHizIKk0PMuZW kWEYVm+qryCxjNdmMEDkwuugyZY8NXSPGPqrsB+1o8Me0ZnIeh4M2LWI0aRKRGNOE/zRk1aPosG BlAM1b/4X5g2vAkmeR1gjtNsexlrOmuvEPUsNdgkMtxQ== X-Google-Smtp-Source: AGHT+IGI/5JvgYhd7bnfcYyzI14T/qSQRiDtfGNIcfKqV4gEjKNytZJRly7oswdpyjJJkJsgXTgLEw== X-Received: by 2002:a05:6a21:611:b0:1b5:d00e:98e1 with SMTP id adf61e73a8af0-1b8a9b78d1fmr1292108637.15.1718180156907; Wed, 12 Jun 2024 01:15:56 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:15:56 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 14/16] hw/misc: riscv_wgchecker: Implement correct block-access behavior Date: Wed, 12 Jun 2024 16:14:14 +0800 Message-Id: <20240612081416.29704-15-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::431; envelope-from=jim.shu@sifive.com; helo=mail-pf1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 ab03fd671f..55e5e8127f 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 Wed Jun 12 08:14:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694633 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 5AD55C27C53 for ; Wed, 12 Jun 2024 08:18:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ9N-0005EV-FT; Wed, 12 Jun 2024 04:16:09 -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 1sHJ9M-0005Cz-0J for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:08 -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 1sHJ9I-0006pL-SC for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:07 -0400 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1f6f031549bso18335775ad.3 for ; Wed, 12 Jun 2024 01:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180163; x=1718784963; 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=YBsKz2cXW2irXTYX6EDVGeIkb/sGQaekYYfYimSeHNs=; b=HYYkazSea+v0kWRPaUOkwuoPTLEmjqUJsBfA4nWFPULem3yUJeZSrugi5ah1sLVbOB XMhsg8eXUF1dMp43rjyQeAn9RBXbsiElnypCR7Y2CGZEv+CcQF83KT9LjRalS3En7l+R IkGWoYlpQFDgLwrwd96SNo/SKcomLnhH3ZWVW62g6v2ciq24hRvXLyEaJHR2FTC2vEtt ae2l8wb93Sy97BzIS0cCz9WOtVephP+kMOle9bnKS2zTzq+UB84JCHeO1MdtrpZhi830 wlQQppL2ohlst/JLRbiMCv/d1M5Yh+EtyOBjQkniHGCvlPv8ES9l58rB4Ks1EQDjQTTt YHYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180163; x=1718784963; 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=YBsKz2cXW2irXTYX6EDVGeIkb/sGQaekYYfYimSeHNs=; b=txZw7ORv6OVQSjnevK8718xIZbr8ajvopTfNKp5hWdwY1THSENm+iTqSeGUHAVFHjM PIEEa7Ajbv1BkrGUVW1dUYyOnRf65QodWan3V04kWavHijteB8fKfO+WL/X7hLWdYimh moD4Ip7Ro7jyz3oEyFpijkBXLiLBkhDIAJjYWYDo+YKzeHCLJszhxjZn+892r/aoMDGm CR/z1qDOgjg0aBNJa68qd5rNnjMfxlDzE8+jm1BUxba8C2SbRWAvjMpAgcIm5VPFVUeB XlV1BpZuYd6ZvHTN86IQwUllSZGiJZerNxFQmxnHdDcMB8OH2WSwcYAzHJE6Elx1B+fy E6Dg== X-Gm-Message-State: AOJu0YwiUV2ft8LgF4TyUZlNoe3npNvdyadp1ekG4vMYPE20azNjMvuk 2cZFqy+2FAr7IWWQagLZgL88P3P9x8xYoQFlxZfZ5PvyXHdnKxuN8pGDTLU7GsPm6XXyJGT4sC9 f+1YgT51HKgZsbpxBFdxbMIVA/Z8k8T8Q9PhqQJKbR+xa3iAeC2v1Rf6ERFebClc3b5kA62l+bs PoIL/npoC/E+r9PEFLP2IsbbRE6IDIM0CqUWkDjqpnMg== X-Google-Smtp-Source: AGHT+IG37UdgaXu8P2JE+gz6Z04qZbuplDZsS5uh0eTnm+7cZyvd+6A2KsrYWqSuWBp0hb0P1u7NNA== X-Received: by 2002:a17:902:d2c6:b0:1f7:178e:60a4 with SMTP id d9443c01a7336-1f83b517aabmr13665965ad.7.1718180162752; Wed, 12 Jun 2024 01:16:02 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.15.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:16:02 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 15/16] hw/misc: riscv_wgchecker: Check the slot settings in translate Date: Wed, 12 Jun 2024 16:14:15 +0800 Message-Id: <20240612081416.29704-16-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass 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, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 55e5e8127f..cab4e40921 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 a64c7f0f9f..80907c45d2 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -359,3 +359,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 Wed Jun 12 08:14:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Shu X-Patchwork-Id: 13694635 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 1252BC27C53 for ; Wed, 12 Jun 2024 08:18:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sHJ9V-0005nL-Fg; Wed, 12 Jun 2024 04:16:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sHJ9U-0005eA-4i for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:16 -0400 Received: from mail-pl1-x630.google.com ([2607:f8b0:4864:20::630]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sHJ9P-0006qm-Ar for qemu-devel@nongnu.org; Wed, 12 Jun 2024 04:16:15 -0400 Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-1f70131063cso16961535ad.2 for ; Wed, 12 Jun 2024 01:16:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; t=1718180169; x=1718784969; darn=nongnu.org; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=7Zs56IfQW4V8sqUEW1KobOHNpim94d18CajV+uj3sek=; b=iU64JaUXOpMTAeRp3dYWTrEaWAPX9MxC/5KwT9aQFYKYeUyR0x9FjvYhH+N/tbXcFC KJjBHzIR8c1YGSDbrVsx/zobqZhoVQQdkWfNYAiRkxeZRwqALZduk4GESaQM5BkCVwd8 nkXzO567aml6DK9B3ABS8i+wRtjRD6gs1NO/GORqfwPwKDwifwvy17MBwPPFnDt4E7P/ FyZ2RvmTSLnm2QS1y9ncXoQJAGxX67IutFKATEP6Xoi3+Gc1Fhd7U2RDsp8IHcjbIE5H kWq5LFIaor+lHNJTQbHqobHWXIIrGf01HhmLR4jFeb94WdzrKLOLjmqn1zHIpn4q+Hu1 wbFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718180169; x=1718784969; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7Zs56IfQW4V8sqUEW1KobOHNpim94d18CajV+uj3sek=; b=JczqtIUIrvhsjqDR4L7u5r0MXPDh0HzK+ciiGflFMIDa2mKmWYwUpI/InwhJZFnqnU EO3zMZ7OZRolCbdV0xr+pA2liVmJF/Wy8MgRNxeXc8jPJCmwhqtW+euOPpaaH1j5tFpW UvWhU0QPOT+lxFan2XjLw7QiFxJjYgcDSiWHEH9GHR9TVPT9zgtEJpka1pWlZDq1utwB yxEAx+YgjwEka1zV6TohxmXdJEy+AEOYgc/i0NdtzInuFn20HoRwYLvTEuCYz10Dwnke uofXaBFxXmTFYL+FoXghT3MNIABRWV5cRYd0UET6IDqPfd6h/brFInw28WoGvqQkbwRQ rgWQ== X-Gm-Message-State: AOJu0Ywqb0qA/zecvr1Z4/bqC0Odq6Do3smg5LZK4zUnxbs6Tf1LKkKh xY0wQhddn6AnKr1pfBIDv1jpsjbbNutnUkieQtynd3WnwFpyY6kmAIvE+fv+MNgSMwtF04inuKT US69mz02fnDXi6zaX2ZKe2rCWk1bqDGn72bKojrmBgPX1uCU8vlXjiHWq2JU769dYPcdoaJa4kp PkpF+Ml4FtnY6P3J0jGzgQxMDWECmLAGTd/LuFUKNirw== X-Google-Smtp-Source: AGHT+IFZI0uD97KN8S3AD0WaGGdqs9bMHQ35x0UNs/HsiXiPw2iJARhoCvv/DnkcypVwlwTRn0BWFQ== X-Received: by 2002:a17:903:2283:b0:1f7:187f:cb5a with SMTP id d9443c01a7336-1f83b565eb1mr12729405ad.11.1718180168578; Wed, 12 Jun 2024 01:16:08 -0700 (PDT) Received: from hsinchu26.internal.sifive.com (59-124-168-89.hinet-ip.hinet.net. [59.124.168.89]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1f8393e8e53sm11363875ad.16.2024.06.12.01.16.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 01:16:08 -0700 (PDT) From: Jim Shu To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org Cc: Richard Henderson , Paolo Bonzini , Palmer Dabbelt , Alistair Francis , Bin Meng , Weiwei Li , Daniel Henrique Barboza , Liu Zhiwei , Eduardo Habkost , Marcel Apfelbaum , =?utf-8?q?Philippe_Mathieu-D?= =?utf-8?q?aud=C3=A9?= , Yanan Wang , Peter Xu , David Hildenbrand , Peter Maydell , Michael Rolnik , "Edgar E. Iglesias" , Song Gao , Laurent Vivier , Aurelien Jarno , Jiaxun Yang , Aleksandar Rikalo , Stafford Horne , Nicholas Piggin , Yoshinori Sato , Ilya Leoshkevich , Thomas Huth , Mark Cave-Ayland , Artyom Tarasenko , Bastian Koppelmann , Max Filippov , qemu-arm@nongnu.org (open list:ARM TCG CPUs), qemu-ppc@nongnu.org (open list:PowerPC TCG CPUs), qemu-s390x@nongnu.org (open list:S390 TCG CPUs), Jim Shu Subject: [RFC PATCH 16/16] hw/riscv: virt: Add WorldGuard support Date: Wed, 12 Jun 2024 16:14:16 +0800 Message-Id: <20240612081416.29704-17-jim.shu@sifive.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240612081416.29704-1-jim.shu@sifive.com> References: <20240612081416.29704-1-jim.shu@sifive.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::630; envelope-from=jim.shu@sifive.com; helo=mail-pl1-x630.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+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 | 10 +++ hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 163 ++++++++++++++++++++++++++++++++++++- include/hw/riscv/virt.h | 17 +++- 4 files changed, 186 insertions(+), 5 deletions(-) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index 9a06f95a34..2d2992dc34 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -116,6 +116,16 @@ The following machine-specific options are supported: having AIA IMSIC (i.e. "aia=aplic-imsic" selected). When not specified, the default number of per-HART VS-level AIA IMSIC pages is 0. +- 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". + This option is restricted to the TCG accelerator. + Running Linux kernel -------------------- diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index a2030e3a6f..7804fdbb7a 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -56,6 +56,7 @@ config RISCV_VIRT select PLATFORM_BUS select ACPI select ACPI_PCI + select RISCV_WORLDGUARD config SHAKTI_C bool diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 4fdb660525..eed49ebd02 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -55,6 +55,7 @@ #include "hw/acpi/aml-build.h" #include "qapi/qapi-visit-common.h" #include "hw/virtio/virtio-iommu.h" +#include "hw/misc/riscv_worldguard.h" /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */ static bool virt_use_kvm_aia(RISCVVirtState *s) @@ -76,6 +77,9 @@ static const MemMapEntry virt_memmap[] = { [VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 }, [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, [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) }, @@ -101,6 +105,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) @@ -151,7 +187,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; @@ -160,6 +197,15 @@ static void virt_flash_map(RISCVVirtState *s, sysmem); virt_flash_map1(s->flash[1], flashbase + flashsize, flashsize, sysmem); + + if (info) { + wgc_append_child(info, + sysbus_mmio_get_region(SYS_BUS_DEVICE(s->flash[0]), 0), + flashbase); + wgc_append_child(info, + sysbus_mmio_get_region(SYS_BUS_DEVICE(s->flash[1]), 0), + flashbase + flashsize); + } } static void create_pcie_irq_map(RISCVVirtState *s, void *fdt, char *nodename, @@ -1303,6 +1349,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++) { @@ -1547,6 +1665,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); @@ -1574,10 +1696,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)); @@ -1586,7 +1714,16 @@ static void virt_machine_init(MachineState *machine) pflash_cfi01_legacy_drive(s->flash[i], drive_get(IF_PFLASH, 0, i)); } - virt_flash_map(s, system_memory); + + if (tcg_enabled() && s->have_wg) { + virt_flash_map(s, system_memory, &wgcinfo[WGC_FLASH]); + } else { + virt_flash_map(s, system_memory, NULL); + } + + if (tcg_enabled() && s->have_wg) { + virt_create_worldguard(wgcinfo, WGC_NUM, mmio_irqchip); + } /* load/create device tree */ if (machine->dtb) { @@ -1614,6 +1751,20 @@ static void virt_machine_instance_init(Object *obj) s->acpi = 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); @@ -1794,6 +1945,12 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) NULL, NULL); object_class_property_set_description(oc, "acpi", "Enable ACPI"); + + object_class_property_add_bool(oc, "wg", virt_get_wg, + virt_set_wg); + object_class_property_set_description(oc, "wg", + "Set on/off to enable/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 3db839160f..4d78702daf 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -57,6 +57,7 @@ struct RISCVVirtState { bool have_aclint; RISCVVirtAIAType aia_type; int aia_guests; + bool have_wg; char *oem_id; char *oem_table_id; OnOffAuto acpi; @@ -84,12 +85,18 @@ enum { VIRT_PCIE_MMIO, VIRT_PCIE_PIO, VIRT_PLATFORM_BUS, - VIRT_PCIE_ECAM + VIRT_PCIE_ECAM, + VIRT_WGC_DRAM, + VIRT_WGC_FLASH, + VIRT_WGC_UART }; 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 */ @@ -99,7 +106,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) @@ -153,4 +160,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