mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.1159.1.129 (413d868bPMWkW0lZg_MuAYIrmx7XDQ)
Make writable pagetables a domain creation option.
This commit is contained in:
1 parent
d8fb4ece8d
commit
8be47dac0f
10 files changed
+80
-60
No files matched your search
@@ -1,9 +1,15 @@
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
.section __xen_guest
|
||||
.asciz "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0"
|
||||
.ascii "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0"
|
||||
.ascii ",LOADER=generic"
|
||||
#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
|
||||
.ascii ",PT_MODE_WRITABLE"
|
||||
#endif
|
||||
.byte 0
|
||||
|
||||
.text
|
||||
#include <linux/config.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/segment.h>
|
||||
|
||||
@@ -1295,10 +1295,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable,
|
||||
VMASST_TYPE_4gb_segments);
|
||||
#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable,
|
||||
VMASST_TYPE_writable_pagetables);
|
||||
#endif
|
||||
|
||||
pm_idle = xen_cpu_idle;
|
||||
|
||||
|
||||
+24
-22
@@ -557,10 +557,7 @@ int construct_dom0(struct domain *p,
|
||||
* *_start address are page-aligned, except v_start (and v_end) which are
|
||||
* superpage-aligned.
|
||||
*/
|
||||
unsigned long v_start;
|
||||
unsigned long vkern_start;
|
||||
unsigned long vkern_entry;
|
||||
unsigned long vkern_end;
|
||||
struct domain_setup_info dsi;
|
||||
unsigned long vinitrd_start;
|
||||
unsigned long vinitrd_end;
|
||||
unsigned long vphysmap_start;
|
||||
@@ -584,6 +581,8 @@ int construct_dom0(struct domain *p,
|
||||
if ( test_bit(DF_CONSTRUCTED, &p->flags) )
|
||||
BUG();
|
||||
|
||||
memset(&dsi, 0, sizeof(struct domain_setup_info));
|
||||
|
||||
printk("*** LOADING DOMAIN 0 ***\n");
|
||||
|
||||
/*
|
||||
@@ -598,12 +597,11 @@ int construct_dom0(struct domain *p,
|
||||
* We'll have to revisit this if we ever support PAE (64GB).
|
||||
*/
|
||||
|
||||
rc = parseelfimage(image_start, image_len, &v_start,
|
||||
&vkern_start, &vkern_end, &vkern_entry);
|
||||
rc = parseelfimage(image_start, image_len, &dsi);
|
||||
if ( rc != 0 )
|
||||
return rc;
|
||||
|
||||
if ( (v_start & (PAGE_SIZE-1)) != 0 )
|
||||
if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
|
||||
{
|
||||
printk("Initial guest OS must load to a page boundary.\n");
|
||||
return -EINVAL;
|
||||
@@ -618,7 +616,7 @@ int construct_dom0(struct domain *p,
|
||||
*/
|
||||
for ( nr_pt_pages = 2; ; nr_pt_pages++ )
|
||||
{
|
||||
vinitrd_start = round_pgup(vkern_end);
|
||||
vinitrd_start = round_pgup(dsi.v_kernend);
|
||||
vinitrd_end = vinitrd_start + initrd_len;
|
||||
vphysmap_start = round_pgup(vinitrd_end);
|
||||
vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long));
|
||||
@@ -631,7 +629,7 @@ int construct_dom0(struct domain *p,
|
||||
v_end = (vstack_end + (1<<22)-1) & ~((1<<22)-1);
|
||||
if ( (v_end - vstack_end) < (512 << 10) )
|
||||
v_end += 1 << 22; /* Add extra 4MB to get >= 512kB padding. */
|
||||
if ( (((v_end - v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >>
|
||||
if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >>
|
||||
L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
|
||||
break;
|
||||
}
|
||||
@@ -651,20 +649,20 @@ int construct_dom0(struct domain *p,
|
||||
" Start info: %08lx->%08lx\n"
|
||||
" Boot stack: %08lx->%08lx\n"
|
||||
" TOTAL: %08lx->%08lx\n",
|
||||
vkern_start, vkern_end,
|
||||
dsi.v_kernstart, dsi.v_kernend,
|
||||
vinitrd_start, vinitrd_end,
|
||||
vphysmap_start, vphysmap_end,
|
||||
vpt_start, vpt_end,
|
||||
vstartinfo_start, vstartinfo_end,
|
||||
vstack_start, vstack_end,
|
||||
v_start, v_end);
|
||||
printk(" ENTRY ADDRESS: %08lx\n", vkern_entry);
|
||||
dsi.v_start, v_end);
|
||||
printk(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
|
||||
|
||||
if ( (v_end - v_start) > (nr_pages * PAGE_SIZE) )
|
||||
if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
|
||||
{
|
||||
printk("Initial guest OS requires too much space\n"
|
||||
"(%luMB is greater than %luMB limit)\n",
|
||||
(v_end-v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
|
||||
(v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -672,7 +670,7 @@ int construct_dom0(struct domain *p,
|
||||
* Protect the lowest 1GB of memory. We use a temporary mapping there
|
||||
* from which we copy the kernel and ramdisk images.
|
||||
*/
|
||||
if ( v_start < (1<<30) )
|
||||
if ( dsi.v_start < (1<<30) )
|
||||
{
|
||||
printk("Initial loading isn't allowed to lowest 1GB of memory.\n");
|
||||
return -EINVAL;
|
||||
@@ -691,7 +689,7 @@ int construct_dom0(struct domain *p,
|
||||
p->tot_pages++; p->max_pages++;
|
||||
}
|
||||
|
||||
mpt_alloc = (vpt_start - v_start) + alloc_start;
|
||||
mpt_alloc = (vpt_start - dsi.v_start) + alloc_start;
|
||||
|
||||
SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
|
||||
SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
|
||||
@@ -715,9 +713,9 @@ int construct_dom0(struct domain *p,
|
||||
mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR);
|
||||
p->mm.pagetable = mk_pagetable((unsigned long)l2start);
|
||||
|
||||
l2tab += l2_table_offset(v_start);
|
||||
l2tab += l2_table_offset(dsi.v_start);
|
||||
mfn = alloc_start >> PAGE_SHIFT;
|
||||
for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
|
||||
for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
|
||||
{
|
||||
if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
@@ -726,7 +724,7 @@ int construct_dom0(struct domain *p,
|
||||
*l2tab++ = mk_l2_pgentry((unsigned long)l1start | L2_PROT);
|
||||
clear_page(l1tab);
|
||||
if ( count == 0 )
|
||||
l1tab += l1_table_offset(v_start);
|
||||
l1tab += l1_table_offset(dsi.v_start);
|
||||
}
|
||||
*l1tab++ = mk_l1_pgentry((mfn << PAGE_SHIFT) | L1_PROT);
|
||||
|
||||
@@ -762,7 +760,7 @@ int construct_dom0(struct domain *p,
|
||||
page->u.inuse.type_info &= ~PGT_type_mask;
|
||||
page->u.inuse.type_info |= PGT_l1_page_table;
|
||||
page->u.inuse.type_info |=
|
||||
((v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift;
|
||||
((dsi.v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift;
|
||||
|
||||
get_page(page, p); /* an extra ref because of readable mapping */
|
||||
}
|
||||
@@ -771,6 +769,10 @@ int construct_dom0(struct domain *p,
|
||||
l1start = l1tab = (l1_pgentry_t *)l2_pgentry_to_phys(*l2tab);
|
||||
}
|
||||
|
||||
/* Set up domain options */
|
||||
if (dsi.use_writable_pagetables)
|
||||
vm_assist(p, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
|
||||
|
||||
/* Set up shared-info area. */
|
||||
update_dom_time(p->shared_info);
|
||||
p->shared_info->domain_time = 0;
|
||||
@@ -804,7 +806,7 @@ int construct_dom0(struct domain *p,
|
||||
{
|
||||
mfn = pfn + (alloc_start>>PAGE_SHIFT);
|
||||
#ifndef NDEBUG
|
||||
#define REVERSE_START ((v_end - v_start) >> PAGE_SHIFT)
|
||||
#define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT)
|
||||
if ( pfn > REVERSE_START )
|
||||
mfn = (alloc_end>>PAGE_SHIFT) - (pfn - REVERSE_START);
|
||||
#endif
|
||||
@@ -854,7 +856,7 @@ int construct_dom0(struct domain *p,
|
||||
shadow_mode_enable(&p->mm, SHM_test);
|
||||
#endif
|
||||
|
||||
new_thread(p, vkern_entry, vstack_end, vstartinfo_start);
|
||||
new_thread(p, dsi.v_kernentry, vstack_end, vstartinfo_start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -308,3 +308,25 @@ int final_setup_guestos(struct domain *p, dom0_builddomain_t *builddomain)
|
||||
xfree(c);
|
||||
return rc;
|
||||
}
|
||||
|
||||
long vm_assist(struct domain *p, unsigned int cmd, unsigned int type)
|
||||
{
|
||||
if ( type > MAX_VMASST_TYPE )
|
||||
return -EINVAL;
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
case VMASST_CMD_enable:
|
||||
set_bit(type, &p->vm_assist);
|
||||
if (vm_assist_info[type].enable)
|
||||
(*vm_assist_info[type].enable)(p);
|
||||
return 0;
|
||||
case VMASST_CMD_disable:
|
||||
clear_bit(type, &p->vm_assist);
|
||||
if (vm_assist_info[type].disable)
|
||||
(*vm_assist_info[type].disable)(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
+9
-9
@@ -18,10 +18,7 @@ static inline int is_loadable_phdr(Elf_Phdr *phdr)
|
||||
|
||||
int parseelfimage(char *elfbase,
|
||||
unsigned long elfsize,
|
||||
unsigned long *pvirtstart,
|
||||
unsigned long *pkernstart,
|
||||
unsigned long *pkernend,
|
||||
unsigned long *pkernentry)
|
||||
struct domain_setup_info *dsi)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
|
||||
Elf_Phdr *phdr;
|
||||
@@ -109,13 +106,16 @@ int parseelfimage(char *elfbase,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*pvirtstart = kernstart;
|
||||
dsi->v_start = kernstart;
|
||||
if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
|
||||
*pvirtstart = simple_strtoul(p+10, &p, 0);
|
||||
dsi->v_start = simple_strtoul(p+10, &p, 0);
|
||||
|
||||
*pkernstart = kernstart;
|
||||
*pkernend = kernend;
|
||||
*pkernentry = ehdr->e_entry;
|
||||
if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
|
||||
dsi->use_writable_pagetables = 1;
|
||||
|
||||
dsi->v_kernstart = kernstart;
|
||||
dsi->v_kernend = kernend;
|
||||
dsi->v_kernentry = ehdr->e_entry;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-18
@@ -365,24 +365,7 @@ long do_xen_version(int cmd)
|
||||
|
||||
long do_vm_assist(unsigned int cmd, unsigned int type)
|
||||
{
|
||||
if ( type > MAX_VMASST_TYPE )
|
||||
return -EINVAL;
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
case VMASST_CMD_enable:
|
||||
set_bit(type, ¤t->vm_assist);
|
||||
if (vm_assist_info[type].enable)
|
||||
(*vm_assist_info[type].enable)();
|
||||
return 0;
|
||||
case VMASST_CMD_disable:
|
||||
clear_bit(type, ¤t->vm_assist);
|
||||
if (vm_assist_info[type].disable)
|
||||
(*vm_assist_info[type].disable)();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOSYS;
|
||||
return vm_assist(current, cmd, type);
|
||||
}
|
||||
|
||||
long do_ni_hypercall(void)
|
||||
|
||||
@@ -363,8 +363,8 @@ int memguard_is_guarded(void *p);
|
||||
|
||||
|
||||
typedef struct {
|
||||
void (*enable)(void);
|
||||
void (*disable)(void);
|
||||
void (*enable)(struct domain *);
|
||||
void (*disable)(struct domain *);
|
||||
} vm_assist_info_t;
|
||||
extern vm_assist_info_t vm_assist_info[];
|
||||
|
||||
|
||||
@@ -525,8 +525,6 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
extern int loadelfimage(char *);
|
||||
extern int parseelfimage(
|
||||
char *, unsigned long, unsigned long *,
|
||||
unsigned long *, unsigned long *, unsigned long *);
|
||||
extern int parseelfimage(char *, unsigned long, struct domain_setup_info *);
|
||||
|
||||
#endif /* __XEN_ELF_H__ */
|
||||
@@ -14,10 +14,13 @@
|
||||
#define reserve_bootmem(_p,_l) \
|
||||
printk("Memory Reservation 0x%lx, %lu bytes\n", (_p), (_l))
|
||||
|
||||
struct domain;
|
||||
|
||||
/* kernel.c */
|
||||
#define printk printf
|
||||
void printf(const char *format, ...);
|
||||
void panic(const char *format, ...);
|
||||
long vm_assist(struct domain *, unsigned int, unsigned int);
|
||||
|
||||
/* vsprintf.c */
|
||||
extern int sprintf(char * buf, const char * fmt, ...)
|
||||
|
||||
@@ -146,6 +146,16 @@ struct domain
|
||||
atomic_t pausecnt;
|
||||
};
|
||||
|
||||
struct domain_setup_info
|
||||
{
|
||||
unsigned long v_start;
|
||||
unsigned long v_kernstart;
|
||||
unsigned long v_kernend;
|
||||
unsigned long v_kernentry;
|
||||
|
||||
unsigned int use_writable_pagetables;
|
||||
};
|
||||
|
||||
#include <asm/uaccess.h> /* for KERNEL_DS */
|
||||
|
||||
extern struct domain idle0_task;
|
||||
|
||||