From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 B4FDAC44501 for ; Wed, 15 Jul 2026 12:00:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=KjYDN+7EM7Yvzl2aRWCfwJrzMD6Nz8HQwAfKQduR34E=; b=Ou/GNteSebUuBKWyGU5jz9Spt4 nVVQ5qnU1/Wk8f+iMTiNcS/RC1jUs7cDGhx92a//6QHxbByXnmjdJDNfwwMNwgzA8+Vl0XRSBfxHG 5Akv9OFJ/tPQdvjwjoI6z+QbfGaHFW8hs/LEHslOodCS5z8mnI2iO5KzzvTaqPUJduPWwk1Y/muJb K4UU7G5VmCidA+sKwq28fK8/am4hraAOivXmjKogopkO82b6yscX9WR6bR/FK56JHDa75WdPZ1gGD qDD/7tR6PhyXQ4Zdpd27pB6riZXf7h26gadM8DEhoHBux9xiylSbQDhz575ruYCeD+Ggzm0eKnEDR N7EkA/dA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wjyHW-0000000EfnK-1quu; Wed, 15 Jul 2026 12:00:06 +0000 Received: from mail-ej1-x64a.google.com ([2a00:1450:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wjyGu-0000000Ef4E-1vLd for linux-arm-kernel@lists.infradead.org; Wed, 15 Jul 2026 11:59:29 +0000 Received: by mail-ej1-x64a.google.com with SMTP id a640c23a62f3a-c1662ffbf57so193446466b.2 for ; Wed, 15 Jul 2026 04:59:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784116765; x=1784721565; darn=lists.infradead.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=KjYDN+7EM7Yvzl2aRWCfwJrzMD6Nz8HQwAfKQduR34E=; b=KnYlmgBlxsijnRCjJzzYiusJsfi6tEJuqDGcYRRgJ/5jNLxM4QuQ3PkyxHWxw9EXmC VwPnij+teeKPLY1OHbcveramEY8SYxA1u0Vu/bpkl5qZhsXtMrYd1337TGzG1tPfdAUD DM0GjgY2mK+GTuzAdunkrAmM5oeuaKZKVaL40TrlIHM3iGGjiaLbKlFM+WXucjNaLz87 TGzIaAExF16PMygo6ETseLuWBPCeKBJDFv/9CY87sx86LtH6B97khf1qtnbdY8e/0ZpO uOfgloU9rgI5xp7dui7gJaX135hNTVDW5vdEFIEN4Y+ZNTeyzIZMqrsrpDZaGvLCAiXS uorg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784116765; x=1784721565; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=KjYDN+7EM7Yvzl2aRWCfwJrzMD6Nz8HQwAfKQduR34E=; b=WHVbKi53u4zKJrK+x/M98SW14ITqeJg0MJTNCpqf/4IOVNS3jLKsfEuB2KzrPcsVVI KWbLqunqnLBvu+ejXzPrcAm5skUZi8vv+BafcB//ISu2Wh0bjnD6kdm/b4CYQfbVO9SS 0ouIr2zjT78X6gF4L+8oTzT+5FY0FeS9CMmdcTnx8zHQw6BTN11wpZrcPMsaRN3FPc20 IWG/iIg/AYxUB2McUpttSYOLgbFoNTAKR9kQG1ICtcfF/Nj3b+y2MtbOcyfjQQrhaiyL PPNF92RSVypysmzHzcaggZ1ehg6d3QycM80QIIOM+seDiKJr9Cvg8S3nAoMeHGgcy91K SLHg== X-Gm-Message-State: AOJu0Yxzye7RmtRkC88dRROp2Q+1FBvn+U4O0rEAMIobRu1MJSs4j6Ur NZbRR2zPYo06utAFiLj0UZ1dF8WZTqgmeRUiaoSwwdJFQwnnkaoe6VhfcaTatgLMsv3UQ2JzgQU jju/DxNOKQczN/+gvsS8AVkungDLv45PKv/tvURYSTJO6AEquZMWBIZIIjvXA8sDllB31THh5s5 kyNvfledExLqsglZectjQXcw1T7NVuzfpPMwAT72IIb/NxW4Yler6yDNYl3gzL2DuT3A== X-Received: from ejjr20.prod.google.com ([2002:a17:906:7054:b0:c12:9227:4a93]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:1804:b0:c12:34ed:da0b with SMTP id a640c23a62f3a-c1667b099abmr363811866b.55.1784116765282; Wed, 15 Jul 2026 04:59:25 -0700 (PDT) Date: Wed, 15 Jul 2026 11:58:51 +0000 In-Reply-To: <20260715115906.2664882-1-smostafa@google.com> Mime-Version: 1.0 References: <20260715115906.2664882-1-smostafa@google.com> X-Mailer: git-send-email 2.55.0.141.g00534a21ce-goog Message-ID: <20260715115906.2664882-11-smostafa@google.com> Subject: [PATCH v7 10/24] iommu/arm-smmu-v3-kvm: Add SMMUv3 driver From: Mostafa Saleh To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, iommu@lists.linux.dev Cc: catalin.marinas@arm.com, will@kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com, joro@8bytes.org, jgg@ziepe.ca, mark.rutland@arm.com, qperret@google.com, tabba@google.com, vdonnefort@google.com, sebastianene@google.com, keirf@google.com, Jean-Philippe Brucker , Mostafa Saleh Content-Type: text/plain; charset="UTF-8" X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260715_045928_527770_0490057B X-CRM114-Status: GOOD ( 23.74 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jean-Philippe Brucker Add the skeleton for an Arm SMMUv3 driver at EL2. The driver rely on an array of SMMUv3s on the system, where at init it will donate the array and the resources of the SMMUv3s so they can't be changed by the host after de-privilege. This array will be populated in the next patch. Signed-off-by: Jean-Philippe Brucker Signed-off-by: Mostafa Saleh --- arch/arm64/kvm/hyp/nvhe/Makefile | 5 ++ drivers/iommu/arm/Kconfig | 9 ++ .../iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c | 87 +++++++++++++++++++ .../iommu/arm/arm-smmu-v3/pkvm/arm_smmu_v3.h | 27 ++++++ 4 files changed, 128 insertions(+) create mode 100644 drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c create mode 100644 drivers/iommu/arm/arm-smmu-v3/pkvm/arm_smmu_v3.h diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile index b3e7473f18d2..dcb75fb5b4f1 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -33,6 +33,11 @@ hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o hyp-obj-$(CONFIG_NVHE_EL2_TRACING) += trace.o events.o hyp-obj-y += $(lib-objs) +HYP_SMMU_V3_DRV_PATH = ../../../../../drivers/iommu/arm/arm-smmu-v3 + +hyp-obj-$(CONFIG_ARM_SMMU_V3_PKVM) += $(HYP_SMMU_V3_DRV_PATH)/pkvm/arm-smmu-v3.o \ + $(HYP_SMMU_V3_DRV_PATH)/arm-smmu-v3-common-lib.o + # Path to simple_ring_buffer.c CFLAGS_trace.nvhe.o += -I$(srctree)/kernel/trace/ diff --git a/drivers/iommu/arm/Kconfig b/drivers/iommu/arm/Kconfig index 5fac08b89dee..916f4723238d 100644 --- a/drivers/iommu/arm/Kconfig +++ b/drivers/iommu/arm/Kconfig @@ -141,3 +141,12 @@ config QCOM_IOMMU select ARM_DMA_USE_IOMMU help Support for IOMMU on certain Qualcomm SoCs. + +config ARM_SMMU_V3_PKVM + bool "ARM SMMUv3 support for protected Virtual Machines" + depends on KVM && ARM64 && ARM_SMMU_V3=y + help + Enable a SMMUv3 driver in the KVM hypervisor, to protect VMs against + memory accesses from devices owned by the host. + + Say Y here if you intend to enable KVM in protected mode. diff --git a/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c new file mode 100644 index 000000000000..fee5db6c9c20 --- /dev/null +++ b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm-smmu-v3.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * pKVM hyp driver for the Arm SMMUv3 + * + * Copyright (C) 2022 Linaro Ltd. + */ +#include + +#include +#include + +#include "arm_smmu_v3.h" + +size_t __ro_after_init kvm_hyp_arm_smmu_v3_count; +struct hyp_arm_smmu_v3_device *kvm_hyp_arm_smmu_v3_smmus; + +#define for_each_smmu(smmu) \ + for ((smmu) = kvm_hyp_arm_smmu_v3_smmus; \ + (smmu) != &kvm_hyp_arm_smmu_v3_smmus[kvm_hyp_arm_smmu_v3_count]; \ + (smmu)++) + +/* Put the device in a state that can be probed by the host driver. */ +static void smmu_deinit_device(struct hyp_arm_smmu_v3_device *smmu) +{ + WARN_ON(__pkvm_hyp_donate_host_mmio(smmu->mmio_addr, smmu->mmio_size)); + smmu->base = NULL; +} + +static int smmu_init_device(struct hyp_arm_smmu_v3_device *smmu) +{ + unsigned long haddr; + int ret; + + if (!PAGE_ALIGNED(smmu->mmio_addr | smmu->mmio_size)) + return -EINVAL; + + ret = __pkvm_host_donate_hyp_mmio(smmu->mmio_addr, smmu->mmio_size, &haddr); + if (ret) + return ret; + + smmu->base = (void __iomem *)haddr; + + return 0; +} + +/* Called while is the host is still trusted. */ +static int smmu_init(void) +{ + size_t smmu_arr_size = PAGE_ALIGN(sizeof(*kvm_hyp_arm_smmu_v3_smmus) * + kvm_hyp_arm_smmu_v3_count); + struct hyp_arm_smmu_v3_device *smmu; + u64 pfn, nr_pages; + int ret; + + kvm_hyp_arm_smmu_v3_smmus = kern_hyp_va(kvm_hyp_arm_smmu_v3_smmus); + pfn = hyp_virt_to_pfn(kvm_hyp_arm_smmu_v3_smmus); + nr_pages = smmu_arr_size >> PAGE_SHIFT; + + ret = __pkvm_host_donate_hyp(pfn, nr_pages); + if (ret) + return ret; + + for_each_smmu(smmu) { + ret = smmu_init_device(smmu); + if (ret) + goto out_reclaim_smmu; + } + + return 0; + +out_reclaim_smmu: + while (smmu != kvm_hyp_arm_smmu_v3_smmus) + smmu_deinit_device(--smmu); + WARN_ON(__pkvm_hyp_donate_host(pfn, nr_pages)); + return ret; +} + +static int smmu_host_stage2_idmap(phys_addr_t start, phys_addr_t end, int prot) +{ + return 0; +} + +/* Shared with the kernel driver in EL1 */ +struct pkvm_iommu_ops smmu_ops = { + .init = smmu_init, + .host_stage2_idmap = smmu_host_stage2_idmap, +}; diff --git a/drivers/iommu/arm/arm-smmu-v3/pkvm/arm_smmu_v3.h b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm_smmu_v3.h new file mode 100644 index 000000000000..0d9e48b201f5 --- /dev/null +++ b/drivers/iommu/arm/arm-smmu-v3/pkvm/arm_smmu_v3.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __KVM_ARM_SMMU_V3_H +#define __KVM_ARM_SMMU_V3_H + +#include + +/* + * Parameters from the trusted host: + * @mmio_addr base address of the SMMU registers + * @mmio_size size of the registers resource + * + * Other members are filled and used at runtime by the SMMU driver. + * @base Virtual address of SMMU registers + */ +struct hyp_arm_smmu_v3_device { + phys_addr_t mmio_addr; + size_t mmio_size; + void __iomem *base; +}; + +extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count); +#define kvm_hyp_arm_smmu_v3_count kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count) + +extern struct hyp_arm_smmu_v3_device *kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus); +#define kvm_hyp_arm_smmu_v3_smmus kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus) + +#endif /* __KVM_ARM_SMMU_V3_H */ -- 2.55.0.141.g00534a21ce-goog