More code cleanups.

This commit is contained in:
Kevin Lawton 2003-01-02 17:05:47 +00:00
parent 31a4a389a1
commit ae92b55818
5 changed files with 164 additions and 167 deletions

View File

@ -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();

View File

@ -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

View File

@ -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__ */

View File

@ -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

View File

@ -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.