ia64/xen-unstable

changeset 259:9c04a98c7932

bitkeeper revision 1.105.1.8 (3e63781aEVDfQh1rIWk8m6mnaO7HtA)

Merge labyrinth.cl.cam.ac.uk:/usr/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/local/scratch/kaf24/bd-xeno
author kaf24@labyrinth.cl.cam.ac.uk
date Mon Mar 03 15:43:22 2003 +0000 (2003-03-03)
parents cbf732c2b28c cc4b8df6bd54
children d5a6350b99c8 7233489302e6 73453fd4320b
files .rootkeys tools/balloon/Makefile tools/balloon/README tools/balloon/balloon.c xen/arch/i386/entry.S xen/common/dom_mem_ops.c xen/common/domain.c xen/common/memory.c xen/include/hypervisor-ifs/hypervisor-if.h xen/include/xeno/dom_mem_ops.h xen/include/xeno/sched.h xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h
line diff
     1.1 --- a/.rootkeys	Sun Mar 02 16:22:59 2003 +0000
     1.2 +++ b/.rootkeys	Mon Mar 03 15:43:22 2003 +0000
     1.3 @@ -176,6 +176,9 @@ 3ddb79bbP31im-mx2NbfthSeqty1Dg old/xenol
     1.4  3e15d52e0_j129JPvo7xfYGndVFpwQ old/xenolinux-2.4.16-sparse/mm/memory.c
     1.5  3e15d535DLvpzTrLRUIerB69LpJD1g old/xenolinux-2.4.16-sparse/mm/mremap.c
     1.6  3e15d531m1Y1_W8ki64AFOU_ua4C4w old/xenolinux-2.4.16-sparse/mm/swapfile.c
     1.7 +3e6377b24eQqYMsDi9XrFkIgTzZ47A tools/balloon/Makefile
     1.8 +3e6377d6eiFjF1hHIS6JEIOFk62xSA tools/balloon/README
     1.9 +3e6377dbGcgnisKw16DPCaND7oGO3Q tools/balloon/balloon.c
    1.10  3e4d00468-FN2VDeEHo96zxrMHK_mA tools/domain_builder/Makefile
    1.11  3e4d0046SPau_y0sw2WLJz8QkqNoRA tools/domain_builder/README
    1.12  3e4d0046bbdH0GsI9J_1Eb4ZQHfIiQ tools/domain_builder/dom0_defs.h
    1.13 @@ -226,6 +229,7 @@ 3e397e66AyyD5fYraAySWuwi9uqSXg xen/commo
    1.14  3ddb79bddEYJbcURvqqcx99Yl2iAhQ xen/common/block.c
    1.15  3ddb79bdrqnW93GR9gZk1OJe1qK-iQ xen/common/brlock.c
    1.16  3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c
    1.17 +3e6377e4i0c9GtKN65e99OtRbw3AZw xen/common/dom_mem_ops.c
    1.18  3ddb79bdYO5D8Av12NHqPeSviav7cg xen/common/domain.c
    1.19  3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/common/domain_page.c
    1.20  3ddb79bdeyutmaXEfpQvvxj7eQ0fCw xen/common/event.c
    1.21 @@ -399,6 +403,7 @@ 3ddb79c259jh8hE7vre_8NuE7nwNSA xen/inclu
    1.22  3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xeno/ctype.h
    1.23  3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xeno/delay.h
    1.24  3ddb79c2PMeWTK86y4C3F4MzHw4A1g xen/include/xeno/dom0_ops.h
    1.25 +3e6377eaioRoNm0m_HSDEAd4Vqrq_w xen/include/xeno/dom_mem_ops.h
    1.26  3ddb79c1uaWQZj551j1O0B5z8AnHOg xen/include/xeno/elevator.h
    1.27  3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xeno/errno.h
    1.28  3ddb79c0rMjudDKkJku_mkm0J-BZgw xen/include/xeno/etherdevice.h
    1.29 @@ -463,6 +468,9 @@ 3e5a4e65IEPjnWPZ5w3TxS5scV8Ewg xenolinux
    1.30  3e5a4e65n-KhsEAs-A4ULiStBp-r6w xenolinux-2.4.21-pre4-sparse/arch/xeno/boot/Makefile
    1.31  3e5a4e65OV_j_DBtjzt5vej771AJsA xenolinux-2.4.21-pre4-sparse/arch/xeno/config.in
    1.32  3e5a4e65TNEycLeXqPSXQJQm_xGecA xenolinux-2.4.21-pre4-sparse/arch/xeno/defconfig
    1.33 +3e6377f5xwPfYZkPHPrDbEq1PRN7uQ xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile
    1.34 +3e6377f8Me8IqtvEhb70XFgOvqQH7A xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c
    1.35 +3e6377fbMjXWAQd0XN0FWv4fDEo6fg xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h
    1.36  3e5a4e65iHEuC5sjFhj42XALYbLVRw xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/Makefile
    1.37  3e5a4e65pP5spJErBW69pJxSSdK9RA xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block.c
    1.38  3e5a4e65GtI9JZRAjuRdXaxt_4ohyQ xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/block/xl_block_test.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/balloon/Makefile	Mon Mar 03 15:43:22 2003 +0000
     2.3 @@ -0,0 +1,9 @@
     2.4 +CC = gcc
     2.5 +TARGET=balloon
     2.6 +
     2.7 +TARGET: balloon.c
     2.8 +	$(CC) -O2 -Wall -o $(TARGET) balloon.c
     2.9 +
    2.10 +clean:
    2.11 +	$(RM) *.o $(TARGET) *~
    2.12 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/balloon/README	Mon Mar 03 15:43:22 2003 +0000
     3.3 @@ -0,0 +1,17 @@
     3.4 +Xeno Balloon driver supports two operations:
     3.5 +
     3.6 +1. Inflating - which means domain giving up pages of mem to xen.
     3.7 +2. Deflating - which means reclaiming memory pages from xen.
     3.8 +
     3.9 +Currently, domain can only claim pages from xen up to the number of 
    3.10 +previously released ones. This is to change. 
    3.11 +
    3.12 +Example:
    3.13 +
    3.14 +# balloon inflate 1000
    3.15 +
    3.16 +Give up 1000 pages to xen.
    3.17 +
    3.18 +# balloon deflate 1000
    3.19 +
    3.20 +Claim 1000 pages from xen.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/balloon/balloon.c	Mon Mar 03 15:43:22 2003 +0000
     4.3 @@ -0,0 +1,114 @@
     4.4 +/******************************************************************************
     4.5 + * balloon.c
     4.6 + *
     4.7 + * Xeno balloon driver userspace control tool. Used to shrink/grow domain's 
     4.8 + * memory.
     4.9 + *
    4.10 + * Copyright (c) 2003, B Dragovic
    4.11 + */
    4.12 +
    4.13 +#include <stdio.h>
    4.14 +#include <stdlib.h>
    4.15 +#include <string.h>
    4.16 +#include <errno.h>
    4.17 +#include <unistd.h>
    4.18 +#include <sys/types.h>
    4.19 +#include <sys/stat.h>
    4.20 +#include <fcntl.h>
    4.21 +
    4.22 +#define INFLATE_BALLOON      "inflate"   /* return mem to hypervisor */
    4.23 +#define DEFLATE_BALLOON      "deflate"   /* claim mem from hypervisor */
    4.24 +
    4.25 +/* THIS IS TAKEN FROM XENOLINUX BALLOON DRIVER */
    4.26 +#define USER_INFLATE_BALLOON  1   /* return mem to hypervisor */
    4.27 +#define USER_DEFLATE_BALLOON  2   /* claim mem from hypervisor */
    4.28 +typedef struct user_balloon_op {
    4.29 +    unsigned int    op;
    4.30 +    unsigned long   size;
    4.31 +} user_balloon_op_t;
    4.32 +/* END OF CODE TAKEN FROM XENOLINUX BALLOON DRIVER */
    4.33 +
    4.34 +
    4.35 +static int open_balloon_proc()
    4.36 +{
    4.37 +    return open("/proc/xeno/balloon", O_RDWR);
    4.38 +}
    4.39 +
    4.40 +/* inflate balloon function signals to kernel it should relinquish memory */
    4.41 +static int inflate_balloon(unsigned long num_pages)
    4.42 +{
    4.43 +    user_balloon_op_t bop;
    4.44 +    int proc_fd;
    4.45 +
    4.46 +    if((proc_fd = open_balloon_proc()) <= 0){
    4.47 +        printf("Error opening balloon proc file.\n");
    4.48 +        return 0;
    4.49 +    }
    4.50 +
    4.51 +    bop.op   = USER_INFLATE_BALLOON;
    4.52 +    bop.size = num_pages;
    4.53 +    if ( write(proc_fd, &bop, sizeof(bop)) <= 0 )
    4.54 +    {
    4.55 +        printf("Error writing to balloon proc file.\n");
    4.56 +        return 0;
    4.57 +    }
    4.58 +
    4.59 +    close(proc_fd);
    4.60 +    return 1;
    4.61 +}
    4.62 +
    4.63 +/* deflate balloon function signals to kernel it should claim memory */
    4.64 +static int deflate_balloon(unsigned long num_pages)
    4.65 +{
    4.66 +    user_balloon_op_t bop;
    4.67 +    int proc_fd;
    4.68 +
    4.69 +    if((proc_fd = open_balloon_proc()) <= 0){
    4.70 +        printf("Error opening balloon proc file.\n");
    4.71 +        return 0;
    4.72 +    }
    4.73 +
    4.74 +    bop.op   = USER_DEFLATE_BALLOON;
    4.75 +    bop.size = num_pages;
    4.76 +    if(write(proc_fd, &bop, sizeof(bop)) <= 0){
    4.77 +        printf("Error writing to balloon proc file.\n");
    4.78 +        return 0;
    4.79 +    }
    4.80 +
    4.81 +    close(proc_fd);
    4.82 +    return 1;
    4.83 +}
    4.84 +
    4.85 +int main(int argc, char *argv[])
    4.86 +{
    4.87 +    unsigned long num_pages;
    4.88 +
    4.89 +    if(argc < 2){
    4.90 +        printf("Usage: balloon <inflate|deflate> <num_pages>\n");
    4.91 +        return -1;
    4.92 +    }
    4.93 +
    4.94 +    num_pages = atol(argv[2]);
    4.95 +
    4.96 +    if(!strcmp(argv[1], INFLATE_BALLOON)){
    4.97 +        if(!inflate_balloon(num_pages)){
    4.98 +            perror("Inflating balloon failed");
    4.99 +            return -1;
   4.100 +        }
   4.101 +
   4.102 +    } else if (!strcmp(argv[1], DEFLATE_BALLOON)){
   4.103 +        if(!deflate_balloon(num_pages)){
   4.104 +            perror("Deflating balloon failed");
   4.105 +            return -1;
   4.106 +        }
   4.107 +
   4.108 +    } else {
   4.109 +        printf("Unrecognized command line argument.\n");
   4.110 +        return -1;
   4.111 +    }
   4.112 +
   4.113 +    return 0;
   4.114 +}
   4.115 +
   4.116 +    
   4.117 +
     5.1 --- a/xen/arch/i386/entry.S	Sun Mar 02 16:22:59 2003 +0000
     5.2 +++ b/xen/arch/i386/entry.S	Mon Mar 03 15:43:22 2003 +0000
     5.3 @@ -529,6 +529,7 @@ ENTRY(hypervisor_call_table)
     5.4          .long SYMBOL_NAME(do_get_debugreg)
     5.5          .long SYMBOL_NAME(do_update_descriptor)
     5.6          .long SYMBOL_NAME(do_set_fast_trap)
     5.7 +        .long SYMBOL_NAME(do_dom_mem_op)
     5.8          .rept NR_syscalls-(.-hypervisor_call_table)/4
     5.9          .long SYMBOL_NAME(sys_ni_syscall)
    5.10  	.endr
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/common/dom_mem_ops.c	Mon Mar 03 15:43:22 2003 +0000
     6.3 @@ -0,0 +1,144 @@
     6.4 +/******************************************************************************
     6.5 + * dom_mem_ops.c
     6.6 + *
     6.7 + * Code to handle memory related requests from domains eg. balloon driver.
     6.8 + *
     6.9 + * Copyright (c) 2003, B Dragovic
    6.10 + */
    6.11 +
    6.12 +#include <xeno/config.h>
    6.13 +#include <xeno/types.h>
    6.14 +#include <xeno/lib.h>
    6.15 +#include <xeno/dom_mem_ops.h>
    6.16 +#include <xeno/sched.h>
    6.17 +#include <xeno/event.h>
    6.18 +#include <asm/domain_page.h>
    6.19 +
    6.20 +#if 1
    6.21 +#define DPRINTK(_f, _a...) printk( _f , ## _a )
    6.22 +#else
    6.23 +#define DPRINTK(_f, _a...) ((void)0)
    6.24 +#endif
    6.25 +
    6.26 +static long alloc_dom_mem(struct task_struct *p, balloon_def_op_t bop)
    6.27 +{
    6.28 +    struct list_head *temp;
    6.29 +    struct pfn_info  *pf;     /* pfn_info of current page */
    6.30 +    unsigned long     mpfn;   /* machine frame number of current page */
    6.31 +    void             *va;     /* Xen-usable mapping of current page */
    6.32 +    unsigned long     i;
    6.33 +    unsigned long     flags;
    6.34 +
    6.35 +    /* POLICY DECISION: Each domain has a page limit. */
    6.36 +    if( (p->tot_pages + bop.size) > p->max_pages )
    6.37 +        return -ENOMEM;
    6.38 +
    6.39 +    if ( free_pfns < bop.size ) 
    6.40 +        return -ENOMEM;
    6.41 +    
    6.42 +    spin_lock_irqsave(&free_list_lock, flags);
    6.43 +    
    6.44 +    temp = free_list.next;
    6.45 +    for ( i = 0; i < bop.size; i++ )
    6.46 +    {
    6.47 +        /* Get a free page and add it to the domain's page list. */
    6.48 +        pf = list_entry(temp, struct pfn_info, list);
    6.49 +        pf->flags |= p->domain;
    6.50 +        pf->type_count = pf->tot_count = 0;
    6.51 +        temp = temp->next;
    6.52 +        list_del(&pf->list);
    6.53 +        list_add_tail(&pf->list, &p->pg_head);
    6.54 +        free_pfns--;
    6.55 +
    6.56 +        p->tot_pages++;
    6.57 +
    6.58 +        /* Inform the domain of the new page's machine address. */ 
    6.59 +        mpfn = (unsigned long)(pf - frame_table);
    6.60 +        copy_to_user(bop.pages, &mpfn, sizeof(mpfn));
    6.61 +        bop.pages++; 
    6.62 +
    6.63 +        /* Zero out the page to prevent information leakage. */
    6.64 +        va = map_domain_mem(mpfn << PAGE_SHIFT);
    6.65 +        memset(va, 0, PAGE_SIZE);
    6.66 +        unmap_domain_mem(va);
    6.67 +    }
    6.68 +
    6.69 +    spin_unlock_irqrestore(&free_list_lock, flags);
    6.70 +    
    6.71 +    return bop.size;
    6.72 +}
    6.73 +    
    6.74 +static long free_dom_mem(struct task_struct *p, balloon_inf_op_t bop)
    6.75 +{
    6.76 +    struct list_head *temp;
    6.77 +    struct pfn_info  *pf;     /* pfn_info of current page */
    6.78 +    unsigned long     mpfn;   /* machine frame number of current page */
    6.79 +    unsigned long     i;
    6.80 +    unsigned long     flags;
    6.81 +    long              rc = 0;
    6.82 +
    6.83 +    spin_lock_irqsave(&free_list_lock, flags);
    6.84 +    
    6.85 +    temp = free_list.next;
    6.86 +    for ( i = 0; i < bop.size; i++ )
    6.87 +    {
    6.88 +        copy_from_user(&mpfn, bop.pages, sizeof(mpfn));
    6.89 +        bop.pages++;
    6.90 +        if ( mpfn >= max_page )
    6.91 +        {
    6.92 +            DPRINTK("Domain %d page number out of range (%08lx>=%08lx)\n", 
    6.93 +                    p->domain, mpfn, max_page);
    6.94 +            rc = -EINVAL;
    6.95 +            goto out;
    6.96 +        }
    6.97 +
    6.98 +        pf = &frame_table[mpfn];
    6.99 +        if ( (pf->type_count != 0) || 
   6.100 +             (pf->type_count != 0) ||
   6.101 +             (pf->flags != p->domain) )
   6.102 +        {
   6.103 +            DPRINTK("Bad page free for domain %d (%ld, %ld, %08lx)\n",
   6.104 +                    p->domain, pf->type_count, pf->tot_count, pf->flags);
   6.105 +            rc = -EINVAL;
   6.106 +            goto out;
   6.107 +        }
   6.108 +
   6.109 +        pf->flags = 0;
   6.110 +
   6.111 +        list_del(&pf->list);
   6.112 +        list_add(&pf->list, &free_list);
   6.113 +        free_pfns++;
   6.114 +
   6.115 +        p->tot_pages--;
   6.116 +    }
   6.117 +
   6.118 + out:
   6.119 +    spin_unlock_irqrestore(&free_list_lock, flags);
   6.120 +    
   6.121 +    return rc ? rc : bop.size;
   6.122 +}
   6.123 +    
   6.124 +long do_dom_mem_op(dom_mem_op_t *mem_op)
   6.125 +{
   6.126 +    dom_mem_op_t dmop;
   6.127 +    unsigned long ret = 0;
   6.128 +
   6.129 +    if ( copy_from_user(&dmop, mem_op, sizeof(dom_mem_op_t)) )
   6.130 +        return -EFAULT;
   6.131 +
   6.132 +    switch ( dmop.op )
   6.133 +    {
   6.134 +    case BALLOON_DEFLATE_OP:
   6.135 +        ret = alloc_dom_mem(current, dmop.u.balloon_deflate); 
   6.136 +        break;
   6.137 +
   6.138 +    case BALLOON_INFLATE_OP:
   6.139 +        ret = free_dom_mem(current, dmop.u.balloon_inflate); 
   6.140 +        break;
   6.141 +
   6.142 +    default:
   6.143 +        printk("Bad memory operation request %08x.\n", dmop.op);
   6.144 +    }
   6.145 +
   6.146 +    return ret;    
   6.147 +}
     7.1 --- a/xen/common/domain.c	Sun Mar 02 16:22:59 2003 +0000
     7.2 +++ b/xen/common/domain.c	Mon Mar 03 15:43:22 2003 +0000
     7.3 @@ -63,7 +63,7 @@ struct task_struct *do_newdomain(unsigne
     7.4  
     7.5      p->net_ring_base = (net_ring_t *)(p->shared_info + 1);
     7.6      INIT_LIST_HEAD(&p->pg_head);
     7.7 -    p->tot_pages = 0;
     7.8 +    p->max_pages = p->tot_pages = 0;
     7.9      write_lock_irqsave(&tasklist_lock, flags);
    7.10      SET_LINKS(p);
    7.11      write_unlock_irqrestore(&tasklist_lock, flags);
    7.12 @@ -177,6 +177,9 @@ unsigned int alloc_new_dom_mem(struct ta
    7.13      
    7.14      p->tot_pages = req_pages;
    7.15  
    7.16 +    // temporary, max_pages should be explicitly specified
    7.17 +    p->max_pages = p->tot_pages;
    7.18 +
    7.19      return 0;
    7.20  }
    7.21   
     8.1 --- a/xen/common/memory.c	Sun Mar 02 16:22:59 2003 +0000
     8.2 +++ b/xen/common/memory.c	Mon Mar 03 15:43:22 2003 +0000
     8.3 @@ -768,7 +768,7 @@ int do_process_page_updates(page_update_
     8.4              {
     8.5                  MEM_LOG("Bad domain MPT update (dom %d, pfn %ld)",
     8.6                          current->domain, pfn);
     8.7 -            }
     8.8 +            }            
     8.9              break;
    8.10  
    8.11              /*
     9.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Sun Mar 02 16:22:59 2003 +0000
     9.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Mon Mar 03 15:43:22 2003 +0000
     9.3 @@ -38,13 +38,13 @@ typedef struct
     9.4   * Extended requests specify command in least 8 bits of 'value'.
     9.5   */
     9.6  /* A normal page-table update request. */
     9.7 -#define PGREQ_NORMAL           0
     9.8 +#define PGREQ_NORMAL            0
     9.9  /* Update an entry in the machine->physical mapping table. */
    9.10 -#define PGREQ_MPT_UPDATE       1
    9.11 +#define PGREQ_MPT_UPDATE        1
    9.12  /* An extended command. */
    9.13 -#define PGREQ_EXTENDED_COMMAND 2
    9.14 +#define PGREQ_EXTENDED_COMMAND  2
    9.15  /* DOM0 can make entirely unchecked updates which do not affect refcnts. */
    9.16 -#define PGREQ_UNCHECKED_UPDATE 3
    9.17 +#define PGREQ_UNCHECKED_UPDATE  3
    9.18      unsigned long ptr, val; /* *ptr = val */
    9.19  /* Announce a new top-level page table. */
    9.20  #define PGEXT_PIN_L1_TABLE      0
    9.21 @@ -90,6 +90,7 @@ typedef struct
    9.22  #define __HYPERVISOR_get_debugreg         13
    9.23  #define __HYPERVISOR_update_descriptor    14
    9.24  #define __HYPERVISOR_set_fast_trap        15
    9.25 +#define __HYPERVISOR_dom_mem_op           16
    9.26  
    9.27  #define TRAP_INSTR "int $0x82"
    9.28  
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xen/include/xeno/dom_mem_ops.h	Mon Mar 03 15:43:22 2003 +0000
    10.3 @@ -0,0 +1,31 @@
    10.4 +/******************************************************************************
    10.5 + * dom_mem_ops.h
    10.6 + *
    10.7 + * Header file supporting domain related memory operations. N.B. keep in sync
    10.8 + * with xen version. 
    10.9 + *
   10.10 + * Copyright (c) 2003, B Dragovic
   10.11 + */
   10.12 +
   10.13 +#define BALLOON_DEFLATE_OP   0
   10.14 +#define BALLOON_INFLATE_OP   1
   10.15 +
   10.16 +typedef struct balloon_deflate_op {
   10.17 +    unsigned long   size;
   10.18 +    unsigned long   * pages;
   10.19 +} balloon_def_op_t;
   10.20 +
   10.21 +typedef struct balloon_inflate_op {
   10.22 +    unsigned long   size;
   10.23 +    unsigned long   * pages;
   10.24 +} balloon_inf_op_t;
   10.25 +
   10.26 +typedef struct dom_mem_ops
   10.27 +{
   10.28 +    unsigned int op;
   10.29 +    union
   10.30 +    {
   10.31 +        balloon_def_op_t balloon_deflate;
   10.32 +        balloon_inf_op_t balloon_inflate;
   10.33 +    } u;
   10.34 +} dom_mem_op_t;
    11.1 --- a/xen/include/xeno/sched.h	Sun Mar 02 16:22:59 2003 +0000
    11.2 +++ b/xen/include/xeno/sched.h	Mon Mar 03 15:43:22 2003 +0000
    11.3 @@ -67,7 +67,8 @@ struct task_struct {
    11.4      shared_info_t *shared_info;
    11.5      
    11.6      struct list_head pg_head;
    11.7 -    unsigned int tot_pages;
    11.8 +    unsigned int tot_pages;     /* number of pages currently possesed */
    11.9 +    unsigned int max_pages;     /* max number of pages that can be possesed */
   11.10  
   11.11      /* Network I/O */
   11.12      net_ring_t *net_ring_base;
    12.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile	Sun Mar 02 16:22:59 2003 +0000
    12.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/Makefile	Mon Mar 03 15:43:22 2003 +0000
    12.3 @@ -47,12 +47,14 @@ HEAD := arch/xeno/kernel/head.o arch/xen
    12.4  SUBDIRS += arch/xeno/kernel arch/xeno/mm arch/xeno/lib
    12.5  SUBDIRS += arch/xeno/drivers/console arch/xeno/drivers/network
    12.6  SUBDIRS += arch/xeno/drivers/dom0 arch/xeno/drivers/block
    12.7 +SUBDIRS += arch/xeno/drivers/balloon
    12.8  
    12.9  CORE_FILES += arch/xeno/kernel/kernel.o arch/xeno/mm/mm.o
   12.10  CORE_FILES += arch/xeno/drivers/console/con.o
   12.11  CORE_FILES += arch/xeno/drivers/block/blk.o
   12.12  CORE_FILES += arch/xeno/drivers/network/net.o
   12.13  CORE_FILES += arch/xeno/drivers/dom0/dom0.o
   12.14 +CORE_FILES += arch/xeno/drivers/balloon/balloon_driver.o
   12.15  LIBS := $(TOPDIR)/arch/xeno/lib/lib.a $(LIBS) $(TOPDIR)/arch/xeno/lib/lib.a
   12.16  
   12.17  arch/xeno/kernel: dummy
   12.18 @@ -73,6 +75,9 @@ arch/xeno/drivers/block: dummy
   12.19  arch/xeno/drivers/dom0: dummy
   12.20  	$(MAKE) linuxsubdirs SUBDIRS=arch/xeno/drivers/dom0
   12.21  
   12.22 +arch/xeno/drivers/balloon: dummy
   12.23 +	$(MAKE) linuxsubdirs SUBDIRS=arch/xeno/drivers/balloon
   12.24 +
   12.25  MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
   12.26  
   12.27  vmlinux: arch/xeno/vmlinux.lds
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/Makefile	Mon Mar 03 15:43:22 2003 +0000
    13.3 @@ -0,0 +1,3 @@
    13.4 +O_TARGET := balloon_driver.o
    13.5 +obj-y := balloon.o
    13.6 +include $(TOPDIR)/Rules.make
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/balloon.c	Mon Mar 03 15:43:22 2003 +0000
    14.3 @@ -0,0 +1,275 @@
    14.4 +/******************************************************************************
    14.5 + * balloon.c
    14.6 + *
    14.7 + * Xeno balloon driver - enables returning/claiming memory to/from xen
    14.8 + *
    14.9 + * Copyright (c) 2003, B Dragovic
   14.10 + */
   14.11 +
   14.12 +#include <linux/config.h>
   14.13 +#include <linux/module.h>
   14.14 +#include <linux/kernel.h>
   14.15 +#include <linux/sched.h>
   14.16 +#include <linux/errno.h>
   14.17 +#include <linux/proc_fs.h>
   14.18 +
   14.19 +#include <linux/mm.h>
   14.20 +#include <linux/mman.h>
   14.21 +#include <linux/smp_lock.h>
   14.22 +#include <linux/pagemap.h>
   14.23 +
   14.24 +#include <asm/hypervisor.h>
   14.25 +#include <asm/pgalloc.h>
   14.26 +#include <asm/pgtable.h>
   14.27 +#include <asm/uaccess.h>
   14.28 +#include <asm/tlb.h>
   14.29 +
   14.30 +#include "dom_mem_ops.h"
   14.31 +
   14.32 +/* USER DEFINES -- THESE SHOULD BE COPIED TO USER-SPACE TOOLS */
   14.33 +#define USER_INFLATE_BALLOON  1   /* return mem to hypervisor */
   14.34 +#define USER_DEFLATE_BALLOON  2   /* claim mem from hypervisor */
   14.35 +typedef struct user_balloon_op {
   14.36 +    unsigned int  op;
   14.37 +    unsigned long size;
   14.38 +} user_balloon_op_t;
   14.39 +/* END OF USER DEFINE */
   14.40 +
   14.41 +/* Dead entry written into ballon-owned entries in the PMT. */
   14.42 +#define DEAD 0xdeadbeef
   14.43 +
   14.44 +#define BALLOON_ENTRY    "balloon"
   14.45 +extern struct proc_dir_entry *xeno_base;
   14.46 +
   14.47 +static struct proc_dir_entry *balloon_pde;
   14.48 +unsigned long credit;
   14.49 +
   14.50 +static inline unsigned long get_ppte(unsigned long addr)
   14.51 +{
   14.52 +    unsigned long ppte;
   14.53 +    pgd_t *pgd; pmd_t *pmd; pte_t *ptep;
   14.54 +    pgd = pgd_offset_k(addr);
   14.55 +
   14.56 +    if ( pgd_none(*pgd) || pgd_bad(*pgd) ) BUG();
   14.57 +
   14.58 +    pmd = pmd_offset(pgd, addr);
   14.59 +    if ( pmd_none(*pmd) || pmd_bad(*pmd) ) BUG();
   14.60 +
   14.61 +    ptep = pte_offset(pmd, addr);
   14.62 +    ppte = (unsigned long)__pa(ptep);
   14.63 +
   14.64 +    return ppte;
   14.65 +}
   14.66 +
   14.67 +/* main function for relinquishing bit of memory */
   14.68 +static unsigned long inflate_balloon(unsigned long num_pages)
   14.69 +{
   14.70 +    dom_mem_op_t dom_mem_op;
   14.71 +    unsigned long *parray;
   14.72 +    unsigned long *currp;
   14.73 +    unsigned long ret = 0;
   14.74 +    unsigned long vaddr;
   14.75 +    unsigned long i, j;
   14.76 +
   14.77 +    parray = (unsigned long *)kmalloc(num_pages *
   14.78 +                                      sizeof(unsigned long), GFP_KERNEL);
   14.79 +    currp = parray;
   14.80 +
   14.81 +    for ( i = 0; i < num_pages; i++ )
   14.82 +    {
   14.83 +        /* try to obtain a free page, has to be done with GFP_ATOMIC
   14.84 +         * as we do not want to sleep indefinately.
   14.85 +         */
   14.86 +        vaddr = __get_free_page(GFP_ATOMIC);
   14.87 +
   14.88 +        /* if allocation fails, free all reserved pages */
   14.89 +        if(!vaddr){
   14.90 +            printk("Unable to inflate balloon by %ld, only %ld pages free.",
   14.91 +                   num_pages, i);
   14.92 +            currp = parray;
   14.93 +            for(j = 0; j < i; j++){
   14.94 +                free_page(*currp++);
   14.95 +            }
   14.96 +            goto cleanup;
   14.97 +        }
   14.98 +
   14.99 +        *currp++ = vaddr;
  14.100 +    }
  14.101 +
  14.102 +
  14.103 +    currp = parray;
  14.104 +    for ( i = 0; i < num_pages; i++ )
  14.105 +    {
  14.106 +        queue_l1_entry_update(get_ppte(*currp) | PGREQ_NORMAL, 0);
  14.107 +        phys_to_machine_mapping[__pa(*currp) >> PAGE_SHIFT] = DEAD;
  14.108 +        currp++;
  14.109 +    }
  14.110 +
  14.111 +    XENO_flush_page_update_queue();
  14.112 +
  14.113 +    dom_mem_op.op = BALLOON_INFLATE_OP;
  14.114 +    dom_mem_op.u.balloon_inflate.size  = num_pages;
  14.115 +    dom_mem_op.u.balloon_inflate.pages = parray;
  14.116 +    if ( (ret = HYPERVISOR_dom_mem_op(&dom_mem_op)) != num_pages )
  14.117 +    {
  14.118 +        printk("Unable to deflate balloon, error %lx\n", ret);
  14.119 +        goto cleanup;
  14.120 +    }
  14.121 +
  14.122 +    credit += num_pages;
  14.123 +    ret = num_pages;
  14.124 +
  14.125 + cleanup:
  14.126 +    kfree(parray);
  14.127 +
  14.128 +    return ret;
  14.129 +}
  14.130 +
  14.131 +/* install new mem pages obtained by deflate_balloon. function walks 
  14.132 + * phys->machine mapping table looking for DEAD entries and populates
  14.133 + * them.
  14.134 + */
  14.135 +static unsigned long process_new_pages(unsigned long * parray, 
  14.136 +                                       unsigned long num)
  14.137 +{
  14.138 +    /* currently, this function is rather simplistic as 
  14.139 +     * it is assumed that domain reclaims only number of 
  14.140 +     * pages previously released. this is to change soon
  14.141 +     * and the code to extend page tables etc. will be 
  14.142 +     * incorporated here.
  14.143 +     */
  14.144 +     
  14.145 +    unsigned long tot_pages = start_info.nr_pages;   
  14.146 +    unsigned long * curr = parray;
  14.147 +    unsigned long num_installed;
  14.148 +    unsigned long i;
  14.149 +
  14.150 +    num_installed = 0;
  14.151 +    for ( i = 0; i < tot_pages; i++ )
  14.152 +    {
  14.153 +        if ( phys_to_machine_mapping[i] == DEAD )
  14.154 +        {
  14.155 +            phys_to_machine_mapping[i] = *curr;
  14.156 +            queue_l1_entry_update((i << PAGE_SHIFT) | PGREQ_MPT_UPDATE, i);
  14.157 +            queue_l1_entry_update(
  14.158 +                get_ppte((unsigned long)__va(i << PAGE_SHIFT)) | PGREQ_NORMAL, 
  14.159 +                ((*curr) << PAGE_SHIFT) | L1_PROT);
  14.160 +
  14.161 +            *curr = (unsigned long)__va(i << PAGE_SHIFT);
  14.162 +            curr++;
  14.163 +            num_installed++;
  14.164 +        }
  14.165 +    }
  14.166 +
  14.167 +    /* now, this is tricky (and will also change for machine addrs that 
  14.168 +      * are mapped to not previously released addresses). we free pages
  14.169 +      * that were allocated by get_free_page (the mappings are different 
  14.170 +      * now, of course).
  14.171 +      */
  14.172 +    curr = parray;
  14.173 +    for ( i = 0; i < num_installed; i++ )
  14.174 +    {
  14.175 +        free_page(*curr);
  14.176 +        curr++;
  14.177 +    }
  14.178 +
  14.179 +    return num_installed;
  14.180 +}
  14.181 +
  14.182 +static unsigned long deflate_balloon(unsigned long num_pages)
  14.183 +{
  14.184 +    dom_mem_op_t dom_mem_op;
  14.185 +    unsigned long ret;
  14.186 +    unsigned long * parray;
  14.187 +
  14.188 +    if ( num_pages > credit )
  14.189 +    {
  14.190 +        printk("Can not allocate more pages than previously released.\n");
  14.191 +        return -EAGAIN;
  14.192 +    }
  14.193 +
  14.194 +    parray = (unsigned long *)kmalloc(num_pages * sizeof(unsigned long), 
  14.195 +                                      GFP_KERNEL);
  14.196 +
  14.197 +    dom_mem_op.op = BALLOON_DEFLATE_OP;
  14.198 +    dom_mem_op.u.balloon_deflate.size = num_pages;
  14.199 +    dom_mem_op.u.balloon_deflate.pages = parray;
  14.200 +    if((ret = HYPERVISOR_dom_mem_op(&dom_mem_op)) != num_pages){
  14.201 +        printk("Unable to deflate balloon, error %lx\n", ret);
  14.202 +        goto cleanup;
  14.203 +    }
  14.204 +
  14.205 +    if((ret = process_new_pages(parray, num_pages)) < num_pages){
  14.206 +        printk("Unable to deflate balloon by specified %lx pages, only %lx.\n",
  14.207 +               num_pages, ret);
  14.208 +        goto cleanup;
  14.209 +    }
  14.210 +
  14.211 +    ret = num_pages;
  14.212 +
  14.213 + cleanup:
  14.214 +    kfree(parray);
  14.215 +
  14.216 +    return ret;
  14.217 +}
  14.218 +
  14.219 +static int balloon_write(struct file *file, const char *buffer,
  14.220 +                         u_long count, void *data)
  14.221 +{
  14.222 +    user_balloon_op_t bop;
  14.223 +
  14.224 +    /* Only admin can play with the balloon :) */
  14.225 +    if ( !capable(CAP_SYS_ADMIN) )
  14.226 +        return -EPERM;
  14.227 +
  14.228 +    if ( copy_from_user(&bop, buffer, sizeof(bop)) )
  14.229 +        return -EFAULT;
  14.230 +
  14.231 +    switch ( bop.op )
  14.232 +    {
  14.233 +    case USER_INFLATE_BALLOON:
  14.234 +        if ( inflate_balloon(bop.size) < bop.size )
  14.235 +            return -EAGAIN;
  14.236 +        break;
  14.237 +        
  14.238 +    case USER_DEFLATE_BALLOON:
  14.239 +        deflate_balloon(bop.size);
  14.240 +        break;
  14.241 +
  14.242 +    default:
  14.243 +        printk("Unknown command to balloon driver.");
  14.244 +        return -EFAULT;
  14.245 +    }
  14.246 +
  14.247 +    return sizeof(bop);
  14.248 +}
  14.249 +
  14.250 +/*
  14.251 + * main balloon driver initialization function.
  14.252 + */
  14.253 +static int __init init_module(void)
  14.254 +{
  14.255 +    printk(KERN_ALERT "Starting Xeno Balloon driver\n");
  14.256 +
  14.257 +    credit = 0;
  14.258 +
  14.259 +    balloon_pde = create_proc_entry(BALLOON_ENTRY, 0600, xeno_base);
  14.260 +    if ( balloon_pde == NULL )
  14.261 +    {
  14.262 +        printk(KERN_ALERT "Unable to create balloon driver proc entry!");
  14.263 +        return -1;
  14.264 +    }
  14.265 +
  14.266 +    balloon_pde->write_proc = balloon_write;
  14.267 +
  14.268 +    return 0;
  14.269 +}
  14.270 +
  14.271 +static void __exit cleanup_module(void)
  14.272 +{
  14.273 +}
  14.274 +
  14.275 +module_init(init_module);
  14.276 +module_exit(cleanup_module);
  14.277 +
  14.278 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/balloon/dom_mem_ops.h	Mon Mar 03 15:43:22 2003 +0000
    15.3 @@ -0,0 +1,32 @@
    15.4 +/******************************************************************************
    15.5 + * dom_mem_ops.h
    15.6 + *
    15.7 + * Header file supporting domain related memory operations. N.B. keep in sync
    15.8 + * with xen version. 
    15.9 + *
   15.10 + * Copyright (c) 2003, B Dragovic
   15.11 + */
   15.12 +
   15.13 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
   15.14 +#define BALLOON_DEFLATE_OP   0
   15.15 +#define BALLOON_INFLATE_OP   1
   15.16 +
   15.17 +typedef struct balloon_deflate_op {
   15.18 +    unsigned long   size;
   15.19 +    unsigned long   * pages;
   15.20 +} balloon_def_op_t;
   15.21 +
   15.22 +typedef struct balloon_inflate_op {
   15.23 +    unsigned long   size;
   15.24 +    unsigned long   * pages;
   15.25 +} balloon_inf_op_t;
   15.26 +
   15.27 +typedef struct dom_mem_ops
   15.28 +{
   15.29 +    unsigned int op;
   15.30 +    union
   15.31 +    {
   15.32 +        balloon_def_op_t balloon_deflate;
   15.33 +        balloon_inf_op_t balloon_inflate;
   15.34 +    }u;
   15.35 +} dom_mem_op_t;
    16.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c	Sun Mar 02 16:22:59 2003 +0000
    16.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/dom0/dom0_core.c	Mon Mar 03 15:43:22 2003 +0000
    16.3 @@ -53,7 +53,7 @@ typedef struct proc_mem_data {
    16.4  
    16.5  #define MAP_DISCONT     1
    16.6  
    16.7 -static struct proc_dir_entry *xeno_base;
    16.8 +struct proc_dir_entry *xeno_base;
    16.9  static struct proc_dir_entry *dom0_cmd_intf;
   16.10  static struct proc_dir_entry *proc_ft;
   16.11  
    17.1 --- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h	Sun Mar 02 16:22:59 2003 +0000
    17.2 +++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/hypervisor.h	Mon Mar 03 15:43:22 2003 +0000
    17.3 @@ -313,4 +313,15 @@ static inline int HYPERVISOR_set_fast_tr
    17.4      return ret;
    17.5  }
    17.6  
    17.7 +static inline int HYPERVISOR_dom_mem_op(void *dom_mem_op)
    17.8 +{
    17.9 +    int ret;
   17.10 +    __asm__ __volatile__ (
   17.11 +        TRAP_INSTR
   17.12 +        : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
   17.13 +        "b" (dom_mem_op) : "memory" );
   17.14 +
   17.15 +    return ret;
   17.16 +}
   17.17 +
   17.18  #endif /* __HYPERVISOR_H__ */
    18.1 --- a/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h	Sun Mar 02 16:22:59 2003 +0000
    18.2 +++ b/xenolinux-2.4.21-pre4-sparse/include/asm-xeno/page.h	Mon Mar 03 15:43:22 2003 +0000
    18.3 @@ -173,6 +173,10 @@ static __inline__ int get_order(unsigned
    18.4  #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
    18.5  				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
    18.6  
    18.7 +/* VIRT <-> MACHINE conversion */
    18.8 +#define virt_to_machine(_a) (phys_to_machine(__pa(_a)))
    18.9 +#define machine_to_virt(_m) (__va(machine_to_phys(_m)))
   18.10 +
   18.11  #endif /* __KERNEL__ */
   18.12  
   18.13  #endif /* _I386_PAGE_H */