direct-io.hg

view extras/mini-os/gnttab.c @ 11356:af7c87d42bc6

[XEN][POWERPC] Fix PHDR issues with large .data.percpu sections

This patch tells the link to only create one PHDR and place all sections
in it, also removing an unrequired mapping for the .data.percpu section.

This avoids the "Not enough room for program headers (allocated 2, need 3)"

Booted on a JS20.

Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Thu Aug 17 07:10:57 2006 -0400 (2006-08-17)
parents 4a669bd50657
children 2406531dae95
line source
1 /*
2 ****************************************************************************
3 * (C) 2006 - Cambridge University
4 ****************************************************************************
5 *
6 * File: gnttab.c
7 * Author: Steven Smith (sos22@cam.ac.uk)
8 * Changes: Grzegorz Milos (gm281@cam.ac.uk)
9 *
10 * Date: July 2006
11 *
12 * Environment: Xen Minimal OS
13 * Description: Simple grant tables implementation. About as stupid as it's
14 * possible to be and still work.
15 *
16 ****************************************************************************
17 */
18 #include <os.h>
19 #include <mm.h>
20 #include <gnttab.h>
22 #define NR_RESERVED_ENTRIES 8
24 #define NR_GRANT_FRAMES 4
25 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
26 #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1)
28 static grant_entry_t *gnttab_table;
29 static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
30 static grant_ref_t gnttab_free_head;
32 static grant_ref_t
33 get_free_entries(int count)
34 {
35 grant_ref_t ref;
36 grant_ref_t head;
38 ref = head = gnttab_free_head;
39 while (count-- > 1)
40 head = gnttab_list[head];
41 gnttab_free_head = gnttab_list[head];
42 gnttab_list[head] = GNTTAB_LIST_END;
43 return ref;
44 }
46 static void
47 put_free_entry(grant_ref_t gref)
48 {
49 gnttab_list[gref] = gnttab_free_head;
50 gnttab_free_head = gref;
51 }
53 grant_ref_t
54 gnttab_grant_access(domid_t domid, unsigned long frame, int readonly)
55 {
56 grant_ref_t ref;
58 ref = get_free_entries(1);
59 gnttab_table[ref].frame = frame;
60 gnttab_table[ref].domid = domid;
61 wmb();
62 readonly *= GTF_readonly;
63 gnttab_table[ref].flags = GTF_permit_access | readonly;
65 return ref;
66 }
68 grant_ref_t
69 gnttab_grant_transfer(domid_t domid, unsigned long pfn)
70 {
71 grant_ref_t ref;
73 ref = get_free_entries(1);
74 gnttab_table[ref].frame = pfn;
75 gnttab_table[ref].domid = domid;
76 wmb();
77 gnttab_table[ref].flags = GTF_accept_transfer;
79 return ref;
80 }
82 int
83 gnttab_end_access(grant_ref_t ref)
84 {
85 u16 flags, nflags;
87 nflags = gnttab_table[ref].flags;
88 do {
89 if ((flags = nflags) & (GTF_reading|GTF_writing)) {
90 printk("WARNING: g.e. still in use!\n");
91 return 0;
92 }
93 } while ((nflags = synch_cmpxchg(&gnttab_table[ref].flags, flags, 0)) !=
94 flags);
96 put_free_entry(ref);
97 return 1;
98 }
100 unsigned long
101 gnttab_end_transfer(grant_ref_t ref)
102 {
103 unsigned long frame;
104 u16 flags;
106 while (!((flags = gnttab_table[ref].flags) & GTF_transfer_committed)) {
107 if (synch_cmpxchg(&gnttab_table[ref].flags, flags, 0) == flags) {
108 printk("Release unused transfer grant.\n");
109 put_free_entry(ref);
110 return 0;
111 }
112 }
114 /* If a transfer is in progress then wait until it is completed. */
115 while (!(flags & GTF_transfer_completed)) {
116 flags = gnttab_table[ref].flags;
117 }
119 /* Read the frame number /after/ reading completion status. */
120 rmb();
121 frame = gnttab_table[ref].frame;
123 put_free_entry(ref);
125 return frame;
126 }
128 grant_ref_t
129 gnttab_alloc_and_grant(void **map)
130 {
131 unsigned long mfn;
132 grant_ref_t gref;
134 *map = (void *)alloc_page();
135 mfn = virt_to_mfn(*map);
136 gref = gnttab_grant_access(0, mfn, 0);
137 return gref;
138 }
140 static const char *gnttabop_error_msgs[] = GNTTABOP_error_msgs;
142 const char *
143 gnttabop_error(int16_t status)
144 {
145 status = -status;
146 if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
147 return "bad status";
148 else
149 return gnttabop_error_msgs[status];
150 }
152 void
153 init_gnttab(void)
154 {
155 struct gnttab_setup_table setup;
156 unsigned long frames[NR_GRANT_FRAMES];
157 int i;
159 for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
160 gnttab_list[i] = i + 1;
161 gnttab_free_head = NR_RESERVED_ENTRIES;
163 setup.dom = DOMID_SELF;
164 setup.nr_frames = NR_GRANT_FRAMES;
165 set_xen_guest_handle(setup.frame_list, frames);
167 HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
168 gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
169 printk("gnttab_table mapped at %p.\n", gnttab_table);
170 }