X-Git-Url: https://git.proxmox.com/?p=pve-kernel.git;a=blobdiff_plain;f=patches%2Fkernel%2F0013-KVM-x86-emulator-smm-add-structs-for-KVM-s-smram-lay.patch;fp=patches%2Fkernel%2F0013-KVM-x86-emulator-smm-add-structs-for-KVM-s-smram-lay.patch;h=0000000000000000000000000000000000000000;hp=b0aa90b7f3d21e36ecd4cdb7f4f523baa4d6bdf3;hb=12247ad0df0f583b7811a4afe2c90756be3d342b;hpb=00d66e9633d596709f13c3153534014cc2b02aa7 diff --git a/patches/kernel/0013-KVM-x86-emulator-smm-add-structs-for-KVM-s-smram-lay.patch b/patches/kernel/0013-KVM-x86-emulator-smm-add-structs-for-KVM-s-smram-lay.patch deleted file mode 100644 index b0aa90b..0000000 --- a/patches/kernel/0013-KVM-x86-emulator-smm-add-structs-for-KVM-s-smram-lay.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Maxim Levitsky -Date: Wed, 3 Aug 2022 18:50:05 +0300 -Subject: [PATCH] KVM: x86: emulator/smm: add structs for KVM's smram layout - -Those structs will be used to read/write the smram state image. - -Also document the differences between KVM's SMRAM layout and SMRAM -layout that is used by real Intel/AMD cpus. - -Signed-off-by: Maxim Levitsky -Signed-off-by: Thomas Lamprecht ---- - arch/x86/kvm/emulate.c | 6 + - arch/x86/kvm/kvm_emulate.h | 218 +++++++++++++++++++++++++++++++++++++ - arch/x86/kvm/x86.c | 1 + - 3 files changed, 225 insertions(+) - -diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c -index 9106a4d4b9f0..497cf9e08cc7 100644 ---- a/arch/x86/kvm/emulate.c -+++ b/arch/x86/kvm/emulate.c -@@ -5854,3 +5854,9 @@ bool emulator_can_use_gpa(struct x86_emulate_ctxt *ctxt) - - return true; - } -+ -+void __init kvm_emulator_init(void) -+{ -+ __check_smram32_offsets(); -+ __check_smram64_offsets(); -+} -diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h -index 8dff25d267b7..0eb13204bbc2 100644 ---- a/arch/x86/kvm/kvm_emulate.h -+++ b/arch/x86/kvm/kvm_emulate.h -@@ -13,6 +13,7 @@ - #define _ASM_X86_KVM_X86_EMULATE_H - - #include -+#include - #include "fpu.h" - - struct x86_emulate_ctxt; -@@ -481,6 +482,223 @@ enum x86_intercept { - nr_x86_intercepts - }; - -+ -+/* 32 bit KVM's emulated SMM layout. Loosely based on Intel's layout */ -+ -+struct kvm_smm_seg_state_32 { -+ u32 flags; -+ u32 limit; -+ u32 base; -+} __packed; -+ -+struct kvm_smram_state_32 { -+ u32 reserved1[62]; -+ u32 smbase; -+ u32 smm_revision; -+ u32 reserved2[5]; -+ u32 cr4; /* CR4 is not present in Intel/AMD SMRAM image */ -+ u32 reserved3[5]; -+ -+ /* -+ * Segment state is not present/documented in the Intel/AMD SMRAM image -+ * Instead this area on Intel/AMD contains IO/HLT restart flags. -+ */ -+ struct kvm_smm_seg_state_32 ds; -+ struct kvm_smm_seg_state_32 fs; -+ struct kvm_smm_seg_state_32 gs; -+ struct kvm_smm_seg_state_32 idtr; /* IDTR has only base and limit */ -+ struct kvm_smm_seg_state_32 tr; -+ u32 reserved; -+ struct kvm_smm_seg_state_32 gdtr; /* GDTR has only base and limit */ -+ struct kvm_smm_seg_state_32 ldtr; -+ struct kvm_smm_seg_state_32 es; -+ struct kvm_smm_seg_state_32 cs; -+ struct kvm_smm_seg_state_32 ss; -+ -+ u32 es_sel; -+ u32 cs_sel; -+ u32 ss_sel; -+ u32 ds_sel; -+ u32 fs_sel; -+ u32 gs_sel; -+ u32 ldtr_sel; -+ u32 tr_sel; -+ -+ u32 dr7; -+ u32 dr6; -+ u32 gprs[8]; /* GPRS in the "natural" X86 order (EAX/ECX/EDX.../EDI) */ -+ u32 eip; -+ u32 eflags; -+ u32 cr3; -+ u32 cr0; -+} __packed; -+ -+ -+static inline void __check_smram32_offsets(void) -+{ -+#define __CHECK_SMRAM32_OFFSET(field, offset) \ -+ ASSERT_STRUCT_OFFSET(struct kvm_smram_state_32, field, offset - 0xFE00) -+ -+ __CHECK_SMRAM32_OFFSET(reserved1, 0xFE00); -+ __CHECK_SMRAM32_OFFSET(smbase, 0xFEF8); -+ __CHECK_SMRAM32_OFFSET(smm_revision, 0xFEFC); -+ __CHECK_SMRAM32_OFFSET(reserved2, 0xFF00); -+ __CHECK_SMRAM32_OFFSET(cr4, 0xFF14); -+ __CHECK_SMRAM32_OFFSET(reserved3, 0xFF18); -+ __CHECK_SMRAM32_OFFSET(ds, 0xFF2C); -+ __CHECK_SMRAM32_OFFSET(fs, 0xFF38); -+ __CHECK_SMRAM32_OFFSET(gs, 0xFF44); -+ __CHECK_SMRAM32_OFFSET(idtr, 0xFF50); -+ __CHECK_SMRAM32_OFFSET(tr, 0xFF5C); -+ __CHECK_SMRAM32_OFFSET(gdtr, 0xFF6C); -+ __CHECK_SMRAM32_OFFSET(ldtr, 0xFF78); -+ __CHECK_SMRAM32_OFFSET(es, 0xFF84); -+ __CHECK_SMRAM32_OFFSET(cs, 0xFF90); -+ __CHECK_SMRAM32_OFFSET(ss, 0xFF9C); -+ __CHECK_SMRAM32_OFFSET(es_sel, 0xFFA8); -+ __CHECK_SMRAM32_OFFSET(cs_sel, 0xFFAC); -+ __CHECK_SMRAM32_OFFSET(ss_sel, 0xFFB0); -+ __CHECK_SMRAM32_OFFSET(ds_sel, 0xFFB4); -+ __CHECK_SMRAM32_OFFSET(fs_sel, 0xFFB8); -+ __CHECK_SMRAM32_OFFSET(gs_sel, 0xFFBC); -+ __CHECK_SMRAM32_OFFSET(ldtr_sel, 0xFFC0); -+ __CHECK_SMRAM32_OFFSET(tr_sel, 0xFFC4); -+ __CHECK_SMRAM32_OFFSET(dr7, 0xFFC8); -+ __CHECK_SMRAM32_OFFSET(dr6, 0xFFCC); -+ __CHECK_SMRAM32_OFFSET(gprs, 0xFFD0); -+ __CHECK_SMRAM32_OFFSET(eip, 0xFFF0); -+ __CHECK_SMRAM32_OFFSET(eflags, 0xFFF4); -+ __CHECK_SMRAM32_OFFSET(cr3, 0xFFF8); -+ __CHECK_SMRAM32_OFFSET(cr0, 0xFFFC); -+#undef __CHECK_SMRAM32_OFFSET -+} -+ -+ -+/* 64 bit KVM's emulated SMM layout. Based on AMD64 layout */ -+ -+struct kvm_smm_seg_state_64 { -+ u16 selector; -+ u16 attributes; -+ u32 limit; -+ u64 base; -+}; -+ -+struct kvm_smram_state_64 { -+ -+ struct kvm_smm_seg_state_64 es; -+ struct kvm_smm_seg_state_64 cs; -+ struct kvm_smm_seg_state_64 ss; -+ struct kvm_smm_seg_state_64 ds; -+ struct kvm_smm_seg_state_64 fs; -+ struct kvm_smm_seg_state_64 gs; -+ struct kvm_smm_seg_state_64 gdtr; /* GDTR has only base and limit*/ -+ struct kvm_smm_seg_state_64 ldtr; -+ struct kvm_smm_seg_state_64 idtr; /* IDTR has only base and limit*/ -+ struct kvm_smm_seg_state_64 tr; -+ -+ /* I/O restart and auto halt restart are not implemented by KVM */ -+ u64 io_restart_rip; -+ u64 io_restart_rcx; -+ u64 io_restart_rsi; -+ u64 io_restart_rdi; -+ u32 io_restart_dword; -+ u32 reserved1; -+ u8 io_inst_restart; -+ u8 auto_hlt_restart; -+ u8 reserved2[6]; -+ -+ u64 efer; -+ -+ /* -+ * Two fields below are implemented on AMD only, to store -+ * SVM guest vmcb address if the #SMI was received while in the guest mode. -+ */ -+ u64 svm_guest_flag; -+ u64 svm_guest_vmcb_gpa; -+ u64 svm_guest_virtual_int; /* unknown purpose, not implemented */ -+ -+ u32 reserved3[3]; -+ u32 smm_revison; -+ u32 smbase; -+ u32 reserved4[5]; -+ -+ /* ssp and svm_* fields below are not implemented by KVM */ -+ u64 ssp; -+ u64 svm_guest_pat; -+ u64 svm_host_efer; -+ u64 svm_host_cr4; -+ u64 svm_host_cr3; -+ u64 svm_host_cr0; -+ -+ u64 cr4; -+ u64 cr3; -+ u64 cr0; -+ u64 dr7; -+ u64 dr6; -+ u64 rflags; -+ u64 rip; -+ u64 gprs[16]; /* GPRS in a reversed "natural" X86 order (R15/R14/../RCX/RAX.) */ -+}; -+ -+ -+static inline void __check_smram64_offsets(void) -+{ -+#define __CHECK_SMRAM64_OFFSET(field, offset) \ -+ ASSERT_STRUCT_OFFSET(struct kvm_smram_state_64, field, offset - 0xFE00) -+ -+ __CHECK_SMRAM64_OFFSET(es, 0xFE00); -+ __CHECK_SMRAM64_OFFSET(cs, 0xFE10); -+ __CHECK_SMRAM64_OFFSET(ss, 0xFE20); -+ __CHECK_SMRAM64_OFFSET(ds, 0xFE30); -+ __CHECK_SMRAM64_OFFSET(fs, 0xFE40); -+ __CHECK_SMRAM64_OFFSET(gs, 0xFE50); -+ __CHECK_SMRAM64_OFFSET(gdtr, 0xFE60); -+ __CHECK_SMRAM64_OFFSET(ldtr, 0xFE70); -+ __CHECK_SMRAM64_OFFSET(idtr, 0xFE80); -+ __CHECK_SMRAM64_OFFSET(tr, 0xFE90); -+ __CHECK_SMRAM64_OFFSET(io_restart_rip, 0xFEA0); -+ __CHECK_SMRAM64_OFFSET(io_restart_rcx, 0xFEA8); -+ __CHECK_SMRAM64_OFFSET(io_restart_rsi, 0xFEB0); -+ __CHECK_SMRAM64_OFFSET(io_restart_rdi, 0xFEB8); -+ __CHECK_SMRAM64_OFFSET(io_restart_dword, 0xFEC0); -+ __CHECK_SMRAM64_OFFSET(reserved1, 0xFEC4); -+ __CHECK_SMRAM64_OFFSET(io_inst_restart, 0xFEC8); -+ __CHECK_SMRAM64_OFFSET(auto_hlt_restart, 0xFEC9); -+ __CHECK_SMRAM64_OFFSET(reserved2, 0xFECA); -+ __CHECK_SMRAM64_OFFSET(efer, 0xFED0); -+ __CHECK_SMRAM64_OFFSET(svm_guest_flag, 0xFED8); -+ __CHECK_SMRAM64_OFFSET(svm_guest_vmcb_gpa, 0xFEE0); -+ __CHECK_SMRAM64_OFFSET(svm_guest_virtual_int, 0xFEE8); -+ __CHECK_SMRAM64_OFFSET(reserved3, 0xFEF0); -+ __CHECK_SMRAM64_OFFSET(smm_revison, 0xFEFC); -+ __CHECK_SMRAM64_OFFSET(smbase, 0xFF00); -+ __CHECK_SMRAM64_OFFSET(reserved4, 0xFF04); -+ __CHECK_SMRAM64_OFFSET(ssp, 0xFF18); -+ __CHECK_SMRAM64_OFFSET(svm_guest_pat, 0xFF20); -+ __CHECK_SMRAM64_OFFSET(svm_host_efer, 0xFF28); -+ __CHECK_SMRAM64_OFFSET(svm_host_cr4, 0xFF30); -+ __CHECK_SMRAM64_OFFSET(svm_host_cr3, 0xFF38); -+ __CHECK_SMRAM64_OFFSET(svm_host_cr0, 0xFF40); -+ __CHECK_SMRAM64_OFFSET(cr4, 0xFF48); -+ __CHECK_SMRAM64_OFFSET(cr3, 0xFF50); -+ __CHECK_SMRAM64_OFFSET(cr0, 0xFF58); -+ __CHECK_SMRAM64_OFFSET(dr7, 0xFF60); -+ __CHECK_SMRAM64_OFFSET(dr6, 0xFF68); -+ __CHECK_SMRAM64_OFFSET(rflags, 0xFF70); -+ __CHECK_SMRAM64_OFFSET(rip, 0xFF78); -+ __CHECK_SMRAM64_OFFSET(gprs, 0xFF80); -+#undef __CHECK_SMRAM64_OFFSET -+} -+ -+union kvm_smram { -+ struct kvm_smram_state_64 smram64; -+ struct kvm_smram_state_32 smram32; -+ u8 bytes[512]; -+}; -+ -+void __init kvm_emulator_init(void); -+ -+ - /* Host execution mode. */ - #if defined(CONFIG_X86_32) - #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32 -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index a8575f37ced4..6a22f8933b23 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -13187,6 +13187,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_vmgexit_msr_protocol_exit); - static int __init kvm_x86_init(void) - { - kvm_mmu_x86_module_init(); -+ kvm_emulator_init(); - return 0; - } - module_init(kvm_x86_init);