Contents of /trunk/kernel26-xen/patches-2.6.25-r1/1045-2.6.25-xen-blkif-protocol-fallback-hack.patch
Parent Directory | Revision Log
Revision 609 -
(show annotations)
(download)
Fri May 23 17:35:37 2008 UTC (16 years, 4 months ago) by niro
File size: 7787 byte(s)
Fri May 23 17:35:37 2008 UTC (16 years, 4 months ago) by niro
File size: 7787 byte(s)
-using opensuse xen patchset, updated kernel configs
1 | Subject: 32-on-64 blkif protocol negotiation fallback for old guests. |
2 | From: kraxel@suse.de |
3 | References: 244055 |
4 | Patch-mainline: never. |
5 | |
6 | See the comment below. Oh well. |
7 | |
8 | --- |
9 | drivers/xen/blkback/xenbus.c | 10 +-- |
10 | drivers/xen/blktap/xenbus.c | 10 +-- |
11 | drivers/xen/core/Makefile | 2 |
12 | drivers/xen/core/domctl.c | 133 +++++++++++++++++++++++++++++++++++++++++++ |
13 | drivers/xen/core/domctl.h | 2 |
14 | 5 files changed, 148 insertions(+), 9 deletions(-) |
15 | |
16 | Index: head-2007-10-15/drivers/xen/blkback/xenbus.c |
17 | =================================================================== |
18 | --- head-2007-10-15.orig/drivers/xen/blkback/xenbus.c 2007-10-22 10:49:56.000000000 +0200 |
19 | +++ head-2007-10-15/drivers/xen/blkback/xenbus.c 2007-10-22 10:50:20.000000000 +0200 |
20 | @@ -21,6 +21,7 @@ |
21 | #include <linux/module.h> |
22 | #include <linux/kthread.h> |
23 | #include "common.h" |
24 | +#include "../core/domctl.h" |
25 | |
26 | #undef DPRINTK |
27 | #define DPRINTK(fmt, args...) \ |
28 | @@ -457,7 +458,6 @@ again: |
29 | xenbus_transaction_end(xbt, 1); |
30 | } |
31 | |
32 | - |
33 | static int connect_ring(struct backend_info *be) |
34 | { |
35 | struct xenbus_device *dev = be->dev; |
36 | @@ -480,8 +480,10 @@ static int connect_ring(struct backend_i |
37 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; |
38 | err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", |
39 | "%63s", protocol, NULL); |
40 | - if (err) |
41 | - strcpy(protocol, "unspecified, assuming native"); |
42 | + if (err) { |
43 | + strcpy(protocol, "unspecified"); |
44 | + be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid); |
45 | + } |
46 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) |
47 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; |
48 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) |
49 | Index: head-2007-10-15/drivers/xen/blktap/xenbus.c |
50 | =================================================================== |
51 | --- head-2007-10-15.orig/drivers/xen/blktap/xenbus.c 2007-10-22 10:50:02.000000000 +0200 |
52 | +++ head-2007-10-15/drivers/xen/blktap/xenbus.c 2007-10-22 10:50:15.000000000 +0200 |
53 | @@ -39,6 +39,7 @@ |
54 | #include <linux/kthread.h> |
55 | #include <xen/xenbus.h> |
56 | #include "common.h" |
57 | +#include "../core/domctl.h" |
58 | |
59 | |
60 | struct backend_info |
61 | @@ -401,7 +402,6 @@ static void connect(struct backend_info |
62 | return; |
63 | } |
64 | |
65 | - |
66 | static int connect_ring(struct backend_info *be) |
67 | { |
68 | struct xenbus_device *dev = be->dev; |
69 | @@ -424,8 +424,10 @@ static int connect_ring(struct backend_i |
70 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; |
71 | err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", |
72 | "%63s", protocol, NULL); |
73 | - if (err) |
74 | - strcpy(protocol, "unspecified, assuming native"); |
75 | + if (err) { |
76 | + strcpy(protocol, "unspecified"); |
77 | + be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid); |
78 | + } |
79 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) |
80 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; |
81 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) |
82 | Index: head-2007-10-15/drivers/xen/core/Makefile |
83 | =================================================================== |
84 | --- head-2007-10-15.orig/drivers/xen/core/Makefile 2007-10-22 10:47:58.000000000 +0200 |
85 | +++ head-2007-10-15/drivers/xen/core/Makefile 2007-10-18 16:58:11.000000000 +0200 |
86 | @@ -2,7 +2,7 @@ |
87 | # Makefile for the linux kernel. |
88 | # |
89 | |
90 | -obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o firmware.o |
91 | +obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o firmware.o domctl.o |
92 | |
93 | obj-$(CONFIG_PROC_FS) += xen_proc.o |
94 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor_sysfs.o |
95 | Index: head-2007-10-15/drivers/xen/core/domctl.c |
96 | =================================================================== |
97 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
98 | +++ head-2007-10-15/drivers/xen/core/domctl.c 2007-10-18 16:58:11.000000000 +0200 |
99 | @@ -0,0 +1,133 @@ |
100 | +/* |
101 | + * !!! dirty hack alert !!! |
102 | + * |
103 | + * Problem: old guests kernels don't have a "protocol" node |
104 | + * in the frontend xenstore directory, so mixing |
105 | + * 32 and 64bit domains doesn't work. |
106 | + * |
107 | + * Upstream plans to solve this in the tools, by letting them |
108 | + * create a protocol node. Which certainly makes sense. |
109 | + * But it isn't trivial and isn't done yet. Too bad. |
110 | + * |
111 | + * So for the time being we use the get_address_size domctl |
112 | + * hypercall for a pretty good guess. Not nice as the domctl |
113 | + * hypercall isn't supposed to be used by the kernel. Because |
114 | + * we don't want to have dependencies between dom0 kernel and |
115 | + * xen kernel versions. Now we have one. Ouch. |
116 | + */ |
117 | + |
118 | +#include <linux/kernel.h> |
119 | +#include <linux/module.h> |
120 | +#include <asm/hypervisor.h> |
121 | +#include <xen/blkif.h> |
122 | + |
123 | +#include "domctl.h" |
124 | + |
125 | +/* stuff copied from xen/interface/domctl.h, which we can't |
126 | + * include directly for the reasons outlined above .... */ |
127 | + |
128 | +#define XEN_DOMCTL_set_address_size 35 |
129 | +#define XEN_DOMCTL_get_address_size 36 |
130 | +typedef struct xen_domctl_address_size { |
131 | + uint32_t size; |
132 | +} xen_domctl_address_size_t; |
133 | + |
134 | +#define native_address_size (sizeof(unsigned long)*8) |
135 | + |
136 | +/* v4: sles10 sp1: xen 3.0.4 + 32-on-64 patches */ |
137 | +struct xen_domctl_v4 { |
138 | + uint32_t cmd; |
139 | + uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ |
140 | + domid_t domain; |
141 | + union { |
142 | + /* left out lots of other struct xen_domctl_foobar */ |
143 | + struct xen_domctl_address_size address_size; |
144 | + uint64_t dummy_align; |
145 | + uint8_t dummy_pad[128]; |
146 | + } u; |
147 | +}; |
148 | + |
149 | +/* v5: upstream: xen 3.0.5 */ |
150 | +typedef __attribute__((aligned(8))) uint64_t uint64_aligned_t; |
151 | +struct xen_domctl_v5 { |
152 | + uint32_t cmd; |
153 | + uint32_t interface_version; |
154 | + domid_t domain; |
155 | + union { |
156 | + struct xen_domctl_address_size address_size; |
157 | + uint64_aligned_t dummy_align; |
158 | + uint8_t dummy_pad[128]; |
159 | + } u; |
160 | +}; |
161 | + |
162 | +/* The actual code comes here */ |
163 | + |
164 | +static int xen_guest_address_size_v4(int domid) |
165 | +{ |
166 | + struct xen_domctl_v4 domctl; |
167 | + int rc; |
168 | + |
169 | + memset(&domctl, 0, sizeof(domctl)); |
170 | + domctl.cmd = XEN_DOMCTL_get_address_size; |
171 | + domctl.interface_version = 4; |
172 | + domctl.domain = domid; |
173 | + if (0 != (rc = _hypercall1(int, domctl, &domctl))) |
174 | + return rc; |
175 | + return domctl.u.address_size.size; |
176 | +} |
177 | + |
178 | +static int xen_guest_address_size_v5(int domid) |
179 | +{ |
180 | + struct xen_domctl_v5 domctl; |
181 | + int rc; |
182 | + |
183 | + memset(&domctl, 0, sizeof(domctl)); |
184 | + domctl.cmd = XEN_DOMCTL_get_address_size; |
185 | + domctl.interface_version = 5; |
186 | + domctl.domain = domid; |
187 | + if (0 != (rc = _hypercall1(int, domctl, &domctl))) |
188 | + return rc; |
189 | + return domctl.u.address_size.size; |
190 | +} |
191 | + |
192 | +int xen_guest_address_size(int domid) |
193 | +{ |
194 | + int ret; |
195 | + |
196 | + ret = xen_guest_address_size_v4(domid); |
197 | + if (ret == 32 || ret == 64) { |
198 | + printk("%s: v4 domctl worked ok: %d\n", __FUNCTION__, ret); |
199 | + goto done; |
200 | + } |
201 | + |
202 | + ret = xen_guest_address_size_v5(domid); |
203 | + if (ret == 32 || ret == 64) { |
204 | + printk("%s: v5 domctl worked ok: %d\n", __FUNCTION__, ret); |
205 | + goto done; |
206 | + } |
207 | + |
208 | + ret = native_address_size; |
209 | + printk("%s: v4,v5 domctls failed, assuming native: %d\n", |
210 | + __FUNCTION__, ret); |
211 | + |
212 | + done: |
213 | + return ret; |
214 | +} |
215 | +EXPORT_SYMBOL_GPL(xen_guest_address_size); |
216 | + |
217 | +int xen_guest_blkif_protocol(int domid) |
218 | +{ |
219 | + int address_size; |
220 | + |
221 | + address_size = xen_guest_address_size(domid); |
222 | + printk(KERN_DEBUG "%s: domain %d: got address size %d\n", |
223 | + __FUNCTION__, domid, address_size); |
224 | + if (address_size == native_address_size) |
225 | + return BLKIF_PROTOCOL_NATIVE; |
226 | + if (address_size == 32) |
227 | + return BLKIF_PROTOCOL_X86_32; |
228 | + if (address_size == 64) |
229 | + return BLKIF_PROTOCOL_X86_64; |
230 | + return BLKIF_PROTOCOL_NATIVE; |
231 | +} |
232 | +EXPORT_SYMBOL_GPL(xen_guest_blkif_protocol); |
233 | Index: head-2007-10-15/drivers/xen/core/domctl.h |
234 | =================================================================== |
235 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
236 | +++ head-2007-10-15/drivers/xen/core/domctl.h 2007-10-18 16:58:11.000000000 +0200 |
237 | @@ -0,0 +1,2 @@ |
238 | +int xen_guest_address_size(int domid); |
239 | +int xen_guest_blkif_protocol(int domid); |