From: Varad Gautam <varad.gautam@suse.com>
To: kvm@vger.kernel.org, pbonzini@redhat.com, drjones@redhat.com
Cc: marcorr@google.com, zxwang42@gmail.com, erdemaktas@google.com,
rientjes@google.com, seanjc@google.com, brijesh.singh@amd.com,
Thomas.Lendacky@amd.com, jroedel@suse.de, bp@suse.de,
varad.gautam@suse.com
Subject: [kvm-unit-tests 02/13] x86: AMD SEV-ES: Setup #VC exception handler for AMD SEV-ES
Date: Thu, 20 Jan 2022 13:51:11 +0100 [thread overview]
Message-ID: <20220120125122.4633-3-varad.gautam@suse.com> (raw)
In-Reply-To: <20220120125122.4633-1-varad.gautam@suse.com>
AMD SEV-ES defines a new guest exception that gets triggered on
some vmexits to allow the guest to control what state gets shared
with the host. kvm-unit-tests currently relies on UEFI to provide
this #VC exception handler.
Switch the tests to install their own #VC handler on early bootup
to process these exits, just after GHCB has been mapped.
If --amdsev-efi-vc is passed during ./configure, the tests will
continue using the UEFI #VC handler.
Signed-off-by: Varad Gautam <varad.gautam@suse.com>
---
Makefile | 3 +++
configure | 16 ++++++++++++++++
lib/x86/amd_sev.c | 3 ++-
lib/x86/amd_sev.h | 1 +
lib/x86/amd_sev_vc.c | 14 ++++++++++++++
lib/x86/desc.c | 15 +++++++++++++++
lib/x86/desc.h | 1 +
lib/x86/setup.c | 10 ++++++++++
x86/Makefile.common | 1 +
9 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 lib/x86/amd_sev_vc.c
diff --git a/Makefile b/Makefile
index 4f4ad23..94a0162 100644
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,9 @@ else
$(error Cannot build $(ARCH_NAME) tests as EFI apps)
endif
EFI_CFLAGS := -DTARGET_EFI
+ifeq ($(AMDSEV_EFI_VC),y)
+EFI_CFLAGS += -DAMDSEV_EFI_VC
+endif
# The following CFLAGS and LDFLAGS come from:
# - GNU-EFI/Makefile.defaults
# - GNU-EFI/apps/Makefile
diff --git a/configure b/configure
index 41372ef..c687d9f 100755
--- a/configure
+++ b/configure
@@ -29,6 +29,7 @@ host_key_document=
page_size=
earlycon=
target_efi=
+amdsev_efi_vc=
usage() {
cat <<-EOF
@@ -71,6 +72,8 @@ usage() {
Specify a PL011 compatible UART at address ADDR. Supported
register stride is 32 bit only.
--target-efi Boot and run from UEFI
+ --amdsev-efi-vc Use UEFI-provided #VC handlers on AMD SEV/ES. Requires
+ --target-efi.
EOF
exit 1
}
@@ -138,6 +141,9 @@ while [[ "$1" = -* ]]; do
--target-efi)
target_efi=y
;;
+ --amdsev-efi-vc)
+ amdsev_efi_vc=y
+ ;;
--help)
usage
;;
@@ -197,8 +203,17 @@ elif [ "$processor" = "arm" ]; then
processor="cortex-a15"
fi
+if [ "$amdsev_efi_vc" ] && [ "$arch" != "x86_64" ]; then
+ echo "--amdsev-efi-vc requires arch x86_64."
+ usage
+fi
+
if [ "$arch" = "i386" ] || [ "$arch" = "x86_64" ]; then
testdir=x86
+ if [ "$amdsev_efi_vc" ] && [ -z "$target_efi" ]; then
+ echo "--amdsev-efi-vc requires --target-efi."
+ usage
+ fi
elif [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
testdir=arm
if [ "$target" = "qemu" ]; then
@@ -356,6 +371,7 @@ WA_DIVIDE=$wa_divide
GENPROTIMG=${GENPROTIMG-genprotimg}
HOST_KEY_DOCUMENT=$host_key_document
TARGET_EFI=$target_efi
+AMDSEV_EFI_VC=$amdsev_efi_vc
EOF
if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ]; then
echo "TARGET=$target" >> config.mak
diff --git a/lib/x86/amd_sev.c b/lib/x86/amd_sev.c
index 6672214..bde126b 100644
--- a/lib/x86/amd_sev.c
+++ b/lib/x86/amd_sev.c
@@ -14,6 +14,7 @@
#include "x86/vm.h"
static unsigned short amd_sev_c_bit_pos;
+phys_addr_t ghcb_addr;
bool amd_sev_enabled(void)
{
@@ -126,7 +127,7 @@ void setup_ghcb_pte(pgd_t *page_table)
* function searches GHCB's L1 pte, creates corresponding L1 ptes if not
* found, and unsets the c-bit of GHCB's L1 pte.
*/
- phys_addr_t ghcb_addr, ghcb_base_addr;
+ phys_addr_t ghcb_base_addr;
pteval_t *pte;
/* Read the current GHCB page addr */
diff --git a/lib/x86/amd_sev.h b/lib/x86/amd_sev.h
index 6a10f84..afbacf3 100644
--- a/lib/x86/amd_sev.h
+++ b/lib/x86/amd_sev.h
@@ -54,6 +54,7 @@ efi_status_t setup_amd_sev(void);
bool amd_sev_es_enabled(void);
efi_status_t setup_amd_sev_es(void);
void setup_ghcb_pte(pgd_t *page_table);
+void handle_sev_es_vc(struct ex_regs *regs);
unsigned long long get_amd_sev_c_bit_mask(void);
unsigned long long get_amd_sev_addr_upperbound(void);
diff --git a/lib/x86/amd_sev_vc.c b/lib/x86/amd_sev_vc.c
new file mode 100644
index 0000000..8226121
--- /dev/null
+++ b/lib/x86/amd_sev_vc.c
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include "amd_sev.h"
+
+extern phys_addr_t ghcb_addr;
+
+void handle_sev_es_vc(struct ex_regs *regs)
+{
+ struct ghcb *ghcb = (struct ghcb *) ghcb_addr;
+ if (!ghcb) {
+ /* TODO: kill guest */
+ return;
+ }
+}
diff --git a/lib/x86/desc.c b/lib/x86/desc.c
index 16b7256..73aa866 100644
--- a/lib/x86/desc.c
+++ b/lib/x86/desc.c
@@ -3,6 +3,9 @@
#include "processor.h"
#include <setjmp.h>
#include "apic-defs.h"
+#ifdef TARGET_EFI
+#include "amd_sev.h"
+#endif
/* Boot-related data structures */
@@ -228,6 +231,9 @@ EX_E(ac, 17);
EX(mc, 18);
EX(xm, 19);
EX_E(cp, 21);
+#ifdef TARGET_EFI
+EX_E(vc, 29);
+#endif
asm (".pushsection .text \n\t"
"__handle_exception: \n\t"
@@ -293,6 +299,15 @@ void setup_idt(void)
handle_exception(13, check_exception_table);
}
+void setup_amd_sev_es_vc(void)
+{
+ if (!amd_sev_es_enabled())
+ return;
+
+ set_idt_entry(29, &vc_fault, 0);
+ handle_exception(29, handle_sev_es_vc);
+}
+
unsigned exception_vector(void)
{
unsigned char vector;
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index b65539e..4fcbf9f 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -220,6 +220,7 @@ void set_intr_alt_stack(int e, void *fn);
void print_current_tss_info(void);
handler handle_exception(u8 v, handler fn);
void unhandled_exception(struct ex_regs *regs, bool cpu);
+void setup_amd_sev_es_vc(void);
bool test_for_exception(unsigned int ex, void (*trigger_func)(void *data),
void *data);
diff --git a/lib/x86/setup.c b/lib/x86/setup.c
index bbd3468..6013602 100644
--- a/lib/x86/setup.c
+++ b/lib/x86/setup.c
@@ -327,6 +327,16 @@ efi_status_t setup_efi(efi_bootinfo_t *efi_bootinfo)
smp_init();
setup_page_table();
+#ifndef AMDSEV_EFI_VC
+ if (amd_sev_es_enabled()) {
+ /*
+ * Switch away from the UEFI-installed #VC handler.
+ * GHCB has already been mapped at this point.
+ */
+ setup_amd_sev_es_vc();
+ }
+#endif /* AMDSEV_EFI_VC */
+
return EFI_SUCCESS;
}
diff --git a/x86/Makefile.common b/x86/Makefile.common
index 984444e..65d16e7 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -24,6 +24,7 @@ cflatobjs += lib/x86/fault_test.o
cflatobjs += lib/x86/delay.o
ifeq ($(TARGET_EFI),y)
cflatobjs += lib/x86/amd_sev.o
+cflatobjs += lib/x86/amd_sev_vc.o
cflatobjs += lib/efi.o
cflatobjs += x86/efi/reloc_x86_64.o
endif
--
2.32.0
next prev parent reply other threads:[~2022-01-20 12:52 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-20 12:51 [kvm-unit-tests 00/13] Add #VC exception handling for AMD SEV-ES Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 01/13] x86/efi: Allow specifying AMD SEV/SEV-ES guest launch policy Varad Gautam
2022-01-20 16:18 ` Tom Lendacky
2022-01-30 20:04 ` Marc Orr
2022-01-20 12:51 ` Varad Gautam [this message]
2022-01-30 20:36 ` [kvm-unit-tests 02/13] x86: AMD SEV-ES: Setup #VC exception handler for AMD SEV-ES Marc Orr
2022-02-04 10:55 ` Joerg Roedel
2022-02-04 15:57 ` Marc Orr
2022-02-04 16:30 ` Sean Christopherson
2022-02-04 20:09 ` Marc Orr
2022-02-07 21:11 ` Sean Christopherson
2022-02-08 1:58 ` Marc Orr
2022-02-04 17:15 ` Joerg Roedel
2022-02-04 20:12 ` Marc Orr
2022-01-20 12:51 ` [kvm-unit-tests 03/13] x86: Move svm.h to lib/x86/ Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 04/13] lib: x86: Import insn decoder from Linux Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 05/13] x86: AMD SEV-ES: Pull related GHCB definitions and helpers " Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 06/13] x86: AMD SEV-ES: Prepare for #VC processing Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 07/13] x86: AMD SEV-ES: Handle WBINVD #VC Varad Gautam
2022-02-07 21:13 ` Sean Christopherson
2022-01-20 12:51 ` [kvm-unit-tests 08/13] lib/x86: Move xsave helpers to lib/ Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 09/13] x86: AMD SEV-ES: Handle CPUID #VC Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 10/13] x86: AMD SEV-ES: Handle RDTSC/RDTSCP #VC Varad Gautam
2022-02-07 21:17 ` Sean Christopherson
2022-01-20 12:51 ` [kvm-unit-tests 11/13] x86: AMD SEV-ES: Handle MSR #VC Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 12/13] x86: AMD SEV-ES: Handle IOIO #VC Varad Gautam
2022-01-20 12:51 ` [kvm-unit-tests 13/13] x86: AMD SEV-ES: Handle string IO for " Varad Gautam
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=20220120125122.4633-3-varad.gautam@suse.com \
--to=varad.gautam@suse.com \
--cc=Thomas.Lendacky@amd.com \
--cc=bp@suse.de \
--cc=brijesh.singh@amd.com \
--cc=drjones@redhat.com \
--cc=erdemaktas@google.com \
--cc=jroedel@suse.de \
--cc=kvm@vger.kernel.org \
--cc=marcorr@google.com \
--cc=pbonzini@redhat.com \
--cc=rientjes@google.com \
--cc=seanjc@google.com \
--cc=zxwang42@gmail.com \
/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