Revision 8f0605cc tpm/tpm_passthrough.c

b/tpm/tpm_passthrough.c
27 27
#include "qemu-common.h"
28 28
#include "qapi/error.h"
29 29
#include "qemu/sockets.h"
30
#include "backends/tpm.h"
30 31
#include "tpm_int.h"
31 32
#include "hw/hw.h"
32 33
#include "hw/pc.h"
......
43 44
    do { } while (0)
44 45
#endif
45 46

  
46
/* data structures */
47
#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
48
#define TPM_PASSTHROUGH(obj) \
49
    OBJECT_CHECK(TPMPassthruState, (obj), TYPE_TPM_PASSTHROUGH)
47 50

  
51
/* data structures */
48 52
typedef struct TPMPassthruThreadParams {
49 53
    TPMState *tpm_state;
50 54

  
......
53 57
} TPMPassthruThreadParams;
54 58

  
55 59
struct TPMPassthruState {
60
    TPMBackend parent;
61

  
56 62
    TPMBackendThread tbt;
57 63

  
58 64
    TPMPassthruThreadParams tpm_thread_params;
......
65 71
    bool had_startup_error;
66 72
};
67 73

  
74
typedef struct TPMPassthruState TPMPassthruState;
75

  
68 76
#define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0"
69 77

  
70 78
/* functions */
......
149 157
                                          gpointer user_data)
150 158
{
151 159
    TPMPassthruThreadParams *thr_parms = user_data;
152
    TPMPassthruState *tpm_pt = thr_parms->tb->s.tpm_pt;
160
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(thr_parms->tb);
153 161
    TPMBackendCmd cmd = (TPMBackendCmd)data;
154 162

  
155 163
    DPRINTF("tpm_passthrough: processing command type %d\n", cmd);
......
176 184
 */
177 185
static int tpm_passthrough_startup_tpm(TPMBackend *tb)
178 186
{
179
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
187
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
180 188

  
181 189
    /* terminate a running TPM */
182 190
    tpm_backend_thread_end(&tpm_pt->tbt);
183 191

  
184 192
    tpm_backend_thread_create(&tpm_pt->tbt,
185 193
                              tpm_passthrough_worker_thread,
186
                              &tb->s.tpm_pt->tpm_thread_params);
194
                              &tpm_pt->tpm_thread_params);
187 195

  
188 196
    return 0;
189 197
}
190 198

  
191 199
static void tpm_passthrough_reset(TPMBackend *tb)
192 200
{
193
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
201
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
194 202

  
195 203
    DPRINTF("tpm_passthrough: CALL TO TPM_RESET!\n");
196 204

  
......
204 212
static int tpm_passthrough_init(TPMBackend *tb, TPMState *s,
205 213
                                TPMRecvDataCB *recv_data_cb)
206 214
{
207
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
215
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
208 216

  
209 217
    tpm_pt->tpm_thread_params.tpm_state = s;
210 218
    tpm_pt->tpm_thread_params.recv_data_callback = recv_data_cb;
......
220 228

  
221 229
static bool tpm_passthrough_get_startup_error(TPMBackend *tb)
222 230
{
223
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
231
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
224 232

  
225 233
    return tpm_pt->had_startup_error;
226 234
}
......
238 246

  
239 247
static void tpm_passthrough_deliver_request(TPMBackend *tb)
240 248
{
241
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
249
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
242 250

  
243 251
    tpm_backend_thread_deliver_request(&tpm_pt->tbt);
244 252
}
245 253

  
246 254
static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
247 255
{
248
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
256
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
249 257
    int n;
250 258

  
251 259
    /*
......
412 420

  
413 421
static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb)
414 422
{
423
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
415 424
    const char *value;
416 425

  
417 426
    value = qemu_opt_get(opts, "cancel-path");
......
424 433
        value = TPM_PASSTHROUGH_DEFAULT_DEVICE;
425 434
    }
426 435

  
427
    tb->s.tpm_pt->tpm_dev = g_strdup(value);
436
    tpm_pt->tpm_dev = g_strdup(value);
428 437

  
429
    tb->path = g_strdup(tb->s.tpm_pt->tpm_dev);
438
    tb->path = g_strdup(tpm_pt->tpm_dev);
430 439

  
431
    tb->s.tpm_pt->tpm_fd = qemu_open(tb->s.tpm_pt->tpm_dev, O_RDWR);
432
    if (tb->s.tpm_pt->tpm_fd < 0) {
440
    tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR);
441
    if (tpm_pt->tpm_fd < 0) {
433 442
        error_report("Cannot access TPM device using '%s': %s\n",
434
                     tb->s.tpm_pt->tpm_dev, strerror(errno));
443
                     tpm_pt->tpm_dev, strerror(errno));
435 444
        goto err_free_parameters;
436 445
    }
437 446

  
438
    if (tpm_passthrough_test_tpmdev(tb->s.tpm_pt->tpm_fd)) {
447
    if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) {
439 448
        error_report("'%s' is not a TPM device.\n",
440
                     tb->s.tpm_pt->tpm_dev);
449
                     tpm_pt->tpm_dev);
441 450
        goto err_close_tpmdev;
442 451
    }
443 452

  
444 453
    return 0;
445 454

  
446 455
 err_close_tpmdev:
447
    qemu_close(tb->s.tpm_pt->tpm_fd);
448
    tb->s.tpm_pt->tpm_fd = -1;
456
    qemu_close(tpm_pt->tpm_fd);
457
    tpm_pt->tpm_fd = -1;
449 458

  
450 459
 err_free_parameters:
451 460
    g_free(tb->path);
452 461
    tb->path = NULL;
453 462

  
454
    g_free(tb->s.tpm_pt->tpm_dev);
455
    tb->s.tpm_pt->tpm_dev = NULL;
463
    g_free(tpm_pt->tpm_dev);
464
    tpm_pt->tpm_dev = NULL;
456 465

  
457 466
    return 1;
458 467
}
459 468

  
460 469
static TPMBackend *tpm_passthrough_create(QemuOpts *opts, const char *id)
461 470
{
462
    TPMBackend *tb;
471
    Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
472
    TPMBackend *tb = TPM_BACKEND(obj);
473
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
463 474

  
464
    tb = g_new0(TPMBackend, 1);
465
    tb->s.tpm_pt = g_new0(TPMPassthruState, 1);
466 475
    tb->id = g_strdup(id);
467 476
    /* let frontend set the fe_model to proper value */
468 477
    tb->fe_model = -1;
......
473 482
        goto err_exit;
474 483
    }
475 484

  
476
    tb->s.tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tb);
477
    if (tb->s.tpm_pt->cancel_fd < 0) {
485
    tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tb);
486
    if (tpm_pt->cancel_fd < 0) {
478 487
        goto err_exit;
479 488
    }
480 489

  
......
482 491

  
483 492
err_exit:
484 493
    g_free(tb->id);
485
    g_free(tb->s.tpm_pt);
486
    g_free(tb);
487 494

  
488 495
    return NULL;
489 496
}
490 497

  
491 498
static void tpm_passthrough_destroy(TPMBackend *tb)
492 499
{
493
    TPMPassthruState *tpm_pt = tb->s.tpm_pt;
500
    TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb);
494 501

  
495 502
    tpm_passthrough_cancel_cmd(tb);
496 503

  
497 504
    tpm_backend_thread_end(&tpm_pt->tbt);
498 505

  
499 506
    qemu_close(tpm_pt->tpm_fd);
500
    qemu_close(tb->s.tpm_pt->cancel_fd);
507
    qemu_close(tpm_pt->cancel_fd);
501 508

  
502 509
    g_free(tb->id);
503 510
    g_free(tb->path);
504 511
    g_free(tb->cancel_path);
505
    g_free(tb->s.tpm_pt->tpm_dev);
506
    g_free(tb->s.tpm_pt);
507
    g_free(tb);
512
    g_free(tpm_pt->tpm_dev);
508 513
}
509 514

  
510 515
const TPMDriverOps tpm_passthrough_driver = {
......
522 527
    .get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag,
523 528
};
524 529

  
530
static void tpm_passthrough_inst_init(Object *obj)
531
{
532
}
533

  
534
static void tpm_passthrough_inst_finalize(Object *obj)
535
{
536
}
537

  
538
static void tpm_passthrough_class_init(ObjectClass *klass, void *data)
539
{
540
    TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass);
541

  
542
    tbc->ops = &tpm_passthrough_driver;
543
}
544

  
545
static const TypeInfo tpm_passthrough_info = {
546
    .name = TYPE_TPM_PASSTHROUGH,
547
    .parent = TYPE_TPM_BACKEND,
548
    .instance_size = sizeof(TPMPassthruState),
549
    .class_init = tpm_passthrough_class_init,
550
    .instance_init = tpm_passthrough_inst_init,
551
    .instance_finalize = tpm_passthrough_inst_finalize,
552
};
553

  
525 554
static void tpm_passthrough_register(void)
526 555
{
556
    type_register_static(&tpm_passthrough_info);
527 557
    tpm_register_driver(&tpm_passthrough_driver);
528 558
}
529 559

  

Also available in: Unified diff