|
95 | 95 | "int3\n\t"
|
96 | 96 | "vmcode_int80:\n\t"
|
97 | 97 | "int $0x80\n\t"
|
| 98 | + "vmcode_popf_hlt:\n\t" |
| 99 | + "push %ax\n\t" |
| 100 | + "popf\n\t" |
| 101 | + "hlt\n\t" |
98 | 102 | "vmcode_umip:\n\t"
|
99 | 103 | /* addressing via displacements */
|
100 | 104 | "smsw (2052)\n\t"
|
@@ -124,8 +128,8 @@ asm (
|
124 | 128 |
|
125 | 129 | extern unsigned char vmcode[], end_vmcode[];
|
126 | 130 | extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[],
|
127 |
| - vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[], |
128 |
| - vmcode_umip_str[], vmcode_umip_sldt[]; |
| 131 | + vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_popf_hlt[], |
| 132 | + vmcode_umip[], vmcode_umip_str[], vmcode_umip_sldt[]; |
129 | 133 |
|
130 | 134 | /* Returns false if the test was skipped. */
|
131 | 135 | static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
|
@@ -175,7 +179,7 @@ static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
|
175 | 179 | (VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) {
|
176 | 180 | printf("[OK]\tReturned correctly\n");
|
177 | 181 | } else {
|
178 |
| - printf("[FAIL]\tIncorrect return reason\n"); |
| 182 | + printf("[FAIL]\tIncorrect return reason (started at eip = 0x%lx, ended at eip = 0x%lx)\n", eip, v86->regs.eip); |
179 | 183 | nerrs++;
|
180 | 184 | }
|
181 | 185 |
|
@@ -264,6 +268,9 @@ int main(void)
|
264 | 268 | v86.regs.ds = load_addr / 16;
|
265 | 269 | v86.regs.es = load_addr / 16;
|
266 | 270 |
|
| 271 | + /* Use the end of the page as our stack. */ |
| 272 | + v86.regs.esp = 4096; |
| 273 | + |
267 | 274 | assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
|
268 | 275 |
|
269 | 276 | /* #BR -- should deliver SIG??? */
|
@@ -295,6 +302,23 @@ int main(void)
|
295 | 302 | v86.regs.eflags &= ~X86_EFLAGS_IF;
|
296 | 303 | do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set");
|
297 | 304 |
|
| 305 | + /* POPF with VIP set but IF clear: should not trap */ |
| 306 | + v86.regs.eflags = X86_EFLAGS_VIP; |
| 307 | + v86.regs.eax = 0; |
| 308 | + do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP set and IF clear"); |
| 309 | + |
| 310 | + /* POPF with VIP set and IF set: should trap */ |
| 311 | + v86.regs.eflags = X86_EFLAGS_VIP; |
| 312 | + v86.regs.eax = X86_EFLAGS_IF; |
| 313 | + do_test(&v86, vmcode_popf_hlt - vmcode, VM86_STI, 0, "POPF with VIP and IF set"); |
| 314 | + |
| 315 | + /* POPF with VIP clear and IF set: should not trap */ |
| 316 | + v86.regs.eflags = 0; |
| 317 | + v86.regs.eax = X86_EFLAGS_IF; |
| 318 | + do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP clear and IF set"); |
| 319 | + |
| 320 | + v86.regs.eflags = 0; |
| 321 | + |
298 | 322 | /* INT3 -- should cause #BP */
|
299 | 323 | do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3");
|
300 | 324 |
|
|
0 commit comments