[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5.1 01/12] mini-os/tpm{back, front}: Change shared page ABI
Is this in the wrong thread and should be in "[PATCH v5 00/12] vTPM updates for 4.3" as an update to <1363896689-11086-2-git-send-email-dgdegra@xxxxxxxxxxxxx> ? On Fri, 2013-03-22 at 22:30 +0000, 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 given > time, and every packet sent generates a single response packet. This > protocol change should also increase efficiency as it avoids mapping and > 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 packets > larger than a single page (actually 4088 bytes) by allowing the client > to add extra grant references, the mapping of these extra references has > 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 <dgdegra@xxxxxxxxxxxxx> > Cc: Jan Beulich <JBeulich@xxxxxxxx> > > --- > > Changes from v5: handle xenbus states properly, and keep the old header > contents intact. > > 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 | 163 > +++++++++++++++++++------------------- > extras/mini-os/tpmfront.c | 143 ++++++++++++++++++--------------- > xen/include/public/io/tpmif.h | 28 +++++++ > 5 files changed, 190 insertions(+), 152 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 interface > */ > > 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 reqlen, > 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 <sys/stat.h> > /* POSIX IO functions: > diff --git a/extras/mini-os/tpmback.c b/extras/mini-os/tpmback.c > index 658fed1..d6a504e 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", (unsigned > int) tpmif->domid, tpmif->handle); > + if ((err = xenbus_write(XBT_NIL, path, "1"))) > + { > + /* if we got an error here we should carefully remove the interface > and then return */ > + TPMBACK_ERR("Unable to write feature-protocol-v2 node: %s\n", err); > + free(err); > + remove_tpmif(tpmif); > + goto error_post_irq; > + } > + > /*Listen for state changes on the new interface */ > if((err = 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, unsigned int > handle) > tpmif->fe_state_path = NULL; > tpmif->state = XenbusStateInitialising; > tpmif->status = DISCONNECTED; > - tpmif->tx = NULL; > - tpmif->pages = NULL; > + tpmif->page = NULL; > tpmif->flags = 0; > memset(tpmif->uuid, 0, sizeof(tpmif->uuid)); > return tpmif; > @@ -395,9 +401,6 @@ inline tpmif_t* __init_tpmif(domid_t domid, unsigned 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 handle) > goto error; > } > > - /* allocate pages to be used for shared mapping */ > - if((tpmif->pages = malloc(sizeof(void*) * TPMIF_TX_RING_SIZE)) == 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 = 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 = (tpmif_t*) data; > - tpmif_tx_request_t* tx = &tpmif->tx->ring[0].req; > - /* Throw away 0 size events, these can trigger from event channel > unmasking */ > - if(tx->size == 0) > - return; > - > - TPMBACK_DEBUG("EVENT CHANNEL FIRE %u/%u\n", (unsigned int) tpmif->domid, > tpmif->handle); > - tpmif_req_ready(tpmif); > - wake_up(&waitq); > + vtpm_shared_page_t* pg = 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 = 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 = xenbus_read(XBT_NIL, path, &value))) { > + TPMBACK_ERR("Unable to read %s during tpmback initialization! error = > %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 = tpmif->domid; > - if((tpmif->tx = gntmap_map_grant_refs(>pmdev.map, 1, &domid, 0, > &ringref, PROT_READ | PROT_WRITE)) == NULL) { > + if((tpmif->page = gntmap_map_grant_refs(>pmdev.map, 1, &domid, 0, > &ringref, PROT_READ | PROT_WRITE)) == 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; > } > > @@ -633,9 +655,9 @@ static int frontend_changed(tpmif_t* tpmif) > > switch (state) { > case XenbusStateInitialising: > - case XenbusStateInitialised: > break; > > + case XenbusStateInitialised: > case XenbusStateConnected: > if(connect_fe(tpmif)) { > TPMBACK_ERR("Failed to connect to front end %u/%u\n", (unsigned > int) tpmif->domid, tpmif->handle); > @@ -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 = domid; > + tpmcmd->locality = -1; > tpmcmd->handle = handle; > memcpy(tpmcmd->uuid, uuid, sizeof(tpmcmd->uuid)); > tpmcmd->req = 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 = &tpmif->tx->ring[0].req; > - cmd->req_len = tx->size; > + shr = tpmif->page; > + cmd->req_len = shr->length; > + cmd->locality = shr->locality; > + offset = 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", > (unsigned int) tpmif->domid, tpmif->handle); > + goto error; > + } > /* Allocate the buffer */ > if(cmd->req_len) { > if((cmd->req = malloc(cmd->req_len)) == NULL) { > goto error; > } > } > - /* Copy the bits from the shared pages */ > - offset = 0; > - for(i = 0; i < TPMIF_TX_RING_SIZE && offset < cmd->req_len; ++i) { > - tx = &tpmif->tx->ring[i].req; > - > - /* Map the page with the data */ > - domid = (uint32_t)tpmif->domid; > - if((tpmif->pages[i] = gntmap_map_grant_refs(>pmdev.map, 1, &domid, > 0, &tx->ref, PROT_READ)) == 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 = min(cmd->req_len - offset, PAGE_SIZE); > - memcpy(&cmd->req[offset], tpmif->pages[i], tocopy); > - offset += 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", (unsigned > 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 = &tpmif->tx->ring[0].req; > - tx->size = cmd->resp_len; > - > - offset = 0; > - for(i = 0; i < TPMIF_TX_RING_SIZE && offset < cmd->resp_len; ++i) { > - tx = &tpmif->tx->ring[i].req; > - > - /* Map the page with the data */ > - domid = (uint32_t)tpmif->domid; > - if((tpmif->pages[i] = gntmap_map_grant_refs(>pmdev.map, 1, &domid, > 0, &tx->ref, PROT_WRITE)) == 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 = min(cmd->resp_len - offset, PAGE_SIZE); > - memcpy(tpmif->pages[i], &cmd->resp[offset], tocopy); > - offset += tocopy; > - > - /* release the page */ > - gntmap_munmap(>pmdev.map, (unsigned long)tpmif->pages[i], 1); > + shr = tpmif->page; > + shr->length = cmd->resp_len; > > + offset = 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", > (unsigned 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 frontend > */ > tpmif_req_finished(tpmif); > + shr->state = 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 = (struct tpmfront_dev*) data; > + vtpm_shared_page_t* shr = dev->page; > /*If we get a response when we didnt make a request, just ignore it */ > 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 = 0; > #ifdef HAVE_LIBC > if(dev->fd >= 0) { > @@ -176,7 +186,7 @@ static int wait_for_backend_state_changed(struct > tpmfront_dev* dev, XenbusState > ret = wait_for_backend_closed(&events, path); > break; > default: > - break; > + TPMFRONT_ERR("Bad wait state %d, ignoring\n", state); > } > > if((err = 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 = (tpmif_tx_interface_t*) alloc_page(); > - if(dev->tx == NULL) { > + dev->page = (vtpm_shared_page_t*) alloc_page(); > + if(dev->page == NULL) { > TPMFRONT_ERR("Unable to allocate page for shared memory\n"); > goto error; > } > - memset(dev->tx, 0, PAGE_SIZE); > - dev->ring_ref = gnttab_grant_access(dev->bedomid, virt_to_mfn(dev->tx), > 0); > + memset(dev->page, 0, PAGE_SIZE); > + dev->ring_ref = 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* _nodename) > char path[512]; > char* value, *err; > unsigned long long ival; > - int i; > > printk("============= Init TPM Front ================\n"); > > @@ -279,6 +288,15 @@ struct tpmfront_dev* init_tpmfront(const char* _nodename) > goto error; > } > > + /* Publish protocol v2 feature */ > + snprintf(path, 512, "%s/feature-protocol-v2", dev->nodename); > + if ((err = xenbus_write(XBT_NIL, path, "1"))) > + { > + TPMFRONT_ERR("Unable to write feature-protocol-v2 node: %s\n", err); > + 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* > _nodename) > goto error; > } > > - /* Allocate pages that will contain the messages */ > - dev->pages = malloc(sizeof(void*) * TPMIF_TX_RING_SIZE); > - if(dev->pages == NULL) { > + /* Ensure backend is also using protocol v2 */ > + snprintf(path, 512, "%s/feature-protocol-v2", dev->bepath); > + if((err = xenbus_read(XBT_NIL, path, &value))) { > + TPMFRONT_ERR("Unable to read %s during tpmfront initialization! error > = %s\n", path, err); > + free(err); > goto error; > } > - memset(dev->pages, 0, sizeof(void*) * TPMIF_TX_RING_SIZE); > - for(i = 0; i < TPMIF_TX_RING_SIZE; ++i) { > - dev->pages[i] = (void*)alloc_page(); > - if(dev->pages[i] == 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 == 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 = 0; i < TPMIF_TX_RING_SIZE; ++i) { > - if(dev->pages[i]) { > - tx = &dev->tx->ring[i].req; > - if(tx->ref != 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 = NULL; > +#ifdef TPMFRONT_PRINT_DEBUG > int i; > - tpmif_tx_request_t* tx = NULL; > +#endif > /* Error Checking */ > if(dev == NULL || dev->state != XenbusStateConnected) { > TPMFRONT_ERR("Tried to send message through disconnected frontend\n"); > return -1; > } > + shr = dev->page; > > #ifdef TPMFRONT_PRINT_DEBUG > TPMFRONT_DEBUG("Sending Msg to backend size=%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 = 0; length > 0 && i < TPMIF_TX_RING_SIZE; ++i) { > - /* Share the page */ > - tx = &dev->tx->ring[i].req; > - tx->unused = 0; > - tx->addr = virt_to_mach(dev->pages[i]); > - tx->ref = gnttab_grant_access(dev->bedomid, > virt_to_mfn(dev->pages[i]), 0); > - /* Copy the bits to the page */ > - tx->size = length > PAGE_SIZE ? PAGE_SIZE : length; > - memcpy(dev->pages[i], &msg[i * PAGE_SIZE], tx->size); > - > - /* Update counters */ > - length -= tx->size; > + offset = 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 = length; > + barrier(); > + shr->state = VTPM_STATE_SUBMIT; > + > dev->waiting = 1; > dev->resplen = 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 *length) > { > - tpmif_tx_request_t* tx; > - int i; > + unsigned int offset; > + vtpm_shared_page_t* shr = NULL; > +#ifdef TPMFRONT_PRINT_DEBUG > +int i; > +#endif > if(dev == NULL || dev->state != XenbusStateConnected) { > TPMFRONT_ERR("Tried to receive message from disconnected frontend\n"); > return -1; > } > /*Wait for the response */ > wait_event(dev->waitq, (!dev->waiting)); > + shr = dev->page; > > /* Initialize */ > *msg = NULL; > *length = 0; > + offset = sizeof(*shr); > > - /* special case, just quit */ > - tx = &dev->tx->ring[0].req; > - if(tx->size == 0 ) { > - goto quit; > - } > - /* Get the total size */ > - tx = &dev->tx->ring[0].req; > - for(i = 0; i < TPMIF_TX_RING_SIZE && tx->size > 0; ++i) { > - tx = &dev->tx->ring[i].req; > - *length += tx->size; > + if (shr->state != VTPM_STATE_FINISH) > + goto quit; > + > + *length = 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 = dev->respbuf = malloc(*length); > dev->resplen = *length; > + > /* Copy the bits */ > - tx = &dev->tx->ring[0].req; > - for(i = 0; i < TPMIF_TX_RING_SIZE && tx->size > 0; ++i) { > - tx = &dev->tx->ring[i].req; > - memcpy(&(*msg)[i * PAGE_SIZE], dev->pages[i], tx->size); > - gnttab_end_access(tx->ref); > - tx->ref = 0; > - } > + memcpy(*msg, offset + (uint8_t*)shr, *length); > + > #ifdef TPMFRONT_PRINT_DEBUG > TPMFRONT_DEBUG("Received response from backend size=%u", (unsigned int) > *length); > for(i = 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 = locality; > + return 0; > +} > + > #ifdef HAVE_LIBC > #include <errno.h> > int tpmfront_open(struct tpmfront_dev* dev) > diff --git a/xen/include/public/io/tpmif.h b/xen/include/public/io/tpmif.h > index fca2c4e..afa4324 100644 > --- a/xen/include/public/io/tpmif.h > +++ b/xen/include/public/io/tpmif.h > @@ -64,6 +64,34 @@ struct tpmif_tx_interface { > }; > typedef struct tpmif_tx_interface tpmif_tx_interface_t; > > +/****************************************************************************** > + * TPM I/O interface for Xen guest OSes, v2 > + * > + * Author: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> > + * > + */ > + > +enum vtpm_state { > + VTPM_STATE_IDLE, /* no contents / vTPM idle / cancel complete */ > + VTPM_STATE_SUBMIT, /* request ready / vTPM working */ > + VTPM_STATE_FINISH, /* response ready / vTPM idle */ > + VTPM_STATE_CANCEL, /* cancel requested / vTPM working */ > +}; > +/* The backend should only change state to IDLE or FINISH, while the > + * frontend should only change to SUBMIT or CANCEL. */ > + > +struct vtpm_shared_page { > + uint32_t length; /* request/response length in bytes */ > + > + uint8_t state; /* enum vtpm_state */ > + uint8_t locality; /* for the current request */ > + uint8_t pad; /* should be zero */ > + > + uint8_t nr_extra_pages; /* extra pages for long packets; may be zero */ > + uint32_t extra_pages[0]; /* grant IDs; length is actually nr_extra_pages > */ > +}; > +typedef struct vtpm_shared_page vtpm_shared_page_t; > + > #endif > > /* > -- > 1.8.1.4 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |