From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77B0516C6B5; Wed, 28 Aug 2024 10:45:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724841916; cv=none; b=GOX5JGD5K14XR5FjBrgvm7KS+If6x32Polg9t+odl1V5oopkILJ6idTbdlFeztL1jfyDBJrahsWKeJOrbmwEZwonPZP/3NCemxvdACnOcnZaJX5B5VstYa1fmcj11rVIGAoEB1CZA/Kl44771auDZxbJyX9H16z6oykKFnmTziU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724841916; c=relaxed/simple; bh=vNEb1wVW/eejnN1g+r0shkPHa5H6qAq1VkM5+X6HCk0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Bekdbdo5u8T/skWJfD8Orw/dNRH181TeVZ2P5anvA6dCcT2geuXaiEggwI1aQ2HV26wPBLqBOyJUIQlKvFPl/c4a4qdRjGl70Fs5QhHO6YPcBDH5bwnp/JVIr+heYF8+nNb7c9jjl5IPOPCfK2Hg1oSfuqv3woOFhTruewo5NZo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bjS4hA1R; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bjS4hA1R" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7A914C98ECB; Wed, 28 Aug 2024 10:45:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724841916; bh=vNEb1wVW/eejnN1g+r0shkPHa5H6qAq1VkM5+X6HCk0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bjS4hA1Radrt2PkJcPx0XWmB0LCIfhLMoEGZlOFHNNK7Y3gXUbO+Ws7FV5tbmQRB2 5b6AL62/+MZW0yVQcFLLTTv6/MzaeRMfNyAAhg9LBRReI3GeCs80FpOzTh99bfpTQh qvMLKCJD+Cwf3IWksmrv4nTsLLtYlanYQl4QgVXDBE4MSm7VBgLVbh+4pWIdeqk0QH +Ozzmy9VzUYIsV7mNBZNalrBcCJYPlR0kNXq1EbIJQli5joqFeKQpO0T1frZPGm2dG Jh80VbTsq1VPVfxg7g0r707wLidW0zEs8cc6uQ6POW9AlWpV0Wum9qGGdUtiGgCamI o8SB60Vfb/0pw== From: Alexey Gladkov To: linux-kernel@vger.kernel.org, linux-coco@lists.linux.dev Cc: "Alexey Gladkov (Intel)" , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , "Kirill A. Shutemov" , Andrew Morton , Yuan Yao , Geert Uytterhoeven , Yuntao Wang , Kai Huang , Baoquan He , Oleg Nesterov , cho@microsoft.com, decui@microsoft.com, John.Starks@microsoft.com Subject: [PATCH v5 3/6] x86/tdx: Allow MMIO from userspace Date: Wed, 28 Aug 2024 12:44:33 +0200 Message-ID: <1ba5afd6ea4966d8eb5cb1f2b1a1deeb10dea8eb.1724837158.git.legion@kernel.org> X-Mailer: git-send-email 2.46.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-coco@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: "Alexey Gladkov (Intel)" The MMIO emulation is only allowed for kernel space code. It is carried out through a special API, which uses only certain instructions. This does not allow userspace to work with virtual devices. Allow userspace to use the same instructions as kernel space to access MMIO. Additional checks have been added previously. Reviewed-by: Thomas Gleixner Reviewed-by: Kirill A. Shutemov Signed-off-by: Alexey Gladkov (Intel) --- arch/x86/coco/tdx/tdx.c | 43 +++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 99634e12f9a7..5d2d07aa08ce 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -487,6 +487,32 @@ static int valid_vaddr(struct ve_info *ve, enum insn_mmio_type mmio, int size, return 0; } +static int decode_insn_struct(struct insn *insn, struct pt_regs *regs) +{ + char buffer[MAX_INSN_SIZE]; + + if (user_mode(regs)) { + int nr_copied = insn_fetch_from_user(regs, buffer); + + if (nr_copied <= 0) + return -EFAULT; + + if (!insn_decode_from_regs(insn, regs, buffer, nr_copied)) + return -EINVAL; + } else { + if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) + return -EFAULT; + + if (insn_decode(insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) + return -EINVAL; + } + + if (!insn->immediate.got) + return -EINVAL; + + return 0; +} + static int handle_mmio_write(struct insn *insn, enum insn_mmio_type mmio, int size, struct pt_regs *regs, struct ve_info *ve) { @@ -567,21 +593,14 @@ static int handle_mmio_read(struct insn *insn, enum insn_mmio_type mmio, int siz static int handle_mmio(struct pt_regs *regs, struct ve_info *ve) { - char buffer[MAX_INSN_SIZE]; enum insn_mmio_type mmio; struct insn insn = {}; unsigned long vaddr; int size, ret; - /* Only in-kernel MMIO is supported */ - if (WARN_ON_ONCE(user_mode(regs))) - return -EFAULT; - - if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) - return -EFAULT; - - if (insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) - return -EINVAL; + ret = decode_insn_struct(&insn, regs); + if (ret) + return ret; mmio = insn_decode_mmio(&insn, &size); if (WARN_ON_ONCE(mmio == INSN_MMIO_DECODE_FAILED)) @@ -777,6 +796,10 @@ static int virt_exception_user(struct pt_regs *regs, struct ve_info *ve) switch (ve->exit_reason) { case EXIT_REASON_CPUID: return handle_cpuid(regs, ve); + case EXIT_REASON_EPT_VIOLATION: + if (is_private_gpa(ve->gpa)) + panic("Unexpected EPT-violation on private memory."); + return handle_mmio(regs, ve); default: pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); return -EIO; -- 2.46.0