direct-io.hg
changeset 10643: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>
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