⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.h

📁 Bochs这个虚拟机的源代码。学习虚拟机的编写和操作系统的编写有帮助。
💻 H
📖 第 1 页 / 共 2 页
字号:
#define CR0_PE  (1<<0)#define CR0_MP  (1<<1)#define CR0_EM  (1<<2)#define CR0_TS  (1<<3)#define CR0_ET  (1<<4)#define CR0_NE  (1<<5)#define CR0_WP  (1<<16)#define CR0_AM  (1<<18)#define CR0_NW  (1<<29)#define CR0_CD  (1<<30)#define CR0_PG  (1<<31)/* * Complete state of the VM (Virtual Machine). */typedef struct {  Bit32u guestPhyMemAddr; /* Ptr to malloced memory from user space. */  /* Store eflags values of the guest which are virtualized to   * run in the monitor   */  eflags_t veflags;  unsigned executeMethod;  unsigned vmState;  unsigned mon_request;  unsigned guestFaultNo;  Bit32u   pinReqPPI;  unsigned redirect_vector;  Bit32u   kernel_offset;#define MonitorSpace 0#define UserSpace    1#define HostSpace    2  volatile unsigned inMonFault;  /* Extra info on aborts, especially when a message can't   * be printed out   */  unsigned abort_code;  struct {    Bit64u     t0; /* TSC before excecution of guest code */    Bit64u     cyclesElapsed; /* Cycles of guest execution */    unsigned   a20Enable;    /* A20 line enabled? */    Bit32u     a20AddrMask;  /* mask to apply to phy address */    Bit32u     a20IndexMask; /* mask to apply to phy address */    } system;  cpuid_info_t guestCPUIDInfo;/* This macro yields a physical address after applying the A20 line * enable mask to the original physical address. */#define A20Addr(vm, paddr) ( (paddr) & ((vm)->system.a20AddrMask) )#define A20PageIndex(vm, pi) ( (pi) & ((vm)->system.a20IndexMask) )  /* Keep an index of the next available Page Table */  unsigned  ptbl_laddr_map_i;  Bit32u mon_pde_mask; /* Upper 10 bits of monitor lin addr space */  Bit32u mon_pdi;      /* Same value shifted down 22 bits. */  Bit64u vpaging_tsc; /* time stamp of last page mappings flush */  /* We need to keep track of what each of the guest's physical */  /* pages contains, and maintain some additional attributes. */  /* We determine which kinds of information reside in the page, */  /* dynamically. */  phyPageInfo_t pageInfo[MAX_MON_GUEST_PAGES];  /* This is a hack for now.  I need to store the "struct page *"   * information returned by get_user_pages() in the Linux kernel.   * Should clean this up.   */  void  *hostStructPagePtr[MAX_MON_GUEST_PAGES];  /* A revolving queue, which stores information on guest physical memory   * pages which are currently pinned.  Only a certain number of pages   * may be pinned at any one time.  This is a really simplistic   * strategy - when the Q is full, the page which was pinned the   * longest time ago is unpinned to make room.  It's a   * "least recently pinned" strategy.   */#define MaxPhyPagesPinned 1024  /* 4Megs of pinned pages max per VM. */  struct {    unsigned nEntries; /* Number of entries in table. */    unsigned tail;    Bit32u ppi[MaxPhyPagesPinned]; /* Physical Page Index of pinned guest page. */    } guestPhyPagePinQueue;  struct {    volatile unsigned event; /* Any log event occurred. */    /* Inactive, OK to dump to host and change */    volatile unsigned locked;    /* Number of times buffer wrapped since last print to kernel */    /*   debug facility */    volatile unsigned offset; /* Current index within buffer */    volatile unsigned error;  /* Error printing. (ex. string too long) */    } log_buffer_info;  vm_pages_t         pages;  /* memory pages allocated by the host */  /* Host specific fields.  These fields should NOT be accessed */  /* from code which may execute in either host or monitor/guest */  /* spaces, unless you need to _specifically_ manipulate a */  /* host-specific field. */  struct {    vm_addr_t    addr;   /* addresses of data structures in host space */    void       (*__host2mon)(void);   /* Host to guest nexus entry point */    pageEntry_t  nexus_pde;           /* PDE pointing to nexus page table */    } host;  /* Guest specific fields.  These fields should NOT be accessed */  /* from code which may execute in either host or monitor/guest */  /* spaces, unless you need to _specifically_ manipulate a */  /* guest-specific field. */  struct {    vm_addr_t    addr;   /* addresses of data structures in guest space */    void       (*__mon2host)(void);  /* monitor to host entry point */    } guest;  } vm_t;extern char __nexus_start, __nexus_end, __mon_cs;extern char __host2mon, __mon2host, __handle_fault, __handle_int;extern char __ret_to_guest;/* * This structure describes the pages containing the code/data * of the monitor itself (inside the kernel module) */#define Plex86MaxKernelModulePages 128typedef struct {  /* Virtual address space occupied by the kernel module. */  Bit32u startOffset;  Bit32u startOffsetPageAligned;  unsigned nPages; /* Number of pages. */      /* A list of the Physical Page Indeces of the pages comprising the   * kernel module.  A PPI is just the physical page address >> 12.   */  Bit32u ppi[Plex86MaxKernelModulePages];  } kernelModulePages_t;extern kernelModulePages_t kernelModulePages;extern cpuid_info_t        hostCpuIDInfo;#if !defined(IN_HOST_SPACE) && !defined(IN_MONITOR_SPACE)#error "No space defined for this file"#endif#if defined(IN_HOST_SPACE) || defined(IN_MONITOR_SPACE)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) - kernelModulePages.startOffsetPageAligned)/* ============================================================ * These are the functions which are available in either of the * host or monitor/guest spaces. *//* Access to label offsets in nexus.S... From the host address perspective */#define HOST_NEXUS_OFFSET(vm, field) \    ( ((Bit32u)vm->host.addr.nexus) + \      (((Bit32u) &field) - ((Bit32u) &__nexus_start)) )/* From the monitor/guest address perspective. */#define MON_NEXUS_OFFSET(vm, field) \    ( ((Bit32u)vm->guest.addr.nexus) + \      (((Bit32u) &field) - ((Bit32u) &__nexus_start)) )  static __inline__ Bit64uvm_rdtsc(void) {  Bit64u ret;  asm volatile (    "rdtsc"    : "=A" (ret)    );  return ret;  }#endif  /* {HOST, MONITOR} */#ifdef IN_HOST_SPACE/* ========================================================== * These are the functions which are available to the monitor * running in the host space. *//* * Generate a software interrupt */#define soft_int(n)                             \    asm volatile (                              \        "    movb %b0, __soft_int_vector \n\t"  \        "    jmp __soft_int_n            \n\t"  \        "__soft_int_n:                   \n\t"  \        "    sti                         \n\t"  \        "    .byte 0xcd                  \n\t"  \        "__soft_int_vector:              \n\t"  \        "    .byte 0x00                  \n\t"  \        :                                       \        : "r" ((Bit8u) (n) )                    \        : "memory"                              \    )#define Plex86ErrnoEBUSY      1#define Plex86ErrnoENOMEM     2#define Plex86ErrnoEFAULT     3#define Plex86ErrnoEINVAL     4#define Plex86ErrnoEACCES     5#define Plex86ErrnoEAGAIN     6#define vm_save_flags(x) \  asm volatile("pushfl ; popl %0": "=g" (x): :"memory")#define vm_restore_flags(x) \  asm volatile("pushl %0 ; popfl": :"g" (x): "memory", "cc")int      hostInitMonitor(vm_t *);unsigned hostMapMonitor(vm_t *);unsigned hostInitGuestPhyMem(vm_t *);void     hostUnallocVmPages(vm_t *);int      hostAllocVmPages(vm_t *, plex86IoctlRegisterMem_t *registerMsg);void     hostInitShadowPaging(vm_t *vm);void     hostDeviceOpen(vm_t *);unsigned hostModuleInit(void);unsigned hostGetCpuCapabilities(void);int      hostIoctlGeneric(vm_t *vm, void *inode, void *filp,                          unsigned int cmd, unsigned long arg);int      hostIoctlExecute(vm_t *vm, plex86IoctlExecute_t *executeMsg);int      hostIoctlRegisterMem(vm_t *vm, plex86IoctlRegisterMem_t *registerMsg);void     hostCopyGuestStateToUserSpace(vm_t *vm);void     hostReleasePinnedUserPages(vm_t *vm);unsigned hostHandlePagePinRequest(vm_t *vm, Bit32u reqPPI);/* These are the functions that the host-OS-specific file of the * plex86 device driver must define. */unsigned hostOSIdle(void);void    *hostOSAllocZeroedMem(unsigned long size);void     hostOSFreeMem(void *ptr);void    *hostOSAllocZeroedPage(void);void     hostOSFreePage(void *ptr);unsigned hostOSGetAllocedMemPhyPages(Bit32u *page, int max_pages, void *ptr,                                   unsigned size);Bit32u   hostOSGetAndPinUserPage(vm_t *vm, Bit32u userAddr, void **osSpecificPtr,             Bit32u *ppi, Bit32u *kernelAddr);void     hostOSUnpinUserPage(vm_t *vm, Bit32u userAddr, void *osSpecificPtr,             Bit32u ppi, Bit32u *kernelAddr, unsigned dirty);Bit32u   hostOSGetAllocedPagePhyPage(void *ptr);void     hostOSPrint(char *fmt, ...);Bit32u   hostOSKernelOffset(void);int      hostOSConvertPlex86Errno(unsigned ret);void     hostOSModuleCountReset(vm_t *vm, void *inode, void *filp);void     hostOSInstrumentIntRedirCount(unsigned interruptVector);unsigned long hostOSCopyFromUser(void *to, void *from, unsigned long len);unsigned long hostOSCopyToUser(void *to, void *from, unsigned long len);#endif  /* HOST Space */#ifdef IN_MONITOR_SPACE/* ========================================================== * These are the functions which are available to the monitor * running in the monitor/guest space. */void sysFlushPrintBuf(vm_t *);void sysRemapMonitor(vm_t *);int  monprint(vm_t *, char *fmt, ...);int  mon_vsnprintf(char *str, unsigned size, const char *fmt,                   va_list args);void resetPrintBuf(vm_t *);/* Translate from guest laddr to monitor laddr. */#define Guest2Monitor(vm, laddr) ( ((Bit32u) (laddr)) - \                                   vm->guest.addr.nexus->mon_base )void monpanic(vm_t *, char *fmt, ...) __attribute__ ((noreturn));void monpanic_nomess(vm_t *);void toHostGuestFault(vm_t *, unsigned fault);void toHostPinUserPage(vm_t *, Bit32u ppi);void guestPageFault(vm_t *, guest_context_t *context, Bit32u cr2);void *open_guest_phy_page(vm_t *, Bit32u ppage_index, Bit8u *mon_offset);void close_guest_phy_page(vm_t *, Bit32u ppage_index);#define MapLinOK              0#define MapLinMonConflict     1#define MapLinAlreadyMapped   2#define MapLinPPageOOB        3#define MapLinException       4#define MapLinEmulate         5unsigned mapGuestLinAddr(vm_t *, Bit32u guest_laddr,                         Bit32u *guest_ppage_index, unsigned us,                         unsigned rw, Bit32u attr, Bit32u *error);unsigned addPageAttributes(vm_t *, Bit32u ppi, Bit32u attr);phyPageInfo_t *getPageUsage(vm_t *, Bit32u ppage_index);void virtualize_lconstruct(vm_t *, Bit32u l0, Bit32u l1, unsigned perm);unsigned getMonPTi(vm_t *, unsigned pdi, unsigned source);#define invlpg_mon_offset(mon_offset) \  asm volatile ("invlpg (%0)": :"r" (mon_offset): "memory")/* For now nothing, but we should conditionally compile in code * to panic when the expression is not true. */#define VM_ASSERT(vm, expression) \  if ( !(expression) ) \    monpanic(vm, "Assertion (%s) failed at %s:%u", \             #expression, __FILE__, __LINE__)#define CLI() asm volatile ("cli": : : "memory")#define STI() asm volatile ("sti": : : "memory")#endif  /* MONITOR Space. */#endif  /* __MONITOR_H__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -