From patchwork Mon Aug 21 14:47:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vasant Karasulli X-Patchwork-Id: 13359554 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D779EE49A6 for ; Mon, 21 Aug 2023 14:48:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236137AbjHUOsH (ORCPT ); Mon, 21 Aug 2023 10:48:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236131AbjHUOsG (ORCPT ); Mon, 21 Aug 2023 10:48:06 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F933EC for ; Mon, 21 Aug 2023 07:48:04 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id E944722C47; Mon, 21 Aug 2023 14:48:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1692629282; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XZnOncQ4WM9/5/WaDKFUDKSdLjxXMsIud60z4ahraBg=; b=t+huDzNorj5l30diLIAnyVuDxhfMrufiETUDqc1D+94OdYkFNQAe9iy/XGJiTxq1dFXZq5 GH0yFGhHasZ0tWe6f1MpHfaJSJWWktTfBzbmHfnxPJc1TKVg3mvdvHdHXaWC08BZoa1rG8 yo7esIWzC7FzwlAB7H4ltvz1ao8o2Xs= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1692629282; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XZnOncQ4WM9/5/WaDKFUDKSdLjxXMsIud60z4ahraBg=; b=9J7FrpG/DhWiEgutiL0U2gJcFcHJNP3FJHPYw/Hvbz7YW/GRNr+y5b8tqKo09xO6L2ZrKg 76DU4RcwGq71B0Cg== Received: from vasant-suse.fritz.box (vkarasulli.udp.ovpn1.nue.suse.de [10.163.24.134]) by relay2.suse.de (Postfix) with ESMTP id 861D12C143; Mon, 21 Aug 2023 14:48:02 +0000 (UTC) From: Vasant Karasulli To: kvm@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, jroedel@suse.de, drjones@redhat.com, erdemaktas@google.com, marcorr@google.com, papaluri@amd.com, rientjes@google.com, zxwang42@gmail.com, Vasant Karasulli , Varad Gautam Subject: [kvm-unit-tests PATCH v5 05/11] x86: AMD SEV-ES: Pull related GHCB definitions and helpers from Linux Date: Mon, 21 Aug 2023 16:47:45 +0200 Message-Id: <20230821144751.22557-6-vkarasulli@suse.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230821144751.22557-1-vkarasulli@suse.de> References: <20230821144751.22557-1-vkarasulli@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Origin: Linux b320441c04c9bea76cbee1196ae55c20288fd7a6. Suppress -Waddress-of-packed-member to allow taking addresses on struct ghcb / struct vmcb_save_area fields. Signed-off-by: Varad Gautam Signed-off-by: Vasant Karasulli --- lib/x86/amd_sev.h | 136 ++++++++++++++++++++++++++++++++++++++++++++ lib/x86/msr.h | 1 + lib/x86/processor.h | 8 +++ lib/x86/svm.h | 19 +++++-- x86/Makefile.x86_64 | 1 + 5 files changed, 159 insertions(+), 6 deletions(-) -- 2.34.1 diff --git a/lib/x86/amd_sev.h b/lib/x86/amd_sev.h index 713019c..b6b7a13 100644 --- a/lib/x86/amd_sev.h +++ b/lib/x86/amd_sev.h @@ -18,6 +18,90 @@ #include "desc.h" #include "asm/page.h" #include "efi.h" +#include "processor.h" +#include "insn/insn.h" +#include "svm.h" + +#define GHCB_SHARED_BUF_SIZE 2032 + +struct ghcb_save_area { + u8 reserved_0x0[203]; + u8 cpl; + u8 reserved_0xcc[116]; + u64 xss; + u8 reserved_0x148[24]; + u64 dr7; + u8 reserved_0x168[16]; + u64 rip; + u8 reserved_0x180[88]; + u64 rsp; + u8 reserved_0x1e0[24]; + u64 rax; + u8 reserved_0x200[264]; + u64 rcx; + u64 rdx; + u64 rbx; + u8 reserved_0x320[8]; + u64 rbp; + u64 rsi; + u64 rdi; + u64 r8; + u64 r9; + u64 r10; + u64 r11; + u64 r12; + u64 r13; + u64 r14; + u64 r15; + u8 reserved_0x380[16]; + u64 sw_exit_code; + u64 sw_exit_info_1; + u64 sw_exit_info_2; + u64 sw_scratch; + u8 reserved_0x3b0[56]; + u64 xcr0; + u8 valid_bitmap[16]; + u64 x87_state_gpa; +} __packed; + +struct ghcb { + struct ghcb_save_area save; + u8 reserved_save[2048 - sizeof(struct ghcb_save_area)]; + + u8 shared_buffer[GHCB_SHARED_BUF_SIZE]; + + u8 reserved_0xff0[10]; + u16 protocol_version; /* negotiated SEV-ES/GHCB protocol version */ + u32 ghcb_usage; +} __packed; + +#define GHCB_PROTO_OUR 0x0001UL +#define GHCB_PROTOCOL_MAX 1ULL +#define GHCB_DEFAULT_USAGE 0ULL + +#define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); } + +enum es_result { + ES_OK, /* All good */ + ES_UNSUPPORTED, /* Requested operation not supported */ + ES_VMM_ERROR, /* Unexpected state from the VMM */ + ES_DECODE_FAILED, /* Instruction decoding failed */ + ES_EXCEPTION, /* Instruction caused exception */ + ES_RETRY, /* Retry instruction emulation */ +}; + +struct es_fault_info { + unsigned long vector; + unsigned long error_code; + unsigned long cr2; +}; + +/* ES instruction emulation context */ +struct es_em_ctxt { + struct ex_regs *regs; + struct insn insn; + struct es_fault_info fi; +}; /* * AMD Programmer's Manual Volume 3 @@ -59,6 +143,58 @@ 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); +/* GHCB Accessor functions from Linux's include/asm/svm.h */ +#define GHCB_BITMAP_IDX(field) \ + (offsetof(struct ghcb_save_area, field) / sizeof(u64)) + +#define DEFINE_GHCB_ACCESSORS(field) \ + static __always_inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb) \ + { \ + return test_bit(GHCB_BITMAP_IDX(field), \ + (unsigned long *)&ghcb->save.valid_bitmap); \ + } \ + \ + static __always_inline u64 ghcb_get_##field(struct ghcb *ghcb) \ + { \ + return ghcb->save.field; \ + } \ + \ + static __always_inline u64 ghcb_get_##field##_if_valid(struct ghcb *ghcb) \ + { \ + return ghcb_##field##_is_valid(ghcb) ? ghcb->save.field : 0; \ + } \ + \ + static __always_inline void ghcb_set_##field(struct ghcb *ghcb, u64 value) \ + { \ + set_bit(GHCB_BITMAP_IDX(field), \ + (u8 *)&ghcb->save.valid_bitmap); \ + ghcb->save.field = value; \ + } + +DEFINE_GHCB_ACCESSORS(cpl) +DEFINE_GHCB_ACCESSORS(rip) +DEFINE_GHCB_ACCESSORS(rsp) +DEFINE_GHCB_ACCESSORS(rax) +DEFINE_GHCB_ACCESSORS(rcx) +DEFINE_GHCB_ACCESSORS(rdx) +DEFINE_GHCB_ACCESSORS(rbx) +DEFINE_GHCB_ACCESSORS(rbp) +DEFINE_GHCB_ACCESSORS(rsi) +DEFINE_GHCB_ACCESSORS(rdi) +DEFINE_GHCB_ACCESSORS(r8) +DEFINE_GHCB_ACCESSORS(r9) +DEFINE_GHCB_ACCESSORS(r10) +DEFINE_GHCB_ACCESSORS(r11) +DEFINE_GHCB_ACCESSORS(r12) +DEFINE_GHCB_ACCESSORS(r13) +DEFINE_GHCB_ACCESSORS(r14) +DEFINE_GHCB_ACCESSORS(r15) +DEFINE_GHCB_ACCESSORS(sw_exit_code) +DEFINE_GHCB_ACCESSORS(sw_exit_info_1) +DEFINE_GHCB_ACCESSORS(sw_exit_info_2) +DEFINE_GHCB_ACCESSORS(sw_scratch) +DEFINE_GHCB_ACCESSORS(xcr0) + #endif /* CONFIG_EFI */ #endif /* _X86_AMD_SEV_H_ */ diff --git a/lib/x86/msr.h b/lib/x86/msr.h index 0e3fd03..a600d00 100644 --- a/lib/x86/msr.h +++ b/lib/x86/msr.h @@ -140,6 +140,7 @@ #define MSR_AMD64_IBSDCLINAD 0xc0011038 #define MSR_AMD64_IBSDCPHYSAD 0xc0011039 #define MSR_AMD64_IBSCTL 0xc001103a +#define MSR_AMD64_SEV_ES_GHCB 0xc0010130 /* Fam 10h MSRs */ #define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 6555056..dc66ba2 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -800,6 +800,14 @@ static inline void set_bit(int bit, u8 *addr) : "+m" (*addr) : "Ir" (bit) : "cc", "memory"); } +static inline int test_bit(int nr, const volatile unsigned long *addr) +{ + const volatile unsigned long *word = addr + BIT_WORD(nr); + unsigned long mask = BIT_MASK(nr); + + return (*word & mask) != 0; +} + static inline void flush_tlb(void) { ulong cr4; diff --git a/lib/x86/svm.h b/lib/x86/svm.h index 766ff7e..c3e6a30 100644 --- a/lib/x86/svm.h +++ b/lib/x86/svm.h @@ -168,11 +168,13 @@ struct __attribute__ ((__packed__)) vmcb_save_area { struct vmcb_seg ldtr; struct vmcb_seg idtr; struct vmcb_seg tr; - u8 reserved_1[43]; + /* Reserved fields are named following their struct offset */ + u8 reserved_0xa0[42]; + u8 vmpl; u8 cpl; - u8 reserved_2[4]; + u8 reserved_0xcc[4]; u64 efer; - u8 reserved_3[112]; + u8 reserved_0xd8[112]; u64 cr4; u64 cr3; u64 cr0; @@ -180,9 +182,11 @@ struct __attribute__ ((__packed__)) vmcb_save_area { u64 dr6; u64 rflags; u64 rip; - u8 reserved_4[88]; + u8 reserved_0x180[88]; u64 rsp; - u8 reserved_5[24]; + u64 s_cet; + u64 ssp; + u64 isst_addr; u64 rax; u64 star; u64 lstar; @@ -193,13 +197,15 @@ struct __attribute__ ((__packed__)) vmcb_save_area { u64 sysenter_esp; u64 sysenter_eip; u64 cr2; - u8 reserved_6[32]; + u8 reserved_0x248[32]; u64 g_pat; u64 dbgctl; u64 br_from; u64 br_to; u64 last_excp_from; u64 last_excp_to; + u8 reserved_0x298[72]; + u32 spec_ctrl; /* Guest version of SPEC_CTRL at 0x2E0 */ }; struct __attribute__ ((__packed__)) vmcb { @@ -300,6 +306,7 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_EXIT_WRITE_DR6 0x036 #define SVM_EXIT_WRITE_DR7 0x037 #define SVM_EXIT_EXCP_BASE 0x040 +#define SVM_EXIT_LAST_EXCP 0x05f #define SVM_EXIT_INTR 0x060 #define SVM_EXIT_NMI 0x061 #define SVM_EXIT_SMI 0x062 diff --git a/x86/Makefile.x86_64 b/x86/Makefile.x86_64 index 2771a6f..c59b3b6 100644 --- a/x86/Makefile.x86_64 +++ b/x86/Makefile.x86_64 @@ -19,6 +19,7 @@ endif fcf_protection_full := $(call cc-option, -fcf-protection=full,) COMMON_CFLAGS += -mno-red-zone -mno-sse -mno-sse2 $(fcf_protection_full) +COMMON_CFLAGS += -Wno-address-of-packed-member cflatobjs += lib/x86/setjmp64.o cflatobjs += lib/x86/intel-iommu.o