linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
To: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de,
	dave.hansen@intel.com, luto@kernel.org, peterz@infradead.org
Cc: sathyanarayanan.kuppuswamy@linux.intel.com, ak@linux.intel.com,
	dan.j.williams@intel.com, david@redhat.com, hpa@zytor.com,
	seanjc@google.com, thomas.lendacky@amd.com,
	elena.reshetova@intel.com, x86@kernel.org,
	linux-kernel@vger.kernel.org,
	"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
	stable@vger.kernel.org
Subject: [PATCH 2/2] x86/tdx: Do not allow #VE due to EPT violation on the private memory
Date: Fri, 28 Oct 2022 17:12:20 +0300	[thread overview]
Message-ID: <20221028141220.29217-3-kirill.shutemov@linux.intel.com> (raw)
In-Reply-To: <20221028141220.29217-1-kirill.shutemov@linux.intel.com>

Virtualization Exceptions (#VE) are delivered to TDX guests due to
specific guest actions such as using specific instructions or accessing
a specific MSR.

Notable reason for #VE is access to specific guest physical addresses.
It requires special security considerations as it is not fully in
control of the guest kernel. VMM can remove a page from EPT page table
and trigger #VE on access.

The primary use-case for #VE on a memory access is MMIO: VMM removes
page from EPT to trigger exception in the guest which allows guest to
emulate MMIO with hypercalls.

MMIO only happens on shared memory. All conventional kernel memory is
private. This includes everything from kernel stacks to kernel text.

Handling exceptions on arbitrary accesses to kernel memory is
essentially impossible as handling #VE may require access to memory
that also triggers the exception.

TDX module provides mechanism to disable #VE delivery on access to
private memory. If SEPT_VE_DISABLE TD attribute is set, private EPT
violation will not be reflected to the guest as #VE, but will trigger
exit to VMM.

Make sure the attribute is set by VMM. Panic otherwise.

There's small window during the boot before the check where kernel has
early #VE handler. But the handler is only for port I/O and panic as
soon as it sees any other #VE reason.

SEPT_VE_DISABLE makes SEPT violation unrecoverable and terminating the
TD is the only option.

Kernel has no legitimate use-cases for #VE on private memory. It is
either a guest kernel bug (like access of unaccepted memory) or
malicious/buggy VMM that removes guest page that is still in use.

In both cases terminating TD is the right thing to do.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Fixes: 9a22bf6debbf ("x86/traps: Add #VE support for TDX guest")
Cc: stable@vger.kernel.org # v5.19
---
 arch/x86/coco/tdx/tdx.c | 49 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 343d60853b71..a376a0c3fddc 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -34,6 +34,9 @@
 #define VE_GET_PORT_NUM(e)	((e) >> 16)
 #define VE_IS_IO_STRING(e)	((e) & BIT(4))
 
+/* TD Attributes */
+#define ATTR_SEPT_VE_DISABLE	BIT(28)
+
 /* Caches GPA width from TDG.VP.INFO TDCALL */
 static unsigned int gpa_width __ro_after_init;
 
@@ -770,6 +773,52 @@ void __init tdx_early_init(void)
 	 */
 	tdx_parse_tdinfo();
 
+	/*
+	 * Do not allow #VE due to EPT violation on the private memory
+	 *
+	 * Virtualization Exceptions (#VE) are delivered to TDX guests due to
+	 * specific guest actions such as using specific instructions or
+	 * accessing a specific MSR.
+	 *
+	 * Notable reason for #VE is access to specific guest physical
+	 * addresses. It requires special security considerations as it is not
+	 * fully in control of the guest kernel. VMM can remove a page from EPT
+	 * page table and trigger #VE on access.
+	 *
+	 * The primary use-case for #VE on a memory access is MMIO: VMM removes
+	 * page from EPT to trigger exception in the guest which allows guest to
+	 * emulate MMIO with hypercalls.
+	 *
+	 * MMIO only happens on shared memory. All conventional kernel memory is
+	 * private. This includes everything from kernel stacks to kernel text.
+	 *
+	 * Handling exceptions on arbitrary accesses to kernel memory is
+	 * essentially impossible as handling #VE may require access to memory
+	 * that also triggers the exception.
+	 *
+	 * TDX module provides mechanism to disable #VE delivery on access to
+	 * private memory. If SEPT_VE_DISABLE TD attribute is set, private EPT
+	 * violation will not be reflected to the guest as #VE, but will trigger
+	 * exit to VMM.
+	 *
+	 * Make sure the attribute is set by VMM. Panic otherwise.
+	 *
+	 * There's small window during the boot before the check where kernel has
+	 * early #VE handler. But the handler is only for port I/O and panic as
+	 * soon as it sees any other #VE reason.
+	 *
+	 * SEPT_VE_DISABLE makes SEPT violation unrecoverable and terminating
+	 * the TD is the only option.
+	 *
+	 * Kernel has no legitimate use-cases for #VE on private memory. It is
+	 * either a guest kernel bug (like access of unaccepted memory) or
+	 * malicious/buggy VMM that removes guest page that is still in use.
+	 *
+	 * In both cases terminating TD is the right thing to do.
+	 */
+	if (!(td_attr & ATTR_SEPT_VE_DISABLE))
+		panic("TD misconfiguration: SEPT_VE_DISABLE attibute must be set.\n");
+
 	setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
 
 	cc_set_vendor(CC_VENDOR_INTEL);
-- 
2.38.0


  parent reply	other threads:[~2022-10-28 14:12 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-28 14:12 [PATCH 0/2] x86/tdx: Enforce no #VE on private memory accesses Kirill A. Shutemov
2022-10-28 14:12 ` [PATCH 1/2] x86/tdx: Extract GET_INFO call from get_cc_mask() Kirill A. Shutemov
2022-10-28 15:43   ` Dave Hansen
2022-10-28 23:27   ` Dave Hansen
2022-10-28 23:59     ` Kirill A. Shutemov
2022-10-31  4:12       ` Kirill A. Shutemov
2022-10-31 16:42         ` Dave Hansen
2022-10-31 19:19           ` Kirill A. Shutemov
2022-10-31 19:27         ` Andi Kleen
2022-10-31 19:44           ` Dave Hansen
2022-10-31 22:10             ` Kirill A. Shutemov
2022-10-28 14:12 ` Kirill A. Shutemov [this message]
2022-10-28 15:41   ` [PATCH 2/2] x86/tdx: Do not allow #VE due to EPT violation on the private memory Dave Hansen
2022-10-31  4:07   ` Guorui Yu
2022-10-31  4:33     ` Kirill A. Shutemov
2022-10-31 14:22     ` Dave Hansen
2022-11-04 22:36       ` Erdem Aktas
2022-11-04 22:50         ` Dave Hansen
2022-11-07 22:53           ` Erdem Aktas
2022-11-07 23:30             ` Dave Hansen
2022-11-07  5:10       ` Guorui Yu
2022-11-07 13:31         ` Dave Hansen
2022-11-07 13:43           ` Guorui Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221028141220.29217-3-kirill.shutemov@linux.intel.com \
    --to=kirill.shutemov@linux.intel.com \
    --cc=ak@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=david@redhat.com \
    --cc=elena.reshetova@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=seanjc@google.com \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).