bitkeeper revision 1.284 (3f094675ELP7S7P0f1aKb_RV95PM4Q)

Merge steve/keir changes
This commit is contained in:
rac61@labyrinth.cl.cam.ac.uk committed 2003-07-07 10:07:49 +00:00
commit ae33b65c00
29 files changed
+170 -1198

No files matched your search

-11
View File
@@ -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
-3
View File
@@ -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
-20
View File
@@ -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
-29
View File
@@ -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
-8
View File
@@ -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
-5
View File
@@ -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"
-559
View File
@@ -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;
}
}
-61
View File
@@ -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;
}
-36
View File
@@ -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
-45
View File
@@ -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)
-65
View File
@@ -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}
-26
View File
@@ -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
-25
View File
@@ -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
View File
@@ -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 $@
-1
View File
@@ -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
View File
@@ -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;
}
-17
View File
@@ -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) )
+8 -1
View File
@@ -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;
-1
View File
@@ -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
+28 -20
View File
@@ -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 = &current->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 = &current->mm->context.direct_list;
direct_mmap_node_t * node;
struct list_head * curr;
struct list_head * direct_list = &current->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 = &current->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 */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.