From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: Re: Re: [patch/rfc] multiprotocol blkback drivers (32-on-64) Date: Tue, 19 Dec 2006 07:37:33 +0000 Message-ID: <4587A4CD.76E4.0078.0@novell.com> References: <4586D974.76E4.0078.0@novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__Part91B55EAD.0__=" Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Gerd Hoffmann , Keir Fraser Cc: Xen devel list List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__Part91B55EAD.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 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" wrote: > I understand you favor this over the bi-modal approach I took? Any specific > advantages? Jan > >>>> Gerd Hoffmann 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 --=__Part91B55EAD.0__= Content-Type: text/plain; name="xen-bimodal-tpmback.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="xen-bimodal-tpmback.patch" 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 #include #include -#include +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define TPMIF_BIMODAL +#endif #include #include #include @@ -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; =20 /* Physical parameters of the comms window. */ @@ -34,7 +39,7 @@ typedef struct tpmif_st { unsigned int irq; =20 /* The shared rings and indexes. */ - tpmif_tx_interface_t *tx; + tpmif_tx_interface_u tx; struct vm_struct *tx_area; =20 /* Miscellaneous private stuff. */ @@ -54,6 +59,15 @@ typedef struct tpmif_st { char devname[20]; } tpmif_t; =20 +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define tpmif_request(tpmif, rq, n) \ + ((tpmif)->native \ + ? (void)(rq.nat =3D &(tpmif)->tx.nat->ring[n].req) \ + : (void)(rq.alt =3D &(tpmif)->tx.alt->ring[n].req)) +#else +#define tpmif_request(tpmif, rq, n) ((void)(rq =3D &(tpmif)->tx->ring[n].r= eq)) +#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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 =20 memset(tpmif, 0, sizeof (*tpmif)); tpmif->domid =3D domid; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS + tpmif->native =3D 1; /* XXX */ +#endif tpmif->status =3D DISCONNECTED; tpmif->bi =3D bi; snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", = domid); @@ -115,6 +118,12 @@ static void unmap_frontend_page(tpmif_t=20 BUG_ON(ret); } =20 +#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 =20 tpmif->evtchn =3D bind_interdomain.local_port; =20 - tpmif->tx =3D (tpmif_tx_interface_t *)tpmif->tx_area->addr; + tpmif_tx =3D (tpmif_tx_interface_t *)tpmif->tx_area->addr; =20 tpmif->irq =3D 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); =20 - 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); } =20 +#undef tpmif_tx + void __init tpmif_interface_init(void) { tpmif_cachep =3D kmem_cache_create("tpmif_cache", sizeof (tpmif_t),= Index: sle10-sp1-2006-12-05/drivers/xen/tpmback/tpmback.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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); =20 +#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; =20 - tx =3D &tpmif->tx->ring[i].req; + tpmif_request(tpmif, tx, i); =20 - if (0 =3D=3D tx->addr) { + if (0 =3D=3D tx(addr)) { DPRINTK("ERROR: Buffer for outgoing packet NULL?! = i=3D%d\n", i); return 0; } =20 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); =20 if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_r= ef, &map_op, 1))) { @@ -271,12 +277,12 @@ int _packet_write(struct packet *pak, tocopy =3D min_t(size_t, size - offset, PAGE_SIZE); =20 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 =3D tocopy; + tx(size =3D tocopy); =20 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; =20 - tpmif_tx_request_t *tx; - - tx =3D &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 =3D 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; =20 - tx =3D &tpmif->tx->ring[i].req; + tpmif_request(tpmif, tx, i); =20 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); =20 if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_r= ef, &map_op, 1))) { @@ -406,19 +410,19 @@ static int packet_read_shmem(struct pack =20 handle =3D map_op.handle; =20 - if (to_copy > tx->size) { + if (to_copy > tx(size)) { /* * User requests more than what's available */ - to_copy =3D min_t(u32, tx->size, to_copy); + to_copy =3D min_t(u32, tx(size), to_copy); } =20 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= ))); =20 src =3D (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=20 { struct list_head *ent; tpmif_t *tpmif; - tpmif_tx_request_t *tx; + tpmif_tx_request_u tx; =20 DPRINTK("%s: Getting data from front-end(s)!\n", __FUNCTION__); =20 @@ -890,10 +894,10 @@ static void tpm_tx_action(unsigned long=20 tpmif_get(tpmif); remove_from_tpm_schedule_list(tpmif); =20 - tx =3D &tpmif->tx->ring[0].req; + tpmif_request(tpmif, tx, 0); =20 /* pass it up */ - vtpm_receive(tpmif, tx->size); + vtpm_receive(tpmif, tx(size)); =20 tpmif_put(tpmif); } Index: sle10-sp1-2006-12-05/include/xen/interface/io/tpmif.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 @@ */ =20 #ifndef __XEN_PUBLIC_IO_TPMIF_H__ -#define __XEN_PUBLIC_IO_TPMIF_H__ =20 #include "../grant_table.h" =20 -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 =20 /* * 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; =20 +#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 =20 /* This structure must fit in a memory page. */ =20 -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); =20 -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); =20 +#undef tpmif +#undef TPMIF_BIMODAL #endif =20 /* --=__Part91B55EAD.0__= Content-Type: text/plain; name="xen-bimodal-blkif.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="xen-bimodal-blkif.patch" 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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.0000000= 00 +0100 @@ -45,6 +45,14 @@ config XEN_BACKEND Support for backend device drivers that provide I/O services to other virtual machines. =20 +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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 @@ */ =20 #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__ =20 #include "ring.h" @@ -71,27 +95,31 @@ */ #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 =20 -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); =20 -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); =20 /* * STATUS RETURN CODES. @@ -107,12 +135,16 @@ typedef struct blkif_response blkif_resp * Generate blkif ring structures and types. */ =20 +#ifndef BLKIF_BIMODAL DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response); +#endif =20 #define VDISK_CDROM 0x1 #define VDISK_REMOVABLE 0x2 #define VDISK_READONLY 0x4 =20 +#undef blkif +#undef BLKIF_BIMODAL #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */ =20 /* Index: sle10-sp1-2006-12-05/include/xen/interface/io/ring.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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; */ =20 #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 { =20 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 =20 +#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 !=3D = \ + &((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. *=20 @@ -135,6 +194,7 @@ typedef struct __name##_back_ring __name (_s)->req_event =3D (_s)->rsp_event =3D 1; = \ memset((_s)->pad, 0, sizeof((_s)->pad)); \ } while(0) +#define BB_SHARED_RING_INIT(_s) SHARED_RING_INIT(BB_SRING(_s)) =20 #define FRONT_RING_INIT(_r, _s, __size) do { \ (_r)->req_prod_pvt =3D 0; = \ @@ -143,12 +203,24 @@ typedef struct __name##_back_ring __name (_r)->sring =3D (_s); = \ } while (0) =20 +#ifndef BACKEND_RING_BIMODAL #define BACK_RING_INIT(_r, _s, __size) do { \ (_r)->rsp_prod_pvt =3D 0; = \ (_r)->req_cons =3D 0; = \ (_r)->nr_ents =3D __RING_SIZE(_s, __size); = \ (_r)->sring =3D (_s); = \ } while (0) +#else +#define BACK_RING_INIT(_r, _s, __size) do { \ + (_r)->rsp_prod_pvt =3D 0; = \ + (_r)->req_cons =3D 0; = \ + if (ring_native(_r)) \ + (_r)->nr_ents =3D __RING_SIZE((_s).nat, __size); = \ + else \ + (_r)->nr_ents =3D __RING_SIZE((_s).alt, __size); = \ + (_r)->sring =3D (_s); = \ +} while (0) +#endif =20 /* 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 =3D __RING_SIZE(_s, __size); = \ } while (0) =20 +#ifndef BACKEND_RING_BIMODAL #define BACK_RING_ATTACH(_r, _s, __size) do { \ (_r)->sring =3D (_s); = \ (_r)->rsp_prod_pvt =3D (_s)->rsp_prod; = \ (_r)->req_cons =3D (_s)->req_prod; = \ (_r)->nr_ents =3D __RING_SIZE(_s, __size); = \ } while (0) +#else +#define BACK_RING_ATTACH(_r, _s, __size) do { \ + (_r)->sring =3D (_s); = \ + (_r)->rsp_prod_pvt =3D (_s).alt->rsp_prod; = \ + (_r)->req_cons =3D (_s).alt->req_prod; = \ + if (ring_native(_r)) \ + (_r)->nr_ents =3D __RING_SIZE((_s).nat, __size); = \ + else \ + (_r)->nr_ents =3D __RING_SIZE((_s).alt, __size); = \ +} while (0) +#endif =20 /* How big is this ring? */ #define RING_SIZE(_r) \ @@ -180,11 +264,15 @@ typedef struct __name##_back_ring __name (RING_FREE_REQUESTS(_r) =3D=3D 0) =20 /* 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)) =20 #ifdef __GNUC__ -#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \ +#define _RING_HAS_UNCONSUMED_REQUESTS(_r, sring) ({ \ unsigned int req =3D (_r)->sring->req_prod - (_r)->req_cons; = \ unsigned int rsp =3D 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)) =20 /* 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) =3D RING_GET_REQUEST(_r, _idx); = \ +} while (0) +#else +#define BB_RING_GET_REQUEST(_req, _r, _idx) do { \ + if (ring_native(_r)) \ + (_req).nat =3D &(_r)->sring.nat->ring[(_idx) & (RING_SIZE(_r) - = 1)].req; \ + else \ + (_req).alt =3D &(_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 =20 #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) =3D RING_GET_RESPONSE(_r, _idx); = \ +} while (0) +#else +#define BB_RING_GET_RESPONSE(_rsp, _r, _idx) do { \ + if (ring_native(_r)) \ + (_rsp).nat =3D &(_r)->sring.nat->ring[(_idx) & (RING_SIZE(_r) - = 1)].rsp; \ + else \ + (_rsp).alt =3D &(_r)->sring.alt->ring[(_idx) & (RING_SIZE(_r) - = 1)].rsp; \ +} while (0) +#endif =20 /* Loop termination condition: Would the specified index overflow the = ring? */ #define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \ (((_cons) - (_r)->rsp_prod_pvt) >=3D RING_SIZE(_r)) =20 -#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 =3D (_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))= =20 -#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 =3D (_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= )) =20 /* * Notification hold-off (req_event and rsp_event): @@ -250,7 +380,7 @@ typedef struct __name##_back_ring __name * field appropriately. */ =20 -#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \ +#define _RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, sring, _notify) do { \ RING_IDX __old =3D (_r)->sring->req_prod; = \ RING_IDX __new =3D (_r)->req_prod_pvt; = \ wmb(); /* back sees requests /before/ updated producer index */ \ @@ -259,8 +389,12 @@ typedef struct __name##_back_ring __name (_notify) =3D ((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) =20 -#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \ +#define _RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, sring, _notify) do { \ RING_IDX __old =3D (_r)->sring->rsp_prod; = \ RING_IDX __new =3D (_r)->rsp_prod_pvt; = \ wmb(); /* front sees responses /before/ updated producer index */ \ @@ -269,22 +403,34 @@ typedef struct __name##_back_ring __name (_notify) =3D ((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) =20 -#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \ - (_work_to_do) =3D RING_HAS_UNCONSUMED_REQUESTS(_r); = \ +#define _RING_FINAL_CHECK_FOR_REQUESTS(_r, bb, sring, _work_to_do) do { \ + (_work_to_do) =3D bb##RING_HAS_UNCONSUMED_REQUESTS(_r); = \ if (_work_to_do) break; \ (_r)->sring->req_event =3D (_r)->req_cons + 1; = \ mb(); \ - (_work_to_do) =3D RING_HAS_UNCONSUMED_REQUESTS(_r); = \ + (_work_to_do) =3D 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) =20 -#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \ - (_work_to_do) =3D RING_HAS_UNCONSUMED_RESPONSES(_r); = \ +#define _RING_FINAL_CHECK_FOR_RESPONSES(_r, bb, sring, _work_to_do) do {\ + (_work_to_do) =3D bb##RING_HAS_UNCONSUMED_RESPONSES(_r); = \ if (_work_to_do) break; \ (_r)->sring->rsp_event =3D (_r)->rsp_cons + 1; = \ mb(); \ - (_work_to_do) =3D RING_HAS_UNCONSUMED_RESPONSES(_r); = \ + (_work_to_do) =3D 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)= =20 #endif /* __XEN_PUBLIC_IO_RING_H__ */ =20 --=__Part91B55EAD.0__= Content-Type: text/plain; name="xen-bimodal-blktap.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="xen-bimodal-blktap.patch" 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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) =20 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,=20 +static void make_response(blkif_t *blkif, uint64_t id, unsigned short op, int st); =20 /****************************************************************** @@ -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 =3D 1; static int do_block_io_op(blkif_t *blkif) { blkif_back_ring_t *blk_ring =3D &blkif->blk_ring; - blkif_request_t req; + blkif_request_u req; pending_req_t *pending_req; RING_IDX rc, rp; int more_to_do =3D 0; tap_blkif_t *info; =20 rc =3D blk_ring->req_cons; - rp =3D blk_ring->sring->req_prod; + rp =3D blk_ring->BB_SRING(sring)->req_prod; rmb(); /* Ensure we see queued requests up to 'rp'. */ =20 /*Check blkif has corresponding UE ring*/ @@ -1142,10 +1150,10 @@ static int do_block_io_op(blkif_t *blkif break; } =20 - memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req)); + BB_RING_COPY_REQUEST(req, blk_ring, rc); blk_ring->req_cons =3D ++rc; /* before make_response() = */=09 =20 - 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 =20 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 } =20 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 =3D (req->operation =3D=3D BLKIF_OP_WRITE) ? = WRITE : READ; + int op, operation =3D (preq(operation) =3D=3D 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 } =20 /* Check that number of segments is sane. */ - nseg =3D req->nr_segments; + nseg =3D preq(nr_segments); if ( unlikely(nseg =3D=3D 0) ||=20 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 } =20 pending_req->blkif =3D blkif; - pending_req->id =3D req->id; + pending_req->id =3D preq(id); pending_req->operation =3D operation; pending_req->status =3D BLKIF_RSP_OKAY; pending_req->nr_pages =3D nseg; @@ -1238,13 +1246,13 @@ static void dispatch_rw_block_io(blkif_t uvaddr =3D MMAP_VADDR(info->user_vstart, usr_idx, i); kvaddr =3D idx_to_kaddr(mmap_idx, pending_idx, i); =20 - sector =3D req->sector_number + ((PAGE_SIZE / 512) * i); + sector =3D preq(sector_number) + ((PAGE_SIZE / 512) * i); if( (blkif->sectors > 0) && (sector >=3D blkif->sectors) ) = { WPRINTK("BLKTAP: Sector request greater"=20 "than size\n"); WPRINTK("BLKTAP: %s request sector"=20 "[%llu,%llu], Total [%llu]\n", - (req->operation =3D=3D=20 + (preq(operation) =3D=3D 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 =3D=3D WRITE) flags |=3D GNTMAP_readonly; gnttab_set_map_op(&map[op], kvaddr, flags, - req->seg[i].gref, blkif->domid); + preq(seg)[i].gref, blkif->domid); op++; =20 if (!xen_feature(XENFEAT_auto_translated_physmap)) { @@ -1272,7 +1280,7 @@ static void dispatch_rw_block_io(blkif_t if (operation =3D=3D WRITE) flags |=3D 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 =3D 0; i < req->nr_segments; i++) { + for (i =3D 0; i < preq(nr_segments); i++) { unsigned long kvaddr; struct page *pg; =20 @@ -1383,7 +1391,21 @@ static void dispatch_rw_block_io(blkif_t /* Finally, write the request message to the user ring. */ target =3D 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 =3D req->alt.operation; + target->nr_segments =3D req->alt.nr_segments; + target->handle =3D req->alt.handle; + target->sector_number =3D req->alt.sector_number; + BUILD_BUG_ON((typeof(target->seg)*)0 !=3D (typeof(req->alt.= seg)*)0); + memcpy(target->seg, req->alt.seg, + target->nr_segments * sizeof(*target->seg)); + } +#endif target->id =3D 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); }=20 =20 +#undef req =20 =20 /****************************************************************** @@ -1404,10 +1427,15 @@ static void dispatch_rw_block_io(blkif_t */ =20 =20 -static void make_response(blkif_t *blkif, unsigned long id,=20 +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 =3D &blkif->blk_ring; int more_to_do =3D 0; @@ -1415,12 +1443,12 @@ static void make_response(blkif_t *blkif =20 spin_lock_irqsave(&blkif->blk_ring_lock, flags); /* Place on the response ring for the relevant domain. */=20 - resp =3D RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); - resp->id =3D id; - resp->operation =3D op; - resp->status =3D st; + BB_RING_GET_RESPONSE(resp, blk_ring, blk_ring->rsp_prod_pvt); + resp(id =3D id); + resp(operation =3D op); + resp(status =3D 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); =20 if (blk_ring->rsp_prod_pvt =3D=3D 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 =3D 1; =20 }=09 @@ -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 } =20 static int __init blkif_init(void) Index: sle10-sp1-2006-12-05/drivers/xen/blktap/common.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 #include #include +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define BLKIF_BIMODAL +#endif #include -#include #include #include =20 @@ -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; =20 +#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,=20 Index: sle10-sp1-2006-12-05/drivers/xen/blktap/interface.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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) =20 memset(blkif, 0, sizeof(*blkif)); blkif->domid =3D domid; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS + blkif->native =3D 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=20 int tap_blkif_map(blkif_t *blkif, unsigned long shared_page,=20 unsigned int evtchn) { - blkif_sring_t *sring; + blkif_sring_u sring; int err; struct evtchn_bind_interdomain bind_interdomain; =20 @@ -126,7 +129,7 @@ int tap_blkif_map(blkif_t *blkif, unsign =20 blkif->evtchn =3D bind_interdomain.local_port; =20 - sring =3D (blkif_sring_t *)blkif->blk_ring_area->addr; + BB_SRING(sring) =3D (void *)blkif->blk_ring_area->addr; BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); =20 blkif->irq =3D bind_evtchn_to_irqhandler( @@ -141,10 +144,10 @@ void tap_blkif_unmap(blkif_t *blkif) unbind_from_irqhandler(blkif->irq, blkif); blkif->irq =3D 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 =3D NULL; + blkif->blk_ring.BB_SRING(sring) =3D NULL; } } =20 --=__Part91B55EAD.0__= Content-Type: text/plain; name="xen-bimodal-blkback.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="xen-bimodal-blkback.patch" 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 =20 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,=20 +static void make_response(blkif_t *blkif, uint64_t id, unsigned short op, int st); =20 /****************************************************************** @@ -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 =20 static int do_block_io_op(blkif_t *blkif) { blkif_back_ring_t *blk_ring =3D &blkif->blk_ring; - blkif_request_t req; + blkif_request_u req; pending_req_t *pending_req; RING_IDX rc, rp; int more_to_do =3D 0; =20 rc =3D blk_ring->req_cons; - rp =3D blk_ring->sring->req_prod; + rp =3D blk_ring->BB_SRING(sring)->req_prod; rmb(); /* Ensure we see queued requests up to 'rp'. */ =20 while ((rc !=3D rp) && !RING_REQUEST_CONS_OVERFLOW(blk_ring, rc)) = { @@ -317,10 +324,10 @@ static int do_block_io_op(blkif_t *blkif break; } =20 - memcpy(&req, RING_GET_REQUEST(blk_ring, rc), sizeof(req)); + BB_RING_COPY_REQUEST(req, blk_ring, rc); blk_ring->req_cons =3D ++rc; /* before make_response() */ =20 - 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 } =20 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 =3D 0; int operation; =20 - switch (req->operation) { + switch (preq(operation)) { case BLKIF_OP_READ: operation =3D READ; break; @@ -375,31 +382,31 @@ static void dispatch_rw_block_io(blkif_t } =20 /* Check that number of segments is sane. */ - nseg =3D req->nr_segments; + nseg =3D preq(nr_segments); if (unlikely(nseg =3D=3D 0) ||=20 unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) { DPRINTK("Bad number of segments in request (%d)\n", nseg); goto fail_response; } =20 - preq.dev =3D req->handle; - preq.sector_number =3D req->sector_number; + preq.dev =3D preq(handle); + preq.sector_number =3D preq(sector_number); preq.nr_sects =3D 0; =20 pending_req->blkif =3D blkif; - pending_req->id =3D req->id; - pending_req->operation =3D req->operation; + pending_req->id =3D preq(id); + pending_req->operation =3D preq(operation); pending_req->status =3D BLKIF_RSP_OKAY; pending_req->nr_pages =3D nseg; =20 for (i =3D 0; i < nseg; i++) { uint32_t flags; =20 - seg[i].nsec =3D req->seg[i].last_sect - - req->seg[i].first_sect + 1; + seg[i].nsec =3D preq(seg)[i].last_sect - + preq(seg)[i].first_sect + 1; =20 - if ((req->seg[i].last_sect >=3D (PAGE_SIZE >> 9)) || - (req->seg[i].last_sect < req->seg[i].first_sect)) + if ((preq(seg)[i].last_sect >=3D (PAGE_SIZE >> 9)) || + (preq(seg)[i].last_sect < preq(seg)[i].first_sect)) goto fail_response; preq.nr_sects +=3D seg[i].nsec; =20 @@ -407,7 +414,7 @@ static void dispatch_rw_block_io(blkif_t if (operation !=3D READ) flags |=3D 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); } =20 ret =3D 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 =3D map[i].dev_bus_addr |=20 - (req->seg[i].first_sect << 9); + (preq(seg)[i].first_sect << 9); } =20 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); }=20 =20 +#undef req =20 =20 /****************************************************************** @@ -495,10 +503,15 @@ static void dispatch_rw_block_io(blkif_t */ =20 =20 -static void make_response(blkif_t *blkif, unsigned long id,=20 +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 =3D &blkif->blk_ring; int more_to_do =3D 0; @@ -507,12 +520,12 @@ static void make_response(blkif_t *blkif spin_lock_irqsave(&blkif->blk_ring_lock, flags); =20 /* Place on the response ring for the relevant domain. */=20 - resp =3D RING_GET_RESPONSE(blk_ring, blk_ring->rsp_prod_pvt); - resp->id =3D id; - resp->operation =3D op; - resp->status =3D st; + BB_RING_GET_RESPONSE(resp, blk_ring, blk_ring->rsp_prod_pvt); + resp(id =3D id); + resp(operation =3D op); + resp(status =3D 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); =20 if (blk_ring->rsp_prod_pvt =3D=3D 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); =20 - } else if (RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { + } else if (BB_RING_HAS_UNCONSUMED_REQUESTS(blk_ring)) { more_to_do =3D 1; =20 } @@ -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 } =20 static int __init blkif_init(void) Index: sle10-sp1-2006-12-05/drivers/xen/blkback/common.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 #include #include +#ifdef CONFIG_XEN_BIMODAL_BACKENDS +#define BLKIF_BIMODAL +#endif #include -#include #include #include #include @@ -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; =20 +#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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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) =20 memset(blkif, 0, sizeof(*blkif)); blkif->domid =3D domid; +#ifdef CONFIG_XEN_BIMODAL_BACKENDS + blkif->native =3D 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=20 =20 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; =20 @@ -125,7 +128,7 @@ int blkif_map(blkif_t *blkif, unsigned l =20 blkif->evtchn =3D bind_interdomain.local_port; =20 - sring =3D (blkif_sring_t *)blkif->blk_ring_area->addr; + BB_SRING(sring) =3D (void *)blkif->blk_ring_area->addr; BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE); =20 blkif->irq =3D bind_evtchn_to_irqhandler( @@ -150,10 +153,10 @@ void blkif_disconnect(blkif_t *blkif) blkif->irq =3D 0; } =20 - 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 =3D NULL; + blkif->blk_ring.BB_SRING(sring) =3D NULL; } } =20 --=__Part91B55EAD.0__= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --=__Part91B55EAD.0__=--