-
-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KVM: Rudimentary support for VCPI #1880
base: devel
Are you sure you want to change the base?
Conversation
I reverted that optimization in #1881. Other than that - quite interesting, but |
Have you considered the use of |
We still have the vgacpy branch in #1099 |
Can you put it somewhere upwards, |
As in #198 ? |
At the moment this is mostly a playground to see what is possible, with a VCPI client having full control over the VM, and to test some ideas, perhaps find some bugs, it also allows quick checking how DPMI provider X behaves vs. dosemu2's DPMI implementation. Then some of the ideas could go into devel before this would be merged. This is for the moment a KVM only thing, nothing against Arm, just a bonus when KVM is there for now. Sure Windows 95 and various games that need VCPI or flat real mode would be a bonus for sure.
How do you mean, moving the code and data page from the monitor to two pages allocated from the main pool? VCPI spec says they must be mapped into the first 4MB (linear), could be in low space (e.g. I could put the VCPI<->VM86 switch code in bios.S), or mapped from somewhere high (which is what I'm doing now, monitor is high) Note that before VCPI, KVM always identity maps, from guest virtual space to guest physical space. This keeps it consistent with native DPMI. But with VCPI the client has control over page tables so we only have control over physical space except (collaboratively!) for the first 1MB + 64k + up to 3 MB of virtual address space. That's why DPMI had to be disabled in the config, so that extmem is at physical (not linear) 0x110000.
|
This part I don't understand. |
ext_mem is aliased to some high space in |
oh I may be slightly out of date, as I see now that dpmi_base's default was moved from 8MB to 32MB. Which leaves max 31MB for extmem now. Still for HX, 0x400000 (at 4MB linear) needs to be available for DPMI right, see #612? |
Yeah, that's right, and that part |
... instead of in some high addresses. This is needed for vcpi.
I added the patch that is supposed |
In devel this is handled by mapping |
Well I guess the easiest solution for |
This is needed for vcpi. That way it is mapped to the right phys addr under kvm guest. And it doesn't need to be shared that way as we only use the identity mapping.
Hmm, perhaps I've found the simple |
This is needed for vcpi. That way it is mapped to the right phys addr under kvm guest. And it doesn't need to be shared that way as we only use the identity mapping. Don't auto-protect rsv_low in dpmi.
Except that then we shouldn't |
xms_rv built and I think its quite |
If we use identity mappings for ext_mem, then xms can't go below 8Mb to harm HX. So use identity mappings for xms too.
If we use identity mappings for ext_mem, then xms can't go below 8Mb to harm HX. So use identity mappings for xms too.
If we use identity mappings for ext_mem, then xms can't go below 8Mb to harm HX. So use identity mappings for xms too.
If we use identity mappings for ext_mem, then xms can't go below 8Mb to harm HX. So use identity mappings for xms too.
If we use identity mappings for ext_mem, then xms can't go below 8Mb to harm HX. So use identity mappings for xms too.
This is needed for vcpi. That way it is mapped to the right phys addr under kvm guest. And it doesn't need to be shared that way as we only use the identity mapping. Don't auto-protect rsv_low in dpmi.
If we use identity mappings for ext_mem, then xms can't go below 8Mb to harm HX. So use identity mappings for xms too.
I merged identity mapping for |
With this patch:
I eventually see in the log:
So the game corrupts HMA and freedos |
CS is 0x2a8 on enter and mcbs are:
So its a crusader's CS. |
ok, this could be an A20-line issue then. I think perhaps some place needs to force a20 on to make this work. |
The dosbox instructions have some loadfix stuff in them, so that may be it! |
OK I see the bug actually... or |
Our debugger queries the HMA start at boot. And fdpp is too permissive and just enables HMA at that point. Check if HMA is actually enabled before querying its start. That avoids problems.
Should now be fixed. Note that with |
Implement basic VCPI support with limitations. The limitations are: $_dpmi = (0) $_ems = (0) * don't use FDPP * use external XMS provider (HIMEM/FDXMS) VCPI clients allocate memory from XMS only, so EMS needs to report 0 memory, and XMS needs to map identical "physical" memory starting at 0x110000, which would normally be taken by DPMI memory. The page table maps LOW+HMA as usual, then a page at 0x110000 to monitor code implementing a monitor->VCPI client jump and a VCPI client -> VM86 jump. A page at 0x111000 contains the saved monitor GDTR/IDTR/CR3 values and a temporary stack, with hiword(esp)=0, for the client to use. The monitor code is much like Jemm's. When KVM is interrupts the VCPI client through a signal, DOSEMU does its regular things, but CANNOT modify any registers, as the client registers stay in the VM. pic_run() will see VIF is not set, so won't modify, and the kvm.c code needs to use KVM_INTERRUPT if pic_pending(). The only other place that has been adapted for a callback into vm86 is leavedos(). VGAEMU memory is unprotected for now, so updates aren't reliable, and VGA planar modes don't work. DOOM is playable but a bit slow due to frequent VGA I/O port accesses which would normally go via instremu. Duke Nukem 3D runs but with choppy sound and incomplete screen updates.
By dirtying all pages. Can be improved using KVM_GET_DIRTY_LOG.
Much like in dosemu2#198, use the KVM API to track which VGA pages have been written to.
Don't map the physical memory for the VGA buffer then so that all accesses cause an MMIO KVM exit. instremu isn't read for paged memory, and probably this will be fast enough with coalesced MMIO.
Gives much better speed in VGAEMU planar modes.
This allows command line executables to run properly with VCPI and non-zero config.dpmi. For DJGPP that means running cwsdpmi explicitly, and for DOS4GW, SET DOS16M=11 Still needs $_ems=(4), a low enough value so that EMS is enabled but doesn't let VCPI allocate any memory from it.
So that graphics work with VCPI where $_dpmi is not (0).
Otherwise report "unsupported" for int67/ah=de. This should fix CI.
Applies the page allocator to the physical memory area starting at 16M up to 16M + $_ems. To do: deal with DPMI overlaps if $_ems > 16M. This removes all special requirements on dosemu.conf parameters for using VCPI.
$_vcpi = (0) by default, any other value for now means "on" but in future some value > $_ems can denote higher amounts of VCPI memory than EMS memory.
Some VCPI applications rely on page table mappings between the EMS page frame and high memory, so we must set them up and release them on demand as alias mappings.
Yes it works now, thanks, just with noisy error messages when internal XMS is used. |
When config.xms_map_size < config.xms_size (it is default), the lock_EMB may fail for blocks (partly) above 16MB. This isn't fatal and e.g. Crusader Demo will just keep retrying with smaller sizes until it succeeds, so don't spew out this issue to the terminal and leave it to the XMS debug log (dosemu2#1880)
When entering VCPI, we need to convert PROT_NONE maps into MMIO maps, dirty logging is always ok.
XMS now allows mappings up to $_dpmi_base but the mappings need to start at 15MB to allow DMA. If XMS is disabled ($_xms=(0)), extmem can then go up to $_dpmi_base, otherwise up to 15MB. To allow mapping all XMS memory, $_xms is now limited to be <= config.xms_map_size = dpmi_base - (1024+64)k - extmem, otherwise Crusader Demo will complain (dosemu2#1880) All the config checks are now done in a scrub function, to allow clean early exit.
XMS now allows mappings up to $_dpmi_base (default: at 32MB), but the mappings need to start at 15MB or lower to allow at least 1MB that can be accessed via DMA. So now all XMS memory can be mapped in the default configuration for 16MB of XMS, so Crusader Demo will not complain once VCPI is in (dosemu2#1880). If XMS is disabled ($_xms=(0)), extmem can then go up to$_dpmi_base, otherwise up to 15MB. All the config checks are now done in a scrub function, to allow clean early exit.
Implement basic VCPI support with limitations.
The limitations are:
$_dpmi = (0)
$_ems = (0)
VCPI clients allocate memory from XMS only, so EMS needs to report 0 memory, and XMS needs to map identical "physical" memory starting at 0x110000, which would normally be taken by DPMI memory.
The page table maps LOW+HMA as usual, then a page at 0x110000 to monitor code implementing a monitor->VCPI client jump and a VCPI client -> VM86 jump. A page at 0x111000 contains the saved monitor GDTR/IDTR/CR3 values and a temporary stack, with hiword(esp)=0, for the client to use. The monitor code is much like Jemm's.
When KVM interrupts the VCPI client through a signal, DOSEMU does its regular things, but CANNOT modify any registers, as the client registers stay in the VM. pic_run() will see VIF is not set, so won't modify, and the kvm.c code needs to use KVM_INTERRUPT if pic_pending().
The only other place that has been adapted for a callback into vm86 is leavedos().
VGAEMU memory is unprotected for now, so updates aren't reliable, and VGA planar modes don't work.
DOOM is playable but a bit slow due to frequent VGA I/O port accesses which would normally go via instremu. Duke Nukem 3D runs but with choppy sound and incomplete screen updates.