From patchwork Tue Jul 30 15:11:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 13747536 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 1EE02C3DA70 for ; Tue, 30 Jul 2024 15:14:56 +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-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=NUcMDUy/ytSz408a8atqJHxZj/4QAJ020wTCpaqG060=; b=4FBNhchwtNSdPfu32P0llRqIJR 2NE1za4OpiQUqstCRQbiY6WJNTTik49q1nb4nD63b1v1YaQ+TjRv4DbSr4DyXuoUhcSGJSQfgmlcr P9RvC0LKgNUf8A7IvepYL7vDvc4WLU2FyXemjFomsyWnqW91yO/Uy/OSY3Wh18n5V0+D+t35Xe9Dm rQ2YeaWAA6yrKbmWlLih9Qc7CC61Bxir+LC7BQOlzeEan1H4Zk9Qoqp5pwxvCYOAUZTQfRyA/ASK5 XbcQtxYw76TYrzzi9prFCPCypE62WOembzJEEiLcws8q1lXbg+p4eCPXv+1GGWLwMcfKcs+O7QqFD 2gJDdr1g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sYoYl-0000000Fcnj-1q4B; Tue, 30 Jul 2024 15:14:43 +0000 Received: from sin.source.kernel.org ([145.40.73.55]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sYoVk-0000000Fbu6-0ppe for linux-arm-kernel@lists.infradead.org; Tue, 30 Jul 2024 15:11:38 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 311A3CE10C5; Tue, 30 Jul 2024 15:11:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5F1DC4AF0C; Tue, 30 Jul 2024 15:11:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722352293; bh=yj/2UbL6AT3UA9cj75DDWr7HyIl4OJi5TZEY11witfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=axH+xjm/qBZtIYxU9APwZrGU4huJ67+rC7qVEB5khk1nFEjitrYlZC9qsJlQLtSBV KyvJpJMZMRLJInMz+3JF47joB3UXVv32+nDlqvwYXdICqJOJwJG7fpVFRDt6NxTW1S 5Re/+P9mnZAvmPVLgFkMTGYHXeNtKRoPqWnRm0pzuY2ANhsKo1d9YMTnzftlfsBcuV aqAOB2dmItUdnN+US9bKCAhoftD09p4xE8P0feuyZxMPwAZzB++IFhDLxQ79pbvxnR gbNZrYPBOiifMYbp0uWIo2V0xkK8PeA38bODCB3MkNnINR5jKrXZ5b7138D9NLy3gF /wDKDA2Cv9A0A== From: Will Deacon To: linux-arm-kernel@lists.infradead.org Cc: Will Deacon , Sudeep Holla , Catalin Marinas , Lorenzo Pieralisi , Suzuki Poulose , Steven Price , Oliver Upton , Marc Zyngier , linux-coco@lists.linux.dev Subject: [PATCH 6/6] drivers/virt: pkvm: Intercept ioremap using pKVM MMIO_GUARD hypercall Date: Tue, 30 Jul 2024 16:11:12 +0100 Message-Id: <20240730151113.1497-7-will@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20240730151113.1497-1-will@kernel.org> References: <20240730151113.1497-1-will@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240730_081136_737619_BCEFABD9 X-CRM114-Status: GOOD ( 16.27 ) 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 Hook up pKVM's MMIO_GUARD hypercall so that ioremap() and friends will register the target physical address as MMIO with the hypervisor, allowing guest exits to that page to be emulated by the host with full syndrome information. Signed-off-by: Will Deacon --- Documentation/virt/kvm/arm/hypercalls.rst | 26 ++++++++++++++ drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c | 35 +++++++++++++++++++ include/linux/arm-smccc.h | 7 ++++ 3 files changed, 68 insertions(+) diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst index c42580e71bf8..af7bc2c2e0cb 100644 --- a/Documentation/virt/kvm/arm/hypercalls.rst +++ b/Documentation/virt/kvm/arm/hypercalls.rst @@ -116,3 +116,29 @@ memory protection granule advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``. | | | +---------------------------------------------+ | | | | ``INVALID_PARAMETER (-3)`` | +---------------------+----------+----+---------------------------------------------+ + +``ARM_SMCCC_KVM_FUNC_MMIO_GUARD`` +---------------------------------- + +Request that a given memory region is handled as MMIO by the hypervisor, +allowing accesses to this region to be emulated by the KVM host. The size of the +region is equal to the memory protection granule advertised by +``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``. + ++---------------------+-------------------------------------------------------------+ +| Presence: | Optional; pKVM protected guests only. | ++---------------------+-------------------------------------------------------------+ +| Calling convention: | HVC64 | ++---------------------+----------+--------------------------------------------------+ +| Function ID: | (uint32) | 0xC6000007 | ++---------------------+----------+----+---------------------------------------------+ +| Arguments: | (uint64) | R1 | Base IPA of MMIO memory region | +| +----------+----+---------------------------------------------+ +| | (uint64) | R2 | Reserved / Must be zero | +| +----------+----+---------------------------------------------+ +| | (uint64) | R3 | Reserved / Must be zero | ++---------------------+----------+----+---------------------------------------------+ +| Return Values: | (int64) | R0 | ``SUCCESS (0)`` | +| | | +---------------------------------------------+ +| | | | ``INVALID_PARAMETER (-3)`` | ++---------------------+----------+----+---------------------------------------------+ diff --git a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c index 8256cf68fd76..56a3859dda8a 100644 --- a/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c +++ b/drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include @@ -67,6 +69,36 @@ static const struct arm64_mem_crypt_ops pkvm_crypt_ops = { .decrypt = pkvm_set_memory_decrypted, }; +static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size, + pgprot_t *prot) +{ + phys_addr_t end; + pteval_t protval = pgprot_val(*prot); + + /* + * We only expect MMIO emulation for regions mapped with device + * attributes. + */ + if (protval != PROT_DEVICE_nGnRE && protval != PROT_DEVICE_nGnRnE) + return 0; + + phys = PAGE_ALIGN_DOWN(phys); + end = phys + PAGE_ALIGN(size); + + while (phys < end) { + const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID; + int err; + + err = arm_smccc_do_one_page(func_id, phys); + if (err) + return err; + + phys += PAGE_SIZE; + } + + return 0; +} + void pkvm_init_hyp_services(void) { int i; @@ -89,4 +121,7 @@ void pkvm_init_hyp_services(void) pkvm_granule = res.a0; arm64_mem_crypt_ops_register(&pkvm_crypt_ops); + + if (kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_MMIO_GUARD)) + arm64_ioremap_prot_hook_register(&mmio_guard_ioremap_hook); } diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 9cb7c95920b0..e93c1f7cea70 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -118,6 +118,7 @@ #define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2 #define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3 #define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4 +#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 #define ARM_SMCCC_KVM_NUM_FUNCS 128 @@ -158,6 +159,12 @@ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MEM_UNSHARE) +#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_MMIO_GUARD) + /* ptp_kvm counter type ID */ #define KVM_PTP_VIRT_COUNTER 0 #define KVM_PTP_PHYS_COUNTER 1