ia64/xen-unstable

changeset 10657:bbea54da02b5

[MINIOS] Mapping page frames on demand added to the memory management.

Signed-off-by: Steven Smith <sos22@cam.ac.uk>
Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
author kfraser@localhost.localdomain
date Wed Jul 05 14:29:57 2006 +0100 (2006-07-05)
parents 4db818a7dc3f
children d6363854fb35
files extras/mini-os/gnttab.c extras/mini-os/include/gnttab.h extras/mini-os/include/os.h extras/mini-os/kernel.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/extras/mini-os/gnttab.c	Wed Jul 05 14:29:57 2006 +0100
     1.3 @@ -0,0 +1,158 @@
     1.4 +/* 
     1.5 + ****************************************************************************
     1.6 + * (C) 2006 - Cambridge University
     1.7 + ****************************************************************************
     1.8 + *
     1.9 + *        File: gnttab.c
    1.10 + *      Author: Steven Smith (sos22@cam.ac.uk) 
    1.11 + *     Changes: Grzegorz Milos (gm281@cam.ac.uk)
    1.12 + *              
    1.13 + *        Date: July 2006
    1.14 + * 
    1.15 + * Environment: Xen Minimal OS
    1.16 + * Description: Simple grant tables implementation. About as stupid as it's
    1.17 + *  possible to be and still work.
    1.18 + *
    1.19 + ****************************************************************************
    1.20 + */
    1.21 +#include <os.h>
    1.22 +#include <mm.h>
    1.23 +#include <gnttab.h>
    1.24 +
    1.25 +#define NR_RESERVED_ENTRIES 8
    1.26 +
    1.27 +#define NR_GRANT_FRAMES 4
    1.28 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
    1.29 +#define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
    1.30 +
    1.31 +static grant_entry_t *gnttab_table;
    1.32 +static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
    1.33 +static grant_ref_t gnttab_free_head;
    1.34 +
    1.35 +static grant_ref_t
    1.36 +get_free_entries(int count)
    1.37 +{
    1.38 +    grant_ref_t ref;
    1.39 +    grant_ref_t head;
    1.40 +
    1.41 +    ref = head = gnttab_free_head;
    1.42 +    while (count-- > 1)
    1.43 +	head = gnttab_list[head];
    1.44 +    gnttab_free_head = gnttab_list[head];
    1.45 +    gnttab_list[head] = GNTTAB_LIST_END;
    1.46 +    return ref;
    1.47 +}
    1.48 +
    1.49 +static void
    1.50 +put_free_entry(grant_ref_t gref)
    1.51 +{
    1.52 +    gnttab_list[gref] = gnttab_free_head;
    1.53 +    gnttab_free_head = gref;
    1.54 +}
    1.55 +
    1.56 +grant_ref_t
    1.57 +gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
    1.58 +{
    1.59 +    grant_ref_t ref;
    1.60 +
    1.61 +    ref = get_free_entries(1);
    1.62 +    gnttab_table[ref].frame = frame;
    1.63 +    gnttab_table[ref].domid = domid;
    1.64 +    wmb();
    1.65 +    readonly *= GTF_readonly;
    1.66 +    gnttab_table[ref].flags = GTF_permit_access | readonly;
    1.67 +
    1.68 +    return ref;
    1.69 +}
    1.70 +
    1.71 +grant_ref_t
    1.72 +gnttab_grant_transfer(domid_t domid, unsigned long pfn)
    1.73 +{
    1.74 +    grant_ref_t ref;
    1.75 +
    1.76 +    ref = get_free_entries(1);
    1.77 +    gnttab_table[ref].frame = pfn;
    1.78 +    gnttab_table[ref].domid = domid;
    1.79 +    wmb();
    1.80 +    gnttab_table[ref].flags = GTF_accept_transfer;
    1.81 +
    1.82 +    return ref;
    1.83 +}
    1.84 +
    1.85 +int
    1.86 +gnttab_end_access(grant_ref_t ref)
    1.87 +{
    1.88 +    u16 flags, nflags;
    1.89 +
    1.90 +    nflags = gnttab_table[ref].flags;
    1.91 +    do {
    1.92 +        if ((flags = nflags) & (GTF_reading|GTF_writing)) {
    1.93 +            printk("WARNING: g.e. still in use!\n");
    1.94 +            return 0;
    1.95 +        }
    1.96 +    } while ((nflags = synch_cmpxchg(&gnttab_table[ref].flags, flags, 0)) !=
    1.97 +            flags);
    1.98 +
    1.99 +    put_free_entry(ref);
   1.100 +    return 1;
   1.101 +}
   1.102 +
   1.103 +unsigned long
   1.104 +gnttab_end_transfer(grant_ref_t ref)
   1.105 +{
   1.106 +    unsigned long frame;
   1.107 +    u16 flags;
   1.108 +
   1.109 +    while (!((flags = gnttab_table[ref].flags) & GTF_transfer_committed)) {
   1.110 +        if (synch_cmpxchg(&gnttab_table[ref].flags, flags, 0) == flags) {
   1.111 +            printk("Release unused transfer grant.\n");
   1.112 +            put_free_entry(ref);
   1.113 +            return 0;
   1.114 +        }
   1.115 +    }
   1.116 +
   1.117 +    /* If a transfer is in progress then wait until it is completed. */
   1.118 +    while (!(flags & GTF_transfer_completed)) {
   1.119 +        flags = gnttab_table[ref].flags;
   1.120 +    }
   1.121 +
   1.122 +    /* Read the frame number /after/ reading completion status. */
   1.123 +    rmb();
   1.124 +    frame = gnttab_table[ref].frame;
   1.125 +
   1.126 +    put_free_entry(ref);
   1.127 +
   1.128 +    return frame;
   1.129 +}
   1.130 +
   1.131 +grant_ref_t
   1.132 +gnttab_alloc_and_grant(void **map)
   1.133 +{
   1.134 +    unsigned long mfn;
   1.135 +    grant_ref_t gref;
   1.136 +
   1.137 +    *map = (void *)alloc_page();
   1.138 +    mfn = virt_to_mfn(*map);
   1.139 +    gref = gnttab_grant_access(0, mfn, 0);
   1.140 +    return gref;
   1.141 +}
   1.142 +
   1.143 +void
   1.144 +init_gnttab(void)
   1.145 +{
   1.146 +    struct gnttab_setup_table setup;
   1.147 +    unsigned long frames[NR_GRANT_FRAMES];
   1.148 +    int i;
   1.149 +
   1.150 +    for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
   1.151 +	gnttab_list[i] = i + 1;
   1.152 +    gnttab_free_head = NR_RESERVED_ENTRIES;
   1.153 +
   1.154 +    setup.dom = DOMID_SELF;
   1.155 +    setup.nr_frames = NR_GRANT_FRAMES;
   1.156 +    set_xen_guest_handle(setup.frame_list, frames);
   1.157 +
   1.158 +    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
   1.159 +    gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
   1.160 +    printk("gnttab_table mapped at %p.\n", gnttab_table);
   1.161 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/extras/mini-os/include/gnttab.h	Wed Jul 05 14:29:57 2006 +0100
     2.3 @@ -0,0 +1,14 @@
     2.4 +#ifndef __GNTTAB_H__
     2.5 +#define __GNTTAB_H__
     2.6 +
     2.7 +#include <xen/grant_table.h>
     2.8 +
     2.9 +void init_gnttab(void);
    2.10 +grant_ref_t gnttab_alloc_and_grant(void **map);
    2.11 +grant_ref_t gnttab_grant_access(domid_t domid, unsigned long frame,
    2.12 +				int readonly);
    2.13 +grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
    2.14 +unsigned long gnttab_end_transfer(grant_ref_t gref);
    2.15 +int gnttab_end_access(grant_ref_t ref);
    2.16 +
    2.17 +#endif /* !__GNTTAB_H__ */
     3.1 --- a/extras/mini-os/include/os.h	Wed Jul 05 14:29:13 2006 +0100
     3.2 +++ b/extras/mini-os/include/os.h	Wed Jul 05 14:29:57 2006 +0100
     3.3 @@ -445,7 +445,62 @@ static __inline__ unsigned long __ffs(un
     3.4  
     3.5  
     3.6  /********************* common i386 and x86_64  ****************************/
     3.7 +struct __synch_xchg_dummy { unsigned long a[100]; };
     3.8 +#define __synch_xg(x) ((struct __synch_xchg_dummy *)(x))
     3.9  
    3.10 +#define synch_cmpxchg(ptr, old, new) \
    3.11 +((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
    3.12 +                                     (unsigned long)(old), \
    3.13 +                                     (unsigned long)(new), \
    3.14 +                                     sizeof(*(ptr))))
    3.15 +
    3.16 +static inline unsigned long __synch_cmpxchg(volatile void *ptr,
    3.17 +        unsigned long old,
    3.18 +        unsigned long new, int size)
    3.19 +{
    3.20 +    unsigned long prev;
    3.21 +    switch (size) {
    3.22 +        case 1:
    3.23 +            __asm__ __volatile__("lock; cmpxchgb %b1,%2"
    3.24 +                    : "=a"(prev)
    3.25 +                    : "q"(new), "m"(*__synch_xg(ptr)),
    3.26 +                    "0"(old)
    3.27 +                    : "memory");
    3.28 +            return prev;
    3.29 +        case 2:
    3.30 +            __asm__ __volatile__("lock; cmpxchgw %w1,%2"
    3.31 +                    : "=a"(prev)
    3.32 +                    : "r"(new), "m"(*__synch_xg(ptr)),
    3.33 +                    "0"(old)
    3.34 +                    : "memory");
    3.35 +            return prev;
    3.36 +#ifdef __x86_64__
    3.37 +        case 4:
    3.38 +            __asm__ __volatile__("lock; cmpxchgl %k1,%2"
    3.39 +                    : "=a"(prev)
    3.40 +                    : "r"(new), "m"(*__synch_xg(ptr)),
    3.41 +                    "0"(old)
    3.42 +                    : "memory");
    3.43 +            return prev;
    3.44 +        case 8:
    3.45 +            __asm__ __volatile__("lock; cmpxchgq %1,%2"
    3.46 +                    : "=a"(prev)
    3.47 +                    : "r"(new), "m"(*__synch_xg(ptr)),
    3.48 +                    "0"(old)
    3.49 +                    : "memory");
    3.50 +            return prev;
    3.51 +#else
    3.52 +        case 4:
    3.53 +            __asm__ __volatile__("lock; cmpxchgl %1,%2"
    3.54 +                    : "=a"(prev)
    3.55 +                    : "r"(new), "m"(*__synch_xg(ptr)),
    3.56 +                    "0"(old)
    3.57 +                    : "memory");
    3.58 +            return prev;
    3.59 +#endif
    3.60 +    }
    3.61 +    return old;
    3.62 +}
    3.63  
    3.64  
    3.65  static __inline__ void synch_set_bit(int nr, volatile void * addr)
     4.1 --- a/extras/mini-os/kernel.c	Wed Jul 05 14:29:13 2006 +0100
     4.2 +++ b/extras/mini-os/kernel.c	Wed Jul 05 14:29:57 2006 +0100
     4.3 @@ -35,6 +35,7 @@
     4.4  #include <lib.h>
     4.5  #include <sched.h>
     4.6  #include <xenbus.h>
     4.7 +#include <gnttab.h>
     4.8  #include <xen/features.h>
     4.9  #include <xen/version.h>
    4.10  
    4.11 @@ -177,7 +178,10 @@ void start_kernel(start_info_t *si)
    4.12  
    4.13      /* Init the console driver. */
    4.14      init_console();
    4.15 - 
    4.16 +
    4.17 +    /* Init grant tables */
    4.18 +    init_gnttab();
    4.19 +    
    4.20      /* Init scheduler. */
    4.21      init_sched();
    4.22