diff options
author | ach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk> | 2003-03-05 20:14:40 +0000 |
---|---|---|
committer | ach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk> | 2003-03-05 20:14:40 +0000 |
commit | f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e (patch) | |
tree | 1f240422ead5b60bafe8126e850d92338ba6e40e | |
parent | a474d07ad6848eb61c591d57ff64400d66cd9007 (diff) | |
parent | dfca2c82d597482bab554fd1256cdb13154efba7 (diff) | |
download | xen-f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e.tar.gz xen-f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e.tar.bz2 xen-f3c8dfc6270a0d4ac5f81d64b59a42623e45f82e.zip |
bitkeeper revision 1.107 (3e665ab0XNZynD-498WHLN1g1IPRrw)
Merge labyrinth.cl.cam.ac.uk:/usr/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/anfs/scratch/boulderdash/ach61/xeno/xeno.bk
24 files changed, 890 insertions, 71 deletions
@@ -176,6 +176,9 @@ 3e15d52e0_j129JPvo7xfYGndVFpwQ old/xenolinux-2.4.16-sparse/mm/memory.c 3e15d535DLvpzTrLRUIerB69LpJD1g old/xenolinux-2.4.16-sparse/mm/mremap.c 3e15d531m1Y1_W8ki64AFOU_ua4C4w old/xenolinux-2.4.16-sparse/mm/swapfile.c +3e6377b24eQqYMsDi9XrFkIgTzZ47A tools/balloon/Makefile +3e6377d6eiFjF1hHIS6JEIOFk62xSA tools/balloon/README +3e6377dbGcgnisKw16DPCaND7oGO3Q tools/balloon/balloon.c 3e4d00468-FN2VDeEHo96zxrMHK_mA tools/domain_builder/Makefile 3e4d0046SPau_y0sw2WLJz8QkqNoRA tools/domain_builder/README 3e4d0046bbdH0GsI9J_1Eb4ZQHfIiQ tools/domain_builder/dom0_defs.h @@ -226,6 +229,7 @@ 3ddb79bddEYJbcURvqqcx99Yl2iAhQ xen/common/block.c 3ddb79bdrqnW93GR9gZk1OJe1qK-iQ xen/common/brlock.c 3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c +3e6377e4i0c9GtKN65e99OtRbw3AZw xen/common/dom_mem_ops.c 3ddb79bdYO5D8Av12NHqPeSviav7cg xen/common/domain.c 3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/common/domain_page.c 3ddb79bdeyutmaXEfpQvvxj7eQ0fCw xen/common/event.c @@ -400,6 +404,7 @@ 3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xeno/ctype.h 3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xeno/delay.h 3ddb79c2PMeWTK86y4C3F4MzHw4A1g xen/include/xeno/dom0_ops.h +3e6377eaioRoNm0m_HSDEAd4Vqrq_w xen/include/xeno/dom_mem_ops.h 3ddb79c1uaWQZj551j1O0B5z8AnHOg xen/include/xeno/elevator.h 3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xeno/errno.h 3ddb79c0rMjudDKkJku_mkm0J-BZgw xen/include/xeno/etherdevice.h @@ -465,6 +470,9 @@ 3e5a4e65n-KhsEAs-A4ULiStBp-r6w xenolinux-2.4.21-pre4-sparse/arch/xeno/boot/Makefile 3e5a4e65OV_j_DBtjzt5vej771AJsA xenolinux-2.4.21-pre4-sparse/arch/xeno/config.in 3e5a4e65TNEycLeXqPSXQJQm_xGecA xenolinux-2.4.21-pre4-sparse/arch/xeno/defconfig +3e6377f5xwPfYZkPHPrDbEq1PRN7uQ xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile +3e6377f8Me8IqtvEhb70XFgOvqQH7A xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c +3e6377fbMjXWAQd0XN0FWv4fDEo6fg xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h 3e5a4e65iHEuC5sjFhj42XALYbLVRw xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile 3e5a4e65pP5spJErBW69pJxSSdK9RA xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c 3e5a4e65GtI9JZRAjuRdXaxt_4ohyQ xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index 0b34c3a528..57a4902380 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -22,3 +22,134 @@ xenolinux-2.4.16-sparse/scripts/kconfig.tk xen-2.4.16/foo xen-2.4.16/common/domain.c.smh URK +tools/domain_builder/dom_builder.o +tools/domain_builder/dom_kill.o +tools/domain_builder/domain_builder +tools/domain_builder/kill_domain +xen/arch/i386/acpitable.o +xen/arch/i386/apic.o +xen/arch/i386/arch.o +xen/arch/i386/boot/boot.o +xen/arch/i386/delay.o +xen/arch/i386/entry.o +xen/arch/i386/extable.o +xen/arch/i386/i387.o +xen/arch/i386/i8259.o +xen/arch/i386/idle0_task.o +xen/arch/i386/io_apic.o +xen/arch/i386/ioremap.o +xen/arch/i386/irq.o +xen/arch/i386/mm.o +xen/arch/i386/mpparse.o +xen/arch/i386/pci-dma.o +xen/arch/i386/pci-i386.o +xen/arch/i386/pci-irq.o +xen/arch/i386/pci-pc.o +xen/arch/i386/process.o +xen/arch/i386/rwlock.o +xen/arch/i386/setup.o +xen/arch/i386/smp.o +xen/arch/i386/smpboot.o +xen/arch/i386/time.o +xen/arch/i386/trampoline.o +xen/arch/i386/traps.o +xen/arch/i386/usercopy.o +xen/common/ac_timer.o +xen/common/block.o +xen/common/brlock.o +xen/common/common.o +xen/common/dom0_ops.o +xen/common/domain.o +xen/common/domain_page.o +xen/common/event.o +xen/common/kernel.o +xen/common/keyhandler.o +xen/common/lib.o +xen/common/memory.o +xen/common/network.o +xen/common/page_alloc.o +xen/common/perfc.o +xen/common/resource.o +xen/common/schedule.o +xen/common/slab.o +xen/common/softirq.o +xen/common/timer.o +xen/common/vsprintf.o +xen/drivers/block/blkpg.o +xen/drivers/block/driver.o +xen/drivers/block/elevator.o +xen/drivers/block/genhd.o +xen/drivers/block/ll_rw_blk.o +xen/drivers/block/xen_block.o +xen/drivers/char/driver.o +xen/drivers/char/xen_kbd.o +xen/drivers/char/xen_serial.o +xen/drivers/ide/driver.o +xen/drivers/ide/ide-disk.o +xen/drivers/ide/ide-dma.o +xen/drivers/ide/ide-features.o +xen/drivers/ide/ide-geometry.o +xen/drivers/ide/ide-pci.o +xen/drivers/ide/ide-probe.o +xen/drivers/ide/ide-taskfile.o +xen/drivers/ide/ide-xeno.o +xen/drivers/ide/ide.o +xen/drivers/ide/piix.o +xen/drivers/net/3c59x.o +xen/drivers/net/Space.o +xen/drivers/net/driver.o +xen/drivers/net/e1000/e1000.o +xen/drivers/net/e1000/e1000_ethtool.o +xen/drivers/net/e1000/e1000_hw.o +xen/drivers/net/e1000/e1000_main.o +xen/drivers/net/e1000/e1000_param.o +xen/drivers/net/ne/8390.o +xen/drivers/net/ne/ne.o +xen/drivers/net/ne/ne_drv.o +xen/drivers/net/net_init.o +xen/drivers/net/setup.o +xen/drivers/net/tg3.o +xen/drivers/pci/classlist.h +xen/drivers/pci/compat.o +xen/drivers/pci/devlist.h +xen/drivers/pci/driver.o +xen/drivers/pci/gen-devlist +xen/drivers/pci/names.o +xen/drivers/pci/pci.o +xen/drivers/pci/quirks.o +xen/drivers/pci/setup-res.o +xen/drivers/scsi/aacraid/aachba.o +xen/drivers/scsi/aacraid/aacraid.o +xen/drivers/scsi/aacraid/commctrl.o +xen/drivers/scsi/aacraid/comminit.o +xen/drivers/scsi/aacraid/commsup.o +xen/drivers/scsi/aacraid/dpcsup.o +xen/drivers/scsi/aacraid/linit.o +xen/drivers/scsi/aacraid/rx.o +xen/drivers/scsi/aacraid/sa.o +xen/drivers/scsi/constants.o +xen/drivers/scsi/driver.o +xen/drivers/scsi/hosts.o +xen/drivers/scsi/scsi.o +xen/drivers/scsi/scsi_dma.o +xen/drivers/scsi/scsi_error.o +xen/drivers/scsi/scsi_ioctl.o +xen/drivers/scsi/scsi_lib.o +xen/drivers/scsi/scsi_merge.o +xen/drivers/scsi/scsi_proc.o +xen/drivers/scsi/scsi_queue.o +xen/drivers/scsi/scsi_scan.o +xen/drivers/scsi/scsi_syms.o +xen/drivers/scsi/scsicam.o +xen/drivers/scsi/sd.o +xen/image +xen/image.gz +xen/include/asm +xen/include/linux +xen/net/dev.o +xen/net/dev_mcast.o +xen/net/devinit.o +xen/net/eth.o +xen/net/network.o +xen/net/skbuff.o +xen/tools/elf-reloc diff --git a/tools/balloon/Makefile b/tools/balloon/Makefile new file mode 100644 index 0000000000..49bab90077 --- /dev/null +++ b/tools/balloon/Makefile @@ -0,0 +1,9 @@ +CC = gcc +TARGET=balloon + +TARGET: balloon.c + $(CC) -O2 -Wall -o $(TARGET) balloon.c + +clean: + $(RM) *.o $(TARGET) *~ + diff --git a/tools/balloon/README b/tools/balloon/README new file mode 100644 index 0000000000..430e8f41bf --- /dev/null +++ b/tools/balloon/README @@ -0,0 +1,17 @@ +Xeno Balloon driver supports two operations: + +1. Inflating - which means domain giving up pages of mem to xen. +2. Deflating - which means reclaiming memory pages from xen. + +Currently, domain can only claim pages from xen up to the number of +previously released ones. This is to change. + +Example: + +# balloon inflate 1000 + +Give up 1000 pages to xen. + +# balloon deflate 1000 + +Claim 1000 pages from xen. diff --git a/tools/balloon/balloon.c b/tools/balloon/balloon.c new file mode 100644 index 0000000000..9c90a7ab62 --- /dev/null +++ b/tools/balloon/balloon.c @@ -0,0 +1,114 @@ +/****************************************************************************** + * balloon.c + * + * Xeno balloon driver userspace control tool. Used to shrink/grow domain's + * memory. + * + * Copyright (c) 2003, B Dragovic + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#define INFLATE_BALLOON "inflate" /* return mem to hypervisor */ +#define DEFLATE_BALLOON "deflate" /* claim mem from hypervisor */ + +/* THIS IS TAKEN FROM XENOLINUX BALLOON DRIVER */ +#define USER_INFLATE_BALLOON 1 /* return mem to hypervisor */ +#define USER_DEFLATE_BALLOON 2 /* claim mem from hypervisor */ +typedef struct user_balloon_op { + unsigned int op; + unsigned long size; +} user_balloon_op_t; +/* END OF CODE TAKEN FROM XENOLINUX BALLOON DRIVER */ + + +static int open_balloon_proc() +{ + return open("/proc/xeno/balloon", O_RDWR); +} + +/* inflate balloon function signals to kernel it should relinquish memory */ +static int inflate_balloon(unsigned long num_pages) +{ + user_balloon_op_t bop; + int proc_fd; + + if((proc_fd = open_balloon_proc()) <= 0){ + printf("Error opening balloon proc file.\n"); + return 0; + } + + bop.op = USER_INFLATE_BALLOON; + bop.size = num_pages; + if ( write(proc_fd, &bop, sizeof(bop)) <= 0 ) + { + printf("Error writing to balloon proc file.\n"); + return 0; + } + + close(proc_fd); + return 1; +} + +/* deflate balloon function signals to kernel it should claim memory */ +static int deflate_balloon(unsigned long num_pages) +{ + user_balloon_op_t bop; + int proc_fd; + + if((proc_fd = open_balloon_proc()) <= 0){ + printf("Error opening balloon proc file.\n"); + return 0; + } + + bop.op = USER_DEFLATE_BALLOON; + bop.size = num_pages; + if(write(proc_fd, &bop, sizeof(bop)) <= 0){ + printf("Error writing to balloon proc file.\n"); + return 0; + } + + close(proc_fd); + return 1; +} + +int main(int argc, char *argv[]) +{ + unsigned long num_pages; + + if(argc < 2){ + printf("Usage: balloon <inflate|deflate> <num_pages>\n"); + return -1; + } + + num_pages = atol(argv[2]); + + if(!strcmp(argv[1], INFLATE_BALLOON)){ + if(!inflate_balloon(num_pages)){ + perror("Inflating balloon failed"); + return -1; + } + + } else if (!strcmp(argv[1], DEFLATE_BALLOON)){ + if(!deflate_balloon(num_pages)){ + perror("Deflating balloon failed"); + return -1; + } + + } else { + printf("Unrecognized command line argument.\n"); + return -1; + } + + return 0; +} + + + diff --git a/tools/domain_builder/dom_builder.c b/tools/domain_builder/dom_builder.c index 18bc643734..a402aef99c 100644 --- a/tools/domain_builder/dom_builder.c +++ b/tools/domain_builder/dom_builder.c @@ -52,10 +52,10 @@ static void dom_mem_cleanup(dom_mem_t * dom_mem) 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"); - } + + if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){ + dbstatus("Error unmapping domain's memory.\n"); + } close(mem_fd); } @@ -163,7 +163,7 @@ static dom0_newdomain_t * create_new_domain(long req_mem) close(id_fd); sprintf(cmd_path, "Reserved %ld kbytes memory and assigned id %d to the" - "new domain.", req_mem, dom_data->domain); + " new domain.", req_mem, dom_data->domain); dbstatus(cmd_path); return dom_data; @@ -386,6 +386,7 @@ static int launch_domain(dom_meminfo_t * meminfo) dbstatus("Launched the new domain!"); close(cmd_fd); + return 0; } int main(int argc, char **argv) @@ -401,51 +402,45 @@ int main(int argc, char **argv) int kernel_fd; int count; int cmd_len; - int ret = 0; + int rc = -1; - unsigned long addr; + unsigned long addr; - if(argc < 4){ + if(argc < 4) { dberr("Usage: dom_builder <kbytes_mem> <image> <num_vifs> " - "<boot_params>\n"); - ret = -1; + "<boot_params>\n"); goto out; } /* 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){ - ret = -1; + if(kernel_fd < 0) { + rc = errno; goto out; } - + /* request the creation of new domain */ - dom_data = create_new_domain(atol(argv[1])); - if(dom_data == 0){ - ret = -1; + if(!(dom_data = create_new_domain(atol(argv[1])))) goto out; - } /* 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)){ - ret = -1; + if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT-10), + dom_data->domain, &dom_os_image)) goto out; - } /* the following code does the actual domain building */ - meminfo = setup_guestos(dom_data->domain, kernel_fd, load_addr, ksize, - &dom_os_image); - if(meminfo == NULL){ - printf("Domain Builder: debug: meminfo NULL\n"); - ret = -1; - dom_mem_cleanup(&dom_os_image); + meminfo = setup_guestos(dom_data->domain, kernel_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; } - dom_mem_cleanup(&dom_os_image); - meminfo->virt_load_addr = load_addr; meminfo->num_vifs = atoi(argv[3]); meminfo->cmd_line[0] = '\0'; @@ -471,13 +466,11 @@ int main(int argc, char **argv) dbstatus(status); /* and launch the domain */ - if(launch_domain(meminfo) != 0) - ret = -1; - + rc = launch_domain(meminfo); out: - if( ret >= 0 ) + if( rc >= 0 ) return meminfo->domain; else - return ret; + return rc; } diff --git a/xen/arch/i386/entry.S b/xen/arch/i386/entry.S index 928a96ed4e..cd49578168 100644 --- a/xen/arch/i386/entry.S +++ b/xen/arch/i386/entry.S @@ -529,6 +529,7 @@ ENTRY(hypervisor_call_table) .long SYMBOL_NAME(do_get_debugreg) .long SYMBOL_NAME(do_update_descriptor) .long SYMBOL_NAME(do_set_fast_trap) + .long SYMBOL_NAME(do_dom_mem_op) .rept NR_syscalls-(.-hypervisor_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c new file mode 100644 index 0000000000..08a47652d3 --- /dev/null +++ b/xen/common/dom_mem_ops.c @@ -0,0 +1,144 @@ +/****************************************************************************** + * dom_mem_ops.c + * + * Code to handle memory related requests from domains eg. balloon driver. + * + * Copyright (c) 2003, B Dragovic + */ + +#include <xeno/config.h> +#include <xeno/types.h> +#include <xeno/lib.h> +#include <xeno/dom_mem_ops.h> +#include <xeno/sched.h> +#include <xeno/event.h> +#include <asm/domain_page.h> + +#if 1 +#define DPRINTK(_f, _a...) printk( _f , ## _a ) +#else +#define DPRINTK(_f, _a...) ((void)0) +#endif + +static long alloc_dom_mem(struct task_struct *p, balloon_def_op_t bop) +{ + struct list_head *temp; + struct pfn_info *pf; /* pfn_info of current page */ + unsigned long mpfn; /* machine frame number of current page */ + void *va; /* Xen-usable mapping of current page */ + unsigned long i; + unsigned long flags; + + /* POLICY DECISION: Each domain has a page limit. */ + if( (p->tot_pages + bop.size) > p->max_pages ) + return -ENOMEM; + + if ( free_pfns < bop.size ) + return -ENOMEM; + + spin_lock_irqsave(&free_list_lock, flags); + + temp = free_list.next; + for ( i = 0; i < bop.size; i++ ) + { + /* Get a free page and add it to the domain's page list. */ + pf = list_entry(temp, struct pfn_info, list); + pf->flags |= p->domain; + pf->type_count = pf->tot_count = 0; + temp = temp->next; + list_del(&pf->list); + list_add_tail(&pf->list, &p->pg_head); + free_pfns--; + + p->tot_pages++; + + /* Inform the domain of the new page's machine address. */ + mpfn = (unsigned long)(pf - frame_table); + copy_to_user(bop.pages, &mpfn, sizeof(mpfn)); + bop.pages++; + + /* Zero out the page to prevent information leakage. */ + va = map_domain_mem(mpfn << PAGE_SHIFT); + memset(va, 0, PAGE_SIZE); + unmap_domain_mem(va); + } + + spin_unlock_irqrestore(&free_list_lock, flags); + + return bop.size; +} + +static long free_dom_mem(struct task_struct *p, balloon_inf_op_t bop) +{ + struct list_head *temp; + struct pfn_info *pf; /* pfn_info of current page */ + unsigned long mpfn; /* machine frame number of current page */ + unsigned long i; + unsigned long flags; + long rc = 0; + + spin_lock_irqsave(&free_list_lock, flags); + + temp = free_list.next; + for ( i = 0; i < bop.size; i++ ) + { + copy_from_user(&mpfn, bop.pages, sizeof(mpfn)); + bop.pages++; + if ( mpfn >= max_page ) + { + DPRINTK("Domain %d page number out of range (%08lx>=%08lx)\n", + p->domain, mpfn, max_page); + rc = -EINVAL; + goto out; + } + + pf = &frame_table[mpfn]; + if ( (pf->type_count != 0) || + (pf->type_count != 0) || + (pf->flags != p->domain) ) + { + DPRINTK("Bad page free for domain %d (%ld, %ld, %08lx)\n", + p->domain, pf->type_count, pf->tot_count, pf->flags); + rc = -EINVAL; + goto out; + } + + pf->flags = 0; + + list_del(&pf->list); + list_add(&pf->list, &free_list); + free_pfns++; + + p->tot_pages--; + } + + out: + spin_unlock_irqrestore(&free_list_lock, flags); + + return rc ? rc : bop.size; +} + +long do_dom_mem_op(dom_mem_op_t *mem_op) +{ + dom_mem_op_t dmop; + unsigned long ret = 0; + + if ( copy_from_user(&dmop, mem_op, sizeof(dom_mem_op_t)) ) + return -EFAULT; + + switch ( dmop.op ) + { + case BALLOON_DEFLATE_OP: + ret = alloc_dom_mem(current, dmop.u.balloon_deflate); + break; + + case BALLOON_INFLATE_OP: + ret = free_dom_mem(current, dmop.u.balloon_inflate); + break; + + default: + printk("Bad memory operation request %08x.\n", dmop.op); + } + + return ret; +} diff --git a/xen/common/domain.c b/xen/common/domain.c index 89efe59f64..7ec09a8bb8 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -63,7 +63,7 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu) p->net_ring_base = (net_ring_t *)(p->shared_info + 1); INIT_LIST_HEAD(&p->pg_head); - p->tot_pages = 0; + p->max_pages = p->tot_pages = 0; write_lock_irqsave(&tasklist_lock, flags); SET_LINKS(p); write_unlock_irqrestore(&tasklist_lock, flags); @@ -177,6 +177,9 @@ unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes) p->tot_pages = req_pages; + // temporary, max_pages should be explicitly specified + p->max_pages = p->tot_pages; + return 0; } @@ -206,6 +209,9 @@ void release_task(struct task_struct *p) REMOVE_LINKS(p); write_unlock_irq(&tasklist_lock); + /* XXX SMH: so below is screwed currently; need ref counting on vifs, + vhds, etc and proper clean up. Until then just blow the memory :-( */ +#if 0 /* * Safe! Only queue skbuffs with tasklist_lock held. * Only access shared_info with tasklist_lock held. @@ -225,6 +231,9 @@ void release_task(struct task_struct *p) free_all_dom_mem(p); free_task_struct(p); +#else + printk("XEN::release_task: not freeing memory etc yet XXX FIXME.\n"); +#endif } diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index dcd1daa564..8bb4fecab0 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -76,7 +76,7 @@ void halt_machine(u_char key, void *dev_id, struct pt_regs *regs) /* XXX SMH: this is keir's fault */ static char *task_states[] = { - "Running", + "Runnable", "Interruptible Sleep", "Uninterruptible Sleep", NULL, "Stopped", @@ -104,9 +104,8 @@ void do_task_queues(u_char key, void *dev_id, struct pt_regs *regs) printk("Notifying guest...\n"); set_bit(_EVENT_DEBUG, &s->events); } - } + } while ( (p = p->next_task) != &idle0_task ); - while ( (p = p->next_task) != &idle0_task ); read_unlock_irqrestore(&tasklist_lock, flags); } diff --git a/xen/common/memory.c b/xen/common/memory.c index 0c534ad3d1..4a0304aaf8 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -768,7 +768,7 @@ int do_process_page_updates(page_update_request_t *ureqs, int count) { MEM_LOG("Bad domain MPT update (dom %d, pfn %ld)", current->domain, pfn); - } + } break; /* diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 6ecac5848e..31cc8b18d8 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -38,13 +38,13 @@ typedef struct * Extended requests specify command in least 8 bits of 'value'. */ /* A normal page-table update request. */ -#define PGREQ_NORMAL 0 +#define PGREQ_NORMAL 0 /* Update an entry in the machine->physical mapping table. */ -#define PGREQ_MPT_UPDATE 1 +#define PGREQ_MPT_UPDATE 1 /* An extended command. */ -#define PGREQ_EXTENDED_COMMAND 2 +#define PGREQ_EXTENDED_COMMAND 2 /* DOM0 can make entirely unchecked updates which do not affect refcnts. */ -#define PGREQ_UNCHECKED_UPDATE 3 +#define PGREQ_UNCHECKED_UPDATE 3 unsigned long ptr, val; /* *ptr = val */ /* Announce a new top-level page table. */ #define PGEXT_PIN_L1_TABLE 0 @@ -90,6 +90,7 @@ typedef struct #define __HYPERVISOR_get_debugreg 13 #define __HYPERVISOR_update_descriptor 14 #define __HYPERVISOR_set_fast_trap 15 +#define __HYPERVISOR_dom_mem_op 16 #define TRAP_INSTR "int $0x82" diff --git a/xen/include/xeno/dom_mem_ops.h b/xen/include/xeno/dom_mem_ops.h new file mode 100644 index 0000000000..0aaddf2129 --- /dev/null +++ b/xen/include/xeno/dom_mem_ops.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * dom_mem_ops.h + * + * Header file supporting domain related memory operations. N.B. keep in sync + * with xen version. + * + * Copyright (c) 2003, B Dragovic + */ + +#define BALLOON_DEFLATE_OP 0 +#define BALLOON_INFLATE_OP 1 + +typedef struct balloon_deflate_op { + unsigned long size; + unsigned long * pages; +} balloon_def_op_t; + +typedef struct balloon_inflate_op { + unsigned long size; + unsigned long * pages; +} balloon_inf_op_t; + +typedef struct dom_mem_ops +{ + unsigned int op; + union + { + balloon_def_op_t balloon_deflate; + balloon_inf_op_t balloon_inflate; + } u; +} dom_mem_op_t; diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h index 0b7d96d790..da86349149 100644 --- a/xen/include/xeno/sched.h +++ b/xen/include/xeno/sched.h @@ -68,7 +68,8 @@ struct task_struct { shared_info_t *shared_info; struct list_head pg_head; - unsigned int tot_pages; + unsigned int tot_pages; /* number of pages currently possesed */ + unsigned int max_pages; /* max number of pages that can be possesed */ /* Network I/O */ net_ring_t *net_ring_base; diff --git a/xen/net/dev.c b/xen/net/dev.c index 0bf8125014..03039e9c81 100644 --- a/xen/net/dev.c +++ b/xen/net/dev.c @@ -657,10 +657,11 @@ static void add_to_net_schedule_list_tail(net_vif_t *vif) /* Destructor function for tx skbs. */ static void tx_skb_release(struct sk_buff *skb) { - int i; + int i, send = 0; net_vif_t *vif = sys_vif_list[skb->src_vif]; unsigned int idx; tx_shadow_entry_t *tx; + unsigned long cpu_mask; for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) put_page_tot(skb_shinfo(skb)->frags[i].page); @@ -691,9 +692,7 @@ static void tx_skb_release(struct sk_buff *skb) if ( idx == vif->shadow_ring->tx_idx ) BUG(); tx = &vif->shadow_ring->tx_ring[idx]; vif->shadow_ring->tx_cons = TX_RING_INC(idx); - if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event ) - set_bit(_EVENT_NET_TX, - &sys_vif_list[skb->src_vif]->domain->shared_info->events); + if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event ) send = 1; } while ( tx->status != RING_STATUS_OK ); /* Now skip over any more bad descriptors, up to the next good one. */ @@ -705,13 +704,19 @@ static void tx_skb_release(struct sk_buff *skb) (tx->status == RING_STATUS_OK) ) break; vif->shadow_ring->tx_cons = TX_RING_INC(idx); - if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event ) - set_bit(_EVENT_NET_TX, - &sys_vif_list[skb->src_vif]->domain->shared_info->events); + if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event ) send = 1; } while ( 1 ); - /* Finally, update shared consumer index to the new private value. */ + /* Update shared consumer index to the new private value. */ vif->net_ring->tx_cons = vif->shadow_ring->tx_cons; + + /* Send a transmit event if requested. */ + if ( send ) + { + cpu_mask = mark_guest_event( + sys_vif_list[skb->src_vif]->domain, _EVENT_NET_TX); + guest_event_notify(cpu_mask); + } } diff --git a/xenolinux-2.4.21-pre4-sparse/Makefile b/xenolinux-2.4.21-pre4-sparse/Makefile index d7a36f6fe0..29cdd72d2a 100644 --- a/xenolinux-2.4.21-pre4-sparse/Makefile +++ b/xenolinux-2.4.21-pre4-sparse/Makefile @@ -8,7 +8,8 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) # Xeno hack XXX -ARCH=xeno +ARCH := xeno +SUBARCH := i386 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g") @@ -361,7 +362,7 @@ include/linux/version.h: ./Makefile comma := , init/version.o: init/version.c include/linux/compile.h include/config/MARKER - $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(SUBARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c init/main.o: init/main.c include/config/MARKER $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $@ $< diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile b/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile index 544af84605..557fe98217 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile @@ -47,12 +47,14 @@ HEAD := arch/xeno/kernel/head.o arch/xeno/kernel/init_task.o SUBDIRS += arch/xeno/kernel arch/xeno/mm arch/xeno/lib SUBDIRS += arch/xeno/drivers/console arch/xeno/drivers/network SUBDIRS += arch/xeno/drivers/dom0 arch/xeno/drivers/block +SUBDIRS += arch/xeno/drivers/balloon CORE_FILES += arch/xeno/kernel/kernel.o arch/xeno/mm/mm.o CORE_FILES += arch/xeno/drivers/console/con.o CORE_FILES += arch/xeno/drivers/block/blk.o CORE_FILES += arch/xeno/drivers/network/net.o CORE_FILES += arch/xeno/drivers/dom0/dom0.o +CORE_FILES += arch/xeno/drivers/balloon/balloon_driver.o LIBS := $(TOPDIR)/arch/xeno/lib/lib.a $(LIBS) $(TOPDIR)/arch/xeno/lib/lib.a arch/xeno/kernel: dummy @@ -73,6 +75,9 @@ arch/xeno/drivers/block: dummy arch/xeno/drivers/dom0: dummy $(MAKE) linuxsubdirs SUBDIRS=arch/xeno/drivers/dom0 +arch/xeno/drivers/balloon: dummy + $(MAKE) linuxsubdirs SUBDIRS=arch/xeno/drivers/balloon + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot vmlinux: arch/xeno/vmlinux.lds diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile new file mode 100644 index 0000000000..f780a515e0 --- /dev/null +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile @@ -0,0 +1,3 @@ +O_TARGET := balloon_driver.o +obj-y := balloon.o +include $(TOPDIR)/Rules.make diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c new file mode 100644 index 0000000000..abe5884800 --- /dev/null +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c @@ -0,0 +1,275 @@ +/****************************************************************************** + * balloon.c + * + * Xeno balloon driver - enables returning/claiming memory to/from xen + * + * Copyright (c) 2003, B Dragovic + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <linux/proc_fs.h> + +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/smp_lock.h> +#include <linux/pagemap.h> + +#include <asm/hypervisor.h> +#include <asm/pgalloc.h> +#include <asm/pgtable.h> +#include <asm/uaccess.h> +#include <asm/tlb.h> + +#include "dom_mem_ops.h" + +/* USER DEFINES -- THESE SHOULD BE COPIED TO USER-SPACE TOOLS */ +#define USER_INFLATE_BALLOON 1 /* return mem to hypervisor */ +#define USER_DEFLATE_BALLOON 2 /* claim mem from hypervisor */ +typedef struct user_balloon_op { + unsigned int op; + unsigned long size; +} user_balloon_op_t; +/* END OF USER DEFINE */ + +/* Dead entry written into ballon-owned entries in the PMT. */ +#define DEAD 0xdeadbeef + +#define BALLOON_ENTRY "balloon" +extern struct proc_dir_entry *xeno_base; + +static struct proc_dir_entry *balloon_pde; +unsigned long credit; + +static inline unsigned long get_ppte(unsigned long addr) +{ + unsigned long ppte; + pgd_t *pgd; pmd_t *pmd; pte_t *ptep; + pgd = pgd_offset_k(addr); + + if ( pgd_none(*pgd) || pgd_bad(*pgd) ) BUG(); + + pmd = pmd_offset(pgd, addr); + if ( pmd_none(*pmd) || pmd_bad(*pmd) ) BUG(); + + ptep = pte_offset(pmd, addr); + ppte = (unsigned long)__pa(ptep); + + return ppte; +} + +/* main function for relinquishing bit of memory */ +static unsigned long inflate_balloon(unsigned long num_pages) +{ + dom_mem_op_t dom_mem_op; + unsigned long *parray; + unsigned long *currp; + unsigned long ret = 0; + unsigned long vaddr; + unsigned long i, j; + + parray = (unsigned long *)kmalloc(num_pages * + sizeof(unsigned long), GFP_KERNEL); + currp = parray; + + for ( i = 0; i < num_pages; i++ ) + { + /* try to obtain a free page, has to be done with GFP_ATOMIC + * as we do not want to sleep indefinately. + */ + vaddr = __get_free_page(GFP_ATOMIC); + + /* if allocation fails, free all reserved pages */ + if(!vaddr){ + printk("Unable to inflate balloon by %ld, only %ld pages free.", + num_pages, i); + currp = parray; + for(j = 0; j < i; j++){ + free_page(*currp++); + } + goto cleanup; + } + + *currp++ = vaddr; + } + + + currp = parray; + for ( i = 0; i < num_pages; i++ ) + { + queue_l1_entry_update(get_ppte(*currp) | PGREQ_NORMAL, 0); + phys_to_machine_mapping[__pa(*currp) >> PAGE_SHIFT] = DEAD; + currp++; + } + + XENO_flush_page_update_queue(); + + dom_mem_op.op = BALLOON_INFLATE_OP; + dom_mem_op.u.balloon_inflate.size = num_pages; + dom_mem_op.u.balloon_inflate.pages = parray; + if ( (ret = HYPERVISOR_dom_mem_op(&dom_mem_op)) != num_pages ) + { + printk("Unable to deflate balloon, error %lx\n", ret); + goto cleanup; + } + + credit += num_pages; + ret = num_pages; + + cleanup: + kfree(parray); + + return ret; +} + +/* install new mem pages obtained by deflate_balloon. function walks + * phys->machine mapping table looking for DEAD entries and populates + * them. + */ +static unsigned long process_new_pages(unsigned long * parray, + unsigned long num) +{ + /* currently, this function is rather simplistic as + * it is assumed that domain reclaims only number of + * pages previously released. this is to change soon + * and the code to extend page tables etc. will be + * incorporated here. + */ + + unsigned long tot_pages = start_info.nr_pages; + unsigned long * curr = parray; + unsigned long num_installed; + unsigned long i; + + num_installed = 0; + for ( i = 0; i < tot_pages; i++ ) + { + if ( phys_to_machine_mapping[i] == DEAD ) + { + phys_to_machine_mapping[i] = *curr; + queue_l1_entry_update((i << PAGE_SHIFT) | PGREQ_MPT_UPDATE, i); + queue_l1_entry_update( + get_ppte((unsigned long)__va(i << PAGE_SHIFT)) | PGREQ_NORMAL, + ((*curr) << PAGE_SHIFT) | L1_PROT); + + *curr = (unsigned long)__va(i << PAGE_SHIFT); + curr++; + num_installed++; + } + } + + /* now, this is tricky (and will also change for machine addrs that + * are mapped to not previously released addresses). we free pages + * that were allocated by get_free_page (the mappings are different + * now, of course). + */ + curr = parray; + for ( i = 0; i < num_installed; i++ ) + { + free_page(*curr); + curr++; + } + + return num_installed; +} + +static unsigned long deflate_balloon(unsigned long num_pages) +{ + dom_mem_op_t dom_mem_op; + unsigned long ret; + unsigned long * parray; + + if ( num_pages > credit ) + { + printk("Can not allocate more pages than previously released.\n"); + return -EAGAIN; + } + + parray = (unsigned long *)kmalloc(num_pages * sizeof(unsigned long), + GFP_KERNEL); + + dom_mem_op.op = BALLOON_DEFLATE_OP; + dom_mem_op.u.balloon_deflate.size = num_pages; + dom_mem_op.u.balloon_deflate.pages = parray; + if((ret = HYPERVISOR_dom_mem_op(&dom_mem_op)) != num_pages){ + printk("Unable to deflate balloon, error %lx\n", ret); + goto cleanup; + } + + if((ret = process_new_pages(parray, num_pages)) < num_pages){ + printk("Unable to deflate balloon by specified %lx pages, only %lx.\n", + num_pages, ret); + goto cleanup; + } + + ret = num_pages; + + cleanup: + kfree(parray); + + return ret; +} + +static int balloon_write(struct file *file, const char *buffer, + u_long count, void *data) +{ + user_balloon_op_t bop; + + /* Only admin can play with the balloon :) */ + if ( !capable(CAP_SYS_ADMIN) ) + return -EPERM; + + if ( copy_from_user(&bop, buffer, sizeof(bop)) ) + return -EFAULT; + + switch ( bop.op ) + { + case USER_INFLATE_BALLOON: + if ( inflate_balloon(bop.size) < bop.size ) + return -EAGAIN; + break; + + case USER_DEFLATE_BALLOON: + deflate_balloon(bop.size); + break; + + default: + printk("Unknown command to balloon driver."); + return -EFAULT; + } + + return sizeof(bop); +} + +/* + * main balloon driver initialization function. + */ +static int __init init_module(void) +{ + printk(KERN_ALERT "Starting Xeno Balloon driver\n"); + + credit = 0; + + balloon_pde = create_proc_entry(BALLOON_ENTRY, 0600, xeno_base); + if ( balloon_pde == NULL ) + { + printk(KERN_ALERT "Unable to create balloon driver proc entry!"); + return -1; + } + + balloon_pde->write_proc = balloon_write; + + return 0; +} + +static void __exit cleanup_module(void) +{ +} + +module_init(init_module); +module_exit(cleanup_module); + + diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h new file mode 100644 index 0000000000..c473f193e7 --- /dev/null +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * dom_mem_ops.h + * + * Header file supporting domain related memory operations. N.B. keep in sync + * with xen version. + * + * Copyright (c) 2003, B Dragovic + */ + +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED) +#define BALLOON_DEFLATE_OP 0 +#define BALLOON_INFLATE_OP 1 + +typedef struct balloon_deflate_op { + unsigned long size; + unsigned long * pages; +} balloon_def_op_t; + +typedef struct balloon_inflate_op { + unsigned long size; + unsigned long * pages; +} balloon_inf_op_t; + +typedef struct dom_mem_ops +{ + unsigned int op; + union + { + balloon_def_op_t balloon_deflate; + balloon_inf_op_t balloon_inflate; + }u; +} dom_mem_op_t; diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c index f8af85358b..c36ab02e96 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c @@ -53,7 +53,7 @@ typedef struct proc_mem_data { #define MAP_DISCONT 1 -static struct proc_dir_entry *xeno_base; +struct proc_dir_entry *xeno_base; static struct proc_dir_entry *dom0_cmd_intf; static struct proc_dir_entry *proc_ft; diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c index c9acaf43ee..7ef9ce4ef8 100644 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c @@ -23,6 +23,7 @@ #include <asm/io.h> #include <net/sock.h> +#include <net/pkt_sched.h> #define NET_TX_IRQ _EVENT_NET_TX #define NET_RX_IRQ _EVENT_NET_RX @@ -65,7 +66,20 @@ struct net_private spinlock_t tx_lock; }; - + +static void dbg_network_int(int irq, void *dev_id, struct pt_regs *ptregs) +{ + struct net_device *dev = (struct net_device *)dev_id; + struct net_private *np = dev->priv; + printk(KERN_ALERT "tx_full = %d, tx_entries = %d, tx_idx = %d," + " tx_cons = %d, tx_prod = %d, tx_event = %d, state=%d\n", + np->tx_full, atomic_read(&np->tx_entries), np->tx_idx, + np->net_ring->tx_cons, np->net_ring->tx_prod, + np->net_ring->tx_event, + test_bit(__LINK_STATE_XOFF, &dev->state)); +} + + static int network_open(struct net_device *dev) { struct net_private *np = dev->priv; @@ -123,6 +137,14 @@ static int network_open(struct net_device *dev) goto fail; } + error = request_irq(_EVENT_DEBUG, dbg_network_int, SA_SHIRQ, + "debug", dev); + if ( error ) + { + printk(KERN_WARNING "%s: Non-fatal error -- no debug interrupt\n", + dev->name); + } + printk("XenoLinux Virtual Network Driver installed as %s\n", dev->name); netif_start_queue(dev); @@ -147,17 +169,28 @@ static void network_tx_buf_gc(struct net_device *dev) struct net_private *np = dev->priv; struct sk_buff *skb; unsigned long flags; + unsigned int cons; spin_lock_irqsave(&np->tx_lock, flags); - for ( i = np->tx_idx; i != np->net_ring->tx_cons; i = TX_RING_INC(i) ) - { - skb = np->tx_skb_ring[i]; - dev_kfree_skb_any(skb); - atomic_dec(&np->tx_entries); - } + do { + cons = np->net_ring->tx_cons; - np->tx_idx = i; + for ( i = np->tx_idx; i != cons; i = TX_RING_INC(i) ) + { + skb = np->tx_skb_ring[i]; + dev_kfree_skb_any(skb); + atomic_dec(&np->tx_entries); + } + + np->tx_idx = i; + + /* Set a new event, then check for race with update of tx_cons. */ + np->net_ring->tx_event = + TX_RING_ADD(cons, (atomic_read(&np->tx_entries)>>1) + 1); + smp_mb(); + } + while ( cons != np->net_ring->tx_cons ); if ( np->tx_full && (atomic_read(&np->tx_entries) < TX_MAX_ENTRIES) ) { @@ -262,17 +295,9 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) { np->tx_full = 1; netif_stop_queue(dev); - np->net_ring->tx_event = - TX_RING_ADD(np->tx_idx, atomic_read(&np->tx_entries) >> 1); - } - else - { - /* Avoid unnecessary tx interrupts. */ - np->net_ring->tx_event = TX_RING_INC(np->net_ring->tx_prod); } spin_unlock_irq(&np->tx_lock); - /* Must do this after setting tx_event: race with updates of tx_cons. */ network_tx_buf_gc(dev); HYPERVISOR_net_update(); diff --git a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h index df25598730..16f37cfe65 100644 --- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h +++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h @@ -313,4 +313,15 @@ static inline int HYPERVISOR_set_fast_trap(int idx) return ret; } +static inline int HYPERVISOR_dom_mem_op(void *dom_mem_op) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op), + "b" (dom_mem_op) : "memory" ); + + return ret; +} + #endif /* __HYPERVISOR_H__ */ diff --git a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h index e157a31a36..aad36820b7 100644 --- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h +++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h @@ -173,6 +173,10 @@ static __inline__ int get_order(unsigned long size) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +/* VIRT <-> MACHINE conversion */ +#define virt_to_machine(_a) (phys_to_machine(__pa(_a))) +#define machine_to_virt(_m) (__va(machine_to_phys(_m))) + #endif /* __KERNEL__ */ #endif /* _I386_PAGE_H */ |