]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
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-2008-09-15/drivers/xen/blkback/xenbus.c | |
17 | =================================================================== | |
18 | --- head-2008-09-15.orig/drivers/xen/blkback/xenbus.c 2008-09-15 15:10:36.000000000 +0200 | |
19 | +++ head-2008-09-15/drivers/xen/blkback/xenbus.c 2008-09-15 15:10:39.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 | @@ -488,8 +489,10 @@ static int connect_ring(struct backend_i | |
29 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; | |
30 | err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", | |
31 | "%63s", protocol, NULL); | |
32 | - if (err) | |
33 | - strcpy(protocol, "unspecified, assuming native"); | |
34 | + if (err) { | |
35 | + strcpy(protocol, "unspecified"); | |
36 | + be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid); | |
37 | + } | |
38 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) | |
39 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; | |
40 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) | |
41 | Index: head-2008-09-15/drivers/xen/blktap/xenbus.c | |
42 | =================================================================== | |
43 | --- head-2008-09-15.orig/drivers/xen/blktap/xenbus.c 2008-09-15 15:10:36.000000000 +0200 | |
44 | +++ head-2008-09-15/drivers/xen/blktap/xenbus.c 2008-09-15 15:10:39.000000000 +0200 | |
45 | @@ -39,6 +39,7 @@ | |
46 | #include <linux/kthread.h> | |
47 | #include <xen/xenbus.h> | |
48 | #include "common.h" | |
49 | +#include "../core/domctl.h" | |
50 | ||
51 | ||
52 | struct backend_info | |
53 | @@ -426,8 +427,10 @@ static int connect_ring(struct backend_i | |
54 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; | |
55 | err = xenbus_gather(XBT_NIL, dev->otherend, "protocol", | |
56 | "%63s", protocol, NULL); | |
57 | - if (err) | |
58 | - strcpy(protocol, "unspecified, assuming native"); | |
59 | + if (err) { | |
60 | + strcpy(protocol, "unspecified"); | |
61 | + be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid); | |
62 | + } | |
63 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE)) | |
64 | be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; | |
65 | else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32)) | |
66 | Index: head-2008-09-15/drivers/xen/core/Makefile | |
67 | =================================================================== | |
68 | --- head-2008-09-15.orig/drivers/xen/core/Makefile 2008-09-15 14:45:31.000000000 +0200 | |
69 | +++ head-2008-09-15/drivers/xen/core/Makefile 2008-09-15 15:10:39.000000000 +0200 | |
70 | @@ -2,7 +2,7 @@ | |
71 | # Makefile for the linux kernel. | |
72 | # | |
73 | ||
74 | -obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o firmware.o | |
75 | +obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o firmware.o domctl.o | |
76 | ||
77 | obj-$(CONFIG_PCI) += pci.o | |
78 | obj-$(CONFIG_PROC_FS) += xen_proc.o | |
79 | Index: head-2008-09-15/drivers/xen/core/domctl.c | |
80 | =================================================================== | |
81 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
82 | +++ head-2008-09-15/drivers/xen/core/domctl.c 2008-09-15 15:10:39.000000000 +0200 | |
83 | @@ -0,0 +1,113 @@ | |
84 | +/* | |
85 | + * !!! dirty hack alert !!! | |
86 | + * | |
87 | + * Problem: old guests kernels don't have a "protocol" node | |
88 | + * in the frontend xenstore directory, so mixing | |
89 | + * 32 and 64bit domains doesn't work. | |
90 | + * | |
91 | + * Upstream plans to solve this in the tools, by letting them | |
92 | + * create a protocol node. Which certainly makes sense. | |
93 | + * But it isn't trivial and isn't done yet. Too bad. | |
94 | + * | |
95 | + * So for the time being we use the get_address_size domctl | |
96 | + * hypercall for a pretty good guess. Not nice as the domctl | |
97 | + * hypercall isn't supposed to be used by the kernel. Because | |
98 | + * we don't want to have dependencies between dom0 kernel and | |
99 | + * xen kernel versions. Now we have one. Ouch. | |
100 | + */ | |
101 | + | |
102 | +#include <linux/kernel.h> | |
103 | +#include <linux/module.h> | |
104 | +#include <asm/hypervisor.h> | |
105 | +#include <xen/blkif.h> | |
106 | + | |
107 | +#include "domctl.h" | |
108 | + | |
109 | +/* stuff copied from xen/interface/domctl.h, which we can't | |
110 | + * include directly for the reasons outlined above .... */ | |
111 | + | |
112 | +#define XEN_DOMCTL_get_address_size 36 | |
113 | +typedef struct xen_domctl_address_size { | |
114 | + uint32_t size; | |
115 | +} xen_domctl_address_size_t; | |
116 | + | |
117 | +typedef __attribute__((aligned(8))) uint64_t uint64_aligned_t; | |
118 | + | |
119 | +union xen_domctl { | |
120 | + /* v4: sles10 sp1: xen 3.0.4 + 32-on-64 patches */ | |
121 | + struct { | |
122 | + uint32_t cmd; | |
123 | + uint32_t interface_version; | |
124 | + domid_t domain; | |
125 | + union { | |
126 | + /* left out lots of other struct xen_domctl_foobar */ | |
127 | + struct xen_domctl_address_size address_size; | |
128 | + uint64_t dummy_align; | |
129 | + uint8_t dummy_pad[128]; | |
130 | + } u; | |
131 | + } v4; | |
132 | + | |
133 | + /* v5: upstream: xen 3.1 */ | |
134 | + struct { | |
135 | + uint32_t cmd; | |
136 | + uint32_t interface_version; | |
137 | + domid_t domain; | |
138 | + union { | |
139 | + struct xen_domctl_address_size address_size; | |
140 | + uint64_aligned_t dummy_align; | |
141 | + uint8_t dummy_pad[128]; | |
142 | + } u; | |
143 | + } v5; | |
144 | +}; | |
145 | + | |
146 | +/* The actual code comes here */ | |
147 | + | |
148 | +static inline int hypervisor_domctl(void *domctl) | |
149 | +{ | |
150 | + return _hypercall1(int, domctl, domctl); | |
151 | +} | |
152 | + | |
153 | +int xen_guest_address_size(int domid) | |
154 | +{ | |
155 | + union xen_domctl domctl; | |
156 | + int low, ret; | |
157 | + | |
158 | +#define guest_address_size(ver) do { \ | |
159 | + memset(&domctl, 0, sizeof(domctl)); \ | |
160 | + domctl.v##ver.cmd = XEN_DOMCTL_get_address_size; \ | |
161 | + domctl.v##ver.interface_version = low = ver; \ | |
162 | + domctl.v##ver.domain = domid; \ | |
163 | + ret = hypervisor_domctl(&domctl) ?: domctl.v##ver.u.address_size.size; \ | |
164 | + if (ret == 32 || ret == 64) { \ | |
165 | + printk("v" #ver " domctl worked ok: dom%d is %d-bit\n", \ | |
166 | + domid, ret); \ | |
167 | + return ret; \ | |
168 | + } \ | |
169 | +} while (0) | |
170 | + | |
171 | + guest_address_size(5); | |
172 | +#if CONFIG_XEN_COMPAT < 0x030100 | |
173 | + guest_address_size(4); | |
174 | +#endif | |
175 | + | |
176 | + ret = BITS_PER_LONG; | |
177 | + printk("v%d...5 domctls failed, assuming dom%d is native: %d\n", | |
178 | + low, domid, ret); | |
179 | + | |
180 | + return ret; | |
181 | +} | |
182 | +EXPORT_SYMBOL_GPL(xen_guest_address_size); | |
183 | + | |
184 | +int xen_guest_blkif_protocol(int domid) | |
185 | +{ | |
186 | + int address_size = xen_guest_address_size(domid); | |
187 | + | |
188 | + if (address_size == BITS_PER_LONG) | |
189 | + return BLKIF_PROTOCOL_NATIVE; | |
190 | + if (address_size == 32) | |
191 | + return BLKIF_PROTOCOL_X86_32; | |
192 | + if (address_size == 64) | |
193 | + return BLKIF_PROTOCOL_X86_64; | |
194 | + return BLKIF_PROTOCOL_NATIVE; | |
195 | +} | |
196 | +EXPORT_SYMBOL_GPL(xen_guest_blkif_protocol); | |
197 | Index: head-2008-09-15/drivers/xen/core/domctl.h | |
198 | =================================================================== | |
199 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
200 | +++ head-2008-09-15/drivers/xen/core/domctl.h 2008-09-15 15:10:39.000000000 +0200 | |
201 | @@ -0,0 +1,2 @@ | |
202 | +int xen_guest_address_size(int domid); | |
203 | +int xen_guest_blkif_protocol(int domid); |