]>
Commit | Line | Data |
---|---|---|
54ebe3cb TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Maxim Levitsky <mlevitsk@redhat.com> | |
3 | Date: Tue, 21 Jun 2022 18:08:58 +0300 | |
4 | Subject: [PATCH] KVM: x86: emulator/smm: add structs for KVM's smram layout | |
5 | ||
6 | Those structs will be used to read/write the smram state image. | |
7 | ||
8 | Also document the differences between KVM's SMRAM layout and SMRAM | |
9 | layout that is used by real Intel/AMD cpus. | |
10 | ||
11 | Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> | |
12 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
13 | --- | |
14 | arch/x86/kvm/kvm_emulate.h | 139 +++++++++++++++++++++++++++++++++++++ | |
15 | 1 file changed, 139 insertions(+) | |
16 | ||
17 | diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h | |
18 | index 8dff25d267b7..3bbf7c1c5b18 100644 | |
19 | --- a/arch/x86/kvm/kvm_emulate.h | |
20 | +++ b/arch/x86/kvm/kvm_emulate.h | |
21 | @@ -481,6 +481,145 @@ enum x86_intercept { | |
22 | nr_x86_intercepts | |
23 | }; | |
24 | ||
25 | + | |
26 | +/* | |
27 | + * 32 bit KVM's emulated SMM layout | |
28 | + * Loosely based on Intel's layout | |
29 | + */ | |
30 | + | |
31 | +struct kvm_smm_seg_state_32 { | |
32 | + u32 flags; | |
33 | + u32 limit; | |
34 | + u32 base; | |
35 | +} __packed; | |
36 | + | |
37 | +struct kvm_smram_state_32 { | |
38 | + | |
39 | + u32 reserved1[62]; /* FE00 - FEF7 */ | |
40 | + u32 smbase; /* FEF8 */ | |
41 | + u32 smm_revision; /* FEFC */ | |
42 | + u32 reserved2[5]; /* FF00-FF13 */ | |
43 | + /* CR4 is not present in Intel/AMD SMRAM image*/ | |
44 | + u32 cr4; /* FF14 */ | |
45 | + u32 reserved3[5]; /* FF18 */ | |
46 | + | |
47 | + /* | |
48 | + * Segment state is not present/documented in the | |
49 | + * Intel/AMD SMRAM image | |
50 | + */ | |
51 | + struct kvm_smm_seg_state_32 ds; /* FF2C */ | |
52 | + struct kvm_smm_seg_state_32 fs; /* FF38 */ | |
53 | + struct kvm_smm_seg_state_32 gs; /* FF44 */ | |
54 | + /* idtr has only base and limit*/ | |
55 | + struct kvm_smm_seg_state_32 idtr; /* FF50 */ | |
56 | + struct kvm_smm_seg_state_32 tr; /* FF5C */ | |
57 | + u32 reserved; /* FF68 */ | |
58 | + /* gdtr has only base and limit*/ | |
59 | + struct kvm_smm_seg_state_32 gdtr; /* FF6C */ | |
60 | + struct kvm_smm_seg_state_32 ldtr; /* FF78 */ | |
61 | + struct kvm_smm_seg_state_32 es; /* FF84 */ | |
62 | + struct kvm_smm_seg_state_32 cs; /* FF90 */ | |
63 | + struct kvm_smm_seg_state_32 ss; /* FF9C */ | |
64 | + | |
65 | + u32 es_sel; /* FFA8 */ | |
66 | + u32 cs_sel; /* FFAC */ | |
67 | + u32 ss_sel; /* FFB0 */ | |
68 | + u32 ds_sel; /* FFB4 */ | |
69 | + u32 fs_sel; /* FFB8 */ | |
70 | + u32 gs_sel; /* FFBC */ | |
71 | + u32 ldtr_sel; /* FFC0 */ | |
72 | + u32 tr_sel; /* FFC4 */ | |
73 | + | |
74 | + u32 dr7; /* FFC8 */ | |
75 | + u32 dr6; /* FFCC */ | |
76 | + | |
77 | + /* GPRS in the "natural" X86 order (RAX/RCX/RDX.../RDI)*/ | |
78 | + u32 gprs[8]; /* FFD0-FFEC */ | |
79 | + | |
80 | + u32 eip; /* FFF0 */ | |
81 | + u32 eflags; /* FFF4 */ | |
82 | + u32 cr3; /* FFF8 */ | |
83 | + u32 cr0; /* FFFC */ | |
84 | +} __packed; | |
85 | + | |
86 | +/* | |
87 | + * 64 bit KVM's emulated SMM layout | |
88 | + * Based on AMD64 layout | |
89 | + */ | |
90 | + | |
91 | +struct kvm_smm_seg_state_64 { | |
92 | + u16 selector; | |
93 | + u16 attributes; | |
94 | + u32 limit; | |
95 | + u64 base; | |
96 | +}; | |
97 | + | |
98 | +struct kvm_smram_state_64 { | |
99 | + struct kvm_smm_seg_state_64 es; /* FE00 (R/O) */ | |
100 | + struct kvm_smm_seg_state_64 cs; /* FE10 (R/O) */ | |
101 | + struct kvm_smm_seg_state_64 ss; /* FE20 (R/O) */ | |
102 | + struct kvm_smm_seg_state_64 ds; /* FE30 (R/O) */ | |
103 | + struct kvm_smm_seg_state_64 fs; /* FE40 (R/O) */ | |
104 | + struct kvm_smm_seg_state_64 gs; /* FE50 (R/O) */ | |
105 | + | |
106 | + /* gdtr has only base and limit*/ | |
107 | + struct kvm_smm_seg_state_64 gdtr; /* FE60 (R/O) */ | |
108 | + struct kvm_smm_seg_state_64 ldtr; /* FE70 (R/O) */ | |
109 | + | |
110 | + /* idtr has only base and limit*/ | |
111 | + struct kvm_smm_seg_state_64 idtr; /* FE80 (R/O) */ | |
112 | + struct kvm_smm_seg_state_64 tr; /* FE90 (R/O) */ | |
113 | + | |
114 | + /* I/O restart and auto halt restart are not implemented by KVM */ | |
115 | + u64 io_restart_rip; /* FEA0 (R/O) */ | |
116 | + u64 io_restart_rcx; /* FEA8 (R/O) */ | |
117 | + u64 io_restart_rsi; /* FEB0 (R/O) */ | |
118 | + u64 io_restart_rdi; /* FEB8 (R/O) */ | |
119 | + u32 io_restart_dword; /* FEC0 (R/O) */ | |
120 | + u32 reserved1; /* FEC4 */ | |
121 | + u8 io_instruction_restart; /* FEC8 (R/W) */ | |
122 | + u8 auto_halt_restart; /* FEC9 (R/W) */ | |
123 | + u8 reserved2[6]; /* FECA-FECF */ | |
124 | + | |
125 | + u64 efer; /* FED0 (R/O) */ | |
126 | + | |
127 | + /* | |
128 | + * Implemented on AMD only, to store current SVM guest address. | |
129 | + * svm_guest_virtual_int has unknown purpose, not implemented. | |
130 | + */ | |
131 | + | |
132 | + u64 svm_guest_flag; /* FED8 (R/O) */ | |
133 | + u64 svm_guest_vmcb_gpa; /* FEE0 (R/O) */ | |
134 | + u64 svm_guest_virtual_int; /* FEE8 (R/O) */ | |
135 | + | |
136 | + u32 reserved3[3]; /* FEF0-FEFB */ | |
137 | + u32 smm_revison; /* FEFC (R/O) */ | |
138 | + u32 smbase; /* FFF0 (R/W) */ | |
139 | + u32 reserved4[5]; /* FF04-FF17 */ | |
140 | + | |
141 | + /* SSP and SVM fields below are not implemented by KVM */ | |
142 | + u64 ssp; /* FF18 (R/W) */ | |
143 | + u64 svm_guest_pat; /* FF20 (R/O) */ | |
144 | + u64 svm_host_efer; /* FF28 (R/O) */ | |
145 | + u64 svm_host_cr4; /* FF30 (R/O) */ | |
146 | + u64 svm_host_cr3; /* FF38 (R/O) */ | |
147 | + u64 svm_host_cr0; /* FF40 (R/O) */ | |
148 | + | |
149 | + u64 cr4; /* FF48 (R/O) */ | |
150 | + u64 cr3; /* FF50 (R/O) */ | |
151 | + u64 cr0; /* FF58 (R/O) */ | |
152 | + | |
153 | + u64 dr7; /* FF60 (R/O) */ | |
154 | + u64 dr6; /* FF68 (R/O) */ | |
155 | + | |
156 | + u64 rflags; /* FF70 (R/W) */ | |
157 | + u64 rip; /* FF78 (R/W) */ | |
158 | + | |
159 | + /* GPRS in a reversed "natural" X86 order (R15/R14/../RCX/RAX.) */ | |
160 | + u64 gprs[16]; /* FF80-FFFF (R/W) */ | |
161 | +}; | |
162 | + | |
163 | + | |
164 | /* Host execution mode. */ | |
165 | #if defined(CONFIG_X86_32) | |
166 | #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32 |