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 #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; /* 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 /*