⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tpm-tis-device

📁 xen 3.2.2 源码
💻
📖 第 1 页 / 共 3 页
字号:
+static CPUWriteMemoryFunc *tis_writefn[3]={+    tis_mem_writel,+    tis_mem_writel,+    tis_mem_writel+};++/*+ * Save the internal state of this interface for later resumption.+ * Need to get any outstanding responses from the vTPM back, so+ * this might delay the suspend for a while.+ */+static void tpm_save(QEMUFile* f,void* opaque)+{+    tpmState* s=(tpmState*)opaque;+    uint8_t locty = s->active_loc;+    int c;++    /* need to wait for outstanding requests to complete */+    if (s->loc[locty].state == STATE_EXECUTION) {+        int repeats = 30; /* 30 seconds; really should be infty */+        while (repeats > 0 &&+               !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) {+            int n = TPM_Receive(s, &s->buffer);+            if (n > 0) {+                if (IS_VALID_LOC(s->active_loc)) {+                    s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;+                    s->loc[s->active_loc].state = STATE_COMPLETION;+                    tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);+                }+                /* close the connection with the vTPM for good */+                close_vtpm_channel(s, 1);+                break;+            }+            sleep(1);+        }+    }++    if (IS_COMM_WITH_VTPM(s)) {+        close_vtpm_channel(s, 1);+    }++    qemu_put_be32s(f,&s->offset);+    qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT);+    qemu_put_8s(f, &s->active_loc);+    qemu_put_8s(f, &s->irq_pending);+    for (c = 0; c < NUM_LOCALITIES; c++) {+        qemu_put_be32s(f, &s->loc[c].state);+        qemu_put_8s(f, &s->loc[c].access);+        qemu_put_8s(f, &s->loc[c].sts);+        qemu_put_be32s(f, &s->loc[c].inte);+        qemu_put_be32s(f, &s->loc[c].ints);+    }+}++/*+ * load TIS interface state+ */+static int tpm_load(QEMUFile* f,void* opaque,int version_id)+{+    tpmState* s=(tpmState*)opaque;+    int c;++    if (version_id != 1)+        return -EINVAL;++    qemu_get_be32s(f,&s->offset);+    qemu_get_buffer(f, s->buffer.buf, TPM_MAX_PKT);+    qemu_get_8s(f, &s->active_loc);+    qemu_get_8s(f, &s->irq_pending);+    for (c = 0; c < NUM_LOCALITIES; c++) {+        qemu_get_be32s(f, &s->loc[c].state);+        qemu_get_8s(f, &s->loc[c].access);+        qemu_get_8s(f, &s->loc[c].sts);+        qemu_get_be32s(f, &s->loc[c].inte);+        qemu_get_be32s(f, &s->loc[c].ints);+    }++    /* need to be able to get the instance number from the xenstore */+    s->vtpm_instance = vtpm_instance_from_xenstore();+    if (s->vtpm_instance == VTPM_BAD_INSTANCE)+        return -EINVAL;+    tpm_initialize_instance(s, s->vtpm_instance);++    return 0;+}+++typedef struct LPCtpmState {+    tpmState tpm;+    int mem;+} LPCtpmState;+++/*+ * initialize TIS interface+ */+void tpm_tis_init(SetIRQFunc *set_irq, void *opaque, int irq)+{+    LPCtpmState *d;+    tpmState *s;+    int c = 0;+    uint32_t vtpm_in;++    vtpm_in = vtpm_instance_from_xenstore();+    /* no valid vtpm instance -> no device */+    if (vtpm_in == VTPM_BAD_INSTANCE)+        return;++    d = qemu_mallocz(sizeof(LPCtpmState));+    d->mem = cpu_register_io_memory(0, tis_readfn, tis_writefn, d);++    if (d->mem == -1) {+       return;+    }++    cpu_register_physical_memory(TIS_ADDR_BASE,+                                 0x1000 * NUM_LOCALITIES, d->mem);++    /* initialize tpmState */+    s = &d->tpm;++    s->offset = 0;+    s->active_loc = NO_LOCALITY;++    while (c < NUM_LOCALITIES) {+        s->loc[c].access = (1 << 7);+        s->loc[c].sts = 0;+        s->loc[c].inte = (1 << 3);+        s->loc[c].ints = 0;+        s->loc[c].state = STATE_IDLE;+        c++;+    }+    s->poll_timer = qemu_new_timer(vm_clock, tis_poll_timer, s);+    s->set_irq = set_irq;+    s->irq_opaque = opaque;+    s->irq = irq;+    s->vtpm_instance = vtpm_in;+    s->Transmitlayer = -1;+    s->tpmTx.fd[0] = -1;+    s->tpmTx.fd[1] = -1;+    s->aborting_locty = NO_LOCALITY;++    tpm_initialize_instance(s, s->vtpm_instance);+    memset(s->buffer.buf,0,sizeof(s->buffer.buf));++    register_savevm("tpm-tis", 0, 1, tpm_save, tpm_load, s);+}++/****************************************************************************/+/*  optional verbose logging of data to/from vtpm                           */+/****************************************************************************/+#ifdef DEBUG_TPM+static void showBuff(unsigned char *buff, char *string)+{+    uint32_t i, len;++    len = tpm_get_size_from_buffer(buff);+    fprintf(logfile,"%s length = %d\n", string, len);+    for (i = 0; i < len; i++) {+        if (i && !(i % 16)) {+            fprintf(logfile,"\n");+        }+        fprintf(logfile,"%.2X ", buff[i]);+    }+    fprintf(logfile,"\n");+}+#endif++/****************************************************************************/+/* Transmit request to TPM and read Response                                */+/****************************************************************************/++const static unsigned char tpm_failure[] = {+    0x00, 0x00,+    0x00, 0x00, 0x00, 0x0a,+    0x00, 0x00, 0x00, 0x09+};+++/*+ * Send a TPM request.+ */+static int TPM_Send(tpmState *s, tpmBuffer *buffer, uint8_t locty, char *msg)+{+    int len;+    uint32_t size = tpm_get_size_from_buffer(buffer->buf);++    /* try to establish a connection to the vTPM */+    if ( !IS_COMM_WITH_VTPM(s)) {+        open_vtpm_channel(s);+    }++    if ( !IS_COMM_WITH_VTPM(s)) {+        unsigned char tag = buffer->buf[1];++        /* there's a failure response from the TPM */+        memcpy(buffer->buf, tpm_failure, sizeof(tpm_failure));+        buffer->buf[1] = tag + 3;+        if (IS_VALID_LOC(s->active_loc)) {+            s->loc[s->active_loc].sts = STS_DATA_AVAILABLE | STS_VALID;+        }+#ifdef DEBUG_TPM+        fprintf(logfile,"No TPM running!\n");+#endif+        /* the request went out ok. */+        return sizeof(buffer->instance) + size;+    }++#ifdef DEBUG_TPM+    showBuff(buffer->buf, "To TPM");+#endif++    /* transmit the locality in the highest 3 bits */+    buffer->instance[0] &= 0x1f;+    buffer->instance[0] |= (locty << 5);++    len = vTPMTransmit[s->Transmitlayer].write(s, buffer);+    if (len < 0) {+        s->Transmitlayer = -1;+    }+    return len;+}++/*+ * Try to receive data from the file descriptor. Since it is in+ * non-blocking mode it is possible that no data are actually received -+ * whatever calls this function needs to try again later.+ */+static int TPM_Receive(tpmState *s, tpmBuffer *buffer)+{+    int off;++    off = vTPMTransmit[s->Transmitlayer].read(s, buffer);++    if (off < 0) {+        /* EAGAIN is set in errno due to non-blocking mode */+        return -1;+    }++    if (off == 0) {+#ifdef DEBUG_TPM+        fprintf(logfile,"TPM GONE? errno=%d\n",errno);+#endif+        close_vtpm_channel(s, 1);+        /* pretend that data are available */+        if (IS_VALID_LOC(s->active_loc)) {+            s->loc[s->active_loc].sts = STS_VALID | STS_DATA_AVAILABLE;+            s->loc[s->active_loc].state = STATE_COMPLETION;+            tis_raise_irq(s, s->active_loc, INT_DATA_AVAILABLE);+        }+        return -1;+    }++#ifdef DEBUG_TPM+    if (off > sizeof(buffer->instance ) + 6) {+        uint32_t size = tpm_get_size_from_buffer(buffer->buf);+        if (size + sizeof(buffer->instance) != off) {+            fprintf(logfile,"TPM: Packet size is bad! %d != %d\n",+                    (int)(size + sizeof(buffer->instance)),+                    off);+        } else {+            uint32_t ret;+            showBuff(buffer->buf, "From TPM");+            ret = (buffer->buf[8])*256 + buffer->buf[9];+            if (ret)+                fprintf(logfile,"Receive failed with error %d\n", ret);+            else+                fprintf(logfile,"Receive succeeded. Got response of length %d (=%d)\n",+                       size, off);+        }+    }+#endif++    /* assuming reading in one chunk for now */+    return off;+}+++/****************************************************************************+   Helper functions for reading data from the xenstore such as+   reading virtual TPM instance information+ ****************************************************************************/+int has_tpm_device(void)+{+    int ret = 0;+    struct xs_handle *handle = xs_daemon_open();+    if (handle) {+        ret = xenstore_domain_has_devtype(handle, "vtpm");+        xs_daemon_close(handle);+    }+    return ret;+}+++/*+ * Wait until hotplug scripts have finished then read the vTPM instance+ * number from the xenstore.+ */+static uint32_t vtpm_instance_from_xenstore(void)+{+    unsigned int num;+    uint32_t number = VTPM_BAD_INSTANCE;+    int end = 0;+    char *token = "tok";+    int subscribed = 0;+    int ctr = 0;+    fd_set readfds;++    struct xs_handle *handle = xs_daemon_open();++    FD_ZERO(&readfds);++    if (handle) {+        char **e = xenstore_domain_get_devices(handle, "vtpm", &num);+        int fd = xs_fileno(handle);+        FD_SET(fd, &readfds);+        if (e) {+            do {+                struct timeval tv = {+                    .tv_sec  = 30,+                    .tv_usec = 0,+                };+                /* need to make sure that the hotplug scripts have finished */+                char *status = xenstore_read_hotplug_status(handle,+                                                            "vtpm",+                                                            e[0]);+                if (status) {+                    if (!strcmp(status, "connected")) {+                        char *inst = xenstore_backend_read_variable(handle,+                                                                    "vtpm",+                                                                    e[0],+                                                                   "instance");+                        if (1 != (sscanf(inst,"%d",&number)))+                            number = VTPM_BAD_INSTANCE;+                        free(inst);+                    } else {+                        fprintf(logfile,+                                "bad status '%s' from vtpm hotplug\n",+                                status);+                    }+                    free(status);+                    end = 1;+                } else {+                    /* no status, yet */+                    int rc;+                    unsigned int nr;+                    char **f;++                    if (!subscribed) {+                        rc = xenstore_subscribe_to_hotplug_status(handle,+                                                                  "vtpm",+                                                                  e[0],+                                                                  token);+                        if (rc != 0)+                            break;+                        subscribed = 1;+                    }+                    rc = select(fd+1, &readfds, NULL, NULL, &tv);+                    /* get what's available -- drain the fd */+                    f = xs_read_watch(handle, &nr);+                    ctr++;+                    free(f);+                    if (ctr > 2)+                        end = 1;+                }+            } while (end == 0);+            free(e);+        }+        if (subscribed) {+            /* clean up */+            xenstore_unsubscribe_from_hotplug_status(handle,+                                                     "vtpm",+                                                     e[0],+                                                     token);+        }+        xs_daemon_close(handle);+    }+    if (number == VTPM_BAD_INSTANCE)+        fprintf(logfile, "no valid vtpm instance");+    else+        fprintf(logfile,"vtpm instance:%d\n",number);+    return number;+}Index: ioemu/vl.h===================================================================--- ioemu.orig/vl.h	2007-05-10 15:19:29.000000000 +0100+++ ioemu/vl.h	2007-05-10 15:19:29.000000000 +0100@@ -1086,6 +1086,10 @@ /* smbus_eeprom.c */ SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf); +/* tpm_tis.c */+int has_tpm_device(void);+void tpm_tis_init(SetIRQFunc *set_irq, void *irq_opaque, int irq);+ /* piix4acpi.c */ extern void pci_piix4_acpi_init(PCIBus *bus, int devfn); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -