All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <jbeulich@novell.com>
To: Gerd Hoffmann <kraxel@suse.de>, Keir Fraser <keir@xensource.com>
Cc: Xen devel list <xen-devel@lists.xensource.com>
Subject: Re: Re: [patch/rfc] multiprotocol blkback drivers (32-on-64)
Date: Tue, 19 Dec 2006 07:37:33 +0000	[thread overview]
Message-ID: <4587A4CD.76E4.0078.0@novell.com> (raw)
In-Reply-To: <C1AC874A.6458%keir@xensource.com>

[-- Attachment #1: Type: text/plain, Size: 2616 bytes --]

By adding abstraction to the ring macros and the affected headers, and then replacing
direct structure member accesses with appropriate macros. Reference patches
attached (not checked whether they would apply cleanly on -unstable). Jan

>>> Keir Fraser <keir@xensource.com> 18.12.06 18:58 >>>
Gerd's description is along the lines of what I would implement myself. How
does your bi-modal approach work?

 -- Keir

On 18/12/06 17:09, "Jan Beulich" <jbeulich@novell.com> wrote:

> I understand you favor this over the bi-modal approach I took? Any specific
> advantages? Jan
> 
>>>> Gerd Hoffmann <kraxel@suse.de> 18.12.06 17:39 >>>
> Hi,
> 
> This is a patch for the block interface, frontend drivers, backend
> drivers and tools to support multiple ring protocols.  Right there are
> now just two: the 32bit and the 64bit one.  If needed it can be extended.
> 
> Interface changes (io/blkif.h)
>  * Have both request structs there, with "v1" and "v2" added to the
>    name.  The old name is aliased to the native protocol of the
>    architecture.
>  * Add helper functions to convert v1/v2 requests to native.
> 
> Frontend changes:
>  * Create a new node "protocol", add the protocol number it speaks
>    there.
> 
> Backend changes:
>  * Look at the "protocol" number of the frontend and switch ring
>    handling accordingly.  If the protocol node isn't present it assumes
>    native protocol.
>  * As the request struct is copied anyway before being processed (for
>    security reasons) it is converted to native at that point so most
>    backend code doesn't need to know what the frontend speaks.
>  * In case of blktap this is completely transparent to userspace, the
>    kernel/userspace ring is always native no matter what the frontend
>    speaks.
> 
> Tools changes:
>  * Add one more option to the disk configuration, so one can specify the
>    protocol the frontend speaks in the config file.  This is needed for
>    old frontends which don't advertise the protocol they are speaking
>    themself.
>    I'm not that happy with this approach, but it works for now and I'm
>    kida lost in the stack of python classes doing domain and device
>    handling ...
> 
> Consider the code experimental, not all frontend/backend combinations
> are tested.
> 
> Comments?  Questions?  Suggesions?
> 
> cheers,
>   Gerd
> 
> PS: Anyone working on blkback/blktap code sharing?  While walking
>     through the code I've noticed quite alot of it is cut&paste ...


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com 
http://lists.xensource.com/xen-devel

[-- Attachment #2: xen-bimodal-tpmback.patch --]
[-- Type: text/plain, Size: 10406 bytes --]

Enhance tpmback to be capable of dealing with bi-modal operation (frontend
running in with different word size than backend).

Index: sle10-sp1-2006-12-05/drivers/xen/tpmback/common.h
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/tpmback/common.h	2006-12-07 16:43:42.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/tpmback/common.h	2006-12-07 16:45:08.000000000 +0100
@@ -12,7 +12,9 @@
 #include <linux/slab.h>
 #include <xen/evtchn.h>
 #include <xen/driver_util.h>
-#include <xen/interface/grant_table.h>
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define TPMIF_BIMODAL
+#endif
 #include <xen/interface/io/tpmif.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
@@ -27,6 +29,9 @@ typedef struct tpmif_st {
 	struct list_head tpmif_list;
 	/* Unique identifier for this interface. */
 	domid_t domid;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+	unsigned char native;
+#endif
 	unsigned int handle;
 
 	/* Physical parameters of the comms window. */
@@ -34,7 +39,7 @@ typedef struct tpmif_st {
 	unsigned int irq;
 
 	/* The shared rings and indexes. */
-	tpmif_tx_interface_t *tx;
+	tpmif_tx_interface_u tx;
 	struct vm_struct *tx_area;
 
 	/* Miscellaneous private stuff. */
@@ -54,6 +59,15 @@ typedef struct tpmif_st {
 	char devname[20];
 } tpmif_t;
 
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define tpmif_request(tpmif, rq, n) \
+	((tpmif)->native \
+	 ? (void)(rq.nat = &(tpmif)->tx.nat->ring[n].req) \
+	 : (void)(rq.alt = &(tpmif)->tx.alt->ring[n].req))
+#else
+#define tpmif_request(tpmif, rq, n) ((void)(rq = &(tpmif)->tx->ring[n].req))
+#endif
+
 void tpmif_disconnect_complete(tpmif_t * tpmif);
 tpmif_t *tpmif_find(domid_t domid, struct backend_info *bi);
 void tpmif_interface_init(void);
Index: sle10-sp1-2006-12-05/drivers/xen/tpmback/interface.c
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/tpmback/interface.c	2006-12-07 16:43:42.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/tpmback/interface.c	2006-12-07 16:45:08.000000000 +0100
@@ -30,6 +30,9 @@ static tpmif_t *alloc_tpmif(domid_t domi
 
 	memset(tpmif, 0, sizeof (*tpmif));
 	tpmif->domid = domid;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+	tpmif->native = 1; /* XXX */
+#endif
 	tpmif->status = DISCONNECTED;
 	tpmif->bi = bi;
 	snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid);
@@ -115,6 +118,12 @@ static void unmap_frontend_page(tpmif_t 
 	BUG_ON(ret);
 }
 
+#ifndef CONFIG_XEN_BIMODAL_BACKENDS
+#define tpmif_tx tpmif->tx
+#else
+#define tpmif_tx tpmif->tx.nat
+#endif
+
 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
 {
 	int err;
@@ -147,7 +156,7 @@ int tpmif_map(tpmif_t *tpmif, unsigned l
 
 	tpmif->evtchn = bind_interdomain.local_port;
 
-	tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
+	tpmif_tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
 	tpmif->irq = bind_evtchn_to_irqhandler(
 		tpmif->evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
@@ -162,7 +171,7 @@ void tpmif_disconnect_complete(tpmif_t *
 	if (tpmif->irq)
 		unbind_from_irqhandler(tpmif->irq, tpmif);
 
-	if (tpmif->tx) {
+	if (tpmif_tx) {
 		unmap_frontend_page(tpmif);
 		free_vm_area(tpmif->tx_area);
 	}
@@ -170,6 +179,8 @@ void tpmif_disconnect_complete(tpmif_t *
 	free_tpmif(tpmif);
 }
 
+#undef tpmif_tx
+
 void __init tpmif_interface_init(void)
 {
 	tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
Index: sle10-sp1-2006-12-05/drivers/xen/tpmback/tpmback.c
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/tpmback/tpmback.c	2006-12-07 16:43:42.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/tpmback/tpmback.c	2006-12-07 16:45:08.000000000 +0100
@@ -70,6 +70,12 @@ static int packet_read_shmem(struct pack
 			     char *buffer, int isuserbuffer, u32 left);
 static int vtpm_queue_packet(struct packet *pak);
 
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define tx(op) (tpmif->native ? (tx.nat->op) : (tx.alt->op))
+#else
+#define tx(op) (tx->op)
+#endif
+
 /***************************************************************
  Buffer copying fo user and kernel space buffes.
 ***************************************************************/
@@ -244,17 +250,17 @@ int _packet_write(struct packet *pak,
 		unsigned int tocopy;
 		struct gnttab_map_grant_ref map_op;
 		struct gnttab_unmap_grant_ref unmap_op;
-		tpmif_tx_request_t *tx;
+		tpmif_tx_request_u tx;
 
-		tx = &tpmif->tx->ring[i].req;
+		tpmif_request(tpmif, tx, i);
 
-		if (0 == tx->addr) {
+		if (0 == tx(addr)) {
 			DPRINTK("ERROR: Buffer for outgoing packet NULL?! i=%d\n", i);
 			return 0;
 		}
 
 		gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
-				  GNTMAP_host_map, tx->ref, tpmif->domid);
+				  GNTMAP_host_map, tx(ref), tpmif->domid);
 
 		if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
 						       &map_op, 1))) {
@@ -271,12 +277,12 @@ int _packet_write(struct packet *pak,
 		tocopy = min_t(size_t, size - offset, PAGE_SIZE);
 
 		if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) |
-					      (tx->addr & ~PAGE_MASK)),
+					      (unsigned long)tx(addr & ~PAGE_MASK)),
 				     &data[offset], tocopy, isuserbuffer)) {
 			tpmif_put(tpmif);
 			return -EFAULT;
 		}
-		tx->size = tocopy;
+		tx(size = tocopy);
 
 		gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i),
 				    GNTMAP_host_map, handle);
@@ -375,9 +381,6 @@ static int packet_read_shmem(struct pack
 	u32 to_copy;
 	grant_handle_t handle;
 
-	tpmif_tx_request_t *tx;
-
-	tx = &tpmif->tx->ring[0].req;
 	/*
 	 * Start copying data at the page with index 'index'
 	 * and within that page at offset 'offset'.
@@ -385,14 +388,15 @@ static int packet_read_shmem(struct pack
 	 */
 	to_copy = min_t(u32, PAGE_SIZE - pg_offset, room_left);
 	while (to_copy > 0) {
+		tpmif_tx_request_u tx;
 		void *src;
 		struct gnttab_map_grant_ref map_op;
 		struct gnttab_unmap_grant_ref unmap_op;
 
-		tx = &tpmif->tx->ring[i].req;
+		tpmif_request(tpmif, tx, i);
 
 		gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i),
-				  GNTMAP_host_map, tx->ref, tpmif->domid);
+				  GNTMAP_host_map, tx(ref), tpmif->domid);
 
 		if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
 						       &map_op, 1))) {
@@ -406,19 +410,19 @@ static int packet_read_shmem(struct pack
 
 		handle = map_op.handle;
 
-		if (to_copy > tx->size) {
+		if (to_copy > tx(size)) {
 			/*
 			 * User requests more than what's available
 			 */
-			to_copy = min_t(u32, tx->size, to_copy);
+			to_copy = min_t(u32, tx(size), to_copy);
 		}
 
 		DPRINTK("Copying from mapped memory at %08lx\n",
 			(unsigned long)(idx_to_kaddr(tpmif, i) |
-					(tx->addr & ~PAGE_MASK)));
+					(unsigned long)tx(addr & ~PAGE_MASK)));
 
 		src = (void *)(idx_to_kaddr(tpmif, i) |
-			       ((tx->addr & ~PAGE_MASK) + pg_offset));
+			       ((unsigned long)tx(addr & ~PAGE_MASK) + pg_offset));
 		if (copy_to_buffer(&buffer[offset],
 				   src, to_copy, isuserbuffer)) {
 			return -EFAULT;
@@ -879,7 +883,7 @@ static void tpm_tx_action(unsigned long 
 {
 	struct list_head *ent;
 	tpmif_t *tpmif;
-	tpmif_tx_request_t *tx;
+	tpmif_tx_request_u tx;
 
 	DPRINTK("%s: Getting data from front-end(s)!\n", __FUNCTION__);
 
@@ -890,10 +894,10 @@ static void tpm_tx_action(unsigned long 
 		tpmif_get(tpmif);
 		remove_from_tpm_schedule_list(tpmif);
 
-		tx = &tpmif->tx->ring[0].req;
+		tpmif_request(tpmif, tx, 0);
 
 		/* pass it up */
-		vtpm_receive(tpmif, tx->size);
+		vtpm_receive(tpmif, tx(size));
 
 		tpmif_put(tpmif);
 	}
Index: sle10-sp1-2006-12-05/include/xen/interface/io/tpmif.h
===================================================================
--- sle10-sp1-2006-12-05.orig/include/xen/interface/io/tpmif.h	2006-12-07 16:43:42.000000000 +0100
+++ sle10-sp1-2006-12-05/include/xen/interface/io/tpmif.h	2006-12-07 16:45:08.000000000 +0100
@@ -32,17 +32,39 @@
  */
 
 #ifndef __XEN_PUBLIC_IO_TPMIF_H__
-#define __XEN_PUBLIC_IO_TPMIF_H__
 
 #include "../grant_table.h"
 
-struct tpmif_tx_request {
+#ifndef tpmif
+# ifdef TPMIF_BIMODAL
+#  define BACKEND_RING_BIMODAL
+#  if defined(__linux__) && defined(__KERNEL__)
+#   ifdef CONFIG_64BIT
+#    define long int
+#   else
+#    define long long long __attribute__((__aligned__(8)))
+#   endif
+#  else
+#   error Environment unsupported for bi-modal operation.
+#  endif
+#  define tpmif(x) tpmif_alt_##x
+#  include "tpmif.h"
+#  undef long
+# endif
+# define tpmif(x) tpmif_##x
+#endif
+
+#define __XEN_PUBLIC_IO_TPMIF_H__
+
+struct tpmif(tx_request) {
     unsigned long addr;   /* Machine address of packet.   */
     grant_ref_t ref;      /* grant table access reference */
     uint16_t unused;
     uint16_t size;        /* Packet size in bytes.        */
 };
-typedef struct tpmif_tx_request tpmif_tx_request_t;
+typedef struct tpmif(tx_request) tpmif(tx_request_t);
+
+#ifndef TPMIF_TX_RING_SIZE
 
 /*
  * The TPMIF_TX_RING_SIZE defines the number of pages the
@@ -50,20 +72,38 @@ typedef struct tpmif_tx_request tpmif_tx
  */
 typedef uint32_t TPMIF_RING_IDX;
 
+#ifdef TPMIF_BIMODAL
+typedef union {
+	struct tpmif_tx_request *nat;
+	struct tpmif_alt_tx_request *alt;
+} tpmif_tx_request_u;
+typedef union {
+	struct tpmif_tx_interface *nat;
+	struct tpmif_alt_tx_interface *alt;
+} tpmif_tx_interface_u;
+#else
+typedef struct tpmif_tx_request *tpmif_tx_request_u;
+typedef struct tpmif_tx_interface *tpmif_tx_interface_u;
+#endif
+
+#endif
+
 #define TPMIF_TX_RING_SIZE 10
 
 /* This structure must fit in a memory page. */
 
-struct tpmif_ring {
-    struct tpmif_tx_request req;
+struct tpmif(ring) {
+    struct tpmif(tx_request) req;
 };
-typedef struct tpmif_ring tpmif_ring_t;
+typedef struct tpmif(ring) tpmif(ring_t);
 
-struct tpmif_tx_interface {
-    struct tpmif_ring ring[TPMIF_TX_RING_SIZE];
+struct tpmif(tx_interface) {
+    struct tpmif(ring) ring[TPMIF_TX_RING_SIZE];
 };
-typedef struct tpmif_tx_interface tpmif_tx_interface_t;
+typedef struct tpmif(tx_interface) tpmif(tx_interface_t);
 
+#undef tpmif
+#undef TPMIF_BIMODAL
 #endif
 
 /*

[-- Attachment #3: xen-bimodal-blkif.patch --]
[-- Type: text/plain, Size: 21741 bytes --]

Enhance blkif and ring handling to be capable of dealing with bi-modal
operation (frontend running in with different word size than backend).

Index: sle10-sp1-2006-12-05/drivers/xen/Kconfig
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/Kconfig	2006-12-07 16:43:54.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/Kconfig	2006-12-07 16:44:54.000000000 +0100
@@ -45,6 +45,14 @@ config XEN_BACKEND
           Support for backend device drivers that provide I/O services
           to other virtual machines.
 
+config XEN_BIMODAL_BACKENDS
+	bool "Bi-modal backend driver support"
+        depends on XEN_BACKEND && (X86_PAE || X86_64)
+	default y
+	help
+	  Build backend device drivers providing support for both
+	  native as well as compatibility guests.
+
 config XEN_BLKDEV_BACKEND
 	tristate "Block-device backend driver"
         depends on XEN_BACKEND
Index: sle10-sp1-2006-12-05/include/xen/interface/io/blkif.h
===================================================================
--- sle10-sp1-2006-12-05.orig/include/xen/interface/io/blkif.h	2006-12-07 16:43:54.000000000 +0100
+++ sle10-sp1-2006-12-05/include/xen/interface/io/blkif.h	2006-12-07 16:44:54.000000000 +0100
@@ -25,6 +25,30 @@
  */
 
 #ifndef __XEN_PUBLIC_IO_BLKIF_H__
+#ifndef blkif
+# ifdef BLKIF_BIMODAL
+#  define BACKEND_RING_BIMODAL
+#  if defined(__linux__) && defined(__KERNEL__)
+#   ifdef CONFIG_64BIT
+#    pragma pack(push, 4)
+#   else
+#    define uint64_t uint64_t __attribute__((__aligned__(8)))
+#   endif
+#  else
+#   error Environment unsupported for bi-modal operation.
+#  endif
+#  define blkif(x) blkif_alt_##x
+#  include "blkif.h"
+#  if defined(__linux__) && defined(__KERNEL__)
+#   ifdef CONFIG_64BIT
+#    pragma pack(pop)
+#   else
+#    undef uint64_t
+#   endif
+#  endif
+# endif
+# define blkif(x) blkif_##x
+#endif
 #define __XEN_PUBLIC_IO_BLKIF_H__
 
 #include "ring.h"
@@ -71,27 +95,31 @@
  */
 #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
 
-struct blkif_request {
+#ifndef BLKIF_RSP_ERROR
+struct blkif_request_segment {
+    grant_ref_t gref;        /* reference to I/O buffer frame        */
+    /* @first_sect: first sector in frame to transfer (inclusive).   */
+    /* @last_sect: last sector in frame to transfer (inclusive).     */
+    uint8_t     first_sect, last_sect;
+};
+#endif
+
+struct blkif(request) {
     uint8_t        operation;    /* BLKIF_OP_???                         */
     uint8_t        nr_segments;  /* number of segments                   */
     blkif_vdev_t   handle;       /* only for read/write requests         */
     uint64_t       id;           /* private guest value, echoed in resp  */
     blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
-    struct blkif_request_segment {
-        grant_ref_t gref;        /* reference to I/O buffer frame        */
-        /* @first_sect: first sector in frame to transfer (inclusive).   */
-        /* @last_sect: last sector in frame to transfer (inclusive).     */
-        uint8_t     first_sect, last_sect;
-    } seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 };
-typedef struct blkif_request blkif_request_t;
+typedef struct blkif(request) blkif(request_t);
 
-struct blkif_response {
+struct blkif(response) {
     uint64_t        id;              /* copied from request */
     uint8_t         operation;       /* copied from request */
     int16_t         status;          /* BLKIF_RSP_???       */
 };
-typedef struct blkif_response blkif_response_t;
+typedef struct blkif(response) blkif(response_t);
 
 /*
  * STATUS RETURN CODES.
@@ -107,12 +135,16 @@ typedef struct blkif_response blkif_resp
  * Generate blkif ring structures and types.
  */
 
+#ifndef BLKIF_BIMODAL
 DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
+#endif
 
 #define VDISK_CDROM        0x1
 #define VDISK_REMOVABLE    0x2
 #define VDISK_READONLY     0x4
 
+#undef blkif
+#undef BLKIF_BIMODAL
 #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
 
 /*
Index: sle10-sp1-2006-12-05/include/xen/interface/io/ring.h
===================================================================
--- sle10-sp1-2006-12-05.orig/include/xen/interface/io/ring.h	2006-12-07 16:43:54.000000000 +0100
+++ sle10-sp1-2006-12-05/include/xen/interface/io/ring.h	2006-12-07 16:44:54.000000000 +0100
@@ -78,6 +78,7 @@ typedef unsigned int RING_IDX;
  */
 
 #define DEFINE_RING_TYPES(__name, __req_t, __rsp_t)                     \
+DEFINE_ALT_RING_TYPES(__name);                                          \
                                                                         \
 /* Shared ring entry */                                                 \
 union __name##_sring_entry {                                            \
@@ -106,14 +107,72 @@ struct __name##_back_ring {             
     RING_IDX rsp_prod_pvt;                                              \
     RING_IDX req_cons;                                                  \
     unsigned int nr_ents;                                               \
-    struct __name##_sring *sring;                                       \
+    __name##_sring_u sring;                                             \
 };                                                                      \
                                                                         \
+CHECK_RING_TYPES(__name)                                                \
+                                                                        \
 /* Syntactic sugar */                                                   \
 typedef struct __name##_sring __name##_sring_t;                         \
 typedef struct __name##_front_ring __name##_front_ring_t;               \
 typedef struct __name##_back_ring __name##_back_ring_t
 
+#ifdef BACKEND_RING_BIMODAL
+#define DEFINE_ALT_RING_TYPES(__name)                                   \
+                                                                        \
+/* Shared ring entry */                                                 \
+union __name##_alt_sring_entry {                                        \
+    struct __name##_alt_request req;                                    \
+    struct __name##_alt_response rsp;                                   \
+};                                                                      \
+                                                                        \
+/* Shared ring page */                                                  \
+typedef struct __name##_alt_sring {                                     \
+    RING_IDX req_prod, req_event;                                       \
+    RING_IDX rsp_prod, rsp_event;                                       \
+    uint8_t  pad[48];                                                   \
+    union __name##_alt_sring_entry ring[1]; /* variable-length */       \
+} __name##_alt_sring_t;                                                 \
+                                                                        \
+typedef union {                                                         \
+    struct __name##_sring *nat;                                         \
+    struct __name##_alt_sring *alt;                                     \
+} __name##_sring_u;                                                     \
+                                                                        \
+typedef union {                                                         \
+    struct __name##_request nat;                                        \
+    struct __name##_alt_request alt;                                    \
+} __name##_request_u;                                                   \
+                                                                        \
+typedef union {                                                         \
+    struct __name##_response *nat;                                      \
+    struct __name##_alt_response *alt;                                  \
+} __name##_response_u
+
+#define CHECK_SRING_FIELD(__name, __fld)                                \
+    BUILD_BUG_ON(&((struct __name ## _sring *)0)->__fld !=              \
+                 &((struct __name ## _alt_sring *)0)->__fld)
+
+#define CHECK_RING_TYPES(__name)                                        \
+static inline void _##__name##_check_ring_types_(void) {                \
+    CHECK_SRING_FIELD(__name, req_prod);                                \
+    CHECK_SRING_FIELD(__name, req_event);                               \
+    CHECK_SRING_FIELD(__name, rsp_prod);                                \
+    CHECK_SRING_FIELD(__name, rsp_event);                               \
+    CHECK_SRING_FIELD(__name, pad);                                     \
+}
+#define BB_SRING(_s) _s.alt
+#else
+#define DEFINE_ALT_RING_TYPES(__name)                                   \
+typedef struct __name##_sring *__name##_sring_u;                        \
+typedef struct __name##_request __name##_request_u;                     \
+typedef struct __name##_response *__name##_response_u
+
+#define CHECK_RING_TYPES(__name)
+
+#define BB_SRING(_s) _s
+#endif
+
 /*
  * Macros for manipulating rings.
  * 
@@ -135,6 +194,7 @@ typedef struct __name##_back_ring __name
     (_s)->req_event = (_s)->rsp_event = 1;                              \
     memset((_s)->pad, 0, sizeof((_s)->pad));                            \
 } while(0)
+#define BB_SHARED_RING_INIT(_s) SHARED_RING_INIT(BB_SRING(_s))
 
 #define FRONT_RING_INIT(_r, _s, __size) do {                            \
     (_r)->req_prod_pvt = 0;                                             \
@@ -143,12 +203,24 @@ typedef struct __name##_back_ring __name
     (_r)->sring = (_s);                                                 \
 } while (0)
 
+#ifndef BACKEND_RING_BIMODAL
 #define BACK_RING_INIT(_r, _s, __size) do {                             \
     (_r)->rsp_prod_pvt = 0;                                             \
     (_r)->req_cons = 0;                                                 \
     (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
     (_r)->sring = (_s);                                                 \
 } while (0)
+#else
+#define BACK_RING_INIT(_r, _s, __size) do {                             \
+    (_r)->rsp_prod_pvt = 0;                                             \
+    (_r)->req_cons = 0;                                                 \
+    if (ring_native(_r))                                                \
+        (_r)->nr_ents = __RING_SIZE((_s).nat, __size);                  \
+    else                                                                \
+        (_r)->nr_ents = __RING_SIZE((_s).alt, __size);                  \
+    (_r)->sring = (_s);                                                 \
+} while (0)
+#endif
 
 /* Initialize to existing shared indexes -- for recovery */
 #define FRONT_RING_ATTACH(_r, _s, __size) do {                          \
@@ -158,12 +230,24 @@ typedef struct __name##_back_ring __name
     (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
 } while (0)
 
+#ifndef BACKEND_RING_BIMODAL
 #define BACK_RING_ATTACH(_r, _s, __size) do {                           \
     (_r)->sring = (_s);                                                 \
     (_r)->rsp_prod_pvt = (_s)->rsp_prod;                                \
     (_r)->req_cons = (_s)->req_prod;                                    \
     (_r)->nr_ents = __RING_SIZE(_s, __size);                            \
 } while (0)
+#else
+#define BACK_RING_ATTACH(_r, _s, __size) do {                           \
+    (_r)->sring = (_s);                                                 \
+    (_r)->rsp_prod_pvt = (_s).alt->rsp_prod;                            \
+    (_r)->req_cons = (_s).alt->req_prod;                                \
+    if (ring_native(_r))                                                \
+        (_r)->nr_ents = __RING_SIZE((_s).nat, __size);                  \
+    else                                                                \
+        (_r)->nr_ents = __RING_SIZE((_s).alt, __size);                  \
+} while (0)
+#endif
 
 /* How big is this ring? */
 #define RING_SIZE(_r)                                                   \
@@ -180,11 +264,15 @@ typedef struct __name##_back_ring __name
     (RING_FREE_REQUESTS(_r) == 0)
 
 /* Test if there are outstanding messages to be processed on a ring. */
-#define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \
+#define _RING_HAS_UNCONSUMED_RESPONSES(_r, sring)                       \
     ((_r)->sring->rsp_prod - (_r)->rsp_cons)
+#define RING_HAS_UNCONSUMED_RESPONSES(_r)                               \
+    _RING_HAS_UNCONSUMED_RESPONSES(_r, sring)
+#define BB_RING_HAS_UNCONSUMED_RESPONSES(_r)                            \
+    _RING_HAS_UNCONSUMED_RESPONSES(_r, BB_SRING(sring))
 
 #ifdef __GNUC__
-#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({                             \
+#define _RING_HAS_UNCONSUMED_REQUESTS(_r, sring) ({                     \
     unsigned int req = (_r)->sring->req_prod - (_r)->req_cons;          \
     unsigned int rsp = RING_SIZE(_r) -                                  \
         ((_r)->req_cons - (_r)->rsp_prod_pvt);                          \
@@ -192,33 +280,75 @@ typedef struct __name##_back_ring __name
 })
 #else
 /* Same as above, but without the nice GCC ({ ... }) syntax. */
-#define RING_HAS_UNCONSUMED_REQUESTS(_r)                                \
+#define _RING_HAS_UNCONSUMED_REQUESTS(_r, sring)                        \
     ((((_r)->sring->req_prod - (_r)->req_cons) <                        \
       (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ?        \
      ((_r)->sring->req_prod - (_r)->req_cons) :                         \
      (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
 #endif
+#define RING_HAS_UNCONSUMED_REQUESTS(_r)                                \
+    _RING_HAS_UNCONSUMED_REQUESTS(_r, sring)
+#define BB_RING_HAS_UNCONSUMED_REQUESTS(_r)                             \
+    _RING_HAS_UNCONSUMED_REQUESTS(_r, BB_SRING(sring))
 
 /* Direct access to individual ring elements, by index. */
 #define RING_GET_REQUEST(_r, _idx)                                      \
     (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+#ifndef BACKEND_RING_BIMODAL
+#define BB_RING_GET_REQUEST(_req, _r, _idx) do {                        \
+    (_req) = RING_GET_REQUEST(_r, _idx);                                \
+} while (0)
+#else
+#define BB_RING_GET_REQUEST(_req, _r, _idx) do {                        \
+    if (ring_native(_r))                                                \
+        (_req).nat = &(_r)->sring.nat->ring[(_idx) & (RING_SIZE(_r) - 1)].req; \
+    else                                                                \
+        (_req).alt = &(_r)->sring.alt->ring[(_idx) & (RING_SIZE(_r) - 1)].req; \
+} while (0)
+#endif
+
+#define RING_COPY_REQUEST(_req, _r, _idx)                               \
+    memcpy(&(_req), RING_GET_REQUEST(_r, _idx), sizeof(_req))
+#ifndef BACKEND_RING_BIMODAL
+#define BB_RING_COPY_REQUEST RING_COPY_REQUEST
+#else
+#define BB_RING_COPY_REQUEST(_req, _r, _idx) (ring_native(_r) ?         \
+    memcpy(&(_req), &(_r)->sring.nat->ring[(_idx) & (RING_SIZE(_r) - 1)].req, sizeof((_req).nat)) : \
+    memcpy(&(_req), &(_r)->sring.alt->ring[(_idx) & (RING_SIZE(_r) - 1)].req, sizeof((_req).alt)))
+#endif
 
 #define RING_GET_RESPONSE(_r, _idx)                                     \
     (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
+#ifndef BACKEND_RING_BIMODAL
+#define BB_RING_GET_RESPONSE(_rsp, _r, _idx) do {                       \
+    (_rsp) = RING_GET_RESPONSE(_r, _idx);                               \
+} while (0)
+#else
+#define BB_RING_GET_RESPONSE(_rsp, _r, _idx) do {                       \
+    if (ring_native(_r))                                                \
+        (_rsp).nat = &(_r)->sring.nat->ring[(_idx) & (RING_SIZE(_r) - 1)].rsp; \
+    else                                                                \
+        (_rsp).alt = &(_r)->sring.alt->ring[(_idx) & (RING_SIZE(_r) - 1)].rsp; \
+} while (0)
+#endif
 
 /* Loop termination condition: Would the specified index overflow the ring? */
 #define RING_REQUEST_CONS_OVERFLOW(_r, _cons)                           \
     (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
 
-#define RING_PUSH_REQUESTS(_r) do {                                     \
+#define _RING_PUSH_REQUESTS(_r, sring) do {                             \
     wmb(); /* back sees requests /before/ updated producer index */     \
     (_r)->sring->req_prod = (_r)->req_prod_pvt;                         \
 } while (0)
+#define RING_PUSH_REQUESTS(_r) _RING_PUSH_REQUESTS(_r, sring)
+#define BB_RING_PUSH_REQUESTS(_r) _RING_PUSH_REQUESTS(_r, BB_SRING(sring))
 
-#define RING_PUSH_RESPONSES(_r) do {                                    \
+#define _RING_PUSH_RESPONSES(_r, sring) do {                            \
     wmb(); /* front sees responses /before/ updated producer index */   \
     (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt;                         \
 } while (0)
+#define RING_PUSH_RESPONSES(_r) _RING_PUSH_RESPONSES(_r, sring)
+#define BB_RING_PUSH_RESPONSES(_r) _RING_PUSH_RESPONSES(_r, BB_SRING(sring))
 
 /*
  * Notification hold-off (req_event and rsp_event):
@@ -250,7 +380,7 @@ typedef struct __name##_back_ring __name
  *  field appropriately.
  */
 
-#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do {           \
+#define _RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, sring, _notify) do {   \
     RING_IDX __old = (_r)->sring->req_prod;                             \
     RING_IDX __new = (_r)->req_prod_pvt;                                \
     wmb(); /* back sees requests /before/ updated producer index */     \
@@ -259,8 +389,12 @@ typedef struct __name##_back_ring __name
     (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) <           \
                  (RING_IDX)(__new - __old));                            \
 } while (0)
+#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify)                \
+    _RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, sring, _notify)
+#define BB_RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify)             \
+    _RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, BB_SRING(sring), _notify)
 
-#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do {          \
+#define _RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, sring, _notify) do {  \
     RING_IDX __old = (_r)->sring->rsp_prod;                             \
     RING_IDX __new = (_r)->rsp_prod_pvt;                                \
     wmb(); /* front sees responses /before/ updated producer index */   \
@@ -269,22 +403,34 @@ typedef struct __name##_back_ring __name
     (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) <           \
                  (RING_IDX)(__new - __old));                            \
 } while (0)
+#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify)               \
+    _RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, sring, _notify)
+#define BB_RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify)            \
+    _RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, BB_SRING(sring), _notify)
 
-#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do {             \
-    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
+#define _RING_FINAL_CHECK_FOR_REQUESTS(_r, bb, sring, _work_to_do) do { \
+    (_work_to_do) = bb##RING_HAS_UNCONSUMED_REQUESTS(_r);               \
     if (_work_to_do) break;                                             \
     (_r)->sring->req_event = (_r)->req_cons + 1;                        \
     mb();                                                               \
-    (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r);                   \
+    (_work_to_do) = bb##RING_HAS_UNCONSUMED_REQUESTS(_r);               \
 } while (0)
+#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do)                  \
+    _RING_FINAL_CHECK_FOR_REQUESTS(_r, , sring, _work_to_do)
+#define BB_RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do)               \
+    _RING_FINAL_CHECK_FOR_REQUESTS(_r, BB_, BB_SRING(sring), _work_to_do)
 
-#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do {            \
-    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
+#define _RING_FINAL_CHECK_FOR_RESPONSES(_r, bb, sring, _work_to_do) do {\
+    (_work_to_do) = bb##RING_HAS_UNCONSUMED_RESPONSES(_r);              \
     if (_work_to_do) break;                                             \
     (_r)->sring->rsp_event = (_r)->rsp_cons + 1;                        \
     mb();                                                               \
-    (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r);                  \
+    (_work_to_do) = bb##RING_HAS_UNCONSUMED_RESPONSES(_r);              \
 } while (0)
+#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do)                 \
+    _RING_FINAL_CHECK_FOR_RESPONSES(_r, , sring, _work_to_do)
+#define BB_RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do)              \
+    _RING_FINAL_CHECK_FOR_RESPONSES(_r, BB_, BB_SRING(sring), _work_to_do)
 
 #endif /* __XEN_PUBLIC_IO_RING_H__ */
 

[-- Attachment #4: xen-bimodal-blktap.patch --]
[-- Type: text/plain, Size: 12015 bytes --]

Enhance blktap to be capable of dealing with bi-modal operation (frontend
running in with different word size than backend).

Index: sle10-sp1-2006-12-05/drivers/xen/blktap/blktap.c
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/blktap/blktap.c	2006-12-07 16:43:47.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/blktap/blktap.c	2006-12-07 16:45:05.000000000 +0100
@@ -154,7 +154,7 @@ module_param(debug_lvl, int, 0644);
  */
 typedef struct {
 	blkif_t       *blkif;
-	unsigned long  id;
+	uint64_t       id;
 	unsigned short mem_idx;
 	int            nr_pages;
 	atomic_t       pendcnt;
@@ -757,9 +757,9 @@ void blktap_kick_user(int idx)
 
 static int do_block_io_op(blkif_t *blkif);
 static void dispatch_rw_block_io(blkif_t *blkif,
-				 blkif_request_t *req,
+				 blkif_request_u *req,
 				 pending_req_t *pending_req);
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, uint64_t id,
                           unsigned short op, int st);
 
 /******************************************************************
@@ -1085,18 +1085,26 @@ irqreturn_t tap_blkif_be_int(int irq, vo
 /******************************************************************
  * DOWNWARD CALLS -- These interface with the block-device layer proper.
  */
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define req(op) (blkif_native(blkif) ? (req.nat.op) : (req.alt.op))
+#define preq(op) (blkif_native(blkif) ? (req->nat.op) : (req->alt.op))
+#else
+#define req(op) (req.op)
+#define preq(op) (req->op)
+#endif
+
 static int print_dbug = 1;
 static int do_block_io_op(blkif_t *blkif)
 {
 	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-	blkif_request_t req;
+	blkif_request_u req;
 	pending_req_t *pending_req;
 	RING_IDX rc, rp;
 	int more_to_do = 0;
 	tap_blkif_t *info;
 
 	rc = blk_ring->req_cons;
-	rp = blk_ring->sring->req_prod;
+	rp = blk_ring->BB_SRING(sring)->req_prod;
 	rmb(); /* Ensure we see queued requests up to 'rp'. */
 
 	/*Check blkif has corresponding UE ring*/
@@ -1142,10 +1150,10 @@ static int do_block_io_op(blkif_t *blkif
 			break;
 		}
 
-		memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req));
+		BB_RING_COPY_REQUEST(req, blk_ring, rc);
 		blk_ring->req_cons = ++rc; /* before make_response() */	
 
-		switch (req.operation) {
+		switch (req(operation)) {
 		case BLKIF_OP_READ:
 			blkif->st_rd_req++;
 			dispatch_rw_block_io(blkif, &req, pending_req);
@@ -1158,8 +1166,8 @@ static int do_block_io_op(blkif_t *blkif
 
 		default:
 			WPRINTK("unknown operation [%d]\n",
-				req.operation);
-			make_response(blkif, req.id, req.operation,
+				req(operation));
+			make_response(blkif, req(id), req(operation),
 				      BLKIF_RSP_ERROR);
 			free_req(pending_req);
 			break;
@@ -1172,11 +1180,11 @@ static int do_block_io_op(blkif_t *blkif
 }
 
 static void dispatch_rw_block_io(blkif_t *blkif,
-				 blkif_request_t *req,
+				 blkif_request_u *req,
 				 pending_req_t *pending_req)
 {
 	extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
-	int op, operation = (req->operation == BLKIF_OP_WRITE) ? WRITE : READ;
+	int op, operation = (preq(operation) == BLKIF_OP_WRITE) ? WRITE : READ;
 	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2];
 	unsigned int nseg;
 	int ret, i;
@@ -1202,7 +1210,7 @@ static void dispatch_rw_block_io(blkif_t
 	}
 
 	/* Check that number of segments is sane. */
-	nseg = req->nr_segments;
+	nseg = preq(nr_segments);
 	if ( unlikely(nseg == 0) || 
 	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) ) {
 		WPRINTK("Bad number of segments in request (%d)\n", nseg);
@@ -1224,7 +1232,7 @@ static void dispatch_rw_block_io(blkif_t
 	}
 
 	pending_req->blkif     = blkif;
-	pending_req->id        = req->id;
+	pending_req->id        = preq(id);
 	pending_req->operation = operation;
 	pending_req->status    = BLKIF_RSP_OKAY;
 	pending_req->nr_pages  = nseg;
@@ -1238,13 +1246,13 @@ static void dispatch_rw_block_io(blkif_t
 		uvaddr = MMAP_VADDR(info->user_vstart, usr_idx, i);
 		kvaddr = idx_to_kaddr(mmap_idx, pending_idx, i);
 
-		sector = req->sector_number + ((PAGE_SIZE / 512) * i);
+		sector = preq(sector_number) + ((PAGE_SIZE / 512) * i);
 		if( (blkif->sectors > 0) && (sector >= blkif->sectors) ) {
 			WPRINTK("BLKTAP: Sector request greater" 
 			       "than size\n");
 			WPRINTK("BLKTAP: %s request sector" 
 			       "[%llu,%llu], Total [%llu]\n",
-			       (req->operation == 
+			       (preq(operation) ==
 				BLKIF_OP_WRITE ? "WRITE" : "READ"),
 				(long long unsigned) sector,
 				(long long unsigned) sector>>9,
@@ -1255,7 +1263,7 @@ static void dispatch_rw_block_io(blkif_t
 		if (operation == WRITE)
 			flags |= GNTMAP_readonly;
 		gnttab_set_map_op(&map[op], kvaddr, flags,
-				  req->seg[i].gref, blkif->domid);
+				  preq(seg)[i].gref, blkif->domid);
 		op++;
 
 		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -1272,7 +1280,7 @@ static void dispatch_rw_block_io(blkif_t
 			if (operation == WRITE)
 				flags |= GNTMAP_readonly;
 			gnttab_set_map_op(&map[op], ptep, flags,
-					  req->seg[i].gref, blkif->domid);
+					  preq(seg)[i].gref, blkif->domid);
 			op++;
 		}
 	}
@@ -1356,7 +1364,7 @@ static void dispatch_rw_block_io(blkif_t
 	if (xen_feature(XENFEAT_auto_translated_physmap))
 		down_write(&info->vma->vm_mm->mmap_sem);
 	/* Mark mapped pages as reserved: */
-	for (i = 0; i < req->nr_segments; i++) {
+	for (i = 0; i < preq(nr_segments); i++) {
 		unsigned long kvaddr;
 		struct page *pg;
 
@@ -1383,7 +1391,21 @@ static void dispatch_rw_block_io(blkif_t
 	/* Finally, write the request message to the user ring. */
 	target = RING_GET_REQUEST(&info->ufe_ring,
 				  info->ufe_ring.req_prod_pvt);
-	memcpy(target, req, sizeof(*req));
+#ifndef CONFIG_XEN_BIMODAL_BACKENDS
+	memcpy(target, &req, sizeof(req));
+#else
+	if (blkif_native(blkif))
+		memcpy(target, &req->nat, sizeof(req->nat));
+	else {
+		target->operation     = req->alt.operation;
+		target->nr_segments   = req->alt.nr_segments;
+		target->handle        = req->alt.handle;
+		target->sector_number = req->alt.sector_number;
+		BUILD_BUG_ON((typeof(target->seg)*)0 != (typeof(req->alt.seg)*)0);
+		memcpy(target->seg, req->alt.seg,
+		       target->nr_segments * sizeof(*target->seg));
+	}
+#endif
 	target->id = usr_idx;
 	wmb(); /* blktap_poll() reads req_prod_pvt asynchronously */
 	info->ufe_ring.req_prod_pvt++;
@@ -1393,10 +1415,11 @@ static void dispatch_rw_block_io(blkif_t
 	WPRINTK("Reached Fail_flush\n");
 	fast_flush_area(pending_req, pending_idx, usr_idx, blkif->dev_num);
  fail_response:
-	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
+	make_response(blkif, preq(id), preq(operation), BLKIF_RSP_ERROR);
 	free_req(pending_req);
 } 
 
+#undef req
 
 
 /******************************************************************
@@ -1404,10 +1427,15 @@ static void dispatch_rw_block_io(blkif_t
  */
 
 
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, uint64_t id,
                           unsigned short op, int st)
 {
-	blkif_response_t *resp;
+	blkif_response_u  resp;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define resp(op) (blkif_native(blkif) ? (resp.nat->op) : (resp.alt->op))
+#else
+#define resp(op) (resp->op)
+#endif
 	unsigned long     flags;
 	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
 	int more_to_do = 0;
@@ -1415,12 +1443,12 @@ static void make_response(blkif_t *blkif
 
 	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
 	/* Place on the response ring for the relevant domain. */ 
-	resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
-	resp->id        = id;
-	resp->operation = op;
-	resp->status    = st;
+	BB_RING_GET_RESPONSE(resp, blk_ring, blk_ring->rsp_prod_pvt);
+	resp(id        = id);
+	resp(operation = op);
+	resp(status    = st);
 	blk_ring->rsp_prod_pvt++;
-	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
+	BB_RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
 
 	if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) {
 		/*
@@ -1428,8 +1456,8 @@ static void make_response(blkif_t *blkif
 		 * notifications if requests are already in flight (lower
 		 * overheads and promotes batching).
 		 */
-		RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
-	} else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
+		BB_RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
+	} else if (BB_RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
 		more_to_do = 1;
 
 	}	
@@ -1438,6 +1466,7 @@ static void make_response(blkif_t *blkif
 		blkif_notify_work(blkif);
 	if (notify)
 		notify_remote_via_irq(blkif->irq);
+#undef resp
 }
 
 static int __init blkif_init(void)
Index: sle10-sp1-2006-12-05/drivers/xen/blktap/common.h
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/blktap/common.h	2006-12-07 16:43:47.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/blktap/common.h	2006-12-07 16:45:05.000000000 +0100
@@ -39,8 +39,10 @@
 #include <asm/pgalloc.h>
 #include <xen/evtchn.h>
 #include <asm/hypervisor.h>
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define BLKIF_BIMODAL
+#endif
 #include <xen/interface/io/blkif.h>
-#include <xen/interface/io/ring.h>
 #include <xen/gnttab.h>
 #include <xen/driver_util.h>
 
@@ -54,6 +56,9 @@ struct backend_info;
 typedef struct blkif_st {
 	/* Unique identifier for this interface. */
 	domid_t           domid;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+	unsigned char     native;
+#endif
 	unsigned int      handle;
 	/* Physical parameters of the comms window. */
 	unsigned int      evtchn;
@@ -87,6 +92,15 @@ typedef struct blkif_st {
 	uint64_t        sectors;
 } blkif_t;
 
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define blkif_native(blkif) ((blkif)->native)
+static inline int ring_native(const blkif_back_ring_t *ring) {
+	return blkif_native(container_of(ring, blkif_t, blk_ring));
+}
+#else
+#define blkif_native(blkif) 1
+#endif
+
 blkif_t *tap_alloc_blkif(domid_t domid);
 void tap_blkif_free(blkif_t *blkif);
 int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, 
Index: sle10-sp1-2006-12-05/drivers/xen/blktap/interface.c
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/blktap/interface.c	2006-12-07 16:43:47.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/blktap/interface.c	2006-12-07 16:45:05.000000000 +0100
@@ -46,6 +46,9 @@ blkif_t *tap_alloc_blkif(domid_t domid)
 
 	memset(blkif, 0, sizeof(*blkif));
 	blkif->domid = domid;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+	blkif->native = 1; /* XXX */
+#endif
 	spin_lock_init(&blkif->blk_ring_lock);
 	atomic_set(&blkif->refcnt, 1);
 	init_waitqueue_head(&blkif->wq);
@@ -96,7 +99,7 @@ static void unmap_frontend_page(blkif_t 
 int tap_blkif_map(blkif_t *blkif, unsigned long shared_page, 
 		  unsigned int evtchn)
 {
-	blkif_sring_t *sring;
+	blkif_sring_u sring;
 	int err;
 	struct evtchn_bind_interdomain bind_interdomain;
 
@@ -126,7 +129,7 @@ int tap_blkif_map(blkif_t *blkif, unsign
 
 	blkif->evtchn = bind_interdomain.local_port;
 
-	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
+	BB_SRING(sring) = (void *)blkif->blk_ring_area->addr;
 	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
 	blkif->irq = bind_evtchn_to_irqhandler(
@@ -141,10 +144,10 @@ void tap_blkif_unmap(blkif_t *blkif)
 		unbind_from_irqhandler(blkif->irq, blkif);
 		blkif->irq = 0;
 	}
-	if (blkif->blk_ring.sring) {
+	if (blkif->blk_ring.BB_SRING(sring)) {
 		unmap_frontend_page(blkif);
 		free_vm_area(blkif->blk_ring_area);
-		blkif->blk_ring.sring = NULL;
+		blkif->blk_ring.BB_SRING(sring) = NULL;
 	}
 }
 

[-- Attachment #5: xen-bimodal-blkback.patch --]
[-- Type: text/plain, Size: 10602 bytes --]

Enhance blkback to be capable of dealing with bi-modal operation (frontend
running in with different word size than backend).

Index: sle10-sp1-2006-12-05/drivers/xen/blkback/blkback.c
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/blkback/blkback.c	2006-12-07 16:43:52.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/blkback/blkback.c	2006-12-07 16:45:02.000000000 +0100
@@ -70,7 +70,7 @@ module_param(debug_lvl, int, 0644);
  */
 typedef struct {
 	blkif_t       *blkif;
-	unsigned long  id;
+	uint64_t       id;
 	int            nr_pages;
 	atomic_t       pendcnt;
 	unsigned short operation;
@@ -105,9 +105,9 @@ static inline unsigned long vaddr(pendin
 
 static int do_block_io_op(blkif_t *blkif);
 static void dispatch_rw_block_io(blkif_t *blkif,
-				 blkif_request_t *req,
+				 blkif_request_u *req,
 				 pending_req_t *pending_req);
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, uint64_t id,
 			  unsigned short op, int st);
 
 /******************************************************************
@@ -295,17 +295,24 @@ irqreturn_t blkif_be_int(int irq, void *
 /******************************************************************
  * DOWNWARD CALLS -- These interface with the block-device layer proper.
  */
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define req(op) (blkif_native(blkif) ? (req.nat.op) : (req.alt.op))
+#define preq(op) (blkif_native(blkif) ? (req->nat.op) : (req->alt.op))
+#else
+#define req(op) (req.op)
+#define preq(op) (req->op)
+#endif
 
 static int do_block_io_op(blkif_t *blkif)
 {
 	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
-	blkif_request_t req;
+	blkif_request_u req;
 	pending_req_t *pending_req;
 	RING_IDX rc, rp;
 	int more_to_do = 0;
 
 	rc = blk_ring->req_cons;
-	rp = blk_ring->sring->req_prod;
+	rp = blk_ring->BB_SRING(sring)->req_prod;
 	rmb(); /* Ensure we see queued requests up to 'rp'. */
 
 	while ((rc != rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) {
@@ -317,10 +324,10 @@ static int do_block_io_op(blkif_t *blkif
 			break;
 		}
 
-		memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req));
+		BB_RING_COPY_REQUEST(req, blk_ring, rc);
 		blk_ring->req_cons = ++rc; /* before make_response() */
 
-		switch (req.operation) {
+		switch (req(operation)) {
 		case BLKIF_OP_READ:
 			blkif->st_rd_req++;
 			dispatch_rw_block_io(blkif, &req, pending_req);
@@ -334,8 +341,8 @@ static int do_block_io_op(blkif_t *blkif
 			break;
 		default:
 			DPRINTK("error: unknown block io operation [%d]\n",
-				req.operation);
-			make_response(blkif, req.id, req.operation,
+				req(operation));
+			make_response(blkif, req(id), req(operation),
 				      BLKIF_RSP_ERROR);
 			free_req(pending_req);
 			break;
@@ -345,7 +352,7 @@ static int do_block_io_op(blkif_t *blkif
 }
 
 static void dispatch_rw_block_io(blkif_t *blkif,
-				 blkif_request_t *req,
+				 blkif_request_u *req,
 				 pending_req_t *pending_req)
 {
 	extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
@@ -359,7 +366,7 @@ static void dispatch_rw_block_io(blkif_t
 	int ret, i, nbio = 0;
 	int operation;
 
-	switch (req->operation) {
+	switch (preq(operation)) {
 	case BLKIF_OP_READ:
 		operation = READ;
 		break;
@@ -375,31 +382,31 @@ static void dispatch_rw_block_io(blkif_t
 	}
 
 	/* Check that number of segments is sane. */
-	nseg = req->nr_segments;
+	nseg = preq(nr_segments);
 	if (unlikely(nseg == 0) || 
 	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
 		DPRINTK("Bad number of segments in request (%d)\n", nseg);
 		goto fail_response;
 	}
 
-	preq.dev           = req->handle;
-	preq.sector_number = req->sector_number;
+	preq.dev           = preq(handle);
+	preq.sector_number = preq(sector_number);
 	preq.nr_sects      = 0;
 
 	pending_req->blkif     = blkif;
-	pending_req->id        = req->id;
-	pending_req->operation = req->operation;
+	pending_req->id        = preq(id);
+	pending_req->operation = preq(operation);
 	pending_req->status    = BLKIF_RSP_OKAY;
 	pending_req->nr_pages  = nseg;
 
 	for (i = 0; i < nseg; i++) {
 		uint32_t flags;
 
-		seg[i].nsec = req->seg[i].last_sect -
-			req->seg[i].first_sect + 1;
+		seg[i].nsec = preq(seg)[i].last_sect -
+			preq(seg)[i].first_sect + 1;
 
-		if ((req->seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
-		    (req->seg[i].last_sect < req->seg[i].first_sect))
+		if ((preq(seg)[i].last_sect >= (PAGE_SIZE >> 9)) ||
+		    (preq(seg)[i].last_sect < preq(seg)[i].first_sect))
 			goto fail_response;
 		preq.nr_sects += seg[i].nsec;
 
@@ -407,7 +414,7 @@ static void dispatch_rw_block_io(blkif_t
 		if (operation != READ)
 			flags |= GNTMAP_readonly;
 		gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags,
-				  req->seg[i].gref, blkif->domid);
+				  preq(seg)[i].gref, blkif->domid);
 	}
 
 	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
@@ -429,7 +436,7 @@ static void dispatch_rw_block_io(blkif_t
 			pending_req, i)) >> PAGE_SHIFT,
 			FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
 		seg[i].buf  = map[i].dev_bus_addr | 
-			(req->seg[i].first_sect << 9);
+			(preq(seg)[i].first_sect << 9);
 	}
 
 	if (ret)
@@ -484,10 +491,11 @@ static void dispatch_rw_block_io(blkif_t
  fail_flush:
 	fast_flush_area(pending_req);
  fail_response:
-	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
+	make_response(blkif, preq(id), preq(operation), BLKIF_RSP_ERROR);
 	free_req(pending_req);
 } 
 
+#undef req
 
 
 /******************************************************************
@@ -495,10 +503,15 @@ static void dispatch_rw_block_io(blkif_t
  */
 
 
-static void make_response(blkif_t *blkif, unsigned long id, 
+static void make_response(blkif_t *blkif, uint64_t id,
 			  unsigned short op, int st)
 {
-	blkif_response_t *resp;
+	blkif_response_u  resp;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define resp(op) (blkif_native(blkif) ? (resp.nat->op) : (resp.alt->op))
+#else
+#define resp(op) (resp->op)
+#endif
 	unsigned long     flags;
 	blkif_back_ring_t *blk_ring = &blkif->blk_ring;
 	int more_to_do = 0;
@@ -507,12 +520,12 @@ static void make_response(blkif_t *blkif
 	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
 
 	/* Place on the response ring for the relevant domain. */ 
-	resp = RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt);
-	resp->id        = id;
-	resp->operation = op;
-	resp->status    = st;
+	BB_RING_GET_RESPONSE(resp, blk_ring, blk_ring->rsp_prod_pvt);
+	resp(id        = id);
+	resp(operation = op);
+	resp(status    = st);
 	blk_ring->rsp_prod_pvt++;
-	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
+	BB_RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(blk_ring, notify);
 
 	if (blk_ring->rsp_prod_pvt == blk_ring->req_cons) {
 		/*
@@ -520,9 +533,9 @@ static void make_response(blkif_t *blkif
 		 * notifications if requests are already in flight (lower
 		 * overheads and promotes batching).
 		 */
-		RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
+		BB_RING_FINAL_CHECK_FOR_REQUESTS(blk_ring, more_to_do);
 
-	} else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
+	} else if (BB_RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) {
 		more_to_do = 1;
 
 	}
@@ -532,6 +545,7 @@ static void make_response(blkif_t *blkif
 		blkif_notify_work(blkif);
 	if (notify)
 		notify_remote_via_irq(blkif->irq);
+#undef resp
 }
 
 static int __init blkif_init(void)
Index: sle10-sp1-2006-12-05/drivers/xen/blkback/common.h
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/blkback/common.h	2006-12-07 16:43:52.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/blkback/common.h	2006-12-07 16:45:02.000000000 +0100
@@ -40,8 +40,10 @@
 #include <asm/pgalloc.h>
 #include <xen/evtchn.h>
 #include <asm/hypervisor.h>
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define BLKIF_BIMODAL
+#endif
 #include <xen/interface/io/blkif.h>
-#include <xen/interface/io/ring.h>
 #include <xen/gnttab.h>
 #include <xen/driver_util.h>
 #include <xen/xenbus.h>
@@ -63,6 +65,9 @@ struct backend_info;
 typedef struct blkif_st {
 	/* Unique identifier for this interface. */
 	domid_t           domid;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+	unsigned char     native;
+#endif
 	unsigned int      handle;
 	/* Physical parameters of the comms window. */
 	unsigned int      evtchn;
@@ -96,6 +101,15 @@ typedef struct blkif_st {
 	grant_ref_t    shmem_ref;
 } blkif_t;
 
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+#define blkif_native(blkif) ((blkif)->native)
+static inline int ring_native(const blkif_back_ring_t *ring) {
+	return blkif_native(container_of(ring, blkif_t, blk_ring));
+}
+#else
+#define blkif_native(blkif) 1
+#endif
+
 blkif_t *blkif_alloc(domid_t domid);
 void blkif_disconnect(blkif_t *blkif);
 void blkif_free(blkif_t *blkif);
Index: sle10-sp1-2006-12-05/drivers/xen/blkback/interface.c
===================================================================
--- sle10-sp1-2006-12-05.orig/drivers/xen/blkback/interface.c	2006-12-07 16:43:52.000000000 +0100
+++ sle10-sp1-2006-12-05/drivers/xen/blkback/interface.c	2006-12-07 16:45:02.000000000 +0100
@@ -46,6 +46,9 @@ blkif_t *blkif_alloc(domid_t domid)
 
 	memset(blkif, 0, sizeof(*blkif));
 	blkif->domid = domid;
+#ifdef CONFIG_XEN_BIMODAL_BACKENDS
+	blkif->native = 1; /* XXX */
+#endif
 	spin_lock_init(&blkif->blk_ring_lock);
 	atomic_set(&blkif->refcnt, 1);
 	init_waitqueue_head(&blkif->wq);
@@ -95,7 +98,7 @@ static void unmap_frontend_page(blkif_t 
 
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
-	blkif_sring_t *sring;
+	blkif_sring_u sring;
 	int err;
 	struct evtchn_bind_interdomain bind_interdomain;
 
@@ -125,7 +128,7 @@ int blkif_map(blkif_t *blkif, unsigned l
 
 	blkif->evtchn = bind_interdomain.local_port;
 
-	sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
+	BB_SRING(sring) = (void *)blkif->blk_ring_area->addr;
 	BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
 	blkif->irq = bind_evtchn_to_irqhandler(
@@ -150,10 +153,10 @@ void blkif_disconnect(blkif_t *blkif)
 		blkif->irq = 0;
 	}
 
-	if (blkif->blk_ring.sring) {
+	if (blkif->blk_ring.BB_SRING(sring)) {
 		unmap_frontend_page(blkif);
 		free_vm_area(blkif->blk_ring_area);
-		blkif->blk_ring.sring = NULL;
+		blkif->blk_ring.BB_SRING(sring) = NULL;
 	}
 }
 

[-- Attachment #6: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

  reply	other threads:[~2006-12-19  7:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-18 16:39 [patch/rfc] multiprotocol blkback drivers (32-on-64) Gerd Hoffmann
2006-12-18 17:09 ` Jan Beulich
2006-12-18 17:58   ` Keir Fraser
2006-12-19  7:37     ` Jan Beulich [this message]
2006-12-19  8:20   ` Gerd Hoffmann
2006-12-19  7:55 ` Jan Beulich
2006-12-19  8:35   ` Gerd Hoffmann
2006-12-19 13:32   ` Gerd Hoffmann
2006-12-19 14:20     ` Keir Fraser
2006-12-20 15:12       ` Gerd Hoffmann
2006-12-20 15:47         ` Jan Beulich
2006-12-20 16:07           ` Keir Fraser

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4587A4CD.76E4.0078.0@novell.com \
    --to=jbeulich@novell.com \
    --cc=keir@xensource.com \
    --cc=kraxel@suse.de \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.