mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
bitkeeper revision 1.284 (3f094675ELP7S7P0f1aKb_RV95PM4Q)
Merge steve/keir changes
This commit is contained in:
commit
ae33b65c00
29 files changed
+170
-1198
No files matched your search
@@ -105,17 +105,6 @@
|
||||
3ec41f7ek1RffqN2yRUzSTkD5m1J6w tools/control/web/tmpl/xenohead.def
|
||||
3ec41f7e1ZpfCsgQ2qRJBooBn_iRtA tools/control/web/tmpl/xenostyle.css
|
||||
3eb781fc6vgq5yhkJRGDLY9gWWRY2A tools/control/xenctl
|
||||
3e4d00468-FN2VDeEHo96zxrMHK_mA tools/domain_builder/Makefile
|
||||
3e4d0046SPau_y0sw2WLJz8QkqNoRA tools/domain_builder/README
|
||||
3e4d0046bbdH0GsI9J_1Eb4ZQHfIiQ tools/domain_builder/dom0_defs.h
|
||||
3ee609abdxnu1GvbtXnPlMfEkTEIwQ tools/domain_builder/dom0_ops.h
|
||||
3e4d0046ouLij_CMN_j7-dUHZIBI_A tools/domain_builder/dom_builder.c
|
||||
3e4d0046EKs06fY0CWDEgZQcn7DYUg tools/domain_builder/dom_kill.c
|
||||
3e4d0046aPbGiRTtdWxqY5b3ytWurA tools/domain_builder/hypervisor_defs.h
|
||||
3e4d00468aE86IfyjfrJwYoxzM7pAw tools/domain_builder/mem_defs.h
|
||||
3e71afadoAI0VvAGKebLpToVQxUKfQ tools/domain_builder/mynewdom
|
||||
3e4d0046VHhXwFuG5FK34AVxqd5A_A tools/domain_builder/newdom
|
||||
3e4d0046IBzDIeaMbQB-e2QB2ahbig tools/domain_builder/vifinit
|
||||
3eb781fdl4lXWYZzmqDDUAYhAThRqQ tools/internal/Makefile
|
||||
3eb781fdc539MQQm47rYRCCR3N5i-Q tools/internal/dom0_defs.h
|
||||
3ee609b3Yr4aggmLSKmhiIzT8-nURA tools/internal/dom0_ops.h
|
||||
|
||||
@@ -21,7 +21,6 @@ all:
|
||||
$(MAKE) -C xen
|
||||
$(MAKE) -C tools/balloon
|
||||
$(MAKE) -C tools/control
|
||||
$(MAKE) -C tools/domain_builder
|
||||
$(MAKE) -C tools/internal
|
||||
$(MAKE) -C tools/vdmanager
|
||||
|
||||
@@ -29,7 +28,6 @@ install: all
|
||||
$(MAKE) -C xen install
|
||||
$(MAKE) -C tools/balloon install
|
||||
$(MAKE) -C tools/control install
|
||||
$(MAKE) -C tools/domain_builder install
|
||||
$(MAKE) -C tools/internal install
|
||||
$(MAKE) -C tools/vdmanager install
|
||||
|
||||
@@ -38,7 +36,6 @@ clean:
|
||||
$(MAKE) -C xen clean
|
||||
$(MAKE) -C tools/balloon clean
|
||||
$(MAKE) -C tools/control clean
|
||||
$(MAKE) -C tools/domain_builder clean
|
||||
$(MAKE) -C tools/internal clean
|
||||
$(MAKE) -C tools/vdmanager clean
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
CC = gcc
|
||||
BUILDER = domain_builder
|
||||
KILL = kill_domain
|
||||
|
||||
all: dom_builder.o dom_kill.o
|
||||
$(CC) -o $(BUILDER) dom_builder.o
|
||||
$(CC) -o $(KILL) dom_kill.o
|
||||
|
||||
install: all
|
||||
cp domain_builder kill_domain ../../../install/bin
|
||||
|
||||
dom_builder.o: dom_builder.c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
|
||||
$(CC) -c dom_builder.c
|
||||
|
||||
dom_kill.o: dom_kill.c dom0_ops.h dom0_defs.h
|
||||
$(CC) -c dom_kill.c
|
||||
|
||||
clean:
|
||||
$(RM) *.o domain_builder kill_domain
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
A couple of simple steps to get you going:
|
||||
|
||||
1. do make (suitable Makefile is in the source dir)
|
||||
2. copy over andy's vifinit script to local dir
|
||||
3. copy over xenolinux guestos image (NB. image needs to be uncompressed, so
|
||||
if the only image you have is image.gz do gunzip image.gz before doing
|
||||
anything further)
|
||||
4. add executable permissions to newdom and vifint
|
||||
5. edit newdom script and change it as it suits you
|
||||
|
||||
newdom script takes guestos image file name as first parameter and newdom id
|
||||
as second parameter, eg.:
|
||||
|
||||
./newdom xenolinux 1
|
||||
|
||||
should initiate building of dom1 with the image contained in file named
|
||||
xenolinux in local dir.
|
||||
|
||||
in general, domain_builder application takes three parameters: requested
|
||||
memory in kb, guestos image file name and number of vifs to be created, eg.
|
||||
|
||||
./domain_builder 16000 xenolinux 1
|
||||
|
||||
would build domX reserving 16MB mem, creating 1 vif and using os image stored
|
||||
as xenolinux in local dir.
|
||||
|
||||
happy booting!
|
||||
|
||||
boris
|
||||
@@ -1,8 +0,0 @@
|
||||
#define PROC_XENO_ROOT "xeno"
|
||||
#define PROC_CMD "dom0_cmd"
|
||||
#define PROC_DOM_PREFIX "dom"
|
||||
#define PROC_DOM_MEM "mem"
|
||||
#define PROC_DOM_DATA "new_dom_data"
|
||||
|
||||
#define MAX_PATH 256
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
#define NO_DOM0_OP_T
|
||||
#include "../../xen/include/hypervisor-ifs/dom0_ops.h"
|
||||
#undef NO_DOM0_OP_T
|
||||
#include "../../xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h"
|
||||
@@ -1,559 +0,0 @@
|
||||
/*
|
||||
* XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk
|
||||
* This code is released under terms and conditions of GNU GPL :).
|
||||
* Usage: <executable> <mem_kb> <os image> <num_vifs>
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hypervisor_defs.h"
|
||||
#include "dom0_ops.h"
|
||||
#include "dom0_defs.h"
|
||||
#include "mem_defs.h"
|
||||
|
||||
#define PERR_STRING "Xeno Domain Builder"
|
||||
|
||||
#define GUEST_SIG "XenoGues"
|
||||
#define SIG_LEN 8
|
||||
|
||||
/*
|
||||
* NB. No ring-3 access in initial guestOS pagetables. Note that we allow
|
||||
* ring-3 privileges in the page directories, so that the guestOS may later
|
||||
* decide to share a 4MB region with applications.
|
||||
*/
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
|
||||
|
||||
/* standardized error reporting function */
|
||||
static void dberr(char *msg)
|
||||
{
|
||||
printf("%s: %s\n", PERR_STRING, msg);
|
||||
}
|
||||
|
||||
/* status reporting function */
|
||||
static void dbstatus(char * msg)
|
||||
{
|
||||
printf("Domain Builder: %s\n", msg);
|
||||
}
|
||||
|
||||
static int do_kill_domain(int dom_id, int force)
|
||||
{
|
||||
char cmd_path[MAX_PATH];
|
||||
dom0_op_t dop;
|
||||
int cmd_fd;
|
||||
|
||||
dop.cmd = DOM0_DESTROYDOMAIN;
|
||||
dop.u.killdomain.domain = dom_id;
|
||||
dop.u.killdomain.force = force;
|
||||
|
||||
/* open the /proc command interface */
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
cmd_fd = open(cmd_path, O_WRONLY);
|
||||
if(cmd_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
close(cmd_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clean up domain's memory allocations */
|
||||
static void dom_mem_cleanup(dom_mem_t * dom_mem)
|
||||
{
|
||||
char mem_path[MAX_PATH];
|
||||
int mem_fd;
|
||||
|
||||
/* open the domain's /proc mem interface */
|
||||
sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/",
|
||||
PROC_DOM_PREFIX, dom_mem->domain, "/", PROC_DOM_MEM);
|
||||
|
||||
mem_fd = open(mem_path, O_WRONLY);
|
||||
if(mem_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
}
|
||||
|
||||
if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){
|
||||
dbstatus("Error unmapping domain's memory.\n");
|
||||
}
|
||||
|
||||
close(mem_fd);
|
||||
}
|
||||
|
||||
/* ask dom0 to export domains memory through /proc */
|
||||
static int setup_dom_memmap(unsigned long pfn, int pages, int dom)
|
||||
{
|
||||
char cmd_path[MAX_PATH];
|
||||
dom0_op_t dop;
|
||||
int cmd_fd;
|
||||
|
||||
dop.cmd = MAP_DOM_MEM;
|
||||
dop.u.dommem.start_pfn = pfn;
|
||||
dop.u.dommem.tot_pages = pages;
|
||||
dop.u.dommem.domain = dom;
|
||||
|
||||
/* open the /proc command interface */
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
cmd_fd = open(cmd_path, O_WRONLY);
|
||||
if(cmd_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
close(cmd_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* request the actual mapping from dom0 */
|
||||
static unsigned long get_vaddr(unsigned int dom)
|
||||
{
|
||||
char mem_path[MAX_PATH];
|
||||
unsigned long addr;
|
||||
int mem_fd;
|
||||
|
||||
/* open the domain's /proc mem interface */
|
||||
sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/",
|
||||
PROC_DOM_PREFIX, dom, "/", PROC_DOM_MEM);
|
||||
|
||||
mem_fd = open(mem_path, O_RDONLY);
|
||||
if(mem_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get virtual address of mapped region */
|
||||
read(mem_fd, &addr, sizeof(addr));
|
||||
|
||||
close(mem_fd);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int map_dom_mem(unsigned long pfn, int pages, int dom,
|
||||
dom_mem_t * dom_mem)
|
||||
{
|
||||
|
||||
if(setup_dom_memmap(pfn, pages, dom)){
|
||||
perror(PERR_STRING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dom_mem->domain = dom;
|
||||
dom_mem->start_pfn = pfn;
|
||||
dom_mem->tot_pages = pages;
|
||||
if((dom_mem->vaddr = get_vaddr(dom)) == 0){
|
||||
dberr("Error mapping dom memory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create new domain */
|
||||
static dom0_newdomain_t * create_new_domain(long req_mem)
|
||||
{
|
||||
dom0_newdomain_t * dom_data;
|
||||
char cmd_path[MAX_PATH];
|
||||
char dom_id_path[MAX_PATH];
|
||||
dom0_op_t dop;
|
||||
int cmd_fd;
|
||||
int id_fd;
|
||||
|
||||
/* open the /proc command interface */
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
cmd_fd = open(cmd_path, O_WRONLY);
|
||||
if(cmd_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dop.cmd = DOM0_CREATEDOMAIN;
|
||||
dop.u.newdomain.memory_kb = req_mem;
|
||||
dop.u.newdomain.name[0] = 0;
|
||||
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
close(cmd_fd);
|
||||
|
||||
sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/",
|
||||
PROC_DOM_DATA);
|
||||
while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue;
|
||||
dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
|
||||
read(id_fd, dom_data, sizeof(dom0_newdomain_t));
|
||||
close(id_fd);
|
||||
|
||||
sprintf(cmd_path, "Reserved %ld kbytes memory and assigned id %d to the"
|
||||
" new domain.", req_mem, dom_data->domain);
|
||||
dbstatus(cmd_path);
|
||||
|
||||
return dom_data;
|
||||
}
|
||||
|
||||
/* open kernel image and do some sanity checks */
|
||||
static int do_kernel_chcks(char *image, long dom_size,
|
||||
unsigned long * load_addr, size_t * ksize)
|
||||
{
|
||||
char signature[8];
|
||||
char status[MAX_PATH];
|
||||
struct stat stat;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
fd = open(image, O_RDONLY);
|
||||
if(fd < 0){
|
||||
perror(PERR_STRING);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(fstat(fd, &stat) < 0){
|
||||
perror(PERR_STRING);
|
||||
ret = -1;
|
||||
close(fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(stat.st_size > (dom_size << 10)){
|
||||
sprintf(status, "Kernel image size %ld larger than requested "
|
||||
"domain size %ld\n Terminated.\n", stat.st_size, dom_size);
|
||||
dberr(status);
|
||||
ret = -1;
|
||||
close(fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
read(fd, signature, SIG_LEN);
|
||||
if(strncmp(signature, GUEST_SIG, SIG_LEN)){
|
||||
dberr("Kernel image does not contain required signature. "
|
||||
"Terminating.\n");
|
||||
ret = -1;
|
||||
close(fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
read(fd, load_addr, sizeof(unsigned long));
|
||||
|
||||
*ksize = stat.st_size - SIG_LEN - sizeof(unsigned long);
|
||||
|
||||
sprintf(status, "Kernel image %s valid, kernel virtual load address %lx",
|
||||
image, *load_addr);
|
||||
dbstatus(status);
|
||||
|
||||
ret = fd;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* this is the main guestos setup function,
|
||||
* returnes domain descriptor structure to be used when launching
|
||||
* the domain by hypervisor to do some last minute initialization.
|
||||
* page table initialization is done by making a list of page table
|
||||
* requests that are handeled by the hypervisor in the ordinary
|
||||
* manner. this way, many potentially messy things are avoided...
|
||||
*/
|
||||
#define PAGE_TO_VADDR(_pfn) ((void *)(dom_mem->vaddr + ((_pfn) * PAGE_SIZE)))
|
||||
static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
|
||||
unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem)
|
||||
{
|
||||
dom_meminfo_t *meminfo;
|
||||
unsigned long *page_array;
|
||||
page_update_request_t *pgt_updates;
|
||||
dom_mem_t mem_map;
|
||||
dom_meminfo_t *ret = NULL;
|
||||
int alloc_index, num_pt_pages;
|
||||
unsigned long l2tab;
|
||||
unsigned long l1tab = 0;
|
||||
unsigned long num_pgt_updates = 0;
|
||||
unsigned long count, pt_start;
|
||||
dom0_op_t pgupdate_req;
|
||||
char cmd_path[MAX_PATH];
|
||||
int cmd_fd;
|
||||
|
||||
meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
|
||||
page_array = malloc(dom_mem->tot_pages * 4);
|
||||
pgt_updates = (page_update_request_t *)dom_mem->vaddr;
|
||||
alloc_index = dom_mem->tot_pages - 1;
|
||||
|
||||
memset(meminfo, 0, sizeof(meminfo));
|
||||
|
||||
memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
|
||||
|
||||
/* Count bottom-level PTs, rounding up. Include one PTE for shared info. */
|
||||
num_pt_pages =
|
||||
(l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1024) / 1024;
|
||||
|
||||
/* We must also count the page directory. */
|
||||
num_pt_pages++;
|
||||
|
||||
/* Index of first PT page. */
|
||||
pt_start = dom_mem->tot_pages - num_pt_pages;
|
||||
|
||||
/* first allocate page for page dir. allocation goes backwards from the
|
||||
* end of the allocated physical address space.
|
||||
*/
|
||||
l2tab = *(page_array + alloc_index) << PAGE_SHIFT;
|
||||
memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
|
||||
alloc_index--;
|
||||
meminfo->l2_pgt_addr = l2tab;
|
||||
meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages);
|
||||
|
||||
/* pin down l2tab addr as page dir page - causes hypervisor to provide
|
||||
* correct protection for the page
|
||||
*/
|
||||
pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND;
|
||||
pgt_updates->val = PGEXT_PIN_L2_TABLE;
|
||||
pgt_updates++;
|
||||
num_pgt_updates++;
|
||||
|
||||
/*
|
||||
* Initialise the page tables. The final iteration is for the shared_info
|
||||
* PTE -- we break out before filling in the entry, as that is done by
|
||||
* Xen during final setup.
|
||||
*/
|
||||
l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t);
|
||||
for ( count = 0; count < (dom_mem->tot_pages + 1); count++ )
|
||||
{
|
||||
if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
l1tab = *(page_array + alloc_index) << PAGE_SHIFT;
|
||||
memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
|
||||
alloc_index--;
|
||||
|
||||
l1tab += l1_table_offset(virt_load_addr + nr_2_page(count))
|
||||
* sizeof(l1_pgentry_t);
|
||||
|
||||
/* make apropriate entry in the page directory */
|
||||
pgt_updates->ptr = l2tab;
|
||||
pgt_updates->val = l1tab | L2_PROT;
|
||||
pgt_updates++;
|
||||
num_pgt_updates++;
|
||||
l2tab += sizeof(l2_pgentry_t);
|
||||
}
|
||||
|
||||
/* The last PTE we consider is filled in later by Xen. */
|
||||
if ( count == dom_mem->tot_pages ) break;
|
||||
|
||||
if ( count < pt_start )
|
||||
{
|
||||
pgt_updates->ptr = l1tab;
|
||||
pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT;
|
||||
pgt_updates++;
|
||||
num_pgt_updates++;
|
||||
l1tab += sizeof(l1_pgentry_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
pgt_updates->ptr = l1tab;
|
||||
pgt_updates->val =
|
||||
((*(page_array + count) << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
|
||||
pgt_updates++;
|
||||
num_pgt_updates++;
|
||||
l1tab += sizeof(l1_pgentry_t);
|
||||
}
|
||||
|
||||
pgt_updates->ptr =
|
||||
(*(page_array + count) << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
|
||||
pgt_updates->val = count;
|
||||
pgt_updates++;
|
||||
num_pgt_updates++;
|
||||
}
|
||||
|
||||
meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1);
|
||||
meminfo->domain = dom;
|
||||
|
||||
/*
|
||||
* Send the page update requests down to the hypervisor.
|
||||
* NB. We must do this before loading the guest OS image!
|
||||
*/
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) goto out;
|
||||
pgupdate_req.cmd = DO_PGUPDATES;
|
||||
pgupdate_req.u.pgupdate.pgt_update_arr = (unsigned long)dom_mem->vaddr;
|
||||
pgupdate_req.u.pgupdate.num_pgt_updates = num_pgt_updates;
|
||||
write(cmd_fd, &pgupdate_req, sizeof(dom0_op_t));
|
||||
close(cmd_fd);
|
||||
|
||||
/* Load the guest OS image. */
|
||||
if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize )
|
||||
{
|
||||
dberr("Error reading kernel image, could not"
|
||||
" read the whole image. Terminating.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if( initrd_fd )
|
||||
{
|
||||
struct stat stat;
|
||||
unsigned long isize;
|
||||
|
||||
if(fstat(initrd_fd, &stat) < 0){
|
||||
perror(PERR_STRING);
|
||||
close(initrd_fd);
|
||||
goto out;
|
||||
}
|
||||
isize = stat.st_size;
|
||||
|
||||
if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize )
|
||||
{
|
||||
dberr("Error reading initrd image, could not"
|
||||
" read the whole image. Terminating.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
meminfo->virt_mod_addr = virt_load_addr + ksize;
|
||||
meminfo->virt_mod_len = isize;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ret = meminfo;
|
||||
out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int launch_domain(dom_meminfo_t * meminfo)
|
||||
{
|
||||
char cmd_path[MAX_PATH];
|
||||
dom0_op_t dop;
|
||||
int cmd_fd;
|
||||
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
cmd_fd = open(cmd_path, O_WRONLY);
|
||||
if(cmd_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dop.cmd = DOM0_BUILDDOMAIN;
|
||||
memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
|
||||
dop.cmd = DOM0_STARTDOMAIN;
|
||||
memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
|
||||
dbstatus("Launched the new domain!");
|
||||
|
||||
close(cmd_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
dom0_newdomain_t * dom_data;
|
||||
dom_mem_t dom_os_image;
|
||||
dom_mem_t dom_pgt;
|
||||
dom_meminfo_t * meminfo;
|
||||
size_t ksize;
|
||||
unsigned long load_addr;
|
||||
char status[1024];
|
||||
int kernel_fd, initrd_fd = 0;
|
||||
int count;
|
||||
int cmd_len;
|
||||
int rc = -1;
|
||||
int args_start = 4;
|
||||
char initrd_name[1024];
|
||||
|
||||
unsigned long addr;
|
||||
|
||||
/**** this argument parsing code is really _gross_. rewrite me! ****/
|
||||
|
||||
if(argc < 4) {
|
||||
dberr("Usage: dom_builder <kbytes_mem> <image> <num_vifs> "
|
||||
"[<initrd=initrd_name>] <boot_params>\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create new domain and set up all the neccessary mappings */
|
||||
|
||||
kernel_fd = do_kernel_chcks(argv[2], atol(argv[1]), &load_addr, &ksize);
|
||||
if(kernel_fd < 0)
|
||||
return -1;
|
||||
|
||||
/* request the creation of new domain */
|
||||
if(!(dom_data = create_new_domain(atol(argv[1]))))
|
||||
return -1;
|
||||
|
||||
/* map domain's memory */
|
||||
if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT-10),
|
||||
dom_data->domain, &dom_os_image))
|
||||
goto out;
|
||||
|
||||
if( strncmp("initrd=", argv[args_start], 7) == 0 )
|
||||
{
|
||||
strncpy( initrd_name, argv[args_start]+7, sizeof(initrd_name) );
|
||||
initrd_name[sizeof(initrd_name)-1] = 0;
|
||||
printf("initrd present, name = %s\n", initrd_name );
|
||||
args_start++;
|
||||
|
||||
initrd_fd = open(initrd_name, O_RDONLY);
|
||||
if(initrd_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* the following code does the actual domain building */
|
||||
meminfo = setup_guestos(dom_data->domain, kernel_fd, initrd_fd, load_addr,
|
||||
ksize, &dom_os_image);
|
||||
|
||||
/* and unmap the new domain's memory image since we no longer need it */
|
||||
dom_mem_cleanup(&dom_os_image);
|
||||
|
||||
if(!meminfo) {
|
||||
printf("Domain Builder: debug: meminfo NULL\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
meminfo->virt_load_addr = load_addr;
|
||||
meminfo->num_vifs = atoi(argv[3]);
|
||||
meminfo->cmd_line[0] = '\0';
|
||||
cmd_len = 0;
|
||||
for(count = args_start; count < argc; count++){
|
||||
if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){
|
||||
dberr("Size of image boot params too big!\n");
|
||||
break;
|
||||
}
|
||||
strcat(meminfo->cmd_line, argv[count]);
|
||||
strcat(meminfo->cmd_line, " ");
|
||||
cmd_len += strlen(argv[count] + 1);
|
||||
}
|
||||
|
||||
sprintf(status,
|
||||
"About to launch new domain %d with folowing parameters:\n"
|
||||
" * page table base: %lx \n * load address: %lx \n"
|
||||
" * shared info address: %lx \n * start info address: %lx \n"
|
||||
" * number of vifs: %d \n * cmd line: %s \n", meminfo->domain,
|
||||
meminfo->l2_pgt_addr, meminfo->virt_load_addr,
|
||||
meminfo->virt_shinfo_addr, meminfo->virt_startinfo_addr,
|
||||
meminfo->num_vifs, meminfo->cmd_line);
|
||||
dbstatus(status);
|
||||
|
||||
/* and launch the domain */
|
||||
rc = launch_domain(meminfo);
|
||||
|
||||
out:
|
||||
if( rc >= 0 )
|
||||
{
|
||||
return meminfo->domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( dom_data->domain != 0 )
|
||||
do_kill_domain(dom_data->domain, 1);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* A very(!) simple program to kill a domain. (c) Boris Dragovic
|
||||
* Usage: <executable> <mem_kb> <os image> <num_vifs>
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "dom0_ops.h"
|
||||
#include "dom0_defs.h"
|
||||
|
||||
#define PERR_STRING "Xen Domain Killer"
|
||||
|
||||
static int do_kill_domain(int dom_id, int force)
|
||||
{
|
||||
char cmd_path[MAX_PATH];
|
||||
dom0_op_t dop;
|
||||
int cmd_fd;
|
||||
|
||||
dop.cmd = DOM0_DESTROYDOMAIN;
|
||||
dop.u.killdomain.domain = dom_id;
|
||||
dop.u.killdomain.force = force;
|
||||
|
||||
/* open the /proc command interface */
|
||||
sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
|
||||
cmd_fd = open(cmd_path, O_WRONLY);
|
||||
if(cmd_fd < 0){
|
||||
perror(PERR_STRING);
|
||||
return -1;
|
||||
}
|
||||
|
||||
write(cmd_fd, &dop, sizeof(dom0_op_t));
|
||||
close(cmd_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ( (argc < 2) || (argc > 3) )
|
||||
{
|
||||
usage:
|
||||
printf("Usage: kill_domain [-f] <domain_id>\n");
|
||||
printf(" -f: Forces immediate destruction of specified domain\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( (argc == 3) && strcmp("-f", argv[1]) ) goto usage;
|
||||
|
||||
ret = do_kill_domain(atoi(argv[argc-1]), argc == 3);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/******************************************************************************
|
||||
* hypervisor_defs.h
|
||||
*
|
||||
* This needs to be kept in sync with Xen's pagetable update interface!
|
||||
*
|
||||
* Copyright (c) 2002-2003, Keir Fraser & Boris Dragovic
|
||||
*/
|
||||
|
||||
/* taken from include/hypervisor-ifs/hypervisor-if.h */
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* PGREQ_XXX: specified in least-significant bits of 'ptr' field. All requests
|
||||
* specify relevent PTE or PT address in 'ptr'. Normal requests specify update
|
||||
* value in 'value'. Extended requests specify command in least 8 bits of
|
||||
* 'value'.
|
||||
*/
|
||||
unsigned long ptr, val; /* *ptr = val */
|
||||
} page_update_request_t;
|
||||
|
||||
/* A normal page-table update request. */
|
||||
#define PGREQ_NORMAL 0
|
||||
#define PGREQ_MPT_UPDATE 1
|
||||
/* An extended command. */
|
||||
#define PGREQ_EXTENDED_COMMAND 2
|
||||
/* Announce a new top-level page table. */
|
||||
#define PGEXT_PIN_L1_TABLE 0
|
||||
#define PGEXT_PIN_L2_TABLE 1
|
||||
#define PGEXT_PIN_L3_TABLE 2
|
||||
#define PGEXT_PIN_L4_TABLE 3
|
||||
#define PGEXT_UNPIN_TABLE 4
|
||||
#define PGEXT_NEW_BASEPTR 5
|
||||
#define PGEXT_TLB_FLUSH 6
|
||||
#define PGEXT_INVLPG 7
|
||||
#define PGEXT_CMD_MASK 255
|
||||
#define PGEXT_CMD_SHIFT 8
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* memory related definitions needed for userspace domain builder dom0 application. these _need_ to
|
||||
* be kept in sync with the kernel .h files they were copied over from or something horrible will
|
||||
* happen. remmember: god kills a kitten every time you forget to keep these in sync.
|
||||
*
|
||||
* KAF: Boris, these constants are all fixed by x86 hardware. So the kittens are safe for now :-)
|
||||
*
|
||||
* Copyright 2002 by B Dragovic
|
||||
*/
|
||||
|
||||
/* copied over from hypervisor: include/asm-i386/page.h */
|
||||
|
||||
#define _PAGE_PRESENT 0x001
|
||||
#define _PAGE_RW 0x002
|
||||
#define _PAGE_USER 0x004
|
||||
#define _PAGE_PWT 0x008
|
||||
#define _PAGE_PCD 0x010
|
||||
#define _PAGE_ACCESSED 0x020
|
||||
#define _PAGE_DIRTY 0x040
|
||||
#define _PAGE_PAT 0x080
|
||||
#define _PAGE_PSE 0x080
|
||||
#define _PAGE_GLOBAL 0x100
|
||||
|
||||
|
||||
#define L1_PAGETABLE_SHIFT 12
|
||||
#define L2_PAGETABLE_SHIFT 22
|
||||
|
||||
#define ENTRIES_PER_L1_PAGETABLE 1024
|
||||
#define ENTRIES_PER_L2_PAGETABLE 1024
|
||||
|
||||
#define PAGE_SHIFT L1_PAGETABLE_SHIFT
|
||||
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||
|
||||
typedef struct { unsigned long l1_lo; } l1_pgentry_t;
|
||||
typedef struct { unsigned long l2_lo; } l2_pgentry_t;
|
||||
|
||||
#define l1_table_offset(_a) \
|
||||
(((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
|
||||
#define l2_table_offset(_a) \
|
||||
((_a) >> L2_PAGETABLE_SHIFT)
|
||||
|
||||
/* local definitions */
|
||||
|
||||
#define nr_2_page(x) (x << PAGE_SHIFT)
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# mynewdom <size> <extra args>
|
||||
|
||||
SIZE=${1:?"size missing"}
|
||||
|
||||
SITE_NFS=128.232.32.20
|
||||
SITE_GW=128.232.32.1
|
||||
SITE_MASK=255.255.240.0
|
||||
|
||||
shift;
|
||||
|
||||
ARGS="$*"
|
||||
|
||||
IMAGE=../../../xenolinux-2.4.21/arch/xeno/boot/image
|
||||
|
||||
|
||||
LASTDOM=`/bin/ls /proc/xeno/ | grep -v cmd | cut -c4- | sort -rn | head -1`
|
||||
DOM=$[LASTDOM+1]
|
||||
|
||||
echo Domain ${DOM} looks free
|
||||
|
||||
ADDR=`/sbin/ifconfig eth0 | grep inet.addr | sed -e 's/.*inet addr:\([0-9.]*\) .*/\1/'`
|
||||
LO=`echo $ADDR | sed -e 's/[0-9]\+\.[0-9]\+\.[0-9]\+\.\([0-9]\+\)/\1/'`
|
||||
HI=`echo $ADDR | sed -e 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\)\.[0-9]\+/\1/'`
|
||||
NEWADDR=$HI.$[LO+DOM]
|
||||
|
||||
NEWNAME=$NEWADDR
|
||||
LOOKUP=`host $NEWADDR`
|
||||
echo $LOOKUP | grep 'domain name pointer' && NEWNAME=`echo $LOOKUP | sed -e 's!.*domain name pointer \([^ ]\+\).$!\1!'`
|
||||
echo New IP address : ${NEWADDR} name : ${NEWNAME}
|
||||
|
||||
#SITE_GW=`netstat -rn|while read a b c;do case "$a" in 0.0.0.0)echo "$b";;esac;done`
|
||||
NEWNAME=''
|
||||
#${NEWADDR}
|
||||
IP_CONFIG="ip=${NEWADDR}:${SITE_NFS}:${SITE_GW}:${SITE_MASK}:${NEWNAME}:eth0:off"
|
||||
echo IP_CONFIG : ${IP_CONFIG}
|
||||
|
||||
CMDLINE=`cat /proc/cmdline`
|
||||
case $CMDLINE in
|
||||
*root=/dev/nfs*)
|
||||
ROOT_DIR=`echo $CMDLINE | sed -e 's,.*nfsroot=\([^ ]*\).*,\1,'`
|
||||
ROOT_PATH=`echo $ROOT_DIR | sed -e 's!^\(.*\)[0-9]\+$!\1!'`
|
||||
ROOT_NUM=`echo $ROOT_DIR | sed -e 's!^.*\([0-9]\+\)$!\1!'`
|
||||
NEWROOT_DEV="root=/dev/nfs nfsroot=${ROOT_PATH}$[ROOT_NUM+DOM]"
|
||||
;;
|
||||
*root=/dev/[hs]d[abcd][0-9]*|*root=/dev/x[hs]d[abcd][0-9]*)
|
||||
ROOT_DEV=`echo $CMDLINE | sed -e 's!^.*root=\(/dev/[x]*[hs]da[0-9]\+\).*$!\1!'`
|
||||
ROOT_DISK=`echo $ROOT_DEV | sed -e 's!\(/dev/[x]\?[hs]d[a-z]\)[0-9]\+!\1!'`
|
||||
ROOT_PART=`echo $ROOT_DEV | sed -e 's!/dev/[x]\?[hs]d[a-z]\([0-9]\+\)!\1!'`
|
||||
NEWROOT_DEV="root=${ROOT_DISK}$[ROOT_PART+DOM] ro"
|
||||
;;
|
||||
*)
|
||||
echo Could not determine root from /proc/cmdline
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
echo New root arguments : ${NEWROOT_DEV}
|
||||
|
||||
echo ./newdom ${SIZE} ${IMAGE} ${NEWADDR} ${IP_CONFIG} ${NEWROOT_DEV} ${EXTRA_ARGS}
|
||||
|
||||
./newdom ${SIZE} ${IMAGE} ${NEWADDR} ${IP_CONFIG} ${NEWROOT_DEV} ${EXTRA_ARGS}
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# newdom <size> <image> <ip> <root details>
|
||||
# newdom 262144 ../../../xenolinux-2.4.16-kdb/arch/xeno/boot/image 128.232.35.240 root=/dev/nfs nfsroot=/usr/groups/srgboot/xxx/roots/root0
|
||||
# newdom 262144 ../../../xenolinux-2.4.16-kdb/arch/xeno/boot/image 128.232.35.240 root=/dev/xhda7
|
||||
|
||||
|
||||
VIFINIT=./vifinit
|
||||
DOM_BUILDER=./domain_builder
|
||||
|
||||
SIZE=${1:?"size missing"}
|
||||
IMAGE=${2:?"image missing"}
|
||||
IP=${3:?"IP missing"}
|
||||
|
||||
shift; shift; shift
|
||||
|
||||
echo ARGS $*
|
||||
|
||||
$DOM_BUILDER $SIZE $IMAGE 1 $*
|
||||
DOM=$?
|
||||
|
||||
echo DOM= $DOM
|
||||
|
||||
$VIFINIT $DOM 0 $IP
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# vifinit
|
||||
#
|
||||
# This is a silly little script to dump a couple of simple rules down to
|
||||
# the hypervisor to assign a full static IP to a given virtual interface.
|
||||
#
|
||||
# Usage is:
|
||||
#
|
||||
# vifinit [vif dom] [vif idx] [dotted decimal ip address]
|
||||
#
|
||||
if [ $# -ne 3 ] ;
|
||||
then
|
||||
echo "usage: vifinit [vif dom] [vif idx] [dotted decimal ip address]"
|
||||
exit
|
||||
fi
|
||||
|
||||
#outbound rule:
|
||||
echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/vfr
|
||||
|
||||
#inbound rule:
|
||||
echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/vfr
|
||||
|
||||
#----] done.
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
include $(BASEDIR)/arch/$(ARCH)/Rules.mk
|
||||
|
||||
%.o: %.c $(HDRS) Makefile
|
||||
$(CC) -g $(CFLAGS) -c $< -o $@
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.S $(HDRS) Makefile
|
||||
$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
|
||||
|
||||
@@ -647,7 +647,6 @@ ENTRY(hypervisor_call_table)
|
||||
.long SYMBOL_NAME(do_dom_mem_op)
|
||||
.long SYMBOL_NAME(do_multicall)
|
||||
.long SYMBOL_NAME(do_kbd_op)
|
||||
.long SYMBOL_NAME(do_set_priv_levels)
|
||||
.rept NR_syscalls-((.-hypervisor_call_table)/4)
|
||||
.long SYMBOL_NAME(sys_ni_syscall)
|
||||
.endr
|
||||
+3
-12
@@ -348,19 +348,10 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||
}
|
||||
|
||||
|
||||
long do_set_priv_levels(unsigned int new_io_pl, unsigned int new_hypercall_pl)
|
||||
/* XXX Currently the 'domain' field is ignored! XXX */
|
||||
long do_iopl(unsigned int domain, unsigned int new_io_pl)
|
||||
{
|
||||
struct pt_regs *regs = GET_SYSCALL_REGS(current);
|
||||
|
||||
/*
|
||||
* Any domain can reduce privilege required for hypercall access.
|
||||
* Note that access from ring 1 cannot be relinquished.
|
||||
*/
|
||||
current->thread.hypercall_pl = new_hypercall_pl & 3;
|
||||
|
||||
/* Only privileged domains can acquire access to I/O ports. */
|
||||
if ( IS_PRIV(current) )
|
||||
regs->eflags = (regs->eflags & 0xffffcfff) | ((new_io_pl&3) << 12);
|
||||
|
||||
regs->eflags = (regs->eflags & 0xffffcfff) | ((new_io_pl&3) << 12);
|
||||
return 0;
|
||||
}
|
||||
@@ -401,23 +401,6 @@ asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
|
||||
*/
|
||||
if ( (error_code & 3) == 2 )
|
||||
{
|
||||
/*
|
||||
* Hypercalls from rings 2 or 3 fall through to here. If permitted, we
|
||||
* will transfer control to the requested hypercall.
|
||||
*/
|
||||
if ( ((error_code>>3) == HYPERVISOR_CALL_VECTOR) &&
|
||||
(current->thread.hypercall_pl >= (regs->xcs & 3)) )
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"movl %0,%%esp \n"
|
||||
"sti \n"
|
||||
"andl $255,%%eax \n"
|
||||
"call *hypervisor_call_table(,%%eax,4) \n"
|
||||
"movl %%eax,0x18(%%esp) \n"
|
||||
"jmp ret_from_intr \n"
|
||||
: : "r" (regs) );
|
||||
}
|
||||
|
||||
/* This fault must be due to <INT n> instruction. */
|
||||
ti = current->thread.traps + (error_code>>3);
|
||||
if ( ti->dpl >= (regs->xcs & 3) )
|
||||
|
||||
@@ -67,7 +67,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
long ret = 0;
|
||||
dom0_op_t op;
|
||||
|
||||
if ( current->domain != 0 )
|
||||
if ( !IS_PRIV(current) )
|
||||
return -EPERM;
|
||||
|
||||
if ( copy_from_user(&op, u_dom0_op, sizeof(op)) )
|
||||
@@ -239,6 +239,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
break;
|
||||
}
|
||||
|
||||
case DOM0_IOPL:
|
||||
{
|
||||
extern long do_iopl(unsigned int, unsigned int);
|
||||
ret = do_iopl(op.u.iopl.domain, op.u.iopl.iopl);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
|
||||
|
||||
@@ -356,7 +356,6 @@ struct thread_struct {
|
||||
int fast_trap_idx;
|
||||
struct desc_struct fast_trap_desc;
|
||||
trap_info_t traps[256];
|
||||
int hypercall_pl;
|
||||
};
|
||||
|
||||
#define IDT_ENTRIES 256
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
#define DOM0_STOPDOMAIN 11
|
||||
#define DOM0_GETDOMAININFO 12
|
||||
#define DOM0_BUILDDOMAIN 13
|
||||
#define DOM0_IOPL 14
|
||||
|
||||
#define MAX_CMD_LEN 256
|
||||
#define MAX_DOMAIN_NAME 16
|
||||
#define MAX_CMD_LEN 256
|
||||
#define MAX_DOMAIN_NAME 16
|
||||
|
||||
typedef struct dom0_newdomain_st
|
||||
{
|
||||
@@ -60,32 +61,38 @@ typedef struct domain_launch
|
||||
|
||||
typedef struct dom0_bvtctl_st
|
||||
{
|
||||
unsigned long ctx_allow; /* context switch allowance */
|
||||
unsigned long ctx_allow; /* context switch allowance */
|
||||
} dom0_bvtctl_t;
|
||||
|
||||
typedef struct dom0_adjustdom_st
|
||||
{
|
||||
unsigned int domain; /* domain id */
|
||||
unsigned long mcu_adv; /* mcu advance: inverse of weight */
|
||||
unsigned long warp; /* time warp */
|
||||
unsigned long warpl; /* warp limit */
|
||||
unsigned long warpu; /* unwarp time requirement */
|
||||
unsigned long mcu_adv; /* mcu advance: inverse of weight */
|
||||
unsigned long warp; /* time warp */
|
||||
unsigned long warpl; /* warp limit */
|
||||
unsigned long warpu; /* unwarp time requirement */
|
||||
} dom0_adjustdom_t;
|
||||
|
||||
typedef struct dom0_getdominfo_st
|
||||
{
|
||||
unsigned int domain; /* All returns except domain */
|
||||
char name[MAX_DOMAIN_NAME];
|
||||
int processor;
|
||||
int has_cpu;
|
||||
int state;
|
||||
int hyp_events;
|
||||
unsigned long mcu_advance;
|
||||
unsigned long pg_head;
|
||||
unsigned int tot_pages;
|
||||
long long cpu_time;
|
||||
unsigned int domain; /* All returns except domain */
|
||||
char name[MAX_DOMAIN_NAME];
|
||||
int processor;
|
||||
int has_cpu;
|
||||
int state;
|
||||
int hyp_events;
|
||||
unsigned long mcu_advance;
|
||||
unsigned long pg_head;
|
||||
unsigned int tot_pages;
|
||||
long long cpu_time;
|
||||
} dom0_getdominfo_t;
|
||||
|
||||
typedef struct dom0_iopl_st
|
||||
{
|
||||
unsigned int domain;
|
||||
unsigned int iopl;
|
||||
} dom0_iopl_t;
|
||||
|
||||
#ifndef NO_DOM0_OP_T
|
||||
typedef struct dom0_op_st
|
||||
{
|
||||
@@ -95,11 +102,12 @@ typedef struct dom0_op_st
|
||||
dom0_newdomain_t newdomain;
|
||||
dom0_killdomain_t killdomain;
|
||||
dom0_getmemlist_t getmemlist;
|
||||
dom0_bvtctl_t bvtctl;
|
||||
dom0_adjustdom_t adjustdom;
|
||||
dom0_bvtctl_t bvtctl;
|
||||
dom0_adjustdom_t adjustdom;
|
||||
dom_meminfo_t meminfo;
|
||||
dom0_getdominfo_t getdominfo;
|
||||
}
|
||||
dom0_iopl_t iopl;
|
||||
}
|
||||
u;
|
||||
} dom0_op_t;
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#define __HYPERVISOR_dom_mem_op 17
|
||||
#define __HYPERVISOR_multicall 18
|
||||
#define __HYPERVISOR_kbd_op 19
|
||||
#define __HYPERVISOR_set_priv_levels 20
|
||||
|
||||
/* And the trap vector is... */
|
||||
#define TRAP_INSTR "int $0x82"
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
|
||||
#include "dom0_ops.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
/* Private proc-file data structures. */
|
||||
typedef struct proc_data {
|
||||
unsigned int domain;
|
||||
@@ -46,18 +43,7 @@ typedef struct proc_mem_data {
|
||||
int tot_pages;
|
||||
} proc_memdata_t;
|
||||
|
||||
#define XENO_BASE "xeno"
|
||||
#define DOM0_CMD_INTF "dom0_cmd"
|
||||
#define DOM0_NEWDOM "new_dom_data"
|
||||
#define DOM_LIST_INTF "domains"
|
||||
|
||||
#define MAX_LEN 16
|
||||
#define DOM_DIR "dom"
|
||||
#define DOM_MEM "mem"
|
||||
#define DOM_VIF "vif"
|
||||
#define DOM_USAGE "usage"
|
||||
#define DOM_PHD "phd"
|
||||
|
||||
#define MAP_DISCONT 1
|
||||
|
||||
extern struct file_operations dom0_phd_fops;
|
||||
@@ -73,7 +59,7 @@ int direct_disc_unmap(unsigned long, unsigned long, int);
|
||||
static unsigned char readbuf[1204];
|
||||
|
||||
static int cmd_read_proc(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
strcpy(page, readbuf);
|
||||
*readbuf = '\0';
|
||||
@@ -82,50 +68,6 @@ static int cmd_read_proc(char *page, char **start, off_t off,
|
||||
return strlen(page);
|
||||
}
|
||||
|
||||
static ssize_t dom_vif_read(struct file * file, char * buff, size_t size, loff_t * off)
|
||||
{
|
||||
int hyp_buf[32];
|
||||
char buf[128];
|
||||
network_op_t op;
|
||||
static int finished = 0;
|
||||
|
||||
if ( finished )
|
||||
{
|
||||
finished = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
op.cmd = NETWORK_OP_VIFQUERY;
|
||||
op.u.vif_query.domain = (unsigned int)
|
||||
((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
|
||||
op.u.vif_query.buf = hyp_buf;
|
||||
|
||||
(void) HYPERVISOR_network_op(&op);
|
||||
|
||||
if(hyp_buf[0] < 0) {
|
||||
strcpy(buf, "Error getting domain's vif list from hypervisor.\n");
|
||||
} else {
|
||||
int i;
|
||||
int len = 0;
|
||||
strcpy(buf, "No vif found");
|
||||
|
||||
for(i = 1; i <= hyp_buf[0] && len < 127; i++)
|
||||
len += snprintf(buf + len, 127 - len, "%d\n", hyp_buf[i]);
|
||||
}
|
||||
|
||||
if (*off >= (strlen(buf)+1)) return 0;
|
||||
|
||||
copy_to_user(buff, buf, strlen(buf));
|
||||
|
||||
finished = 1;
|
||||
|
||||
return strlen(buf)+1;
|
||||
}
|
||||
|
||||
struct file_operations dom_vif_ops = {
|
||||
read: dom_vif_read
|
||||
};
|
||||
|
||||
static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
|
||||
{
|
||||
char str[256];
|
||||
@@ -166,13 +108,13 @@ static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff
|
||||
(void) HYPERVISOR_network_op(&netop);
|
||||
|
||||
end += snprintf(str + end, 255 - end,
|
||||
"vif%d: sent %lld bytes (%lld packets) "
|
||||
"received %lld bytes (%lld packets)\n",
|
||||
vifs[i],
|
||||
netop.u.vif_getinfo.total_bytes_sent,
|
||||
netop.u.vif_getinfo.total_packets_sent,
|
||||
netop.u.vif_getinfo.total_bytes_received,
|
||||
netop.u.vif_getinfo.total_packets_received);
|
||||
"vif%d: sent %lld bytes (%lld packets) "
|
||||
"received %lld bytes (%lld packets)\n",
|
||||
vifs[i],
|
||||
netop.u.vif_getinfo.total_bytes_sent,
|
||||
netop.u.vif_getinfo.total_packets_sent,
|
||||
netop.u.vif_getinfo.total_bytes_received,
|
||||
netop.u.vif_getinfo.total_packets_received);
|
||||
}
|
||||
|
||||
if (*off >= end + 1) return 0;
|
||||
@@ -193,10 +135,10 @@ static void create_proc_dom_entries(int dom)
|
||||
{
|
||||
struct proc_dir_entry * dir;
|
||||
dom_procdata_t * dom_data;
|
||||
char dir_name[MAX_LEN];
|
||||
char dir_name[16];
|
||||
struct proc_dir_entry * file;
|
||||
|
||||
snprintf(dir_name, MAX_LEN, "%s%d", DOM_DIR, dom);
|
||||
sprintf(dir_name, "dom%d", dom);
|
||||
|
||||
dom_data = (dom_procdata_t *)kmalloc(sizeof(dom_procdata_t), GFP_KERNEL);
|
||||
dom_data->domain = dom;
|
||||
@@ -204,16 +146,7 @@ static void create_proc_dom_entries(int dom)
|
||||
dir = proc_mkdir(dir_name, xeno_base);
|
||||
dir->data = dom_data;
|
||||
|
||||
file = create_proc_entry(DOM_VIF, 0600, dir);
|
||||
if (file != NULL)
|
||||
{
|
||||
file->owner = THIS_MODULE;
|
||||
file->nlink = 1;
|
||||
file->proc_fops = &dom_vif_ops;
|
||||
file->data = (void *) dom;
|
||||
}
|
||||
|
||||
file = create_proc_entry(DOM_USAGE, 0600, dir);
|
||||
file = create_proc_entry("usage", 0600, dir);
|
||||
if (file != NULL)
|
||||
{
|
||||
file->owner = THIS_MODULE;
|
||||
@@ -233,14 +166,14 @@ static void create_proc_dom_entries(int dom)
|
||||
}
|
||||
|
||||
static ssize_t dom_mem_write(struct file * file, const char * buff,
|
||||
size_t size , loff_t * off)
|
||||
size_t size , loff_t * off)
|
||||
{
|
||||
dom_mem_t mem_data;
|
||||
|
||||
copy_from_user(&mem_data, (dom_mem_t *)buff, sizeof(dom_mem_t));
|
||||
|
||||
if(direct_disc_unmap(mem_data.vaddr, mem_data.start_pfn,
|
||||
mem_data.tot_pages) == 0){
|
||||
mem_data.tot_pages) == 0){
|
||||
return sizeof(sizeof(dom_mem_t));
|
||||
} else {
|
||||
return -1;
|
||||
@@ -284,12 +217,12 @@ static int dom_map_mem(unsigned int dom, unsigned long pfn, int tot_pages)
|
||||
/* check if there is already an entry for mem and if so
|
||||
* remove it.
|
||||
*/
|
||||
remove_proc_entry(DOM_MEM, pd);
|
||||
remove_proc_entry("mem", pd);
|
||||
|
||||
/* create new entry with parameters describing what to do
|
||||
* when it is mmaped.
|
||||
*/
|
||||
file = create_proc_entry(DOM_MEM, 0600, pd);
|
||||
file = create_proc_entry("mem", 0600, pd);
|
||||
if(file != NULL)
|
||||
{
|
||||
file->owner = THIS_MODULE;
|
||||
@@ -322,7 +255,7 @@ static ssize_t dom_data_read(struct file * file, char * buff, size_t size, loff_
|
||||
|
||||
copy_to_user((dom0_newdomain_t *)buff, dom_data, sizeof(dom0_newdomain_t));
|
||||
|
||||
remove_proc_entry(DOM0_NEWDOM, xeno_base);
|
||||
remove_proc_entry("new_dom_data", xeno_base);
|
||||
|
||||
kfree(dom_data);
|
||||
|
||||
@@ -334,7 +267,7 @@ struct file_operations newdom_data_fops = {
|
||||
};
|
||||
|
||||
static int cmd_write_proc(struct file *file, const char *buffer,
|
||||
u_long count, void *data)
|
||||
u_long count, void *data)
|
||||
{
|
||||
dom0_op_t op;
|
||||
int ret = 0;
|
||||
@@ -343,16 +276,10 @@ static int cmd_write_proc(struct file *file, const char *buffer,
|
||||
|
||||
copy_from_user(&op, buffer, sizeof(dom0_op_t));
|
||||
|
||||
/* do some sanity checks */
|
||||
if(op.cmd > MAX_CMD){
|
||||
ret = -ENOSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( op.cmd == MAP_DOM_MEM )
|
||||
{
|
||||
ret = dom_map_mem(op.u.dommem.domain, op.u.dommem.start_pfn,
|
||||
op.u.dommem.tot_pages);
|
||||
op.u.dommem.tot_pages);
|
||||
}
|
||||
else if ( op.cmd == DO_PGUPDATES )
|
||||
{
|
||||
@@ -368,14 +295,14 @@ static int cmd_write_proc(struct file *file, const char *buffer,
|
||||
create_proc_dom_entries(ret);
|
||||
|
||||
params = (dom0_newdomain_t *)kmalloc(sizeof(dom0_newdomain_t),
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
params->memory_kb = op.u.newdomain.memory_kb;
|
||||
params->pg_head = op.u.newdomain.pg_head;
|
||||
params->num_vifs = op.u.newdomain.num_vifs;
|
||||
params->domain = op.u.newdomain.domain;
|
||||
|
||||
/* now notify user space of the new domain's id */
|
||||
new_dom_id = create_proc_entry(DOM0_NEWDOM, 0600, xeno_base);
|
||||
new_dom_id = create_proc_entry("new_dom_data", 0600, xeno_base);
|
||||
if ( new_dom_id != NULL )
|
||||
{
|
||||
new_dom_id->owner = THIS_MODULE;
|
||||
@@ -383,14 +310,11 @@ static int cmd_write_proc(struct file *file, const char *buffer,
|
||||
new_dom_id->proc_fops = &newdom_data_fops;
|
||||
new_dom_id->data = (void *)params;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -404,83 +328,87 @@ static rwlock_t proc_xeno_domains_lock = RW_LOCK_UNLOCKED;
|
||||
|
||||
static void *xeno_domains_next(struct seq_file *s, void *v, loff_t *pos)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
if (pos != NULL) { ++ (*pos); }
|
||||
if (!proc_domains_finished) {
|
||||
proc_domains_op.u.getdominfo.domain ++;
|
||||
ret = HYPERVISOR_dom0_op(&proc_domains_op);
|
||||
if (ret < 0) proc_domains_finished = TRUE;
|
||||
}
|
||||
if ( pos != NULL )
|
||||
++(*pos);
|
||||
|
||||
if ( !proc_domains_finished )
|
||||
{
|
||||
proc_domains_op.u.getdominfo.domain++;
|
||||
ret = HYPERVISOR_dom0_op(&proc_domains_op);
|
||||
if ( ret < 0 )
|
||||
proc_domains_finished = 1;
|
||||
}
|
||||
|
||||
return (proc_domains_finished) ? NULL : &proc_domains_op;
|
||||
return (proc_domains_finished) ? NULL : &proc_domains_op;
|
||||
}
|
||||
|
||||
static void *xeno_domains_start(struct seq_file *s, loff_t *ppos)
|
||||
{
|
||||
loff_t pos = *ppos;
|
||||
loff_t pos = *ppos;
|
||||
|
||||
write_lock (&proc_xeno_domains_lock);
|
||||
proc_domains_op.cmd = DOM0_GETDOMAININFO;
|
||||
proc_domains_op.u.getdominfo.domain = 0;
|
||||
(void)HYPERVISOR_dom0_op(&proc_domains_op);
|
||||
proc_domains_finished = FALSE;
|
||||
write_lock (&proc_xeno_domains_lock);
|
||||
proc_domains_op.cmd = DOM0_GETDOMAININFO;
|
||||
proc_domains_op.u.getdominfo.domain = 0;
|
||||
(void)HYPERVISOR_dom0_op(&proc_domains_op);
|
||||
proc_domains_finished = 0;
|
||||
|
||||
while (pos > 0) {
|
||||
pos --;
|
||||
xeno_domains_next (s, NULL, NULL);
|
||||
}
|
||||
while (pos > 0) {
|
||||
pos --;
|
||||
xeno_domains_next (s, NULL, NULL);
|
||||
}
|
||||
|
||||
return (proc_domains_finished) ? NULL : &proc_domains_op;
|
||||
return (proc_domains_finished) ? NULL : &proc_domains_op;
|
||||
}
|
||||
|
||||
static void xeno_domains_stop(struct seq_file *s, void *v)
|
||||
{
|
||||
write_unlock (&proc_xeno_domains_lock);
|
||||
write_unlock (&proc_xeno_domains_lock);
|
||||
}
|
||||
|
||||
static int xeno_domains_show(struct seq_file *s, void *v)
|
||||
{
|
||||
dom0_op_t *di = v;
|
||||
dom0_op_t *di = v;
|
||||
|
||||
/*
|
||||
* Output one domain's details to dom0.
|
||||
*
|
||||
* If you update this format string then change xi_list to match.
|
||||
*/
|
||||
/*
|
||||
* Output one domain's details to dom0.
|
||||
*
|
||||
* If you update this format string then change xi_list to match.
|
||||
*/
|
||||
|
||||
seq_printf (s,
|
||||
"%8d %2d %1d %2d %8d %8ld %p %8d %s\n",
|
||||
di -> u.getdominfo.domain,
|
||||
di -> u.getdominfo.processor,
|
||||
di -> u.getdominfo.has_cpu,
|
||||
di -> u.getdominfo.state,
|
||||
di -> u.getdominfo.hyp_events,
|
||||
di -> u.getdominfo.mcu_advance,
|
||||
(void *)di -> u.getdominfo.pg_head,
|
||||
di -> u.getdominfo.tot_pages,
|
||||
di -> u.getdominfo.name);
|
||||
seq_printf (s,
|
||||
"%8d %2d %1d %2d %8d %8ld %p %8d %s\n",
|
||||
di -> u.getdominfo.domain,
|
||||
di -> u.getdominfo.processor,
|
||||
di -> u.getdominfo.has_cpu,
|
||||
di -> u.getdominfo.state,
|
||||
di -> u.getdominfo.hyp_events,
|
||||
di -> u.getdominfo.mcu_advance,
|
||||
di -> u.getdominfo.pg_head,
|
||||
di -> u.getdominfo.tot_pages,
|
||||
di -> u.getdominfo.name);
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct seq_operations xeno_domains_op = {
|
||||
.start = xeno_domains_start,
|
||||
.next = xeno_domains_next,
|
||||
.stop = xeno_domains_stop,
|
||||
.show = xeno_domains_show,
|
||||
.start = xeno_domains_start,
|
||||
.next = xeno_domains_next,
|
||||
.stop = xeno_domains_stop,
|
||||
.show = xeno_domains_show,
|
||||
};
|
||||
|
||||
static int xeno_domains_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &xeno_domains_op);
|
||||
return seq_open(file, &xeno_domains_op);
|
||||
}
|
||||
|
||||
static struct file_operations proc_xeno_domains_operations = {
|
||||
open: xeno_domains_open,
|
||||
read: seq_read,
|
||||
llseek: seq_lseek,
|
||||
release: seq_release,
|
||||
open: xeno_domains_open,
|
||||
read: seq_read,
|
||||
llseek: seq_lseek,
|
||||
release: seq_release,
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -490,11 +418,11 @@ static struct file_operations proc_xeno_domains_operations = {
|
||||
static int __init init_module(void)
|
||||
{
|
||||
/* xeno proc root setup */
|
||||
xeno_base = proc_mkdir(XENO_BASE, &proc_root);
|
||||
xeno_base = proc_mkdir("xeno", &proc_root);
|
||||
|
||||
/* xeno control interface */
|
||||
*readbuf = '\0';
|
||||
dom0_cmd_intf = create_proc_entry (DOM0_CMD_INTF, 0600, xeno_base);
|
||||
dom0_cmd_intf = create_proc_entry("dom0_cmd", 0600, xeno_base);
|
||||
if ( dom0_cmd_intf != NULL )
|
||||
{
|
||||
dom0_cmd_intf->owner = THIS_MODULE;
|
||||
@@ -504,13 +432,13 @@ static int __init init_module(void)
|
||||
}
|
||||
|
||||
/* domain list interface */
|
||||
dom_list_intf = create_proc_entry (DOM_LIST_INTF, 0400, xeno_base);
|
||||
dom_list_intf = create_proc_entry("domains", 0400, xeno_base);
|
||||
if ( dom_list_intf != NULL )
|
||||
{
|
||||
dom_list_intf -> owner = THIS_MODULE;
|
||||
dom_list_intf -> nlink = 1;
|
||||
dom_list_intf -> proc_fops = &proc_xeno_domains_operations;
|
||||
}
|
||||
{
|
||||
dom_list_intf->owner = THIS_MODULE;
|
||||
dom_list_intf->nlink = 1;
|
||||
dom_list_intf->proc_fops = &proc_xeno_domains_operations;
|
||||
}
|
||||
|
||||
/* set up /proc entries for dom 0 */
|
||||
create_proc_dom_entries(0);
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
#endif
|
||||
|
||||
/* Extra commands dealt with by Xenolinux. */
|
||||
#define MAP_DOM_MEM 14
|
||||
#define DO_PGUPDATES 15
|
||||
#define MAX_CMD 16
|
||||
#define MAP_DOM_MEM 1014
|
||||
#define DO_PGUPDATES 1015
|
||||
|
||||
typedef struct dom_mem
|
||||
{
|
||||
@@ -50,8 +49,8 @@ typedef struct dom0_op_st
|
||||
dom_pgupdate_t pgupdate;
|
||||
dom_meminfo_t meminfo;
|
||||
dom0_getdominfo_t getdominfo;
|
||||
}
|
||||
u;
|
||||
dom0_iopl_t iopl;
|
||||
} u;
|
||||
} dom0_op_t;
|
||||
|
||||
#endif /* __DOM0_DOM0_OPS_H__ */
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <asm/hypervisor-ifs/dom0_ops.h>
|
||||
|
||||
|
||||
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
||||
@@ -15,32 +16,32 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
||||
asmlinkage int sys_iopl(unsigned long unused)
|
||||
{
|
||||
struct pt_regs *regs = (struct pt_regs *)&unused;
|
||||
unsigned int new_io_pl = regs->ebx & 3;
|
||||
unsigned int new_io_pl = regs->ebx;
|
||||
unsigned int old_io_pl = current->thread.io_pl;
|
||||
unsigned int new_hypercall_pl = (regs->ebx >> 2) & 3;
|
||||
unsigned int old_hypercall_pl = current->thread.hypercall_pl;
|
||||
dom0_op_t op;
|
||||
|
||||
/* Need "raw I/O" privileges for direct port access. */
|
||||
if ( (new_io_pl > old_io_pl) &&
|
||||
(!capable(CAP_SYS_RAWIO) || !(start_info.flags & SIF_PRIVILEGED)) )
|
||||
if ( !(start_info.flags & SIF_PRIVILEGED) )
|
||||
return -EPERM;
|
||||
|
||||
/* Just need generic root/admin privileges for direct hypercall access. */
|
||||
if ( (new_hypercall_pl > old_hypercall_pl) && !capable(CAP_SYS_ADMIN) )
|
||||
if ( new_io_pl > 3 )
|
||||
return -EINVAL;
|
||||
|
||||
/* Need "raw I/O" privileges for direct port access. */
|
||||
if ( (new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO) )
|
||||
return -EPERM;
|
||||
|
||||
/* Maintain OS privileges even if user attempts to relinquish them. */
|
||||
if ( new_hypercall_pl == 0 )
|
||||
new_hypercall_pl = 1;
|
||||
if ( (new_io_pl == 0) && (start_info.flags & SIF_PRIVILEGED) )
|
||||
new_io_pl = 1;
|
||||
|
||||
/* Change our version of the privilege levels. */
|
||||
current->thread.io_pl = new_io_pl;
|
||||
current->thread.hypercall_pl = new_hypercall_pl;
|
||||
current->thread.io_pl = new_io_pl;
|
||||
|
||||
/* Force the change at ring 0. */
|
||||
HYPERVISOR_set_priv_levels(new_io_pl, new_hypercall_pl);
|
||||
op.cmd = DOM0_IOPL;
|
||||
op.u.iopl.domain = start_info.dom_id;
|
||||
op.u.iopl.iopl = new_io_pl;
|
||||
HYPERVISOR_dom0_op(&op);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <asm/desc.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/multicall.h>
|
||||
#include <asm/hypervisor-ifs/dom0_ops.h>
|
||||
|
||||
#include <linux/irq.h>
|
||||
|
||||
@@ -274,9 +275,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
|
||||
__asm__ __volatile__ ( "pushfl; popl %0" : "=r" (eflags) : );
|
||||
p->thread.io_pl = (eflags >> 12) & 3;
|
||||
|
||||
/* We're careful with hypercall privileges. Don't allow inheritance. */
|
||||
p->thread.hypercall_pl = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -370,9 +368,14 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
|
||||
}
|
||||
|
||||
queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0);
|
||||
/* Next call will silently fail if we are a non-privileged guest OS. */
|
||||
queue_multicall2(__HYPERVISOR_set_priv_levels,
|
||||
next->io_pl, next->hypercall_pl);
|
||||
if ( start_info.flags & SIF_PRIVILEGED )
|
||||
{
|
||||
dom0_op_t op;
|
||||
op.cmd = DOM0_IOPL;
|
||||
op.u.iopl.domain = start_info.dom_id;
|
||||
op.u.iopl.iopl = next->io_pl;
|
||||
queue_multicall1(__HYPERVISOR_dom0_op, (unsigned long)&op);
|
||||
}
|
||||
|
||||
/* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */
|
||||
execute_multicall_list();
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/hypervisor.h>
|
||||
#include <asm/hypervisor-ifs/dom0_ops.h>
|
||||
|
||||
shared_info_t *HYPERVISOR_shared_info;
|
||||
|
||||
@@ -301,12 +302,16 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
paging_init();
|
||||
|
||||
current->thread.hypercall_pl = 1;
|
||||
if ( start_info.flags & SIF_PRIVILEGED ) {
|
||||
current->thread.io_pl = 1;
|
||||
/* We are privileged guest os - should have IO privileges. */
|
||||
if( HYPERVISOR_set_priv_levels(1, 1) )
|
||||
/* We are privileged guest os - should have IO privileges. */
|
||||
if ( start_info.flags & SIF_PRIVILEGED )
|
||||
{
|
||||
dom0_op_t op;
|
||||
op.cmd = DOM0_IOPL;
|
||||
op.u.iopl.domain = start_info.dom_id;
|
||||
op.u.iopl.iopl = 1;
|
||||
if( HYPERVISOR_dom0_op(&op) != 0 )
|
||||
panic("Unable to obtain IOPL, despite being SIF_PRIVILEGED");
|
||||
current->thread.io_pl = 1;
|
||||
}
|
||||
|
||||
if(start_info.flags & SIF_CONSOLE)
|
||||
|
||||
@@ -14,60 +14,11 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
||||
/*
|
||||
static int direct_mapped(unsigned long addr)
|
||||
{
|
||||
direct_mmap_node_t * node;
|
||||
struct list_head * curr;
|
||||
struct list_head * direct_list = ¤t->mm->context.direct_list;
|
||||
|
||||
curr = direct_list->next;
|
||||
while(curr != direct_list){
|
||||
node = list_entry(curr, direct_mmap_node_t, list);
|
||||
if(node->addr == addr)
|
||||
break;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if(curr == direct_list)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
|
||||
if (len > TASK_SIZE)
|
||||
return -ENOMEM;
|
||||
|
||||
if (addr) {
|
||||
addr = PAGE_ALIGN(addr);
|
||||
vma = find_vma(current->mm, addr);
|
||||
if (TASK_SIZE - len >= addr &&
|
||||
(!vma || addr + len <= vma->vm_start))
|
||||
return addr;
|
||||
}
|
||||
addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
|
||||
|
||||
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
|
||||
if (TASK_SIZE - len < addr)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((!vma || addr + len <= vma->vm_start) && !direct_mapped(addr))
|
||||
return addr;
|
||||
|
||||
addr = vma->vm_end;
|
||||
}
|
||||
}
|
||||
*/
|
||||
struct list_head *find_direct(struct list_head *list, unsigned long addr)
|
||||
{
|
||||
struct list_head * curr;
|
||||
struct list_head * direct_list = ¤t->mm->context.direct_list;
|
||||
direct_mmap_node_t * node;
|
||||
struct list_head * curr;
|
||||
struct list_head * direct_list = ¤t->mm->context.direct_list;
|
||||
direct_mmap_node_t * node;
|
||||
|
||||
for ( curr = direct_list->next; curr != direct_list; curr = curr->next )
|
||||
{
|
||||
@@ -78,15 +29,18 @@ struct list_head *find_direct(struct list_head *list, unsigned long addr)
|
||||
return curr;
|
||||
}
|
||||
|
||||
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long
|
||||
addr, unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
unsigned long arch_get_unmapped_area(struct file *filp,
|
||||
unsigned long addr,
|
||||
unsigned long len,
|
||||
unsigned long pgoff,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct vm_area_struct *vma;
|
||||
direct_mmap_node_t * node;
|
||||
struct list_head * curr;
|
||||
struct list_head * direct_list = ¤t->mm->context.direct_list;
|
||||
|
||||
if (len > TASK_SIZE)
|
||||
if ( len > TASK_SIZE )
|
||||
return -ENOMEM;
|
||||
|
||||
if ( addr )
|
||||
@@ -113,7 +67,8 @@ addr, unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
if ( TASK_SIZE - len < addr ) return -ENOMEM;
|
||||
|
||||
if ( vma && ((curr == direct_list) || (vma->vm_start < node->vm_start)))
|
||||
if ( vma && ((curr == direct_list) ||
|
||||
(vma->vm_start < node->vm_start)) )
|
||||
{
|
||||
/* Do we fit before VMA node? */
|
||||
if ( addr + len <= vma->vm_start ) return addr;
|
||||
|
||||
@@ -364,16 +364,4 @@ static inline long HYPERVISOR_kbd_op(unsigned char op, unsigned char val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline long HYPERVISOR_set_priv_levels(unsigned int new_io_pl,
|
||||
unsigned int new_hypercall_pl)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_set_priv_levels),
|
||||
"b" (new_io_pl), "c" (new_hypercall_pl) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __HYPERVISOR_H__ */
|
||||
@@ -358,7 +358,7 @@ struct thread_struct {
|
||||
unsigned long esp;
|
||||
unsigned long fs;
|
||||
unsigned long gs;
|
||||
unsigned int io_pl, hypercall_pl;
|
||||
unsigned int io_pl;
|
||||
/* Hardware debugging registers */
|
||||
unsigned long debugreg[8]; /* %%db0-7 debug registers */
|
||||
/* fault info */
|
||||
|
||||