Skip to content

Commit 5d53f20

Browse files
committed
cpu/simx86: introduce _CPU_VM_CURRENT(), use for FPE handling
We weren't always getting the correct FPU state with KVM as sometimes the 0xf0 port handler was called via instremu. Introducing _CPU_VM_CURRENT() deals with that correctly. Also there is no need to call cpuemu_update_fpu() as FPU state is already synchronized when entering and leaving cpu-emu. Observed when debugging dosemu2#2708
1 parent 2d00f71 commit 5d53f20

File tree

5 files changed

+14
-15
lines changed

5 files changed

+14
-15
lines changed

src/base/emu-i386/cpu.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ static void fpu_reset(void)
275275
vm86_fpu_state.cwd = 0x0040;
276276
vm86_fpu_state.swd = 0;
277277
// vm86_fpu_state.ftw = 0x5555; //bochs
278-
if (config.cpu_vm == CPUVM_KVM || config.cpu_vm_dpmi == CPUVM_KVM)
278+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
279279
kvm_update_fpu();
280280
}
281281

@@ -291,6 +291,8 @@ static void fpu_io_write(ioport_t port, Bit8u val, void *arg)
291291
switch (port) {
292292
case 0xf0:
293293
pic_untrigger(13);
294+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
295+
kvm_get_fpu();
294296
fpu_ignne = !!(vm86_fpu_state.swd & 0x80);
295297
/* Note: we emuate the "unrecommended" (by Intel) design where the
296298
* untriggering of IGNNE requires an extra write to 0xf0 after fnclex */
@@ -304,10 +306,8 @@ static void fpu_io_write(ioport_t port, Bit8u val, void *arg)
304306
fpu_ignne = 0;
305307
/* fnclex */
306308
vm86_fpu_state.swd &= 0x7f00;
307-
if (config.cpu_vm == CPUVM_KVM || config.cpu_vm_dpmi == CPUVM_KVM)
309+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
308310
kvm_update_fpu();
309-
if (config.cpu_vm == CPUVM_EMU || config.cpu_vm_dpmi == CPUVM_EMU)
310-
cpuemu_update_fpu();
311311
}
312312
break;
313313
}
@@ -368,10 +368,8 @@ int fpu_fpe_handler (unsigned char *csp)
368368
case 0x29: //fldcw
369369
dbug_printf("coprocessor exception, disabling CW load exception because of IGNNE#\n");
370370
vm86_fpu_state.cwd = 0x37f;
371-
if (config.cpu_vm == CPUVM_KVM || config.cpu_vm_dpmi == CPUVM_KVM)
371+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
372372
kvm_update_fpu();
373-
if (config.cpu_vm == CPUVM_EMU || config.cpu_vm_dpmi == CPUVM_EMU)
374-
cpuemu_update_fpu();
375373
return 0;
376374
}
377375
}

src/base/emu-i386/kvm.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,9 +1581,6 @@ int true_kvm_dpmi(cpuctx_t *scp)
15811581
_eip -= 2;
15821582
}
15831583

1584-
if (_trapno == 0x10) {
1585-
kvm_get_fpu(); // needed for the swd check in the port f0 handler
1586-
}
15871584
#if 0
15881585
struct kvm_fpu fpu;
15891586
ioctl(vcpufd, KVM_GET_FPU, &fpu);

src/base/emu-i386/simx86/cpu-emu.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,11 @@ int _CPU_VM_DPMI(void)
15851585
return config.cpu_vm_dpmi;
15861586
}
15871587

1588+
int _CPU_VM_CURRENT(void)
1589+
{
1590+
return in_dpmi_pm() ? _CPU_VM_DPMI() : _CPU_VM();
1591+
}
1592+
15881593
static int lockcnt;
15891594

15901595
void prejit_lock(void)

src/dosext/dpmi/dpmi.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,10 +1486,8 @@ static void finish_clnt_switch(void)
14861486
assert(in_dpmi);
14871487
if (config.cpu_vm_dpmi == CPUVM_KVM)
14881488
update_kvm_idt();
1489-
if (config.cpu_vm == CPUVM_KVM || config.cpu_vm_dpmi == CPUVM_KVM)
1489+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
14901490
kvm_update_fpu();
1491-
if (_CPU_VM() == CPUVM_EMU || _CPU_VM_DPMI() == CPUVM_EMU)
1492-
cpuemu_update_fpu();
14931491
}
14941492

14951493
static int do_ldt_write(unsigned short ldt_entry, unsigned int *lp)
@@ -1540,7 +1538,7 @@ static int ldt_write_low(unsigned short ldt_entry, unsigned int *lp)
15401538

15411539
static void save_prev_clnt_state(void)
15421540
{
1543-
if (_CPU_VM() == CPUVM_KVM || _CPU_VM_DPMI() == CPUVM_KVM)
1541+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
15441542
kvm_get_fpu();
15451543
memcpy(&DPMI_CLIENT.saved_fpu_state, &vm86_fpu_state,
15461544
sizeof(vm86_fpu_state));
@@ -4380,7 +4378,7 @@ void dpmi_init(void)
43804378

43814379
in_dpmi++;
43824380
memset(&DPMIclient[in_dpmi - 1], 0, sizeof(DPMI_CLIENT));
4383-
if (config.cpu_vm == CPUVM_KVM || config.cpu_vm_dpmi == CPUVM_KVM)
4381+
if (_CPU_VM_CURRENT() == CPUVM_KVM)
43844382
kvm_get_fpu();
43854383
memcpy(&DPMIclient[in_dpmi - 1].saved_fpu_state, &vm86_fpu_state,
43864384
sizeof(vm86_fpu_state));

src/include/cpu-emu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int EMU_V86(void);
111111
int EMU_DPMI(void);
112112
int _CPU_VM(void);
113113
int _CPU_VM_DPMI(void);
114+
int _CPU_VM_CURRENT(void);
114115
#else
115116
#define e_gen_sigalrm()
116117
#define e_gen_sigalrm_from_thread()

0 commit comments

Comments
 (0)