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 v5 68/75] x86/realmode: Setup AP jump table
Date: Fri, 24 Jul 2020 18:03:29 +0200 [thread overview]
Message-ID: <20200724160336.5435-69-joro@8bytes.org> (raw)
In-Reply-To: <20200724160336.5435-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 | 68 +++++++++++++++++++++++++++++++++
arch/x86/realmode/init.c | 18 ++++++++-
4 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/sev-es.h b/arch/x86/include/asm/sev-es.h
index 2dd19932a60d..6ca38dc378e0 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 bool handle_vc_boot_ghcb(struct pt_regs *regs);
@@ -91,9 +94,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..a19ce9681ec2 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 88636ff1d451..afd728d6de85 100644
--- a/arch/x86/kernel/sev-es.c
+++ b/arch/x86/kernel/sev-es.c
@@ -21,6 +21,8 @@
#include <linux/mm.h>
#include <asm/cpu_entry_area.h>
+#include <asm/stacktrace.h>
+#include <asm/realmode.h>
#include <asm/sev-es.h>
#include <asm/insn-eval.h>
#include <asm/fpu/internal.h>
@@ -219,6 +221,9 @@ static __always_inline void sev_es_put_ghcb(struct ghcb_state *state)
}
}
+/* Needed in vc_early_vc_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);
@@ -407,6 +412,69 @@ 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 sev_es_get_jump_table_addr(void)
+{
+ struct ghcb_state state;
+ unsigned long flags;
+ struct ghcb *ghcb;
+ u64 ret;
+
+ 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_is_valid_sw_exit_info_1(ghcb) ||
+ !ghcb_is_valid_sw_exit_info_2(ghcb))
+ ret = 0;
+
+ 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 = sev_es_get_jump_table_addr();
+
+ /* Check if AP Jump Table is non-zero and page-aligned */
+ if (!jump_table_addr || jump_table_addr & ~PAGE_MASK)
+ return 0;
+
+ 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..61a52b925d15 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 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.27.0
next prev parent reply other threads:[~2020-07-24 16:05 UTC|newest]
Thread overview: 97+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-24 16:02 [PATCH v5 00/75] x86: SEV-ES Guest Support Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 01/75] KVM: SVM: Add GHCB definitions Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 02/75] KVM: SVM: Add GHCB Accessor functions Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 03/75] KVM: SVM: Use __packed shorthand Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 04/75] x86/cpufeatures: Add SEV-ES CPU feature Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 05/75] x86/traps: Move pf error codes to <asm/trap_pf.h> Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 06/75] x86/insn: Make inat-tables.c suitable for pre-decompression code Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 07/75] x86/umip: Factor out instruction fetch Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 08/75] x86/umip: Factor out instruction decoding Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 09/75] x86/insn: Add insn_get_modrm_reg_off() Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 10/75] x86/insn: Add insn_has_rep_prefix() helper Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 11/75] x86/boot/compressed/64: Disable red-zone usage Joerg Roedel
2020-07-24 17:43 ` Kees Cook
2020-07-24 17:58 ` Arvind Sankar
2020-07-24 16:02 ` [PATCH v5 12/75] x86/boot/compressed/64: Add IDT Infrastructure Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 13/75] x86/boot/compressed/64: Rename kaslr_64.c to ident_map_64.c Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 14/75] x86/boot/compressed/64: Add page-fault handler Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 15/75] x86/boot/compressed/64: Always switch to own page-table Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 16/75] x86/boot/compressed/64: Don't pre-map memory in KASLR code Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 17/75] x86/boot/compressed/64: Change add_identity_map() to take start and end Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 18/75] x86/boot/compressed/64: Add stage1 #VC handler Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 19/75] x86/boot/compressed/64: Call set_sev_encryption_mask earlier Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 20/75] x86/boot/compressed/64: Check return value of kernel_ident_mapping_init() Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 21/75] x86/boot/compressed/64: Add set_page_en/decrypted() helpers Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 22/75] x86/boot/compressed/64: Setup GHCB Based VC Exception handler Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 23/75] x86/boot/compressed/64: Unmap GHCB page before booting the kernel Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 24/75] x86/sev-es: Add support for handling IOIO exceptions Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 25/75] x86/fpu: Move xgetbv()/xsetbv() into separate header Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 26/75] x86/sev-es: Add CPUID handling to #VC handler Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 27/75] x86/idt: Move IDT to data segment Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 28/75] x86/idt: Split idt_data setup out of set_intr_gate() Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 29/75] x86/head/64: Install startup GDT Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 30/75] x86/head/64: Setup MSR_GS_BASE before calling into C code Joerg Roedel
2020-07-24 17:42 ` Kees Cook
2020-07-24 16:02 ` [PATCH v5 31/75] x86/head/64: Load GDT after switch to virtual addresses Joerg Roedel
2020-07-24 17:40 ` Kees Cook
2020-07-24 16:02 ` [PATCH v5 32/75] x86/head/64: Load segment registers earlier Joerg Roedel
2020-07-24 17:42 ` Kees Cook
2020-07-24 16:02 ` [PATCH v5 33/75] x86/head/64: Switch to initial stack earlier Joerg Roedel
2020-07-24 17:43 ` Kees Cook
2020-07-24 16:02 ` [PATCH v5 34/75] x86/head/64: Make fixup_pointer() static inline Joerg Roedel
2020-07-24 17:52 ` Kees Cook
2020-07-24 16:02 ` [PATCH v5 35/75] x86/head/64: Load IDT earlier Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 36/75] x86/head/64: Move early exception dispatch to C code Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 37/75] x86/head/64: Set CR4.FSGSBASE early Joerg Roedel
2020-07-24 16:02 ` [PATCH v5 38/75] x86/sev-es: Add SEV-ES Feature Detection Joerg Roedel
2020-07-24 17:54 ` Kees Cook
2020-07-24 16:03 ` [PATCH v5 39/75] x86/sev-es: Print SEV-ES info into kernel log Joerg Roedel
2020-07-24 17:54 ` Kees Cook
2020-07-24 16:03 ` [PATCH v5 40/75] x86/sev-es: Compile early handler code into kernel image Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 41/75] x86/sev-es: Setup early #VC handler Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 42/75] x86/sev-es: Setup GHCB based boot " Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 43/75] x86/sev-es: Setup per-cpu GHCBs for the runtime handler Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 44/75] x86/sev-es: Allocate and Map IST stack for #VC handler Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 45/75] x86/sev-es: Adjust #VC IST Stack on entering NMI handler Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 46/75] x86/dumpstack/64: Add noinstr version of get_stack_info() Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 47/75] x86/entry/64: Add entry code for #VC handler Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 48/75] x86/sev-es: Add Runtime #VC Exception Handler Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 49/75] x86/sev-es: Wire up existing #VC exit-code handlers Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 50/75] x86/sev-es: Handle instruction fetches from user-space Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 51/75] x86/sev-es: Handle MMIO events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 52/75] x86/sev-es: Handle MMIO String Instructions Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 53/75] x86/sev-es: Handle MSR events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 54/75] x86/sev-es: Handle DR7 read/write events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 55/75] x86/sev-es: Handle WBINVD Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 56/75] x86/sev-es: Handle RDTSC(P) Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 57/75] x86/sev-es: Handle RDPMC Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 58/75] x86/sev-es: Handle INVD Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 59/75] x86/sev-es: Handle MONITOR/MONITORX Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 60/75] x86/sev-es: Handle MWAIT/MWAITX Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 61/75] x86/sev-es: Handle VMMCALL Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 62/75] x86/sev-es: Handle #AC Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 63/75] x86/sev-es: Handle #DB Events Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 64/75] x86/paravirt: Allow hypervisor specific VMMCALL handling under SEV-ES Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 65/75] x86/kvm: Add KVM " Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 66/75] x86/vmware: Add VMware specific handling for VMMCALL " Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 67/75] x86/realmode: Add SEV-ES specific trampoline entry point Joerg Roedel
2020-07-24 16:03 ` Joerg Roedel [this message]
2020-07-24 16:03 ` [PATCH v5 69/75] x86/smpboot: Setup TSS for starting AP Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 70/75] x86/head/64: Don't call verify_cpu() on starting APs Joerg Roedel
2020-07-24 17:57 ` Kees Cook
2020-07-24 16:03 ` [PATCH v5 71/75] x86/head/64: Rename start_cpu0 Joerg Roedel
2020-07-24 17:56 ` Kees Cook
2020-07-24 16:03 ` [PATCH v5 72/75] x86/sev-es: Support CPU offline/online Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 73/75] x86/sev-es: Handle NMI State Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 74/75] x86/efi: Add GHCB mappings when SEV-ES is active Joerg Roedel
2020-07-24 16:03 ` [PATCH v5 75/75] x86/sev-es: Check required CPU features for SEV-ES Joerg Roedel
2020-07-24 17:55 ` Kees Cook
2020-07-30 1:27 ` [PATCH v5 00/75] x86: SEV-ES Guest Support Mike Stunes
2020-07-30 12:26 ` Joerg Roedel
2020-07-30 23:23 ` Mike Stunes
2020-08-18 15:07 ` Joerg Roedel
2020-08-20 0:58 ` Mike Stunes
2020-08-20 12:10 ` Joerg Roedel
2020-08-21 8:05 ` Joerg Roedel
2020-08-21 17:42 ` Mike Stunes
2020-08-22 16:30 ` 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=20200724160336.5435-69-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