|
10 | 10 | */
|
11 | 11 |
|
12 | 12 | #ifndef __BOOT_COMPRESSED
|
13 |
| -#define error(v) pr_err(v) |
14 |
| -#define has_cpuflag(f) boot_cpu_has(f) |
| 13 | +#define error(v) pr_err(v) |
| 14 | +#define has_cpuflag(f) boot_cpu_has(f) |
| 15 | +#define sev_printk(fmt, ...) printk(fmt, ##__VA_ARGS__) |
| 16 | +#define sev_printk_rtl(fmt, ...) printk_ratelimited(fmt, ##__VA_ARGS__) |
15 | 17 | #else
|
16 | 18 | #undef WARN
|
17 | 19 | #define WARN(condition, format...) (!!(condition))
|
| 20 | +#define sev_printk(fmt, ...) |
| 21 | +#define sev_printk_rtl(fmt, ...) |
18 | 22 | #endif
|
19 | 23 |
|
20 | 24 | /* I/O parameters for CPUID-related helpers */
|
@@ -574,13 +578,18 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
|
574 | 578 | {
|
575 | 579 | unsigned int subfn = lower_bits(regs->cx, 32);
|
576 | 580 | unsigned int fn = lower_bits(regs->ax, 32);
|
| 581 | + u16 opcode = *(unsigned short *)regs->ip; |
577 | 582 | struct cpuid_leaf leaf;
|
578 | 583 | int ret;
|
579 | 584 |
|
580 | 585 | /* Only CPUID is supported via MSR protocol */
|
581 | 586 | if (exit_code != SVM_EXIT_CPUID)
|
582 | 587 | goto fail;
|
583 | 588 |
|
| 589 | + /* Is it really a CPUID insn? */ |
| 590 | + if (opcode != 0xa20f) |
| 591 | + goto fail; |
| 592 | + |
584 | 593 | leaf.fn = fn;
|
585 | 594 | leaf.subfn = subfn;
|
586 | 595 |
|
@@ -1170,3 +1179,92 @@ static int vmgexit_psc(struct ghcb *ghcb, struct snp_psc_desc *desc)
|
1170 | 1179 | out:
|
1171 | 1180 | return ret;
|
1172 | 1181 | }
|
| 1182 | + |
| 1183 | +static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt, |
| 1184 | + unsigned long exit_code) |
| 1185 | +{ |
| 1186 | + unsigned int opcode = (unsigned int)ctxt->insn.opcode.value; |
| 1187 | + u8 modrm = ctxt->insn.modrm.value; |
| 1188 | + |
| 1189 | + switch (exit_code) { |
| 1190 | + |
| 1191 | + case SVM_EXIT_IOIO: |
| 1192 | + case SVM_EXIT_NPF: |
| 1193 | + /* handled separately */ |
| 1194 | + return ES_OK; |
| 1195 | + |
| 1196 | + case SVM_EXIT_CPUID: |
| 1197 | + if (opcode == 0xa20f) |
| 1198 | + return ES_OK; |
| 1199 | + break; |
| 1200 | + |
| 1201 | + case SVM_EXIT_INVD: |
| 1202 | + if (opcode == 0x080f) |
| 1203 | + return ES_OK; |
| 1204 | + break; |
| 1205 | + |
| 1206 | + case SVM_EXIT_MONITOR: |
| 1207 | + if (opcode == 0x010f && modrm == 0xc8) |
| 1208 | + return ES_OK; |
| 1209 | + break; |
| 1210 | + |
| 1211 | + case SVM_EXIT_MWAIT: |
| 1212 | + if (opcode == 0x010f && modrm == 0xc9) |
| 1213 | + return ES_OK; |
| 1214 | + break; |
| 1215 | + |
| 1216 | + case SVM_EXIT_MSR: |
| 1217 | + /* RDMSR */ |
| 1218 | + if (opcode == 0x320f || |
| 1219 | + /* WRMSR */ |
| 1220 | + opcode == 0x300f) |
| 1221 | + return ES_OK; |
| 1222 | + break; |
| 1223 | + |
| 1224 | + case SVM_EXIT_RDPMC: |
| 1225 | + if (opcode == 0x330f) |
| 1226 | + return ES_OK; |
| 1227 | + break; |
| 1228 | + |
| 1229 | + case SVM_EXIT_RDTSC: |
| 1230 | + if (opcode == 0x310f) |
| 1231 | + return ES_OK; |
| 1232 | + break; |
| 1233 | + |
| 1234 | + case SVM_EXIT_RDTSCP: |
| 1235 | + if (opcode == 0x010f && modrm == 0xf9) |
| 1236 | + return ES_OK; |
| 1237 | + break; |
| 1238 | + |
| 1239 | + case SVM_EXIT_READ_DR7: |
| 1240 | + if (opcode == 0x210f && |
| 1241 | + X86_MODRM_REG(ctxt->insn.modrm.value) == 7) |
| 1242 | + return ES_OK; |
| 1243 | + break; |
| 1244 | + |
| 1245 | + case SVM_EXIT_VMMCALL: |
| 1246 | + if (opcode == 0x010f && modrm == 0xd9) |
| 1247 | + return ES_OK; |
| 1248 | + |
| 1249 | + break; |
| 1250 | + |
| 1251 | + case SVM_EXIT_WRITE_DR7: |
| 1252 | + if (opcode == 0x230f && |
| 1253 | + X86_MODRM_REG(ctxt->insn.modrm.value) == 7) |
| 1254 | + return ES_OK; |
| 1255 | + break; |
| 1256 | + |
| 1257 | + case SVM_EXIT_WBINVD: |
| 1258 | + if (opcode == 0x90f) |
| 1259 | + return ES_OK; |
| 1260 | + break; |
| 1261 | + |
| 1262 | + default: |
| 1263 | + break; |
| 1264 | + } |
| 1265 | + |
| 1266 | + sev_printk(KERN_ERR "Wrong/unhandled opcode bytes: 0x%x, exit_code: 0x%lx, rIP: 0x%lx\n", |
| 1267 | + opcode, exit_code, ctxt->regs->ip); |
| 1268 | + |
| 1269 | + return ES_UNSUPPORTED; |
| 1270 | +} |
0 commit comments