More code cleanups.
This commit is contained in:
parent
31a4a389a1
commit
ae92b55818
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//// $Id: plex86-interface.cc,v 1.3 2003-01-02 02:11:40 kevinlawton Exp $
|
||||
//// $Id: plex86-interface.cc,v 1.4 2003-01-02 17:05:47 kevinlawton Exp $
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// Copyright (C) 2002 Kevin P. Lawton
|
||||
@ -49,22 +49,22 @@ openFD(void)
|
||||
{
|
||||
if (plex86State) {
|
||||
// This should be the first operation; no state should be set yet.
|
||||
fprintf(stderr, "openFD: plex86State = 0x%x\n", plex86State);
|
||||
fprintf(stderr, "plex86: openFD: plex86State = 0x%x\n", plex86State);
|
||||
return(0); // Error.
|
||||
}
|
||||
|
||||
// Open a new VM.
|
||||
fprintf(stderr, "Opening VM.\n");
|
||||
fprintf(stderr, "Trying /dev/misc/plex86...");
|
||||
fprintf(stderr, "plex86: opening VM.\n");
|
||||
fprintf(stderr, "plex86: trying /dev/misc/plex86...");
|
||||
plex86FD = open("/dev/misc/plex86", O_RDWR);
|
||||
if (plex86FD < 0) {
|
||||
fprintf(stderr, "failed.\n");
|
||||
// Try the old name.
|
||||
fprintf(stderr, "Trying /dev/plex86...");
|
||||
fprintf(stderr, "plex86: trying /dev/plex86...");
|
||||
plex86FD = open("/dev/plex86", O_RDWR);
|
||||
if (plex86FD < 0) {
|
||||
fprintf(stderr, "failed.\n");
|
||||
fprintf(stderr, "Did you load the kernel module?"
|
||||
fprintf(stderr, "plex86: did you load the kernel module?"
|
||||
" Read the toplevel README file!\n");
|
||||
perror ("open");
|
||||
return(-1); // Error.
|
||||
@ -92,7 +92,7 @@ plex86CpuInfo(BX_CPU_C *cpu)
|
||||
bochsCPUID.procSignature.raw = cpu->cpuidInfo.procSignature;
|
||||
bochsCPUID.featureFlags.raw = cpu->cpuidInfo.featureFlags;
|
||||
|
||||
fprintf(stderr, "Passing guest CPUID to plex86.\n");
|
||||
fprintf(stderr, "plex86: passing guest CPUID to plex86.\n");
|
||||
if ( ioctl(plex86FD, PLEX86_CPUID, &bochsCPUID) ) {
|
||||
perror("ioctl CPUID: ");
|
||||
return(0); // Error.
|
||||
@ -116,7 +116,7 @@ plex86AllocateMemory(unsigned nMegs)
|
||||
}
|
||||
|
||||
// Allocate memory from the host OS for the virtual physical memory.
|
||||
fprintf(stderr, "Allocating %dMB of physical memory in VM.\n", nMegs);
|
||||
fprintf(stderr, "plex86: allocating %dMB of physical memory in VM.\n", nMegs);
|
||||
if (ioctl(plex86FD, PLEX86_ALLOCVPHYS, nMegs) == -1) {
|
||||
perror("ioctl ALLOCVPHYS: ");
|
||||
plex86TearDown();
|
||||
@ -125,7 +125,7 @@ plex86AllocateMemory(unsigned nMegs)
|
||||
plex86State |= Plex86StateMemAllocated;
|
||||
|
||||
// Map guest virtual physical memory into user address space and zero it.
|
||||
fprintf(stderr, "Mapping virtualized physical memory into monitor.\n");
|
||||
fprintf(stderr, "plex86: mapping virtualized physical memory into monitor.\n");
|
||||
ptr = (Bit8u*) mmap(NULL, plex86MemSize, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, plex86FD, 0);
|
||||
if (ptr == (void *) -1) {
|
||||
@ -141,7 +141,7 @@ plex86AllocateMemory(unsigned nMegs)
|
||||
// Create a memory mapping of the monitor's print buffer into
|
||||
// user memory. This is used for efficient printing of info that
|
||||
// the monitor prints out.
|
||||
fprintf(stderr, "Mapping monitor print buffer into user mem.\n");
|
||||
fprintf(stderr, "plex86: mapping monitor print buffer into user mem.\n");
|
||||
plex86PrintBuffer = (Bit8u*) mmap(NULL, 4096, PROT_READ,
|
||||
MAP_SHARED, plex86FD, plex86MemSize + 0*4096);
|
||||
if (plex86PrintBuffer == (void *) -1) {
|
||||
@ -154,7 +154,7 @@ plex86AllocateMemory(unsigned nMegs)
|
||||
// Create a memory mapping of the monitor's guest_cpu structure into
|
||||
// user memory. This is used for passing the guest_cpu state between
|
||||
// user and kernel/monitor space.
|
||||
fprintf(stderr, "Mapping guest_cpu structure into user mem.\n");
|
||||
fprintf(stderr, "plex86: mapping guest_cpu structure into user mem.\n");
|
||||
plex86GuestCPU = (guest_cpu_t *) mmap(NULL, 4096, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, plex86FD, plex86MemSize + 1*4096);
|
||||
if (plex86GuestCPU == (void *) -1) {
|
||||
@ -171,21 +171,21 @@ plex86AllocateMemory(unsigned nMegs)
|
||||
unsigned
|
||||
plex86TearDown(void)
|
||||
{
|
||||
fprintf(stderr, "plex86TearDown called.\n");
|
||||
fprintf(stderr, "plex86: plex86TearDown called.\n");
|
||||
|
||||
fprintf(stderr, "Guest Fault Count (FYI):\n");
|
||||
fprintf(stderr, "plex86: guest Fault Count (FYI):\n");
|
||||
for (unsigned f=0; f<32; f++) {
|
||||
if (faultCount[f])
|
||||
fprintf(stderr, "FC[%u] = %u\n", f, faultCount[f]);
|
||||
fprintf(stderr, "plex86: FC[%u] = %u\n", f, faultCount[f]);
|
||||
}
|
||||
|
||||
if ( plex86FD < 0 ) {
|
||||
fprintf(stderr, "plex86TearDown: FD not open.\n");
|
||||
fprintf(stderr, "plex86: plex86TearDown: FD not open.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if ( plex86State & Plex86StateMMapPhyMem ) {
|
||||
fprintf(stderr, "Unmapping guest physical memory.\n");
|
||||
fprintf(stderr, "plex86: unmapping guest physical memory.\n");
|
||||
if (munmap(plex86MemPtr, plex86MemSize) != 0) {
|
||||
perror ("munmap of guest physical memory");
|
||||
return(0); // Failed.
|
||||
@ -194,7 +194,7 @@ plex86TearDown(void)
|
||||
plex86State &= ~Plex86StateMMapPhyMem;
|
||||
|
||||
if ( plex86State & Plex86StateMMapPrintBuffer ) {
|
||||
fprintf(stderr, "Unmapping print buffer.\n");
|
||||
fprintf(stderr, "plex86: unmapping print buffer.\n");
|
||||
if (munmap(plex86PrintBuffer, 4096) != 0) {
|
||||
perror("munmap of print buffer.");
|
||||
return(0); // Failed.
|
||||
@ -203,7 +203,7 @@ plex86TearDown(void)
|
||||
plex86State &= ~Plex86StateMMapPrintBuffer;
|
||||
|
||||
if ( plex86State & Plex86StateMMapGuestCPU ) {
|
||||
fprintf(stderr, "Unmapping guest_cpu structure.\n");
|
||||
fprintf(stderr, "plex86: unmapping guest_cpu structure.\n");
|
||||
if (munmap(plex86GuestCPU, 4096) != 0) {
|
||||
perror("munmap of guest_cpu structure.");
|
||||
return(0); // Failed.
|
||||
@ -211,7 +211,7 @@ plex86TearDown(void)
|
||||
}
|
||||
plex86State &= ~Plex86StateMMapGuestCPU;
|
||||
|
||||
fprintf(stderr, "Tearing down VM.\n");
|
||||
fprintf(stderr, "plex86: tearing down VM.\n");
|
||||
if (ioctl(plex86FD, PLEX86_TEARDOWN, 0) == -1) {
|
||||
perror("ioctl TEARDOWN: ");
|
||||
return(0); // Failed.
|
||||
@ -219,12 +219,14 @@ plex86TearDown(void)
|
||||
plex86State &= ~Plex86StateMemAllocated;
|
||||
|
||||
// Close the connection to the kernel module.
|
||||
fprintf(stderr, "Closing VM device.\n");
|
||||
fprintf(stderr, "plex86: closing VM device.\n");
|
||||
if (close(plex86FD) == -1) {
|
||||
perror("close of VM device\n");
|
||||
return(0); // Failed.
|
||||
}
|
||||
|
||||
plex86FD = -1; // File descriptor is now closed.
|
||||
|
||||
plex86State = 0; // For good measure.
|
||||
|
||||
return(1); // OK.
|
||||
@ -237,7 +239,7 @@ plex86ExecuteInVM(BX_CPU_C *cpu)
|
||||
int ret;
|
||||
|
||||
if ( plex86State != Plex86StateReady ) {
|
||||
fprintf(stderr, "plex86ExecuteInVM: not in ready state (0x%x)\n",
|
||||
fprintf(stderr, "plex86: plex86ExecuteInVM: not in ready state (0x%x)\n",
|
||||
plex86State);
|
||||
BX_PANIC(("plex86ExecuteInVM: bailing"));
|
||||
return(0);
|
||||
@ -302,31 +304,65 @@ plex86ExecuteInVM(BX_CPU_C *cpu)
|
||||
plex86GuestCPU->a20Enable = BX_GET_ENABLE_A20();
|
||||
|
||||
ret = ioctl(plex86FD, PLEX86_EXECUTE, &executeMsg);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ioctl(PLEX86_EXECUTE) returns < 0\n");
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "plex86: ioctl(PLEX86_EXECUTE): ");
|
||||
switch (ret) {
|
||||
case Plex86NoExecute_Method:
|
||||
fprintf(stderr, "bad execute method.\n");
|
||||
break;
|
||||
case Plex86NoExecute_CR0:
|
||||
fprintf(stderr, "bad CR0 value.\n");
|
||||
break;
|
||||
case Plex86NoExecute_CR4:
|
||||
fprintf(stderr, "bad CR4 value.\n");
|
||||
break;
|
||||
case Plex86NoExecute_CS:
|
||||
fprintf(stderr, "bad CS value.\n");
|
||||
break;
|
||||
case Plex86NoExecute_A20:
|
||||
fprintf(stderr, "bad A20 enable value.\n");
|
||||
break;
|
||||
case Plex86NoExecute_Selector:
|
||||
fprintf(stderr, "bad selector value.\n");
|
||||
break;
|
||||
case Plex86NoExecute_DPL:
|
||||
fprintf(stderr, "bad descriptor DPL.\n");
|
||||
break;
|
||||
case Plex86NoExecute_EFlags:
|
||||
fprintf(stderr, "bad EFlags.\n");
|
||||
break;
|
||||
case Plex86NoExecute_Panic:
|
||||
fprintf(stderr, "panic.\n");
|
||||
break;
|
||||
case Plex86NoExecute_VMState:
|
||||
fprintf(stderr, "bad VM state.\n");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ret = %d\n", ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
switch ( executeMsg.monitorState.request ) {
|
||||
case MonReqFlushPrintBuf:
|
||||
fprintf(stderr, "MonReqFlushPrintBuf:\n");
|
||||
fprintf(stderr, "::%s\n", plex86PrintBuffer);
|
||||
break;
|
||||
case MonReqPanic:
|
||||
fprintf(stderr, "MonReqPanic:\n");
|
||||
fprintf(stderr, "::%s\n", plex86PrintBuffer);
|
||||
break;
|
||||
//case MonReqNone:
|
||||
// copyPlex86StateToBochs(cpu);
|
||||
// return(0); /* All OK. */
|
||||
case MonReqGuestFault:
|
||||
faultCount[ executeMsg.monitorState.guestFaultNo ]++;
|
||||
copyPlex86StateToBochs(cpu);
|
||||
return(0); /* All OK. */
|
||||
default:
|
||||
fprintf(stderr, "executeMsg.request = %u\n",
|
||||
executeMsg.monitorState.request);
|
||||
break;
|
||||
else {
|
||||
switch ( executeMsg.monitorState.request ) {
|
||||
case MonReqFlushPrintBuf:
|
||||
fprintf(stderr, "plex86: MonReqFlushPrintBuf:\n");
|
||||
fprintf(stderr, "::%s\n", plex86PrintBuffer);
|
||||
break;
|
||||
case MonReqPanic:
|
||||
fprintf(stderr, "plex86: MonReqPanic:\n");
|
||||
fprintf(stderr, "::%s\n", plex86PrintBuffer);
|
||||
break;
|
||||
//case MonReqNone:
|
||||
// copyPlex86StateToBochs(cpu);
|
||||
// return(0); /* All OK. */
|
||||
case MonReqGuestFault:
|
||||
faultCount[ executeMsg.monitorState.guestFaultNo ]++;
|
||||
copyPlex86StateToBochs(cpu);
|
||||
return(0); /* All OK. */
|
||||
default:
|
||||
fprintf(stderr, "plex86: executeMsg.request = %u\n",
|
||||
executeMsg.monitorState.request);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
plex86TearDown();
|
||||
|
@ -1,47 +1,39 @@
|
||||
Fix monPrint and friends.
|
||||
monpanic breaks up into 2 monprints which hit user space twice.
|
||||
|
||||
Could put the GDT/LDT in linear memory where the guest
|
||||
expect them.
|
||||
expects them.
|
||||
|
||||
Synchronize page writes with iCache in bochs.
|
||||
|
||||
Deal with cycle counts of guest execution in VM, and in
|
||||
bochs/plex86 shim.
|
||||
|
||||
Make a host-null.c file to demonstrate/test the OS-specific
|
||||
files that are needed for a host port.
|
||||
|
||||
Deal with page_usage. How do we update this between timeslices?
|
||||
Do we always clear it? Maybe we should keep a log of things to
|
||||
clear (page_usage, GDT entries, PDE entries, ...) and clear those
|
||||
before returning to user space.
|
||||
|
||||
monpanic breaks up into 2 monprints which hit user space twice.
|
||||
GDT entries for guest need to be cleared upon return from guest
|
||||
execution, or just cleared before invocation of the guest.
|
||||
|
||||
Task segment must be a 32-bit'er.
|
||||
|
||||
Save/restore floating point state of host/VM.
|
||||
|
||||
pack guest_cpu_t structure.
|
||||
|
||||
deduct off some cycles for the IRET/int sequence.
|
||||
|
||||
Delete use of vm->addr, and split print-nexus into parts so we can
|
||||
use direct host or guest fields. I don't like having implicit
|
||||
pointer usage.
|
||||
Conditions for bochs compile using plex86:
|
||||
- Not compiled for debug
|
||||
- x86 host
|
||||
|
||||
Not compiled for debug
|
||||
Compiled for BX_SMP_PROCESSORS == 1
|
||||
cpuid match
|
||||
x86 host
|
||||
paging-mon.c: We can eliminate any code other than CPL==3.
|
||||
|
||||
monitor uses slots 1,2,3 so guest ring3 should not
|
||||
use these slots.
|
||||
|
||||
FIX a20 in system fields.
|
||||
FIX use of CPL in paging-mon.c. We can eliminate any
|
||||
code other than CPL==3.
|
||||
Fix extra PDBR reload in nexus.S
|
||||
|
||||
Manipulation/reading of host page tables needs to be SMP/preempt
|
||||
compatible. Need to do spin-lock (big kernel lock for old Linux)
|
||||
on vma.
|
||||
|
||||
==================== From previous plex86 TODO file ====================
|
||||
|
||||
@ -64,8 +56,6 @@ FIX use of CPL in paging-mon.c. We can eliminate any
|
||||
|
||||
- Many performance enhancements (see PERFORMANCE)
|
||||
|
||||
- Test and get more guests running; list in 'GUESTS'.
|
||||
|
||||
- Allow memory to be mapped anywhere in the physical address
|
||||
space.
|
||||
|
||||
@ -80,17 +70,5 @@ FIX use of CPL in paging-mon.c. We can eliminate any
|
||||
- Deal with LDT
|
||||
|
||||
|
||||
Use monitor unmapped IO port handler rather than user space.
|
||||
|
||||
Get rid of VM message count instrumentation spew to kernel log
|
||||
|
||||
unallocVmPages/unreserve_guest_pages called twice,
|
||||
release & teardown.
|
||||
|
||||
move mapMonitor to -host.c
|
||||
|
||||
Zero out GDT when remapped.
|
||||
|
||||
When is mapMonitor called?
|
||||
|
||||
Fix extra PDBR reload in nexus.S
|
||||
|
@ -396,8 +396,8 @@ typedef struct {
|
||||
struct {
|
||||
Bit64u t0; /* TSC before excecution of guest code */
|
||||
Bit64u cyclesElapsed; /* Cycles of guest execution */
|
||||
unsigned a20; /* address 20 line enabled */
|
||||
Bit32u a20AddrMask; /* mask to apply to phy address */
|
||||
unsigned a20Enable; /* A20 line enabled? */
|
||||
Bit32u a20AddrMask; /* mask to apply to phy address */
|
||||
Bit32u a20IndexMask; /* mask to apply to phy address */
|
||||
} system;
|
||||
|
||||
@ -495,6 +495,14 @@ void mon_memzero(void *ptr, int size);
|
||||
void mon_memcpy(void *dst, void *src, int size);
|
||||
void *mon_memset(void *s, unsigned c, unsigned n);
|
||||
|
||||
/*
|
||||
* We need to set the monitor CS/DS base address so that the module pages,
|
||||
* which are mapped starting at linear address 'laddr' into the guest address
|
||||
* space, reside at the same offset relative to the monitor CS base as they
|
||||
* reside relative to the kernel CS base in the host address space. This way,
|
||||
* we can execute the (non-relocatable) module code within the guest address
|
||||
* space ...
|
||||
*/
|
||||
#define MON_BASE_FROM_LADDR(laddr) \
|
||||
((laddr) - monitor_pages.startOffsetPageAligned)
|
||||
|
||||
@ -662,9 +670,6 @@ unsigned getMonPTi(vm_t *, unsigned pdi, unsigned source);
|
||||
#define CLI() asm volatile ("cli": : : "memory")
|
||||
#define STI() asm volatile ("sti": : : "memory")
|
||||
|
||||
extern const selector_t nullSelector;
|
||||
extern const descriptor_t nullDescriptor;
|
||||
|
||||
#endif /* MONITOR Space. */
|
||||
|
||||
#endif /* __MONITOR_H__ */
|
||||
|
@ -51,18 +51,6 @@ static void mapBlankPage(vm_t *vm, Bit32u *laddr_p, page_t *pageTable);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* We need to set the monitor CS/DS base address so that the module pages,
|
||||
* which are mapped starting at linear address 'laddr' into the guest address
|
||||
* space, reside at the same offset relative to the monitor CS base as they
|
||||
* reside relative to the kernel CS base in the host address space. This way,
|
||||
* we can execute the (non-relocatable) module code within the guest address
|
||||
* space ...
|
||||
*/
|
||||
#define MON_BASE_FROM_LADDR(laddr) \
|
||||
((laddr) - monitor_pages.startOffsetPageAligned)
|
||||
|
||||
|
||||
static const selector_t nullSelector = { raw: 0 };
|
||||
static const descriptor_t nullDescriptor = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@ -126,9 +114,9 @@ initMonitor(vm_t *vm)
|
||||
|
||||
vm->kernel_offset = hostKernelOffset();
|
||||
|
||||
vm->system.a20 = 1; /* start with A20 line enabled */
|
||||
vm->system.a20AddrMask = 0xffffffff; /* all address lines contribute */
|
||||
vm->system.a20IndexMask = 0x000fffff; /* all address lines contribute */
|
||||
vm->system.a20Enable = 1; /* Start with A20 line enabled. */
|
||||
vm->system.a20AddrMask = 0xffffffff; /* All address lines contribute. */
|
||||
vm->system.a20IndexMask = 0x000fffff; /* All address lines contribute. */
|
||||
|
||||
/* Initialize nexus */
|
||||
mon_memzero(vm->host.addr.nexus, 4096);
|
||||
@ -778,7 +766,7 @@ ioctlGeneric(vm_t *vm, void *inode, void *filp,
|
||||
ret = ioctlExecute(vm, &executeMsg);
|
||||
if ( hostCopyToUser((void *)arg, &executeMsg, sizeof(executeMsg)) )
|
||||
return -Plex86ErrnoEFAULT;
|
||||
return ret; /* OK. */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -803,11 +791,11 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
guest_context_t *guest_stack_context;
|
||||
nexus_t *nexus;
|
||||
unsigned s;
|
||||
int retval = 100;
|
||||
int retval;
|
||||
|
||||
if ( (vm->vmState != VMStateReady) ||
|
||||
(vm->mon_request != MonReqNone) ) {
|
||||
retval = 1; /* Fail. */
|
||||
retval = Plex86NoExecute_VMState; /* Fail. */
|
||||
goto handlePanic;
|
||||
}
|
||||
|
||||
@ -817,7 +805,7 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
* cosimulation.
|
||||
*/
|
||||
if (executeMsg->executeMethod != Plex86ExecuteMethodNative) {
|
||||
retval = 2; /* Fail. */
|
||||
retval = Plex86NoExecute_Method; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
|
||||
@ -852,7 +840,7 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
/* 0x8005003b */
|
||||
if ( (guest_cpu->cr0.raw & 0xe0000037) != 0x80000033 ) {
|
||||
hostPrint("plex86: guest CR0=0x%x\n", guest_cpu->cr0.raw);
|
||||
retval = 3; /* Fail. */
|
||||
retval = Plex86NoExecute_CR0; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
|
||||
@ -871,7 +859,7 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
*/
|
||||
if ( (guest_cpu->cr4.raw & 0x000007ff) != 0x00000000 ) {
|
||||
hostPrint("plex86: guest CR4=0x%x\n", guest_cpu->cr4.raw);
|
||||
retval = 4; /* Fail. */
|
||||
retval = Plex86NoExecute_CR4; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
|
||||
@ -881,16 +869,34 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
if ( (guest_cpu->sreg[SRegCS].sel.fields.rpl != 3) ||
|
||||
(guest_cpu->sreg[SRegCS].sel.fields.index == 0) ||
|
||||
(guest_cpu->sreg[SRegCS].des.dpl != 3) ) {
|
||||
retval = 5; /* Fail. */
|
||||
retval = Plex86NoExecute_CS; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
|
||||
/* A20 line must be enabled. */
|
||||
if ( guest_cpu->a20Enable != 1 ) {
|
||||
retval = 6; /* Fail. */
|
||||
retval = Plex86NoExecute_A20; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
|
||||
/* Some code not really used now, since we only support A20 being enabled. */
|
||||
{
|
||||
unsigned newA20Enable;
|
||||
newA20Enable = guest_cpu->a20Enable > 0; /* Make 0 or 1. */
|
||||
if ( newA20Enable != vm->system.a20Enable ) {
|
||||
if ( (!newA20Enable) && guest_cpu->cr0.fields.pg ) {
|
||||
/* A20 disabled, paging on not supported. Well, really I have to
|
||||
* see if it matters. This check was in old plex86 code.
|
||||
*/
|
||||
retval = Plex86NoExecute_A20; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
vm->system.a20Enable = newA20Enable;
|
||||
vm->system.a20AddrMask = 0xffefffff | (newA20Enable << 20);
|
||||
vm->system.a20IndexMask = 0x000ffeff | (newA20Enable << 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* LDT not supported.
|
||||
* Monitor uses GDT slots 1,2,3, so guest segments can not.
|
||||
* Segment descriptor cache DPL should equal 3.
|
||||
@ -902,22 +908,22 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
if ( selector & 0xfffc ) {
|
||||
if ( (selector & 0x0007) != 3 ) {
|
||||
/* Either TI=1 (LDT usage) or RPL!=3. */
|
||||
retval = 7; /* Fail. */
|
||||
retval = Plex86NoExecute_Selector; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
index = selector >> 3;
|
||||
if ( index <= 3 ) {
|
||||
/* Selector index field uses one of the monitor GDT slots. */
|
||||
retval = 8; /* Fail. */
|
||||
retval = Plex86NoExecute_Selector; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
if ( index >= (MON_GDT_SIZE/8) ) {
|
||||
/* Selector index field uses a slot beyond the monitor GDT size. */
|
||||
retval = 9; /* Fail. */
|
||||
retval = Plex86NoExecute_Selector; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
if ( guest_cpu->sreg[s].des.dpl != 3 ) {
|
||||
retval = 10; /* Fail. */
|
||||
retval = Plex86NoExecute_DPL; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
}
|
||||
@ -935,7 +941,7 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
*/
|
||||
if ( (guest_cpu->eflags & (0x001b7302)) !=
|
||||
(0x00000202) ) {
|
||||
retval = 11; /* Fail. */
|
||||
retval = Plex86NoExecute_EFlags; /* Fail. */
|
||||
goto handleFail;
|
||||
}
|
||||
|
||||
@ -1031,7 +1037,7 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
if (!(eflags & 0x200)) {
|
||||
vm_restore_flags(eflags);
|
||||
hostPrint("ioctlExecute: EFLAGS.IF==0\n");
|
||||
retval = 12; /* Fail. */
|
||||
retval = 101; /* Fail. */
|
||||
goto handlePanic;
|
||||
}
|
||||
#endif
|
||||
@ -1062,17 +1068,17 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
else {
|
||||
hostPrint("mapMonitor failed.\n");
|
||||
hostPrint("Panic w/ abort_code=%u\n", vm->abort_code);
|
||||
retval = 100;
|
||||
retval = 102;
|
||||
goto handlePanic;
|
||||
}
|
||||
#endif
|
||||
hostPrint("ioctlExecute: case MonReqRemapMonitor.\n");
|
||||
retval = 13;
|
||||
retval = 103;
|
||||
goto handlePanic;
|
||||
|
||||
case MonReqFlushPrintBuf:
|
||||
hostPrint("ioctlExecute: case MonReqFlushPrintBuf.\n");
|
||||
retval = 14;
|
||||
retval = 104;
|
||||
goto handlePanic;
|
||||
|
||||
case MonReqGuestFault:
|
||||
@ -1084,18 +1090,18 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
executeMsg->monitorState.request = vm->mon_request;
|
||||
executeMsg->monitorState.guestFaultNo = vm->guestFaultNo;
|
||||
vm->mon_request = MonReqNone;
|
||||
return 15;
|
||||
return 0;
|
||||
|
||||
case MonReqPanic:
|
||||
if (vm->abort_code)
|
||||
hostPrint("Panic w/ abort_code=%u\n", vm->abort_code);
|
||||
hostPrint("ioctlExecute: case MonReqPanic.\n");
|
||||
retval = 16;
|
||||
retval = 106;
|
||||
goto handlePanic;
|
||||
|
||||
default:
|
||||
hostPrint("ioctlExecute: default case (%u).\n", vm->mon_request);
|
||||
retval = 17;
|
||||
retval = 107;
|
||||
goto handlePanic;
|
||||
}
|
||||
}
|
||||
@ -1112,7 +1118,7 @@ ioctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg)
|
||||
}
|
||||
|
||||
/* Should not get here. */
|
||||
retval = 100;
|
||||
retval = 108;
|
||||
goto handlePanic;
|
||||
|
||||
handleFail:
|
||||
@ -1275,40 +1281,11 @@ hostPrint("plex86: vm_t size is %u\n", sizeof(vm_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
ioctlSetA20E(vm_t *vm, unsigned long val)
|
||||
{
|
||||
unsigned prev_a20;
|
||||
|
||||
if ( !val && vm->host.addr.guest_cpu->cr0.fields.pg ) {
|
||||
/* Disabling the A20 line with paging on, is not
|
||||
* currently handled.
|
||||
*/
|
||||
xxxprint(vm, "SetA20E: val=0, CR0.PG=1 unhandled\n");
|
||||
return 0; /* fail */
|
||||
}
|
||||
val = (val > 0); /* make 0 or 1 */
|
||||
prev_a20 = vm->system.a20;
|
||||
|
||||
vm->system.a20 = val;
|
||||
vm->system.a20AddrMask = 0xffefffff | (val << 20);
|
||||
vm->system.a20IndexMask = 0x000ffeff | (val << 8);
|
||||
|
||||
if ( prev_a20 != vm->system.a20 ) {
|
||||
/* change in A20 line enable status */
|
||||
vm->modeChange |= ModeChangeEventPaging | ModeChangeRequestPaging;
|
||||
}
|
||||
|
||||
return 1; /* OK */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* */
|
||||
/* Allocate various pages/memory needed by monitor */
|
||||
/* */
|
||||
/*
|
||||
* Allocate various pages/memory needed by monitor.
|
||||
*/
|
||||
|
||||
int
|
||||
allocVmPages( vm_t *vm, unsigned nmegs )
|
||||
@ -1696,17 +1673,6 @@ initShadowPaging(vm_t *vm)
|
||||
/* Update vpaging timestamp. */
|
||||
vm->vpaging_tsc = vm_rdtsc();
|
||||
|
||||
#if 0
|
||||
/* Flush TLB cache. */
|
||||
asm volatile (
|
||||
"movl %%cr3, %%eax\n\t"
|
||||
"movl %%eax, %%cr3"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: "eax", "memory" /* modified */
|
||||
);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* When we remap the monitor page tables, IF guest paging is
|
||||
* enabled, then mark the page containing the guest page directory
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************
|
||||
* $Id: plex86.h,v 1.2 2003-01-02 01:08:43 kevinlawton Exp $
|
||||
* $Id: plex86.h,v 1.3 2003-01-02 17:05:06 kevinlawton Exp $
|
||||
************************************************************************
|
||||
*
|
||||
* plex86: run multiple x86 operating systems concurrently
|
||||
@ -33,7 +33,7 @@ typedef struct {
|
||||
selector_t sel;
|
||||
descriptor_t des;
|
||||
unsigned valid;
|
||||
} guest_sreg_t;
|
||||
} __attribute__ ((packed)) guest_sreg_t;
|
||||
|
||||
#define SRegES 0
|
||||
#define SRegCS 1
|
||||
@ -120,7 +120,7 @@ typedef struct {
|
||||
Bit32u Reserved31_25:7;
|
||||
} __attribute__ ((packed)) fields;
|
||||
} __attribute__ ((packed)) featureFlags;
|
||||
} cpuid_info_t;
|
||||
} __attribute__ ((packed)) cpuid_info_t;
|
||||
|
||||
typedef struct {
|
||||
Bit32u edi;
|
||||
@ -145,7 +145,7 @@ typedef struct {
|
||||
Bit32u cr1, cr2, cr3;
|
||||
cr4_t cr4;
|
||||
unsigned a20Enable;
|
||||
} guest_cpu_t;
|
||||
} __attribute__ ((packed)) guest_cpu_t;
|
||||
|
||||
|
||||
|
||||
@ -175,6 +175,18 @@ typedef struct {
|
||||
#define PLEX86_CPUID 0x6b06
|
||||
#endif
|
||||
|
||||
/* Reasons why plex86 could not execute the guest context in the VM. */
|
||||
#define Plex86NoExecute_Method 1
|
||||
#define Plex86NoExecute_CR0 2
|
||||
#define Plex86NoExecute_CR4 3
|
||||
#define Plex86NoExecute_CS 4
|
||||
#define Plex86NoExecute_A20 5
|
||||
#define Plex86NoExecute_Selector 6
|
||||
#define Plex86NoExecute_DPL 7
|
||||
#define Plex86NoExecute_EFlags 8
|
||||
#define Plex86NoExecute_Panic 9
|
||||
#define Plex86NoExecute_VMState 10
|
||||
|
||||
|
||||
/* Requests that the VM monitor makes to host-kernel space or
|
||||
* host-user space.
|
||||
|
Loading…
x
Reference in New Issue
Block a user