2 * Implementation of the Xen vTPM device frontend
4 * Author: Daniel De Graaf <dgdegra@tycho.nsa.gov>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2,
8 * as published by the Free Software Foundation.
10 #include <linux/errno.h>
11 #include <linux/err.h>
12 #include <linux/interrupt.h>
14 #include <xen/events.h>
15 #include <xen/interface/io/tpmif.h>
16 #include <xen/grant_table.h>
17 #include <xen/xenbus.h>
20 #include <xen/platform_pci.h>
23 struct tpm_chip
*chip
;
24 struct xenbus_device
*dev
;
26 struct vtpm_shared_page
*shr
;
34 VTPM_STATUS_RUNNING
= 0x1,
35 VTPM_STATUS_IDLE
= 0x2,
36 VTPM_STATUS_RESULT
= 0x4,
37 VTPM_STATUS_CANCELED
= 0x8,
40 static u8
vtpm_status(struct tpm_chip
*chip
)
42 struct tpm_private
*priv
= TPM_VPRIV(chip
);
43 switch (priv
->shr
->state
) {
45 return VTPM_STATUS_IDLE
| VTPM_STATUS_CANCELED
;
46 case VTPM_STATE_FINISH
:
47 return VTPM_STATUS_IDLE
| VTPM_STATUS_RESULT
;
48 case VTPM_STATE_SUBMIT
:
49 case VTPM_STATE_CANCEL
: /* cancel requested, not yet canceled */
50 return VTPM_STATUS_RUNNING
;
56 static bool vtpm_req_canceled(struct tpm_chip
*chip
, u8 status
)
58 return status
& VTPM_STATUS_CANCELED
;
61 static void vtpm_cancel(struct tpm_chip
*chip
)
63 struct tpm_private
*priv
= TPM_VPRIV(chip
);
64 priv
->shr
->state
= VTPM_STATE_CANCEL
;
66 notify_remote_via_evtchn(priv
->evtchn
);
69 static unsigned int shr_data_offset(struct vtpm_shared_page
*shr
)
71 return sizeof(*shr
) + sizeof(u32
) * shr
->nr_extra_pages
;
74 static int vtpm_send(struct tpm_chip
*chip
, u8
*buf
, size_t count
)
76 struct tpm_private
*priv
= TPM_VPRIV(chip
);
77 struct vtpm_shared_page
*shr
= priv
->shr
;
78 unsigned int offset
= shr_data_offset(shr
);
81 unsigned long duration
;
83 if (offset
> PAGE_SIZE
)
86 if (offset
+ count
> PAGE_SIZE
)
89 /* Wait for completion of any existing command or cancellation */
90 if (wait_for_tpm_stat(chip
, VTPM_STATUS_IDLE
, chip
->vendor
.timeout_c
,
91 &chip
->vendor
.read_queue
, true) < 0) {
96 memcpy(offset
+ (u8
*)shr
, buf
, count
);
99 shr
->state
= VTPM_STATE_SUBMIT
;
101 notify_remote_via_evtchn(priv
->evtchn
);
103 ordinal
= be32_to_cpu(((struct tpm_input_header
*)buf
)->ordinal
);
104 duration
= tpm_calc_ordinal_duration(chip
, ordinal
);
106 if (wait_for_tpm_stat(chip
, VTPM_STATUS_IDLE
, duration
,
107 &chip
->vendor
.read_queue
, true) < 0) {
108 /* got a signal or timeout, try to cancel */
116 static int vtpm_recv(struct tpm_chip
*chip
, u8
*buf
, size_t count
)
118 struct tpm_private
*priv
= TPM_VPRIV(chip
);
119 struct vtpm_shared_page
*shr
= priv
->shr
;
120 unsigned int offset
= shr_data_offset(shr
);
121 size_t length
= shr
->length
;
123 if (shr
->state
== VTPM_STATE_IDLE
)
126 /* In theory the wait at the end of _send makes this one unnecessary */
127 if (wait_for_tpm_stat(chip
, VTPM_STATUS_RESULT
, chip
->vendor
.timeout_c
,
128 &chip
->vendor
.read_queue
, true) < 0) {
133 if (offset
> PAGE_SIZE
)
136 if (offset
+ length
> PAGE_SIZE
)
137 length
= PAGE_SIZE
- offset
;
142 memcpy(buf
, offset
+ (u8
*)shr
, length
);
147 static const struct tpm_class_ops tpm_vtpm
= {
148 .status
= vtpm_status
,
151 .cancel
= vtpm_cancel
,
152 .req_complete_mask
= VTPM_STATUS_IDLE
| VTPM_STATUS_RESULT
,
153 .req_complete_val
= VTPM_STATUS_IDLE
| VTPM_STATUS_RESULT
,
154 .req_canceled
= vtpm_req_canceled
,
157 static irqreturn_t
tpmif_interrupt(int dummy
, void *dev_id
)
159 struct tpm_private
*priv
= dev_id
;
161 switch (priv
->shr
->state
) {
162 case VTPM_STATE_IDLE
:
163 case VTPM_STATE_FINISH
:
164 wake_up_interruptible(&priv
->chip
->vendor
.read_queue
);
166 case VTPM_STATE_SUBMIT
:
167 case VTPM_STATE_CANCEL
:
174 static int setup_chip(struct device
*dev
, struct tpm_private
*priv
)
176 struct tpm_chip
*chip
;
178 chip
= tpmm_chip_alloc(dev
, &tpm_vtpm
);
180 return PTR_ERR(chip
);
182 init_waitqueue_head(&chip
->vendor
.read_queue
);
185 TPM_VPRIV(chip
) = priv
;
190 /* caller must clean up in case of errors */
191 static int setup_ring(struct xenbus_device
*dev
, struct tpm_private
*priv
)
193 struct xenbus_transaction xbt
;
194 const char *message
= NULL
;
198 priv
->shr
= (void *)__get_free_page(GFP_KERNEL
|__GFP_ZERO
);
200 xenbus_dev_fatal(dev
, -ENOMEM
, "allocating shared ring");
204 rv
= xenbus_grant_ring(dev
, &priv
->shr
, 1, &gref
);
208 priv
->ring_ref
= gref
;
210 rv
= xenbus_alloc_evtchn(dev
, &priv
->evtchn
);
214 rv
= bind_evtchn_to_irqhandler(priv
->evtchn
, tpmif_interrupt
, 0,
217 xenbus_dev_fatal(dev
, rv
, "allocating TPM irq");
220 priv
->chip
->vendor
.irq
= rv
;
223 rv
= xenbus_transaction_start(&xbt
);
225 xenbus_dev_fatal(dev
, rv
, "starting transaction");
229 rv
= xenbus_printf(xbt
, dev
->nodename
,
230 "ring-ref", "%u", priv
->ring_ref
);
232 message
= "writing ring-ref";
233 goto abort_transaction
;
236 rv
= xenbus_printf(xbt
, dev
->nodename
, "event-channel", "%u",
239 message
= "writing event-channel";
240 goto abort_transaction
;
243 rv
= xenbus_printf(xbt
, dev
->nodename
, "feature-protocol-v2", "1");
245 message
= "writing feature-protocol-v2";
246 goto abort_transaction
;
249 rv
= xenbus_transaction_end(xbt
, 0);
253 xenbus_dev_fatal(dev
, rv
, "completing transaction");
257 xenbus_switch_state(dev
, XenbusStateInitialised
);
262 xenbus_transaction_end(xbt
, 1);
264 xenbus_dev_error(dev
, rv
, "%s", message
);
269 static void ring_free(struct tpm_private
*priv
)
275 gnttab_end_foreign_access(priv
->ring_ref
, 0,
276 (unsigned long)priv
->shr
);
278 free_page((unsigned long)priv
->shr
);
280 if (priv
->chip
&& priv
->chip
->vendor
.irq
)
281 unbind_from_irqhandler(priv
->chip
->vendor
.irq
, priv
);
286 static int tpmfront_probe(struct xenbus_device
*dev
,
287 const struct xenbus_device_id
*id
)
289 struct tpm_private
*priv
;
290 struct tpm_chip
*chip
;
293 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
295 xenbus_dev_fatal(dev
, -ENOMEM
, "allocating priv structure");
299 rv
= setup_chip(&dev
->dev
, priv
);
305 rv
= setup_ring(dev
, priv
);
307 chip
= dev_get_drvdata(&dev
->dev
);
308 tpm_chip_unregister(chip
);
313 tpm_get_timeouts(priv
->chip
);
315 return tpm_chip_register(priv
->chip
);
318 static int tpmfront_remove(struct xenbus_device
*dev
)
320 struct tpm_chip
*chip
= dev_get_drvdata(&dev
->dev
);
321 struct tpm_private
*priv
= TPM_VPRIV(chip
);
322 tpm_chip_unregister(chip
);
324 TPM_VPRIV(chip
) = NULL
;
328 static int tpmfront_resume(struct xenbus_device
*dev
)
330 /* A suspend/resume/migrate will interrupt a vTPM anyway */
331 tpmfront_remove(dev
);
332 return tpmfront_probe(dev
, NULL
);
335 static void backend_changed(struct xenbus_device
*dev
,
336 enum xenbus_state backend_state
)
340 switch (backend_state
) {
341 case XenbusStateInitialised
:
342 case XenbusStateConnected
:
343 if (dev
->state
== XenbusStateConnected
)
346 if (xenbus_scanf(XBT_NIL
, dev
->otherend
,
347 "feature-protocol-v2", "%d", &val
) < 0)
350 xenbus_dev_fatal(dev
, -EINVAL
,
351 "vTPM protocol 2 required");
354 xenbus_switch_state(dev
, XenbusStateConnected
);
357 case XenbusStateClosing
:
358 case XenbusStateClosed
:
359 device_unregister(&dev
->dev
);
360 xenbus_frontend_closed(dev
);
367 static const struct xenbus_device_id tpmfront_ids
[] = {
371 MODULE_ALIAS("xen:vtpm");
373 static struct xenbus_driver tpmfront_driver
= {
375 .probe
= tpmfront_probe
,
376 .remove
= tpmfront_remove
,
377 .resume
= tpmfront_resume
,
378 .otherend_changed
= backend_changed
,
381 static int __init
xen_tpmfront_init(void)
386 if (!xen_has_pv_devices())
389 return xenbus_register_frontend(&tpmfront_driver
);
391 module_init(xen_tpmfront_init
);
393 static void __exit
xen_tpmfront_exit(void)
395 xenbus_unregister_driver(&tpmfront_driver
);
397 module_exit(xen_tpmfront_exit
);
399 MODULE_AUTHOR("Daniel De Graaf <dgdegra@tycho.nsa.gov>");
400 MODULE_DESCRIPTION("Xen vTPM Driver");
401 MODULE_LICENSE("GPL");