- Update Xen patches to c/s 1011.
[opensuse:kernel-source.git] / patches.xen / xen-blkif-protocol-fallback-hack
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 --- sle11sp1-2010-03-29.orig/drivers/xen/Kconfig        2010-03-26 08:39:39.000000000 +0100
9 +++ sle11sp1-2010-03-29/drivers/xen/Kconfig     2010-03-29 09:12:44.000000000 +0200
10 @@ -29,6 +29,9 @@ config XEN_PRIVCMD
11         def_bool y
12         depends on PROC_FS
13  
14 +config XEN_DOMCTL
15 +       tristate
16 +
17  config XEN_XENBUS_DEV
18         def_bool y
19         depends on PROC_FS
20 @@ -48,6 +51,7 @@ config XEN_BLKDEV_BACKEND
21         tristate "Block-device backend driver"
22          depends on XEN_BACKEND
23         default XEN_BACKEND
24 +       select XEN_DOMCTL
25         help
26           The block-device backend driver allows the kernel to export its
27           block devices to other guests via a high-performance shared-memory
28 @@ -57,6 +61,7 @@ config XEN_BLKDEV_TAP
29         tristate "Block-device tap backend driver"
30         depends on XEN_BACKEND
31         default XEN_BACKEND
32 +       select XEN_DOMCTL
33         help
34           The block tap driver is an alternative to the block back driver
35           and allows VM block requests to be redirected to userspace through
36 --- sle11sp1-2010-03-29.orig/drivers/xen/blkback/xenbus.c       2010-03-22 12:53:24.000000000 +0100
37 +++ sle11sp1-2010-03-29/drivers/xen/blkback/xenbus.c    2010-03-22 12:53:34.000000000 +0100
38 @@ -21,6 +21,7 @@
39  #include <linux/module.h>
40  #include <linux/kthread.h>
41  #include "common.h"
42 +#include "../core/domctl.h"
43  
44  #undef DPRINTK
45  #define DPRINTK(fmt, args...)                          \
46 @@ -492,8 +493,10 @@ static int connect_ring(struct backend_i
47         be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
48         err = xenbus_gather(XBT_NIL, dev->otherend, "protocol",
49                             "%63s", protocol, NULL);
50 -       if (err)
51 -               strcpy(protocol, "unspecified, assuming native");
52 +       if (err) {
53 +               strcpy(protocol, "unspecified");
54 +               be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid);
55 +       }
56         else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
57                 be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
58         else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32))
59 --- sle11sp1-2010-03-29.orig/drivers/xen/blktap/xenbus.c        2010-01-27 14:59:26.000000000 +0100
60 +++ sle11sp1-2010-03-29/drivers/xen/blktap/xenbus.c     2010-01-27 15:00:09.000000000 +0100
61 @@ -39,6 +39,7 @@
62  #include <linux/kthread.h>
63  #include <xen/xenbus.h>
64  #include "common.h"
65 +#include "../core/domctl.h"
66  
67  
68  struct backend_info
69 @@ -432,8 +433,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 --- sle11sp1-2010-03-29.orig/drivers/xen/core/Makefile  2009-11-06 10:52:02.000000000 +0100
83 +++ sle11sp1-2010-03-29/drivers/xen/core/Makefile       2010-01-04 16:17:00.000000000 +0100
84 @@ -12,4 +12,7 @@ obj-$(CONFIG_XEN_SYSFS)               += xen_sysfs.o
85  obj-$(CONFIG_XEN_SMPBOOT)      += smpboot.o
86  obj-$(CONFIG_SMP)              += spinlock.o
87  obj-$(CONFIG_KEXEC)            += machine_kexec.o
88 +obj-$(CONFIG_XEN_DOMCTL)       += domctl.o
89 +CFLAGS_domctl.o                        := -D__XEN_PUBLIC_XEN_H__ -D__XEN_PUBLIC_GRANT_TABLE_H__
90 +CFLAGS_domctl.o                        += -D__XEN_TOOLS__ -imacros xen/interface/domctl.h
91  obj-$(CONFIG_XEN_XENCOMM)      += xencomm.o
92 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
93 +++ sle11sp1-2010-03-29/drivers/xen/core/domctl.c       2010-01-04 16:15:58.000000000 +0100
94 @@ -0,0 +1,120 @@
95 +/*
96 + * !!!  dirty hack alert  !!!
97 + *
98 + * Problem: old guests kernels don't have a "protocol" node
99 + *          in the frontend xenstore directory, so mixing
100 + *          32 and 64bit domains doesn't work.
101 + *
102 + * Upstream plans to solve this in the tools, by letting them
103 + * create a protocol node.  Which certainly makes sense.
104 + * But it isn't trivial and isn't done yet.  Too bad.
105 + *
106 + * So for the time being we use the get_address_size domctl
107 + * hypercall for a pretty good guess.  Not nice as the domctl
108 + * hypercall isn't supposed to be used by the kernel.  Because
109 + * we don't want to have dependencies between dom0 kernel and
110 + * xen kernel versions.  Now we have one.  Ouch.
111 + */
112 +#undef __XEN_PUBLIC_XEN_H__
113 +#undef __XEN_PUBLIC_GRANT_TABLE_H__
114 +#undef __XEN_TOOLS__
115 +#include <linux/kernel.h>
116 +#include <linux/module.h>
117 +#include <asm/hypervisor.h>
118 +#include <xen/blkif.h>
119 +
120 +#include "domctl.h"
121 +
122 +/* stuff copied from xen/interface/domctl.h, which we can't
123 + * include directly for the reasons outlined above .... */
124 +
125 +typedef struct xen_domctl_address_size {
126 +       uint32_t size;
127 +} xen_domctl_address_size_t;
128 +
129 +typedef __attribute__((aligned(8))) uint64_t uint64_aligned_t;
130 +
131 +union xen_domctl {
132 +       /* v4: sles10 sp1: xen 3.0.4 + 32-on-64 patches */
133 +       struct {
134 +               uint32_t cmd;
135 +               uint32_t interface_version;
136 +               domid_t  domain;
137 +               union {
138 +                       /* left out lots of other struct xen_domctl_foobar */
139 +                       struct xen_domctl_address_size       address_size;
140 +                       uint64_t                             dummy_align;
141 +                       uint8_t                              dummy_pad[128];
142 +               };
143 +       } v4;
144 +
145 +       /* v5: upstream: xen 3.1, v6: upstream: xen 4.0 */
146 +       struct {
147 +               uint32_t cmd;
148 +               uint32_t interface_version;
149 +               domid_t  domain;
150 +               union {
151 +                       struct xen_domctl_address_size       address_size;
152 +                       uint64_aligned_t                     dummy_align;
153 +                       uint8_t                              dummy_pad[128];
154 +               };
155 +       } v5, v6;
156 +};
157 +
158 +/* The actual code comes here */
159 +
160 +static inline int hypervisor_domctl(void *domctl)
161 +{
162 +       return _hypercall1(int, domctl, domctl);
163 +}
164 +
165 +int xen_guest_address_size(int domid)
166 +{
167 +       union xen_domctl domctl;
168 +       int low, ret;
169 +
170 +#define guest_address_size(ver) do {                                   \
171 +       memset(&domctl, 0, sizeof(domctl));                             \
172 +       domctl.v##ver.cmd = XEN_DOMCTL_get_address_size;                \
173 +       domctl.v##ver.interface_version = low = ver;                    \
174 +       domctl.v##ver.domain = domid;                                   \
175 +       ret = hypervisor_domctl(&domctl) ?: domctl.v##ver.address_size.size; \
176 +       if (ret == 32 || ret == 64) {                                   \
177 +               printk("v" #ver " domctl worked ok: dom%d is %d-bit\n", \
178 +                      domid, ret);                                     \
179 +               return ret;                                             \
180 +       }                                                               \
181 +} while (0)
182 +
183 +       BUILD_BUG_ON(XEN_DOMCTL_INTERFACE_VERSION > 6);
184 +       guest_address_size(6);
185 +#if CONFIG_XEN_COMPAT < 0x040000
186 +       guest_address_size(5);
187 +#endif
188 +#if CONFIG_XEN_COMPAT < 0x030100
189 +       guest_address_size(4);
190 +#endif
191 +
192 +       ret = BITS_PER_LONG;
193 +       printk("v%d...6 domctls failed, assuming dom%d is native: %d\n",
194 +              low, domid, ret);
195 +
196 +       return ret;
197 +}
198 +EXPORT_SYMBOL_GPL(xen_guest_address_size);
199 +
200 +int xen_guest_blkif_protocol(int domid)
201 +{
202 +       int address_size = xen_guest_address_size(domid);
203 +
204 +       if (address_size == BITS_PER_LONG)
205 +               return BLKIF_PROTOCOL_NATIVE;
206 +       if (address_size == 32)
207 +               return BLKIF_PROTOCOL_X86_32;
208 +       if (address_size == 64)
209 +               return BLKIF_PROTOCOL_X86_64;
210 +       return BLKIF_PROTOCOL_NATIVE;
211 +}
212 +EXPORT_SYMBOL_GPL(xen_guest_blkif_protocol);
213 +
214 +MODULE_LICENSE("GPL");
215 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
216 +++ sle11sp1-2010-03-29/drivers/xen/core/domctl.h       2008-09-15 15:10:39.000000000 +0200
217 @@ -0,0 +1,2 @@
218 +int xen_guest_address_size(int domid);
219 +int xen_guest_blkif_protocol(int domid);