📄 monitor.h
字号:
/* * plex86: run multiple x86 operating systems concurrently * Copyright (C) 1999-2003 Kevin P. Lawton * * monitor.h: main VM monitor defines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#ifndef __MONITOR_H__#define __MONITOR_H__#if defined(__NetBSD__) || defined(__FreeBSD__)#include <machine/stdarg.h>#else#include <stdarg.h>#endif#include "descriptor.h"#include "descriptor2.h"#include "tss.h"#include "paging.h"#include "eflags.h"#include "guest_context.h"#ifndef UNUSED# define UNUSED(x) ((void)(x))#endif/* Method1: push event info (CPU pushes error code before) */typedef struct { Bit8u pushl; /* Always 0x68 == pushl */ Bit32u vector; /* Interrupt vector number */ Bit8u jmp; /* Always 0xe9 == jmp */ Bit32u reloc; /* Relative offset of destination */} __attribute__ ((packed)) idt_method1_t;/* Method2: push a dummy error first, then event info */typedef struct { Bit8u pushla; /* Always 0x68 == pushl */ Bit32u dummy; /* Dummy error code */ Bit8u pushlb; /* Always 0x68 == pushl */ Bit32u vector; /* Interrupt vector number */ Bit8u jmp; /* Always 0xe9 == jmp */ Bit32u reloc; /* Relative offset of destination */} __attribute__ ((packed)) idt_method2_t;typedef union { idt_method1_t m1; idt_method2_t m2;} idt_stub_t;/* Nexus fields. This C structure maps to identical assembly *//* fields in nexus.S. Make sure to update both! These fields *//* are accessible to the nexus code during the transition from *//* host<->guest and are stored in a single page. */typedef struct { /* guest pointer to vm_t structure. */ void *vm; /* These fields are only used by the transition code. */ /* They hold all info necessary to switch back to the host. */ gdt_info_t host_gdt_info; gdt_info_t host_idt_info; far_jmp_info_t host_jmp_info; far_jmp_info_t host_stack_info; Bit16u host_ldt_sel; Bit16u host_tss_sel; Bit32u host_cr0; Bit32u host_cr2; Bit32u host_cr3; Bit32u host_cr4; /* These fields are filled by the host-side code, and used */ /* by the transition code. They contain all info necessary */ /* to switch to the monitor/guest address space. */ /* This info changes whenever the monitor migrates. */ gdt_info_t mon_gdt_info; gdt_info_t mon_idt_info; far_jmp_info_t mon_jmp_info; far_jmp_info_t mon_stack_info; Bit16u mon_ldt_sel; Bit16u mon_tss_sel; Bit32u mon_base; Bit32u mon_cr0; Bit32u mon_cr3; Bit32u mon_cr4; Bit32u mon_eflags; /* These fields contain info used by the transition code to */ /* create the temporary identity mapping. They never change. */ pageEntry_t transition_pde; pageEntry_t *transition_pde_p_host; pageEntry_t *transition_pde_p_mon; Bit32u transition_laddr;} __attribute__ ((packed)) nexus_t;/* For reference, the following describes where bits from the guest *//* eflags register are stored/managed. *//* *//* Key: *//* g: Flag value as requested by guest *//* V: Virtualized flag value, as loaded in eflags when guest is executing *//* ?: Unhandled yet, request of set bit causes panic for now *//* *//* === ======= ====== ======= ======= ======= *//* |I|V|V|A|V|R|0|N|IO|O|D|I|T|S|Z|0|A|0|P|1|C| flag *//* |D|I|I|C|M|F| |T|PL|F|F|F|F|F|F| |F| |F| |F| *//* | |P|F| | | | | | | | | | | | | | | | | | | *//* |g|?|?|g|V|g|g|g|VV|g|g|V|g|g|g|g|g|g|g|g|g| context->eflags *//* | |?|?| |g| | | |gg| | |g| | | | | | | | | | veflags *//* #define VirtualizedEflags 0x001a3200 */#define VirtualizedEflags 0x001a3300/* I define the 'nexus' as the set of data structures which *//* must exist in the current linear guest address space. The *//* host linear address space is not available while the current *//* guest code is running, since we are using a completely *//* different set of page mappings for the guest. However, *//* at some point an exception/interrupt will occur. The *//* interrupt mechanisms require that several structures exist in *//* the current linear address space in order to service such *//* an event. These data structures make up part of our VM, *//* a thin layer which exists in the guest. Following is a *//* list of what data structures compose this 'nexus': *//* *//* - IDT (max 2048 bytes) *//* - GDT (max 65536 bytes) *//* - LDT (max 65536 bytes) *//* - TSS (max 8328 = 104 + 32 int redir + 8192 I/O permissions) *//* - kernel stack page *//* - transition code (host <--> guest) *//* - interrupt handler stubs *//* - Page Tables; PDE & PTE pages. *//* * Sizes of various nexus data structures used by the monitor */#define PLEX86_MAX_PHY_MEGS 32#define PAGESIZE 4096#define IDT_STUB_SIZE 15#define BytesToPages(b) ( ((b)+4095) >> 12 )#define MON_IDT_SIZE (8*256)#define MON_GDT_SIZE (8*512)#define MON_LDT_SIZE (8*1)#define MON_IDT_STUBS_SIZE (IDT_STUB_SIZE*256)#define MON_TSS_SIZE (104)#define MON_IDT_PAGES BytesToPages(MON_IDT_SIZE)#define MON_GDT_PAGES BytesToPages(MON_GDT_SIZE)#define MON_LDT_PAGES BytesToPages(MON_LDT_SIZE)#define MON_IDT_STUBS_PAGES BytesToPages(MON_IDT_STUBS_SIZE)#define MON_TSS_PAGES BytesToPages(MON_TSS_SIZE)#define MAX_MON_GUEST_PAGES (PLEX86_MAX_PHY_MEGS * 256)/* +++ MON_PAGE_TABLES is kind of random */#define MON_PAGE_TABLES (10*((PLEX86_MAX_PHY_MEGS+3) >> 2))#define MAX_VM_STRUCT_PAGES (68)#define LOG_BUFF_PAGES 1#define LOG_BUFF_SIZE ((LOG_BUFF_PAGES)*4096)/* * Pages allocated for the VM by the host kernel driver. * N Megs of physical memory are allocated, per the user's * request, for the guest OS/application code. * Additionally, some other overhead pages are allocated * for structures such as the page directory, page tables, * and other virtualized facilities. */typedef struct { /* requested size of the guest[] array in megs and pages */ unsigned guest_n_megs; unsigned guest_n_pages; unsigned guest_n_bytes; /* pages comprising the vm_t struct itself. */ Bit32u vm[MAX_VM_STRUCT_PAGES]; /* for the monitor's page directory */ Bit32u page_dir; /* for the monitor's page table */ Bit32u page_tbl[MON_PAGE_TABLES]; /* Map of the linear addresses of page tables currently */ /* mapped into the monitor space. */ Bit32u page_tbl_laddr_map; /* for the extra page table that maps our nexus code and structures */ Bit32u nexus_page_tbl; /* For the CPU state passed between user and kernel/monitor space. */ Bit32u guest_cpu; void *guest_cpu_hostOSPtr; /* We need a Page Table for identity mapping the transition code */ /* between host and monitor spaces. */ Bit32u transition_PT; Bit32u log_buffer[LOG_BUFF_PAGES]; void *log_buffer_hostOSPtr[LOG_BUFF_PAGES]; /* Physical addresses of host pages which comprise the actual */ /* monitor structures. These will be mapped into the current */ /* guest task's linear address space as well. */ Bit32u nexus; Bit32u idt[MON_IDT_PAGES]; Bit32u gdt[MON_GDT_PAGES]; Bit32u ldt[MON_LDT_PAGES]; Bit32u tss[MON_TSS_PAGES]; Bit32u idt_stubs[MON_IDT_STUBS_PAGES]; } vm_pages_t;typedef struct { pageEntry_t *page_dir; page_t *page_tbl; unsigned *page_tbl_laddr_map; page_t *nexus_page_tbl; guest_cpu_t *guest_cpu; page_t *transition_PT; unsigned char *log_buffer; Bit8u *code_phy_page; /* only use in mon space */ Bit8u *tmp_phy_page0; /* only use in mon space */ Bit8u *tmp_phy_page1; /* only use in mon space */ nexus_t *nexus; /* Pointer into the monitor stack, so we can easily retrieve the */ /* stack snapshot upon interrupt/exception. */ guest_context_t *guest_context; gate_t *idt; descriptor_t *gdt; descriptor_t *ldt; tss_t *tss; idt_stub_t *idt_stubs; } vm_addr_t;/* These bits define the possible usage and attributes assigned *//* to a particular guest physical page. These are useful for keeping *//* track of what kinds of system structures are contained in a page *//* at a given time, and if the page has associated cached code *//* information in the prescan logic. We can also tag particular *//* pages with other more static attributes. */typedef union { struct { Bit32u access_perm:2; /* */ Bit32u lmap_count:2; /* */ Bit32u ptbl:1; /* page table */ Bit32u pdir:1; /* page directory */ Bit32u spare0:1; /* (spare) */ Bit32u memMapIO:1; /* MemMapIO */ Bit32u RO:1; /* RO */ Bit32u allocated:1; /* Allocated */ Bit32u pinned:1; /* Pinned by host OS. */ Bit32u spare1:1; /* (spare) */ Bit32u laddr_backlink:20; /* 1st unvirtualized laddr backlink */ } __attribute__ ((packed)) fields; Bit32u raw; } __attribute__ ((packed)) phy_page_attr_t;typedef struct { phy_page_attr_t attr; Bit64u tsc; /* for comparing to CR3 timestamp counter */ Bit32u hostPPI; } __attribute__ ((packed)) phyPageInfo_t;/* Possible values of the access_perm field above. */#define PagePermRW 0#define PagePermRO 1#define PagePermEmulate 2#define PagePermNA PagePermEmulate /* No Access is synomym *//* Bitmasks to access fields in structure above. */#define PageUsagePTbl 0x010#define PageUsagePDir 0x020#define PageUsageMemMapIO 0x080#define PageUsageRO 0x100#define PageUsageAllocated 0x200#define PageUsageSwappable 0x400/* Group of attributes which retain their value, even when CR3 *//* is reloaded and the page mappings are flushed. */#define PageUsageSticky \ ( PageUsageMemMapIO | PageUsageRO | \ PageUsageAllocated | PageUsageSwappable )/* Group of attributes which are not compatible with a Page Table *//* occupying a physical page. */#define PageBadUsage4PTbl \ ( PageUsagePDir | PageUsageMemMapIO | PageUsageRO )/* Group of attributes which are not compatible with a Page Directory *//* occupying a physical page. Keep in mind, when the PDir is marked, *//* no other dynamic bits will be set. */#define PageBadUsage4PDir \ ( PageUsageMemMapIO | PageUsageRO )#define PageUsageCausesNA \ ( PageUsagePTbl | PageUsagePDir | PageUsageMemMapIO )#define PageUsageCausesRO \ ( PageUsageRO )#define PDEUnhandled 0x000001d8#define PTEUnhandled 0x00000198#define ExceptionDE 0 /* Divide Error (fault) */#define ExceptionDB 1 /* Debug (fault/trap) */#define ExceptionBP 3 /* Breakpoint (trap) */#define ExceptionOF 4 /* Overflow (trap) */#define ExceptionBR 5 /* BOUND (fault) */#define ExceptionUD 6#define ExceptionNM 7#define ExceptionDF 8#define ExceptionTS 10#define ExceptionNP 11#define ExceptionSS 12#define ExceptionGP 13#define ExceptionPF 14#define ExceptionMF 16#define ExceptionAC 17
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -