1 Subject: 32-on-64 blkif protocol negotiation fallback for old guests.
6 See the comment below. Oh well.
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(-)
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
21 #include <linux/module.h>
22 #include <linux/kthread.h>
24 +#include "../core/domctl.h"
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);
33 - strcpy(protocol, "unspecified, assuming native");
35 + strcpy(protocol, "unspecified");
36 + be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid);
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
46 #include <linux/kthread.h>
47 #include <xen/xenbus.h>
49 +#include "../core/domctl.h"
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);
58 - strcpy(protocol, "unspecified, assuming native");
60 + strcpy(protocol, "unspecified");
61 + be->blkif->blk_protocol = xen_guest_blkif_protocol(be->blkif->domid);
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
71 # Makefile for the linux kernel.
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
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
85 + * !!! dirty hack alert !!!
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.
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.
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.
102 +#include <linux/kernel.h>
103 +#include <linux/module.h>
104 +#include <asm/hypervisor.h>
105 +#include <xen/blkif.h>
109 +/* stuff copied from xen/interface/domctl.h, which we can't
110 + * include directly for the reasons outlined above .... */
112 +#define XEN_DOMCTL_get_address_size 36
113 +typedef struct xen_domctl_address_size {
115 +} xen_domctl_address_size_t;
117 +typedef __attribute__((aligned(8))) uint64_t uint64_aligned_t;
120 + /* v4: sles10 sp1: xen 3.0.4 + 32-on-64 patches */
123 + uint32_t interface_version;
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];
133 + /* v5: upstream: xen 3.1 */
136 + uint32_t interface_version;
139 + struct xen_domctl_address_size address_size;
140 + uint64_aligned_t dummy_align;
141 + uint8_t dummy_pad[128];
146 +/* The actual code comes here */
148 +static inline int hypervisor_domctl(void *domctl)
150 + return _hypercall1(int, domctl, domctl);
153 +int xen_guest_address_size(int domid)
155 + union xen_domctl domctl;
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", \
171 + guest_address_size(5);
172 +#if CONFIG_XEN_COMPAT < 0x030100
173 + guest_address_size(4);
176 + ret = BITS_PER_LONG;
177 + printk("v%d...5 domctls failed, assuming dom%d is native: %d\n",
182 +EXPORT_SYMBOL_GPL(xen_guest_address_size);
184 +int xen_guest_blkif_protocol(int domid)
186 + int address_size = xen_guest_address_size(domid);
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;
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
202 +int xen_guest_address_size(int domid);
203 +int xen_guest_blkif_protocol(int domid);