]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.xen/xen-blkif-protocol-fallback-hack
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.xen / xen-blkif-protocol-fallback-hack
CommitLineData
2cb7cef9
BS
1Subject: 32-on-64 blkif protocol negotiation fallback for old guests.
2From: kraxel@suse.de
3References: 244055
4Patch-mainline: never.
5
6See 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
16Index: 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))
41Index: 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))
66Index: 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
79Index: 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);
197Index: 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);