mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.22.1.1 (3e3e99f1o3TNE3GpOg3lVm9IdI7Z7Q)
Many files: We now have a shared read-only machine->physical mapping table at start of hypervisor virtual address region.
This commit is contained in:
1 parent
7dff07f37a
commit
5718fab870
9 files changed
+76
-21
No files matched your search
@@ -4,7 +4,7 @@
|
||||
CC := gcc
|
||||
LD := ld
|
||||
# Linker should relocate monitor to this address
|
||||
MONITOR_BASE := 0xFC100000
|
||||
MONITOR_BASE := 0xFC500000
|
||||
# Bootloader should load monitor to this real address
|
||||
LOAD_BASE := 0x00100000
|
||||
CFLAGS := -fno-builtin -O3 -Wall -DMONITOR_BASE=$(MONITOR_BASE)
|
||||
|
||||
@@ -216,13 +216,15 @@ nopaging_gdt_descr:
|
||||
.long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET
|
||||
|
||||
ALIGN
|
||||
/* NB. Rings != 0 get access up to 0xFC400000. This allows access to the */
|
||||
/* machine->physical mapping table. Ring 0 can access all memory. */
|
||||
ENTRY(gdt_table)
|
||||
.quad 0x0000000000000000 /* NULL descriptor */
|
||||
.quad 0x0000000000000000 /* not used */
|
||||
.quad 0x00cfba000000bfff /* 0x11 ring 1 3.95GB code at 0x0 */
|
||||
.quad 0x00cfb2000000bfff /* 0x19 ring 1 3.95GB data at 0x0 */
|
||||
.quad 0x00cffa000000bfff /* 0x23 ring 3 3.95GB code at 0x0 */
|
||||
.quad 0x00cff2000000bfff /* 0x2b ring 3 3.95GB data at 0x0 */
|
||||
.quad 0x00cfba000000c3ff /* 0x11 ring 1 3.95GB code at 0x0 */
|
||||
.quad 0x00cfb2000000c3ff /* 0x19 ring 1 3.95GB data at 0x0 */
|
||||
.quad 0x00cffa000000c3ff /* 0x23 ring 3 3.95GB code at 0x0 */
|
||||
.quad 0x00cff2000000c3ff /* 0x2b ring 3 3.95GB data at 0x0 */
|
||||
.quad 0x00cf9a000000ffff /* 0x30 ring 0 4.00GB code at 0x0 */
|
||||
.quad 0x00cf92000000ffff /* 0x38 ring 0 4.00GB data at 0x0 */
|
||||
.fill NR_CPUS,8,0 /* space for TSS's */
|
||||
|
||||
@@ -73,8 +73,14 @@ void __init paging_init(void)
|
||||
/* Create page table for ioremap(). */
|
||||
ioremap_pt = (void *)get_free_page(GFP_KERNEL);
|
||||
clear_page(ioremap_pt);
|
||||
idle0_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] =
|
||||
idle0_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] =
|
||||
mk_l2_pgentry(__pa(ioremap_pt) | PAGE_HYPERVISOR);
|
||||
|
||||
/* Create read-only mapping of MPT for guest-OS use. */
|
||||
idle0_pg_table[READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
|
||||
idle0_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT];
|
||||
mk_l2_readonly(idle0_pg_table +
|
||||
(READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT));
|
||||
}
|
||||
|
||||
void __init zap_low_mappings (void)
|
||||
|
||||
@@ -6,7 +6,7 @@ OUTPUT_ARCH(i386)
|
||||
ENTRY(start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0xFC000000 + 0x100000;
|
||||
. = 0xFC400000 + 0x100000;
|
||||
_text = .; /* Text and read-only data */
|
||||
.text : {
|
||||
*(.text)
|
||||
|
||||
@@ -576,6 +576,9 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
|
||||
net_ring_t *net_ring;
|
||||
net_vif_t *net_vif;
|
||||
|
||||
/* Sanity! */
|
||||
if ( p->domain != 0 ) BUG();
|
||||
|
||||
if ( strncmp(__va(mod[0].mod_start), "XenoGues", 8) )
|
||||
{
|
||||
printk("DOM%d: Invalid guest OS image\n", dom);
|
||||
@@ -622,10 +625,13 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params)
|
||||
memset(l2tab, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE*sizeof(l2_pgentry_t));
|
||||
p->mm.pagetable = mk_pagetable(phys_l2tab);
|
||||
|
||||
/* Domain 0 gets WRITE access to the read-only machine->physical table. */
|
||||
mk_l2_writeable(l2tab + (READONLY_MPT_VIRT_START >> L2_PAGETABLE_SHIFT));
|
||||
|
||||
/*
|
||||
* NB. The upper limit on this loop does one extra page + pages for frame table.
|
||||
* This is to make sure a pte exists when we want to map the shared_info struct
|
||||
* and frame table struct.
|
||||
* NB. The upper limit on this loop does one extra page + pages for frame
|
||||
* table. This is to make sure a pte exists when we want to map the
|
||||
* shared_info struct and frame table struct.
|
||||
*/
|
||||
|
||||
ft_pages = frame_table_size >> PAGE_SHIFT;
|
||||
|
||||
@@ -224,15 +224,15 @@ void __init init_frametable(unsigned long nr_pages)
|
||||
max_page = nr_pages;
|
||||
frame_table_size = nr_pages * sizeof(struct pfn_info);
|
||||
frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
free_pfns = nr_pages -
|
||||
((MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT);
|
||||
|
||||
frame_table = phys_to_virt(MAX_MONITOR_ADDRESS);
|
||||
frame_table = (frame_table_t *)FRAMETABLE_VIRT_START;
|
||||
memset(frame_table, 0, frame_table_size);
|
||||
|
||||
free_pfns = nr_pages -
|
||||
((__pa(frame_table) + frame_table_size) >> PAGE_SHIFT);
|
||||
|
||||
/* Put all domain-allocatable memory on a free list. */
|
||||
INIT_LIST_HEAD(&free_list);
|
||||
for( page_index = (MAX_MONITOR_ADDRESS + frame_table_size) >> PAGE_SHIFT;
|
||||
for( page_index = (__pa(frame_table) + frame_table_size) >> PAGE_SHIFT;
|
||||
page_index < nr_pages;
|
||||
page_index++ )
|
||||
{
|
||||
@@ -364,6 +364,12 @@ static int get_l2_table(unsigned long page_nr)
|
||||
DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
|
||||
mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR);
|
||||
|
||||
/*
|
||||
* DOM0 has the MPT mapped as WRITABLE.
|
||||
* 'p_l2_entry' happens to be pointing at the right place at this point :-)
|
||||
*/
|
||||
if ( current->domain == 0 ) mk_l2_writeable(p_l2_entry);
|
||||
|
||||
out:
|
||||
unmap_domain_mem(p_l2_entry);
|
||||
return ret;
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
|
||||
#define l1_pgentry_empty(_x) (!l1_pgentry_val(_x))
|
||||
#define l2_pgentry_empty(_x) (!l2_pgentry_val(_x))
|
||||
|
||||
#define __PAGE_OFFSET (0xFC000000)
|
||||
#define __PAGE_OFFSET (0xFC400000)
|
||||
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
|
||||
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
|
||||
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
|
||||
@@ -83,7 +83,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
|
||||
|
||||
/* High table entries are reserved by the hypervisor. */
|
||||
#define DOMAIN_ENTRIES_PER_L2_PAGETABLE \
|
||||
(PAGE_OFFSET >> L2_PAGETABLE_SHIFT)
|
||||
(HYPERVISOR_VIRT_START >> L2_PAGETABLE_SHIFT)
|
||||
#define HYPERVISOR_ENTRIES_PER_L2_PAGETABLE \
|
||||
(ENTRIES_PER_L2_PAGETABLE - DOMAIN_ENTRIES_PER_L2_PAGETABLE)
|
||||
|
||||
@@ -153,6 +153,16 @@ __asm__ __volatile__("invlpg %0": :"m" (*(char *) (__addr)))
|
||||
#define PAGE_HYPERVISOR_RO MAKE_GLOBAL(__PAGE_HYPERVISOR_RO)
|
||||
#define PAGE_HYPERVISOR_NOCACHE MAKE_GLOBAL(__PAGE_HYPERVISOR_NOCACHE)
|
||||
|
||||
#define mk_l2_writeable(_p) \
|
||||
(*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) | _PAGE_RW))
|
||||
#define mk_l2_readonly(_p) \
|
||||
(*(_p) = mk_l2_pgentry(l2_pgentry_val(*(_p)) & ~_PAGE_RW))
|
||||
#define mk_l1_writeable(_p) \
|
||||
(*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) | _PAGE_RW))
|
||||
#define mk_l1_readonly(_p) \
|
||||
(*(_p) = mk_l1_pgentry(l1_pgentry_val(*(_p)) & ~_PAGE_RW))
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
static __inline__ int get_order(unsigned long size)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
#ifndef __HYPERVISOR_IF_H__
|
||||
#define __HYPERVISOR_IF_H__
|
||||
|
||||
/* Virtual addresses beyond this are inaccessible by guest OSes. */
|
||||
/*
|
||||
* Virtual addresses beyond this are not modifiable by guest OSes.
|
||||
* The machine->physical mapping table starts at this address, read-only
|
||||
* to all domains except DOM0.
|
||||
*/
|
||||
#define HYPERVISOR_VIRT_START (0xFC000000UL)
|
||||
|
||||
typedef struct trap_info_st
|
||||
|
||||
@@ -41,12 +41,33 @@
|
||||
#define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
|
||||
#define ____cacheline_aligned __cacheline_aligned
|
||||
|
||||
/* 0-16MB is fixed monitor space. 0-52MB is direct-mapped at top of memory.*/
|
||||
/*** Hypervisor owns top 64MB of virtual address space. ***/
|
||||
#define HYPERVISOR_VIRT_START (0xFC000000UL)
|
||||
|
||||
/*
|
||||
* First 4MB are mapped read-only for all. It's for the machine->physical
|
||||
* mapping table (MPT table). The following are virtual addresses.
|
||||
*/
|
||||
#define READONLY_MPT_VIRT_START (HYPERVISOR_VIRT_START)
|
||||
#define READONLY_MPT_VIRT_END (READONLY_MPT_VIRT_START + (4*1024*1024))
|
||||
/*
|
||||
* Next 16MB is fixed monitor space, which is part of a 48MB direct-mapped
|
||||
* memory region. The following are machine addresses.
|
||||
*/
|
||||
#define MAX_MONITOR_ADDRESS (16*1024*1024)
|
||||
#define MAX_DMA_ADDRESS (16*1024*1024)
|
||||
#define MAX_DIRECTMAP_ADDRESS (52*1024*1024)
|
||||
#define MAX_DIRECTMAP_ADDRESS (48*1024*1024)
|
||||
/* And the virtual addresses for the direct-map region... */
|
||||
#define DIRECTMAP_VIRT_START (READONLY_MPT_VIRT_END)
|
||||
#define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
|
||||
#define MONITOR_VIRT_START (DIRECTMAP_VIRT_START)
|
||||
#define MONITOR_VIRT_END (MONITOR_VIRT_START + MAX_MONITOR_ADDRESS)
|
||||
#define RDWR_MPT_VIRT_START (MONITOR_VIRT_END)
|
||||
#define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + (4*1024*1024))
|
||||
#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
|
||||
#define FRAMETABLE_VIRT_END (DIRECTMAP_VIRT_END)
|
||||
/* Next 4MB of virtual address space used for per-domain mappings (eg. GDT). */
|
||||
#define PERDOMAIN_VIRT_START (PAGE_OFFSET + MAX_DIRECTMAP_ADDRESS)
|
||||
#define PERDOMAIN_VIRT_START (DIRECTMAP_VIRT_END)
|
||||
#define PERDOMAIN_VIRT_END (PERDOMAIN_VIRT_START + (4*1024*1024))
|
||||
/* Penultimate 4MB of virtual address space used for domain page mappings. */
|
||||
#define MAPCACHE_VIRT_START (PERDOMAIN_VIRT_END)
|
||||
|
||||