From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthew Fioravante Subject: Re: [PATCH 01/12] mini-os/tpm{back, front}: Change shared page ABI Date: Tue, 26 Mar 2013 12:29:45 -0400 Message-ID: <5151CCF9.1070307@jhuapl.edu> References: <1363896689-11086-1-git-send-email-dgdegra@tycho.nsa.gov> <1363896689-11086-2-git-send-email-dgdegra@tycho.nsa.gov> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7561949833948339532==" Return-path: In-Reply-To: <1363896689-11086-2-git-send-email-dgdegra@tycho.nsa.gov> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Daniel De Graaf Cc: Konrad Rzeszutek Wilk , "Ian.Campbell@citrix.com" , "xen-devel@lists.xen.org" List-Id: xen-devel@lists.xenproject.org This is a cryptographically signed message in MIME format. --===============7561949833948339532== Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms050806080005080905070101" This is a cryptographically signed message in MIME format. --------------ms050806080005080905070101 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable I'm going to merge your linux changes into my working linux patch with=20 the fixes that are in response to konrad's comments. Will test with this = on the mini-os end and get back to you. After that, we can look at the remaining patches. On 03/21/2013 04:11 PM, Daniel De Graaf wrote: > This changes the vTPM shared page ABI from a copy of the Xen network > interface to a single-page interface that better reflects the expected > behavior of a TPM: only a single request packet can be sent at any give= n > time, and every packet sent generates a single response packet. This > protocol change should also increase efficiency as it avoids mapping an= d > unmapping grants when possible. The vtpm xenbus device now requires a > feature-protocol-v2 node in xenstore to avoid conflicts with existing > (xen-patched) kernels supporting the old interface. > > While the contents of the shared page have been defined to allow packet= s > larger than a single page (actually 4088 bytes) by allowing the client > to add extra grant references, the mapping of these extra references ha= s > not been implemented; a feature node in xenstore may be used in the > future to indicate full support for the multi-page protocol. Most uses > of the TPM should not require this feature. > > Signed-off-by: Daniel De Graaf > > --- > > Changes from v4: use feature-protocol-v2 nodes instead of changing the > device name; add command cancellation support to the protocol. > --- > extras/mini-os/include/tpmback.h | 1 + > extras/mini-os/include/tpmfront.h | 7 +- > extras/mini-os/tpmback.c | 161 +++++++++++++++++++----------= --------- > extras/mini-os/tpmfront.c | 143 +++++++++++++++++------------= ---- > xen/include/public/io/tpmif.h | 49 ++++-------- > 5 files changed, 177 insertions(+), 184 deletions(-) > > diff --git a/extras/mini-os/include/tpmback.h b/extras/mini-os/include/= tpmback.h > index ff86732..ec9eda4 100644 > --- a/extras/mini-os/include/tpmback.h > +++ b/extras/mini-os/include/tpmback.h > @@ -43,6 +43,7 @@ > > struct tpmcmd { > domid_t domid; /* Domid of the frontend */ > + uint8_t locality; /* Locality requested by the frontend */ > unsigned int handle; /* Handle of the frontend */ > unsigned char uuid[16]; /* uuid of the tpm int= erface */ > > diff --git a/extras/mini-os/include/tpmfront.h b/extras/mini-os/include= /tpmfront.h > index fd2cb17..a0c7c4d 100644 > --- a/extras/mini-os/include/tpmfront.h > +++ b/extras/mini-os/include/tpmfront.h > @@ -37,9 +37,7 @@ struct tpmfront_dev { > grant_ref_t ring_ref; > evtchn_port_t evtchn; > > - tpmif_tx_interface_t* tx; > - > - void** pages; > + vtpm_shared_page_t *page; > > domid_t bedomid; > char* nodename; > @@ -77,6 +75,9 @@ void shutdown_tpmfront(struct tpmfront_dev* dev); > * */ > int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t* req, size_t reqle= n, uint8_t** resp, size_t* resplen); > > +/* Set the locality used for communicating with a vTPM */ > +int tpmfront_set_locality(struct tpmfront_dev* dev, int locality); > + > #ifdef HAVE_LIBC > #include > /* POSIX IO functions: > diff --git a/extras/mini-os/tpmback.c b/extras/mini-os/tpmback.c > index 658fed1..1398b37 100644 > --- a/extras/mini-os/tpmback.c > +++ b/extras/mini-os/tpmback.c > @@ -86,10 +86,7 @@ struct tpmif { > evtchn_port_t evtchn; > > /* Shared page */ > - tpmif_tx_interface_t* tx; > - > - /* pointer to TPMIF_RX_RING_SIZE pages */ > - void** pages; > + vtpm_shared_page_t *page; > > enum xenbus_state state; > enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; > @@ -266,6 +263,7 @@ int insert_tpmif(tpmif_t* tpmif) > unsigned int i, j; > tpmif_t* tmp; > char* err; > + char path[512]; > > local_irq_save(flags); > > @@ -303,6 +301,16 @@ int insert_tpmif(tpmif_t* tpmif) > > local_irq_restore(flags); > > + snprintf(path, 512, "backend/vtpm/%u/%u/feature-protocol-v2", (unsi= gned int) tpmif->domid, tpmif->handle); > + if ((err =3D xenbus_write(XBT_NIL, path, "1"))) > + { > + /* if we got an error here we should carefully remove the interf= ace and then return */ > + TPMBACK_ERR("Unable to write feature-protocol-v2 node: %s\n", er= r); > + free(err); > + remove_tpmif(tpmif); > + goto error_post_irq; > + } > + > /*Listen for state changes on the new interface */ > if((err =3D xenbus_watch_path_token(XBT_NIL, tpmif->fe_state_path,= tpmif->fe_state_path, >pmdev.events))) > { > @@ -312,7 +320,6 @@ int insert_tpmif(tpmif_t* tpmif) > remove_tpmif(tpmif); > goto error_post_irq; > } > - > return 0; > error: > local_irq_restore(flags); > @@ -386,8 +393,7 @@ inline tpmif_t* __init_tpmif(domid_t domid, unsigne= d int handle) > tpmif->fe_state_path =3D NULL; > tpmif->state =3D XenbusStateInitialising; > tpmif->status =3D DISCONNECTED; > - tpmif->tx =3D NULL; > - tpmif->pages =3D NULL; > + tpmif->page =3D NULL; > tpmif->flags =3D 0; > memset(tpmif->uuid, 0, sizeof(tpmif->uuid)); > return tpmif; > @@ -395,9 +401,6 @@ inline tpmif_t* __init_tpmif(domid_t domid, unsigne= d int handle) > > void __free_tpmif(tpmif_t* tpmif) > { > - if(tpmif->pages) { > - free(tpmif->pages); > - } > if(tpmif->fe_path) { > free(tpmif->fe_path); > } > @@ -430,12 +433,6 @@ tpmif_t* new_tpmif(domid_t domid, unsigned int han= dle) > goto error; > } > > - /* allocate pages to be used for shared mapping */ > - if((tpmif->pages =3D malloc(sizeof(void*) * TPMIF_TX_RING_SIZE)) =3D= =3D NULL) { > - goto error; > - } > - memset(tpmif->pages, 0, sizeof(void*) * TPMIF_TX_RING_SIZE); > - > if(tpmif_change_state(tpmif, XenbusStateInitWait)) { > goto error; > } > @@ -486,7 +483,7 @@ void free_tpmif(tpmif_t* tpmif) > tpmif->status =3D DISCONNECTING; > mask_evtchn(tpmif->evtchn); > > - if(gntmap_munmap(>pmdev.map, (unsigned long)tpmif->tx, 1)) { > + if(gntmap_munmap(>pmdev.map, (unsigned long)tpmif->page, 1)) {= > TPMBACK_ERR("%u/%u Error occured while trying to unmap shared= page\n", (unsigned int) tpmif->domid, tpmif->handle); > } > > @@ -529,15 +526,27 @@ void free_tpmif(tpmif_t* tpmif) > void tpmback_handler(evtchn_port_t port, struct pt_regs *regs, void *= data) > { > tpmif_t* tpmif =3D (tpmif_t*) data; > - tpmif_tx_request_t* tx =3D &tpmif->tx->ring[0].req; > - /* Throw away 0 size events, these can trigger from event channel u= nmasking */ > - if(tx->size =3D=3D 0) > - return; > - > - TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif->d= omid, tpmif->handle); > - tpmif_req_ready(tpmif); > - wake_up(&waitq); > + vtpm_shared_page_t* pg =3D tpmif->page; > > + switch (pg->state) > + { > + case VTPM_STATE_SUBMIT: > + TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif= ->domid, tpmif->handle); > + tpmif_req_ready(tpmif); > + wake_up(&waitq); > + break; > + case VTPM_STATE_CANCEL: > + /* If we are busy with a request, do nothing */ > + if (tpmif->flags & TPMIF_REQ_READY) > + return; > + /* Acknowledge the cancellation if we are idle */ > + pg->state =3D VTPM_STATE_IDLE; > + notify_remote_via_evtchn(tpmif->evtchn); > + return; > + default: > + /* Spurious wakeup; do nothing */ > + return; > + } > } > > /* Connect to frontend */ > @@ -584,12 +593,25 @@ int connect_fe(tpmif_t* tpmif) > } > free(value); > > + /* Check that protocol v2 is being used */ > + snprintf(path, 512, "%s/feature-protocol-v2", tpmif->fe_path); > + if((err =3D xenbus_read(XBT_NIL, path, &value))) { > + TPMBACK_ERR("Unable to read %s during tpmback initialization! er= ror =3D %s\n", path, err); > + free(err); > + return -1; > + } > + if(strcmp(value, "1")) { > + TPMBACK_ERR("%s has an invalid value (%s)\n", path, value); > + free(value); > + return -1; > + } > + free(value); > + > domid =3D tpmif->domid; > - if((tpmif->tx =3D gntmap_map_grant_refs(>pmdev.map, 1, &domid, 0,= &ringref, PROT_READ | PROT_WRITE)) =3D=3D NULL) { > + if((tpmif->page =3D gntmap_map_grant_refs(>pmdev.map, 1, &domid, = 0, &ringref, PROT_READ | PROT_WRITE)) =3D=3D NULL) { > TPMBACK_ERR("Failed to map grant reference %u/%u\n", (unsigned = int) tpmif->domid, tpmif->handle); > return -1; > } > - memset(tpmif->tx, 0, PAGE_SIZE); > > /*Bind the event channel */ > if((evtchn_bind_interdomain(tpmif->domid, evtchn, tpmback_handler,= tpmif, &tpmif->evtchn))) > @@ -618,7 +640,7 @@ error_post_evtchn: > mask_evtchn(tpmif->evtchn); > unbind_evtchn(tpmif->evtchn); > error_post_map: > - gntmap_munmap(>pmdev.map, (unsigned long)tpmif->tx, 1); > + gntmap_munmap(>pmdev.map, (unsigned long)tpmif->page, 1); > return -1; > } > > @@ -874,6 +896,7 @@ void shutdown_tpmback(void) > inline void init_tpmcmd(tpmcmd_t* tpmcmd, domid_t domid, unsigned int= handle, unsigned char uuid[16]) > { > tpmcmd->domid =3D domid; > + tpmcmd->locality =3D -1; > tpmcmd->handle =3D handle; > memcpy(tpmcmd->uuid, uuid, sizeof(tpmcmd->uuid)); > tpmcmd->req =3D NULL; > @@ -884,12 +907,12 @@ inline void init_tpmcmd(tpmcmd_t* tpmcmd, domid_t= domid, unsigned int handle, un > > tpmcmd_t* get_request(tpmif_t* tpmif) { > tpmcmd_t* cmd; > - tpmif_tx_request_t* tx; > - int offset; > - int tocopy; > - int i; > - uint32_t domid; > + vtpm_shared_page_t* shr; > + unsigned int offset; > int flags; > +#ifdef TPMBACK_PRINT_DEBUG > + int i; > +#endif > > local_irq_save(flags); > > @@ -899,35 +922,22 @@ tpmcmd_t* get_request(tpmif_t* tpmif) { > } > init_tpmcmd(cmd, tpmif->domid, tpmif->handle, tpmif->uuid); > > - tx =3D &tpmif->tx->ring[0].req; > - cmd->req_len =3D tx->size; > + shr =3D tpmif->page; > + cmd->req_len =3D shr->length; > + cmd->locality =3D shr->locality; > + offset =3D sizeof(*shr) + 4*shr->nr_extra_pages; > + if (offset > PAGE_SIZE || offset + cmd->req_len > PAGE_SIZE) { > + TPMBACK_ERR("%u/%u Command size too long for shared page!\n", (u= nsigned int) tpmif->domid, tpmif->handle); > + goto error; > + } > /* Allocate the buffer */ > if(cmd->req_len) { > if((cmd->req =3D malloc(cmd->req_len)) =3D=3D NULL) { > goto error; > } > } > - /* Copy the bits from the shared pages */ > - offset =3D 0; > - for(i =3D 0; i < TPMIF_TX_RING_SIZE && offset < cmd->req_len; ++i) = { > - tx =3D &tpmif->tx->ring[i].req; > - > - /* Map the page with the data */ > - domid =3D (uint32_t)tpmif->domid; > - if((tpmif->pages[i] =3D gntmap_map_grant_refs(>pmdev.map, 1, &= domid, 0, &tx->ref, PROT_READ)) =3D=3D NULL) { > - TPMBACK_ERR("%u/%u Unable to map shared page during read!\n", = (unsigned int) tpmif->domid, tpmif->handle); > - goto error; > - } > - > - /* do the copy now */ > - tocopy =3D min(cmd->req_len - offset, PAGE_SIZE); > - memcpy(&cmd->req[offset], tpmif->pages[i], tocopy); > - offset +=3D tocopy; > - > - /* release the page */ > - gntmap_munmap(>pmdev.map, (unsigned long)tpmif->pages[i], 1); > - > - } > + /* Copy the bits from the shared page(s) */ > + memcpy(cmd->req, offset + (uint8_t*)shr, cmd->req_len); > > #ifdef TPMBACK_PRINT_DEBUG > TPMBACK_DEBUG("Received Tpm Command from %u/%u of size %u", (unsig= ned int) tpmif->domid, tpmif->handle, cmd->req_len); > @@ -958,38 +968,24 @@ error: > > void send_response(tpmcmd_t* cmd, tpmif_t* tpmif) > { > - tpmif_tx_request_t* tx; > - int offset; > - int i; > - uint32_t domid; > - int tocopy; > + vtpm_shared_page_t* shr; > + unsigned int offset; > int flags; > +#ifdef TPMBACK_PRINT_DEBUG > +int i; > +#endif > > local_irq_save(flags); > > - tx =3D &tpmif->tx->ring[0].req; > - tx->size =3D cmd->resp_len; > - > - offset =3D 0; > - for(i =3D 0; i < TPMIF_TX_RING_SIZE && offset < cmd->resp_len; ++i)= { > - tx =3D &tpmif->tx->ring[i].req; > - > - /* Map the page with the data */ > - domid =3D (uint32_t)tpmif->domid; > - if((tpmif->pages[i] =3D gntmap_map_grant_refs(>pmdev.map, 1, &= domid, 0, &tx->ref, PROT_WRITE)) =3D=3D NULL) { > - TPMBACK_ERR("%u/%u Unable to map shared page during write!\n",= (unsigned int) tpmif->domid, tpmif->handle); > - goto error; > - } > - > - /* do the copy now */ > - tocopy =3D min(cmd->resp_len - offset, PAGE_SIZE); > - memcpy(tpmif->pages[i], &cmd->resp[offset], tocopy); > - offset +=3D tocopy; > - > - /* release the page */ > - gntmap_munmap(>pmdev.map, (unsigned long)tpmif->pages[i], 1); > + shr =3D tpmif->page; > + shr->length =3D cmd->resp_len; > > + offset =3D sizeof(*shr) + 4*shr->nr_extra_pages; > + if (offset > PAGE_SIZE || offset + cmd->resp_len > PAGE_SIZE) { > + TPMBACK_ERR("%u/%u Command size too long for shared page!\n", (u= nsigned int) tpmif->domid, tpmif->handle); > + goto error; > } > + memcpy(offset + (uint8_t*)shr, cmd->resp, cmd->resp_len); > > #ifdef TPMBACK_PRINT_DEBUG > TPMBACK_DEBUG("Sent response to %u/%u of size %u", (unsigned int) = tpmif->domid, tpmif->handle, cmd->resp_len); > @@ -1003,6 +999,7 @@ void send_response(tpmcmd_t* cmd, tpmif_t* tpmif) > #endif > /* clear the ready flag and send the event channel notice to the f= rontend */ > tpmif_req_finished(tpmif); > + shr->state =3D VTPM_STATE_FINISH; > notify_remote_via_evtchn(tpmif->evtchn); > error: > local_irq_restore(flags); > diff --git a/extras/mini-os/tpmfront.c b/extras/mini-os/tpmfront.c > index 0218d7f..a15b5cf 100644 > --- a/extras/mini-os/tpmfront.c > +++ b/extras/mini-os/tpmfront.c > @@ -47,11 +47,21 @@ > > void tpmfront_handler(evtchn_port_t port, struct pt_regs *regs, void = *data) { > struct tpmfront_dev* dev =3D (struct tpmfront_dev*) data; > + vtpm_shared_page_t* shr =3D dev->page; > /*If we get a response when we didnt make a request, just ignore i= t */ > if(!dev->waiting) { > return; > } > > + switch (shr->state) { > + case VTPM_STATE_FINISH: /* request was completed */ > + case VTPM_STATE_IDLE: /* request was cancelled */ > + break; > + default: > + /* Spurious wakeup; do nothing, request is still pending */ > + return; > + } > + > dev->waiting =3D 0; > #ifdef HAVE_LIBC > if(dev->fd >=3D 0) { > @@ -176,7 +186,7 @@ static int wait_for_backend_state_changed(struct tp= mfront_dev* dev, XenbusState > ret =3D wait_for_backend_closed(&events, path); > break; > default: > - break; > + TPMFRONT_ERR("Bad wait state %d, ignoring\n", state); > } > > if((err =3D xenbus_unwatch_path_token(XBT_NIL, path, path))) { > @@ -190,13 +200,13 @@ static int tpmfront_connect(struct tpmfront_dev* = dev) > { > char* err; > /* Create shared page */ > - dev->tx =3D (tpmif_tx_interface_t*) alloc_page(); > - if(dev->tx =3D=3D NULL) { > + dev->page =3D (vtpm_shared_page_t*) alloc_page(); > + if(dev->page =3D=3D NULL) { > TPMFRONT_ERR("Unable to allocate page for shared memory\n"); > goto error; > } > - memset(dev->tx, 0, PAGE_SIZE); > - dev->ring_ref =3D gnttab_grant_access(dev->bedomid, virt_to_mfn(dev= ->tx), 0); > + memset(dev->page, 0, PAGE_SIZE); > + dev->ring_ref =3D gnttab_grant_access(dev->bedomid, virt_to_mfn(dev= ->page), 0); > TPMFRONT_DEBUG("grant ref is %lu\n", (unsigned long) dev->ring_ref= ); > > /*Create event channel */ > @@ -228,7 +238,7 @@ error_postevtchn: > unbind_evtchn(dev->evtchn); > error_postmap: > gnttab_end_access(dev->ring_ref); > - free_page(dev->tx); > + free_page(dev->page); > error: > return -1; > } > @@ -240,7 +250,6 @@ struct tpmfront_dev* init_tpmfront(const char* _nod= ename) > char path[512]; > char* value, *err; > unsigned long long ival; > - int i; > > printk("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Init TPM Front =3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"); > > @@ -279,6 +288,15 @@ struct tpmfront_dev* init_tpmfront(const char* _no= dename) > goto error; > } > > + /* Publish protocol v2 feature */ > + snprintf(path, 512, "%s/feature-protocol-v2", dev->nodename); > + if ((err =3D xenbus_write(XBT_NIL, path, "1"))) > + { > + TPMFRONT_ERR("Unable to write feature-protocol-v2 node: %s\n", e= rr); > + free(err); > + goto error; > + } > + > /* Create and publish grant reference and event channel */ > if (tpmfront_connect(dev)) { > goto error; > @@ -289,18 +307,19 @@ struct tpmfront_dev* init_tpmfront(const char* _n= odename) > goto error; > } > > - /* Allocate pages that will contain the messages */ > - dev->pages =3D malloc(sizeof(void*) * TPMIF_TX_RING_SIZE); > - if(dev->pages =3D=3D NULL) { > + /* Ensure backend is also using protocol v2 */ > + snprintf(path, 512, "%s/feature-protocol-v2", dev->bepath); > + if((err =3D xenbus_read(XBT_NIL, path, &value))) { > + TPMFRONT_ERR("Unable to read %s during tpmfront initialization! = error =3D %s\n", path, err); > + free(err); > goto error; > } > - memset(dev->pages, 0, sizeof(void*) * TPMIF_TX_RING_SIZE); > - for(i =3D 0; i < TPMIF_TX_RING_SIZE; ++i) { > - dev->pages[i] =3D (void*)alloc_page(); > - if(dev->pages[i] =3D=3D NULL) { > - goto error; > - } > + if(strcmp(value, "1")) { > + TPMFRONT_ERR("%s has an invalid value (%s)\n", path, value); > + free(value); > + goto error; > } > + free(value); > > TPMFRONT_LOG("Initialization Completed successfully\n"); > > @@ -314,8 +333,6 @@ void shutdown_tpmfront(struct tpmfront_dev* dev) > { > char* err; > char path[512]; > - int i; > - tpmif_tx_request_t* tx; > if(dev =3D=3D NULL) { > return; > } > @@ -349,27 +366,12 @@ void shutdown_tpmfront(struct tpmfront_dev* dev) > /* Wait for the backend to close and unmap shared pages, ignore= any errors */ > wait_for_backend_state_changed(dev, XenbusStateClosed); > > - /* Cleanup any shared pages */ > - if(dev->pages) { > - for(i =3D 0; i < TPMIF_TX_RING_SIZE; ++i) { > - if(dev->pages[i]) { > - tx =3D &dev->tx->ring[i].req; > - if(tx->ref !=3D 0) { > - gnttab_end_access(tx->ref); > - } > - free_page(dev->pages[i]); > - } > - } > - free(dev->pages); > - } > - > /* Close event channel and unmap shared page */ > mask_evtchn(dev->evtchn); > unbind_evtchn(dev->evtchn); > gnttab_end_access(dev->ring_ref); > > - free_page(dev->tx); > - > + free_page(dev->page); > } > > /* Cleanup memory usage */ > @@ -387,13 +389,17 @@ void shutdown_tpmfront(struct tpmfront_dev* dev) > > int tpmfront_send(struct tpmfront_dev* dev, const uint8_t* msg, size_= t length) > { > + unsigned int offset; > + vtpm_shared_page_t* shr =3D NULL; > +#ifdef TPMFRONT_PRINT_DEBUG > int i; > - tpmif_tx_request_t* tx =3D NULL; > +#endif > /* Error Checking */ > if(dev =3D=3D NULL || dev->state !=3D XenbusStateConnected) { > TPMFRONT_ERR("Tried to send message through disconnected fronte= nd\n"); > return -1; > } > + shr =3D dev->page; > > #ifdef TPMFRONT_PRINT_DEBUG > TPMFRONT_DEBUG("Sending Msg to backend size=3D%u", (unsigned int) = length); > @@ -407,19 +413,16 @@ int tpmfront_send(struct tpmfront_dev* dev, const= uint8_t* msg, size_t length) > #endif > > /* Copy to shared pages now */ > - for(i =3D 0; length > 0 && i < TPMIF_TX_RING_SIZE; ++i) { > - /* Share the page */ > - tx =3D &dev->tx->ring[i].req; > - tx->unused =3D 0; > - tx->addr =3D virt_to_mach(dev->pages[i]); > - tx->ref =3D gnttab_grant_access(dev->bedomid, virt_to_mfn(dev->p= ages[i]), 0); > - /* Copy the bits to the page */ > - tx->size =3D length > PAGE_SIZE ? PAGE_SIZE : length; > - memcpy(dev->pages[i], &msg[i * PAGE_SIZE], tx->size); > - > - /* Update counters */ > - length -=3D tx->size; > + offset =3D sizeof(*shr); > + if (length + offset > PAGE_SIZE) { > + TPMFRONT_ERR("Message too long for shared page\n"); > + return -1; > } > + memcpy(offset + (uint8_t*)shr, msg, length); > + shr->length =3D length; > + barrier(); > + shr->state =3D VTPM_STATE_SUBMIT; > + > dev->waiting =3D 1; > dev->resplen =3D 0; > #ifdef HAVE_LIBC > @@ -434,44 +437,44 @@ int tpmfront_send(struct tpmfront_dev* dev, const= uint8_t* msg, size_t length) > } > int tpmfront_recv(struct tpmfront_dev* dev, uint8_t** msg, size_t *le= ngth) > { > - tpmif_tx_request_t* tx; > - int i; > + unsigned int offset; > + vtpm_shared_page_t* shr =3D NULL; > +#ifdef TPMFRONT_PRINT_DEBUG > +int i; > +#endif > if(dev =3D=3D NULL || dev->state !=3D XenbusStateConnected) { > TPMFRONT_ERR("Tried to receive message from disconnected fronte= nd\n"); > return -1; > } > /*Wait for the response */ > wait_event(dev->waitq, (!dev->waiting)); > + shr =3D dev->page; > > /* Initialize */ > *msg =3D NULL; > *length =3D 0; > + offset =3D sizeof(*shr); > > - /* special case, just quit */ > - tx =3D &dev->tx->ring[0].req; > - if(tx->size =3D=3D 0 ) { > - goto quit; > - } > - /* Get the total size */ > - tx =3D &dev->tx->ring[0].req; > - for(i =3D 0; i < TPMIF_TX_RING_SIZE && tx->size > 0; ++i) { > - tx =3D &dev->tx->ring[i].req; > - *length +=3D tx->size; > + if (shr->state !=3D VTPM_STATE_FINISH) > + goto quit; > + > + *length =3D shr->length; > + > + if (*length + offset > PAGE_SIZE) { > + TPMFRONT_ERR("Reply too long for shared page\n"); > + return -1; > } > + > /* Alloc the buffer */ > if(dev->respbuf) { > free(dev->respbuf); > } > *msg =3D dev->respbuf =3D malloc(*length); > dev->resplen =3D *length; > + > /* Copy the bits */ > - tx =3D &dev->tx->ring[0].req; > - for(i =3D 0; i < TPMIF_TX_RING_SIZE && tx->size > 0; ++i) { > - tx =3D &dev->tx->ring[i].req; > - memcpy(&(*msg)[i * PAGE_SIZE], dev->pages[i], tx->size); > - gnttab_end_access(tx->ref); > - tx->ref =3D 0; > - } > + memcpy(*msg, offset + (uint8_t*)shr, *length); > + > #ifdef TPMFRONT_PRINT_DEBUG > TPMFRONT_DEBUG("Received response from backend size=3D%u", (unsign= ed int) *length); > for(i =3D 0; i < *length; ++i) { > @@ -504,6 +507,14 @@ int tpmfront_cmd(struct tpmfront_dev* dev, uint8_t= * req, size_t reqlen, uint8_t* > return 0; > } > > +int tpmfront_set_locality(struct tpmfront_dev* dev, int locality) > +{ > + if (!dev || !dev->page) > + return -1; > + dev->page->locality =3D locality; > + return 0; > +} > + > #ifdef HAVE_LIBC > #include > int tpmfront_open(struct tpmfront_dev* dev) > diff --git a/xen/include/public/io/tpmif.h b/xen/include/public/io/tpmi= f.h > index fca2c4e..ab0c652 100644 > --- a/xen/include/public/io/tpmif.h > +++ b/xen/include/public/io/tpmif.h > @@ -1,7 +1,7 @@ > /********************************************************************= ********** > * tpmif.h > * > - * TPM I/O interface for Xen guest OSes. > + * TPM I/O interface for Xen guest OSes, v2 > * > * Permission is hereby granted, free of charge, to any person obtain= ing a copy > * of this software and associated documentation files (the "Software= "), to > @@ -21,48 +21,31 @@ > * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHE= R > * DEALINGS IN THE SOFTWARE. > * > - * Copyright (c) 2005, IBM Corporation > - * > - * Author: Stefan Berger, stefanb@us.ibm.com > - * Grant table support: Mahadevan Gomathisankaran > - * > - * This code has been derived from tools/libxc/xen/io/netif.h > - * > - * Copyright (c) 2003-2004, Keir Fraser > */ > > #ifndef __XEN_PUBLIC_IO_TPMIF_H__ > #define __XEN_PUBLIC_IO_TPMIF_H__ > > -#include "../grant_table.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. */ > +enum vtpm_state { > + VTPM_STATE_IDLE, /* no contents / vTPM idle / cancel compl= ete */ > + VTPM_STATE_SUBMIT, /* request ready / vTPM working */ > + VTPM_STATE_FINISH, /* response ready / vTPM idle */ > + VTPM_STATE_CANCEL, /* cancel requested / vTPM working */ > }; > -typedef struct tpmif_tx_request tpmif_tx_request_t; > +/* The backend should only change state to IDLE or FINISH, while the > + * frontend should only change to SUBMIT or CANCEL. */ > > -/* > - * The TPMIF_TX_RING_SIZE defines the number of pages the > - * front-end and backend can exchange (=3D size of array). > - */ > -typedef uint32_t TPMIF_RING_IDX; > - > -#define TPMIF_TX_RING_SIZE 1 > +struct vtpm_shared_page { > + uint32_t length; /* request/response length in bytes */ > > -/* This structure must fit in a memory page. */ > - > -struct tpmif_ring { > - struct tpmif_tx_request req; > -}; > -typedef struct tpmif_ring tpmif_ring_t; > + uint8_t state; /* enum vtpm_state */ > + uint8_t locality; /* for the current request */ > + uint8_t pad; /* should be zero */ > > -struct tpmif_tx_interface { > - struct tpmif_ring ring[TPMIF_TX_RING_SIZE]; > + uint8_t nr_extra_pages; /* extra pages for long packets; may be z= ero */ > + uint32_t extra_pages[0]; /* grant IDs; length is actually nr_extra= _pages */ > }; > -typedef struct tpmif_tx_interface tpmif_tx_interface_t; > +typedef struct vtpm_shared_page vtpm_shared_page_t; > > #endif > > -- > 1.8.1.4 > --------------ms050806080005080905070101 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIDyjCC A8YwggMvoAMCAQICBD/xyf0wDQYJKoZIhvcNAQEFBQAwLzELMAkGA1UEBhMCVVMxDzANBgNV BAoTBkpIVUFQTDEPMA0GA1UECxMGQklTRENBMB4XDTEwMDYxMTE4MjIwNloXDTEzMDYxMTE4 NTIwNlowZjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkpIVUFQTDEPMA0GA1UECxMGUGVvcGxl MTUwFgYDVQQLEw9WUE5Hcm91cC1CSVNEQ0EwGwYDVQQDExRNYXR0aGV3IEUgRmlvcmF2YW50 ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnpbwVSP6o1Nb5lcW7dd3yTo9iBJdi7qz 4nANOMFPK7JOy5npKN1iiousl28U/scUJES55gPwAWYJK3uVyQAsA4adgDKi5DoD1UHDQEwp bY7iHLJeq0NPr4BqYNqnCFPbE6HC8zSJrr4qKn+gVUQT39SIFqdiIPJwZL8FYTRQ/zsCAwEA AaOCAbYwggGyMAsGA1UdDwQEAwIHgDArBgNVHRAEJDAigA8yMDEwMDYxMTE4MjIwNlqBDzIw MTIwNzE3MjI1MjA2WjAbBg0rBgEEAbMlCwMBAQEBBAoWCGZpb3JhbWUxMBsGDSsGAQQBsyUL AwEBAQIEChIIMDAxMDQyNjEwWAYJYIZIAYb6ax4BBEsMSVRoZSBwcml2YXRlIGtleSBjb3Jy ZXNwb25kaW5nIHRvIHRoaXMgY2VydGlmaWNhdGUgbWF5IGhhdmUgYmVlbiBleHBvcnRlZC4w KAYDVR0RBCEwH4EdTWF0dGhldy5GaW9yYXZhbnRlQGpodWFwbC5lZHUwUgYDVR0fBEswSTBH oEWgQ6RBMD8xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZKSFVBUEwxDzANBgNVBAsTBkJJU0RD QTEOMAwGA1UEAxMFQ1JMNTYwHwYDVR0jBBgwFoAUCDUpmxH52EU2CyWmF2EJMB1yqeswHQYD VR0OBBYEFO6LYxg6r9wHZ+zdQtBHn1dZ/YTNMAkGA1UdEwQCMAAwGQYJKoZIhvZ9B0EABAww ChsEVjcuMQMCBLAwDQYJKoZIhvcNAQEFBQADgYEAJO9HQh4YNChVLzuZqK5ARJARD8JoujGZ fdo75quvg2jXFQe2sEjvLnxJZgm/pv8fdZakq48CWwjYHKuvIp7sDjTEsQfo+y7SpN/N2NvJ WU5SqfK1VgYtNLRRoGJUB5Q1aZ+Dg95g3kqpyfpUMISJL8IKVLtJVfN4fggFVUYZ9wwxggGr MIIBpwIBATA3MC8xCzAJBgNVBAYTAlVTMQ8wDQYDVQQKEwZKSFVBUEwxDzANBgNVBAsTBkJJ U0RDQQIEP/HJ/TAJBgUrDgMCGgUAoIHLMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ KoZIhvcNAQkFMQ8XDTEzMDMyNjE2Mjk0NVowIwYJKoZIhvcNAQkEMRYEFIDops8DZxSZJz/2 GDHSqZPInuU2MGwGCSqGSIb3DQEJDzFfMF0wCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBAjAK BggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYI KoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEgYA5jnlcKHULHwHP6uw5lpcnS5z7aMTCFe4x jsi9xdR0yrMLEgWWJVcn3YMcqSZnHaL9bDdqShtQKBeEyEn6+QVnfh4PtreR9uqMlUhHEoPT ZOUYgJ+OGNwoNqzlvg6n8cm4mczNLkW2iGLv5dxy4PM565PPr5UvFByB1WV0wAH4BgAAAAAA AA== --------------ms050806080005080905070101-- --===============7561949833948339532== 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.xen.org http://lists.xen.org/xen-devel --===============7561949833948339532==--