kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Joerg Roedel <joro@8bytes.org>
To: x86@kernel.org
Cc: Joerg Roedel <joro@8bytes.org>, Joerg Roedel <jroedel@suse.de>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	hpa@zytor.com, Andy Lutomirski <luto@kernel.org>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Jiri Slaby <jslaby@suse.cz>,
	Dan Williams <dan.j.williams@intel.com>,
	Juergen Gross <jgross@suse.com>,
	Kees Cook <keescook@chromium.org>,
	David Rientjes <rientjes@google.com>,
	Cfir Cohen <cfir@google.com>, Erdem Aktas <erdemaktas@google.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Mike Stunes <mstunes@vmware.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>,
	Martin Radev <martin.b.radev@gmail.com>,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	virtualization@lists.linux-foundation.org
Subject: [PATCH v7 66/72] x86/realmode: Setup AP jump table
Date: Mon,  7 Sep 2020 15:16:07 +0200	[thread overview]
Message-ID: <20200907131613.12703-67-joro@8bytes.org> (raw)
In-Reply-To: <20200907131613.12703-1-joro@8bytes.org>

From: Tom Lendacky <thomas.lendacky@amd.com>

As part of the GHCB specification, the booting of APs under SEV-ES
requires an AP jump table when transitioning from one layer of code to
another (e.g. when going from UEFI to the OS). As a result, each layer
that parks an AP must provide the physical address of an AP jump table
to the next layer via the hypervisor.

Upon booting of the kernel, read the AP jump table address from the
hypervisor. Under SEV-ES, APs are started using the INIT-SIPI-SIPI
sequence. Before issuing the first SIPI request for an AP, the start
CS and IP is programmed into the AP jump table. Upon issuing the SIPI
request, the AP will awaken and jump to that start CS:IP address.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
[ jroedel@suse.de: - Adapted to different code base
                   - Moved AP table setup from SIPI sending path to
		     real-mode setup code
		   - Fix sparse warnings ]
Co-developed-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 arch/x86/include/asm/sev-es.h   |  5 +++
 arch/x86/include/uapi/asm/svm.h |  3 ++
 arch/x86/kernel/sev-es.c        | 69 +++++++++++++++++++++++++++++++++
 arch/x86/realmode/init.c        | 18 ++++++++-
 4 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/sev-es.h b/arch/x86/include/asm/sev-es.h
index 59176e8c6b81..db88e1c3442d 100644
--- a/arch/x86/include/asm/sev-es.h
+++ b/arch/x86/include/asm/sev-es.h
@@ -73,6 +73,9 @@ static inline u64 lower_bits(u64 val, unsigned int bits)
 	return (val & mask);
 }
 
+struct real_mode_header;
+enum stack_type;
+
 /* Early IDT entry points for #VC handler */
 extern void vc_no_ghcb(void);
 extern void vc_boot_ghcb(void);
@@ -92,9 +95,11 @@ static __always_inline void sev_es_ist_exit(void)
 	if (static_branch_unlikely(&sev_es_enable_key))
 		__sev_es_ist_exit();
 }
+extern int sev_es_setup_ap_jump_table(struct real_mode_header *rmh);
 #else
 static inline void sev_es_ist_enter(struct pt_regs *regs) { }
 static inline void sev_es_ist_exit(void) { }
+static inline int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { return 0; }
 #endif
 
 #endif
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index 8f36ae021a7f..346b8a7155e8 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -84,6 +84,9 @@
 /* SEV-ES software-defined VMGEXIT events */
 #define SVM_VMGEXIT_MMIO_READ			0x80000001
 #define SVM_VMGEXIT_MMIO_WRITE			0x80000002
+#define SVM_VMGEXIT_AP_JUMP_TABLE		0x80000005
+#define SVM_VMGEXIT_SET_AP_JUMP_TABLE		0
+#define SVM_VMGEXIT_GET_AP_JUMP_TABLE		1
 #define SVM_VMGEXIT_UNSUPPORTED_EVENT		0x8000ffff
 
 #define SVM_EXIT_ERR           -1
diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c
index 9814ac99aea1..91e32172d355 100644
--- a/arch/x86/kernel/sev-es.c
+++ b/arch/x86/kernel/sev-es.c
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 
 #include <asm/cpu_entry_area.h>
+#include <asm/stacktrace.h>
 #include <asm/sev-es.h>
 #include <asm/insn-eval.h>
 #include <asm/fpu/internal.h>
@@ -214,6 +215,9 @@ static __always_inline void sev_es_put_ghcb(struct ghcb_state *state)
 	}
 }
 
+/* Needed in vc_early_forward_exception */
+void do_early_exception(struct pt_regs *regs, int trapnr);
+
 static inline u64 sev_es_rd_ghcb_msr(void)
 {
 	return native_read_msr(MSR_AMD64_SEV_ES_GHCB);
@@ -402,6 +406,71 @@ static bool vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
 /* Include code shared with pre-decompression boot stage */
 #include "sev-es-shared.c"
 
+static u64 get_jump_table_addr(void)
+{
+	struct ghcb_state state;
+	unsigned long flags;
+	struct ghcb *ghcb;
+	u64 ret = 0;
+
+	local_irq_save(flags);
+
+	ghcb = sev_es_get_ghcb(&state);
+
+	vc_ghcb_invalidate(ghcb);
+	ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_JUMP_TABLE);
+	ghcb_set_sw_exit_info_1(ghcb, SVM_VMGEXIT_GET_AP_JUMP_TABLE);
+	ghcb_set_sw_exit_info_2(ghcb, 0);
+
+	sev_es_wr_ghcb_msr(__pa(ghcb));
+	VMGEXIT();
+
+	if (ghcb_sw_exit_info_1_is_valid(ghcb) &&
+	    ghcb_sw_exit_info_2_is_valid(ghcb))
+		ret = ghcb->save.sw_exit_info_2;
+
+	sev_es_put_ghcb(&state);
+
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+int sev_es_setup_ap_jump_table(struct real_mode_header *rmh)
+{
+	u16 startup_cs, startup_ip;
+	phys_addr_t jump_table_pa;
+	u64 jump_table_addr;
+	u16 __iomem *jump_table;
+
+	jump_table_addr = get_jump_table_addr();
+
+	/* On UP guests there is no jump table so this is not a failure */
+	if (!jump_table_addr)
+	       return 0;
+
+	/* Check if AP Jump Table is page-aligned */
+	if (jump_table_addr & ~PAGE_MASK)
+		return -EINVAL;
+
+	jump_table_pa = jump_table_addr & PAGE_MASK;
+
+	startup_cs = (u16)(rmh->trampoline_start >> 4);
+	startup_ip = (u16)(rmh->sev_es_trampoline_start -
+			   rmh->trampoline_start);
+
+	jump_table = ioremap_encrypted(jump_table_pa, PAGE_SIZE);
+	if (!jump_table)
+		return -EIO;
+
+	writew(startup_ip, &jump_table[0]);
+	writew(startup_cs, &jump_table[1]);
+
+	iounmap(jump_table);
+
+	return 0;
+}
+
 static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
 {
 	struct pt_regs *regs = ctxt->regs;
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 1ed1208931e0..3fb9b60be07a 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -9,6 +9,7 @@
 #include <asm/realmode.h>
 #include <asm/tlbflush.h>
 #include <asm/crash.h>
+#include <asm/sev-es.h>
 
 struct real_mode_header *real_mode_header;
 u32 *trampoline_cr4_features;
@@ -38,6 +39,19 @@ void __init reserve_real_mode(void)
 	crash_reserve_low_1M();
 }
 
+static void sme_sev_setup_real_mode(struct trampoline_header *th)
+{
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+	if (sme_active())
+		th->flags |= TH_FLAGS_SME_ACTIVE;
+
+	if (sev_es_active()) {
+		if (sev_es_setup_ap_jump_table(real_mode_header))
+			panic("Failed to get/update SEV-ES AP Jump Table");
+	}
+#endif
+}
+
 static void __init setup_real_mode(void)
 {
 	u16 real_mode_seg;
@@ -104,13 +118,13 @@ static void __init setup_real_mode(void)
 	*trampoline_cr4_features = mmu_cr4_features;
 
 	trampoline_header->flags = 0;
-	if (sme_active())
-		trampoline_header->flags |= TH_FLAGS_SME_ACTIVE;
 
 	trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
 	trampoline_pgd[0] = trampoline_pgd_entry.pgd;
 	trampoline_pgd[511] = init_top_pgt[511].pgd;
 #endif
+
+	sme_sev_setup_real_mode(trampoline_header);
 }
 
 /*
-- 
2.28.0


  parent reply	other threads:[~2020-09-07 17:27 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-07 13:15 [PATCH v7 00/72] x86: SEV-ES Guest Support Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 01/72] KVM: SVM: nested: Don't allocate VMCB structures on stack Joerg Roedel
2020-11-05 16:24   ` Michael Roth
2020-11-05 16:38     ` Borislav Petkov
2020-11-06  0:31       ` Michael Roth
2020-11-06  0:39         ` Borislav Petkov
2020-11-05 17:46     ` Michael Roth
2020-09-07 13:15 ` [PATCH v7 02/72] KVM: SVM: Add GHCB definitions Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 03/72] KVM: SVM: Add GHCB Accessor functions Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 04/72] KVM: SVM: Use __packed shorthand Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 05/72] x86/cpufeatures: Add SEV-ES CPU feature Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 06/72] x86/traps: Move pf error codes to <asm/trap_pf.h> Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 07/72] x86/insn: Make inat-tables.c suitable for pre-decompression code Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 08/72] x86/umip: Factor out instruction fetch Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 09/72] x86/umip: Factor out instruction decoding Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 10/72] x86/insn: Add insn_get_modrm_reg_off() Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 11/72] x86/insn: Add insn_has_rep_prefix() helper Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 12/72] x86/boot/compressed/64: Disable red-zone usage Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 13/72] x86/boot/compressed/64: Add IDT Infrastructure Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 14/72] x86/boot/compressed/64: Rename kaslr_64.c to ident_map_64.c Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 15/72] x86/boot/compressed/64: Add page-fault handler Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 16/72] x86/boot/compressed/64: Always switch to own page-table Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 17/72] x86/boot/compressed/64: Don't pre-map memory in KASLR code Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 18/72] x86/boot/compressed/64: Change add_identity_map() to take start and end Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 19/72] x86/boot/compressed/64: Add stage1 #VC handler Joerg Roedel
2020-09-07 16:58   ` Borislav Petkov
2020-09-07 13:15 ` [PATCH v7 20/72] x86/boot/compressed/64: Call set_sev_encryption_mask() earlier Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 21/72] x86/boot/compressed/64: Check return value of kernel_ident_mapping_init() Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 22/72] x86/boot/compressed/64: Add set_page_en/decrypted() helpers Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 23/72] x86/boot/compressed/64: Setup GHCB Based VC Exception handler Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 24/72] x86/boot/compressed/64: Unmap GHCB page before booting the kernel Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 25/72] x86/sev-es: Add support for handling IOIO exceptions Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 26/72] x86/fpu: Move xgetbv()/xsetbv() into separate header Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 27/72] x86/sev-es: Add CPUID handling to #VC handler Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 28/72] x86/idt: Split idt_data setup out of set_intr_gate() Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 29/72] x86/head/64: Install startup GDT Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 30/72] x86/head/64: Load GDT after switch to virtual addresses Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 31/72] x86/head/64: Load segment registers earlier Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 32/72] x86/head/64: Switch to initial stack earlier Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 33/72] x86/head/64: Install a CPU bringup IDT Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 34/72] x86/idt: Move two function from k/idt.c to i/a/desc.h Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 35/72] x86/head/64: Move early exception dispatch to C code Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 36/72] x86/sev-es: Add SEV-ES Feature Detection Joerg Roedel
2020-09-07 21:02   ` Borislav Petkov
2020-09-07 13:15 ` [PATCH v7 37/72] x86/sev-es: Print SEV-ES info into kernel log Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 38/72] x86/sev-es: Compile early handler code into kernel image Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 39/72] x86/sev-es: Setup early #VC handler Joerg Roedel
2020-09-08 10:22   ` [PATCH v7.1 " Joerg Roedel
2020-09-08 12:35   ` [PATCH v7.2 39/74] " Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 40/72] x86/sev-es: Setup GHCB based boot " Joerg Roedel
2020-09-08 10:24   ` [PATCH v7.1 " Joerg Roedel
2020-09-08 12:38   ` [PATCH v7.2 40/74] " Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 41/72] x86/sev-es: Setup per-cpu GHCBs for the runtime handler Joerg Roedel
2020-09-08 10:51   ` Borislav Petkov
2020-09-07 13:15 ` [PATCH v7 42/72] x86/sev-es: Allocate and Map IST stack for #VC handler Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 43/72] x86/sev-es: Adjust #VC IST Stack on entering NMI handler Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 44/72] x86/dumpstack/64: Add noinstr version of get_stack_info() Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 45/72] x86/entry/64: Add entry code for #VC handler Joerg Roedel
2021-01-24 14:11   ` Lai Jiangshan
2021-01-28 13:18     ` Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 46/72] x86/sev-es: Add Runtime #VC Exception Handler Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 47/72] x86/sev-es: Wire up existing #VC exit-code handlers Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 48/72] x86/sev-es: Handle instruction fetches from user-space Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 49/72] x86/sev-es: Handle MMIO events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 50/72] x86/sev-es: Handle MMIO String Instructions Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 51/72] x86/sev-es: Handle MSR events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 52/72] x86/sev-es: Handle DR7 read/write events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 53/72] x86/sev-es: Handle WBINVD Events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 54/72] x86/sev-es: Handle RDTSC(P) Events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 55/72] x86/sev-es: Handle RDPMC Events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 56/72] x86/sev-es: Handle INVD Events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 57/72] x86/sev-es: Handle MONITOR/MONITORX Events Joerg Roedel
2020-09-07 13:15 ` [PATCH v7 58/72] x86/sev-es: Handle MWAIT/MWAITX Events Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 59/72] x86/sev-es: Handle VMMCALL Events Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 60/72] x86/sev-es: Handle #AC Events Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 61/72] x86/sev-es: Handle #DB Events Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 62/72] x86/paravirt: Allow hypervisor specific VMMCALL handling under SEV-ES Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 63/72] x86/kvm: Add KVM " Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 64/72] x86/vmware: Add VMware specific handling for VMMCALL " Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 65/72] x86/realmode: Add SEV-ES specific trampoline entry point Joerg Roedel
2020-09-07 13:16 ` Joerg Roedel [this message]
2020-09-07 13:16 ` [PATCH v7 67/72] x86/smpboot: Load TSS and getcpu GDT entry before loading IDT Joerg Roedel
2020-09-08 17:20   ` Borislav Petkov
2020-09-08 18:42     ` Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 68/72] x86/head/64: Don't call verify_cpu() on starting APs Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 69/72] x86/sev-es: Support CPU offline/online Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 70/72] x86/sev-es: Handle NMI State Joerg Roedel
2020-09-07 13:16 ` [PATCH v7 71/72] x86/efi: Add GHCB mappings when SEV-ES is active Joerg Roedel
2020-09-08 17:46   ` Borislav Petkov
2020-09-09  8:27     ` Ard Biesheuvel
2020-09-09 12:44       ` Laszlo Ersek
2020-09-09 13:24         ` Laszlo Ersek
2020-09-09 13:49         ` Tom Lendacky
2020-09-10 12:37           ` Ard Biesheuvel
2020-09-07 13:16 ` [PATCH v7 72/72] x86/sev-es: Check required CPU features for SEV-ES Joerg Roedel

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=20200907131613.12703-67-joro@8bytes.org \
    --to=joro@8bytes.org \
    --cc=cfir@google.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=erdemaktas@google.com \
    --cc=hpa@zytor.com \
    --cc=jgross@suse.com \
    --cc=jroedel@suse.de \
    --cc=jslaby@suse.cz \
    --cc=keescook@chromium.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=martin.b.radev@gmail.com \
    --cc=mhiramat@kernel.org \
    --cc=mstunes@vmware.com \
    --cc=peterz@infradead.org \
    --cc=rientjes@google.com \
    --cc=sean.j.christopherson@intel.com \
    --cc=thomas.lendacky@amd.com \
    --cc=virtualization@lists.linux-foundation.org \
    --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).