mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Clean up the TPM stack a bit.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This commit is contained in:
1 parent
e808fe9ad9
commit
96b9e930ec
5 files changed
+82
-73
No files matched your search
@@ -67,9 +67,6 @@ static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
|
||||
u32 count;
|
||||
unsigned long stop;
|
||||
|
||||
if (!chip)
|
||||
return -ENODEV;
|
||||
|
||||
count = be32_to_cpu(*((__be32 *) (buf + 2)));
|
||||
|
||||
if (count == 0)
|
||||
|
||||
@@ -42,7 +42,6 @@ struct transmission {
|
||||
unsigned int request_len;
|
||||
unsigned char *rcv_buffer;
|
||||
unsigned int buffersize;
|
||||
struct tpm_chip *chip;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
@@ -75,6 +74,8 @@ static struct data_exchange dataex;
|
||||
|
||||
static unsigned long disconnect_time;
|
||||
|
||||
static struct tpmfe_device tpmfe;
|
||||
|
||||
/* local function prototypes */
|
||||
static void __exit cleanup_xen(void);
|
||||
|
||||
@@ -119,7 +120,7 @@ transmission_free(struct transmission *t)
|
||||
static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
|
||||
{
|
||||
int ret_size = 0;
|
||||
struct transmission *t, *temp;
|
||||
struct transmission *t;
|
||||
|
||||
/*
|
||||
* The list with requests must contain one request
|
||||
@@ -127,8 +128,9 @@ static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
|
||||
* was passed to me from the front-end.
|
||||
*/
|
||||
if (dataex.current_request != ptr) {
|
||||
printk("WARNING: The request pointer is different than the pointer "
|
||||
"the shared memory driver returned to me. %p != %p\n",
|
||||
printk("WARNING: The request pointer is different than the "
|
||||
"pointer the shared memory driver returned to me. "
|
||||
"%p != %p\n",
|
||||
dataex.current_request, ptr);
|
||||
}
|
||||
|
||||
@@ -144,16 +146,16 @@ static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NULL != (temp = dataex.current_request)) {
|
||||
transmission_free(temp);
|
||||
if (NULL != (t = dataex.current_request)) {
|
||||
transmission_free(t);
|
||||
dataex.current_request = NULL;
|
||||
}
|
||||
|
||||
t = transmission_alloc();
|
||||
if (NULL != t) {
|
||||
if (t) {
|
||||
unsigned long flags;
|
||||
t->rcv_buffer = kmalloc(count, GFP_KERNEL);
|
||||
if (NULL == t->rcv_buffer) {
|
||||
if (! t->rcv_buffer) {
|
||||
transmission_free(t);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -258,10 +260,6 @@ static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
|
||||
|
||||
if (t != NULL) {
|
||||
unsigned int error = 0;
|
||||
t->rcv_buffer = NULL;
|
||||
t->buffersize = 0;
|
||||
t->chip = chip;
|
||||
|
||||
/*
|
||||
* Queue the packet if the driver below is not
|
||||
* ready, yet, or there is any packet already
|
||||
@@ -304,9 +302,11 @@ static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
|
||||
struct transmission *qt = (struct transmission *) dataex.queued_requests.next;
|
||||
list_del(&qt->next);
|
||||
dataex.current_request = qt;
|
||||
spin_unlock_irqrestore(&dataex.req_list_lock, flags);
|
||||
spin_unlock_irqrestore(&dataex.req_list_lock,
|
||||
flags);
|
||||
|
||||
rc = tpm_fe_send(qt->request,
|
||||
rc = tpm_fe_send(tpmfe.tpm_private,
|
||||
qt->request,
|
||||
qt->request_len,
|
||||
qt);
|
||||
|
||||
@@ -351,7 +351,8 @@ static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
|
||||
* amount of bytes in the request and
|
||||
* a void * pointer (here: transmission structure)
|
||||
*/
|
||||
rc = tpm_fe_send(buf, count, t);
|
||||
rc = tpm_fe_send(tpmfe.tpm_private,
|
||||
buf, count, t);
|
||||
/*
|
||||
* The generic TPM driver will call
|
||||
* the function to receive the response.
|
||||
@@ -373,7 +374,8 @@ queue_it:
|
||||
* queue it.
|
||||
*/
|
||||
dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
|
||||
list_add_tail(&t->next, &dataex.queued_requests);
|
||||
list_add_tail(&t->next,
|
||||
&dataex.queued_requests);
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
@@ -512,7 +514,7 @@ static void __exit cleanup_xen(void)
|
||||
tpm_fe_unregister_receiver();
|
||||
}
|
||||
|
||||
fs_initcall(init_xen);
|
||||
module_init(init_xen);
|
||||
module_exit(cleanup_xen);
|
||||
|
||||
MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
|
||||
|
||||
@@ -56,14 +56,14 @@
|
||||
|
||||
/* locally visible variables */
|
||||
static grant_ref_t gref_head;
|
||||
static struct tpm_private my_private;
|
||||
static struct tpm_private *my_priv;
|
||||
|
||||
/* local function prototypes */
|
||||
static irqreturn_t tpmif_int(int irq,
|
||||
void *tpm_priv,
|
||||
struct pt_regs *ptregs);
|
||||
static void tpmif_rx_action(unsigned long unused);
|
||||
static void tpmif_connect(u16 evtchn, domid_t domid);
|
||||
static void tpmif_connect(struct tpm_private *tp, domid_t domid);
|
||||
static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
|
||||
static int tpm_allocate_buffers(struct tpm_private *tp);
|
||||
static void tpmif_set_connected_state(struct tpm_private *tp,
|
||||
@@ -101,7 +101,7 @@ tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
|
||||
|
||||
static inline struct tx_buffer *tx_buffer_alloc(void)
|
||||
{
|
||||
struct tx_buffer *txb = kmalloc(sizeof (struct tx_buffer),
|
||||
struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (txb) {
|
||||
@@ -117,6 +117,31 @@ static inline struct tx_buffer *tx_buffer_alloc(void)
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Utility function for the tpm_private structure
|
||||
**************************************************************/
|
||||
static inline void tpm_private_init(struct tpm_private *tp)
|
||||
{
|
||||
spin_lock_init(&tp->tx_lock);
|
||||
init_waitqueue_head(&tp->wait_q);
|
||||
}
|
||||
|
||||
static struct tpm_private *tpm_private_get(void)
|
||||
{
|
||||
if (!my_priv) {
|
||||
my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
|
||||
if (my_priv) {
|
||||
tpm_private_init(my_priv);
|
||||
}
|
||||
}
|
||||
return my_priv;
|
||||
}
|
||||
|
||||
static inline void tpm_private_free(struct tpm_private *tp)
|
||||
{
|
||||
kfree(tp);
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
|
||||
The interface to let the tpm plugin register its callback
|
||||
@@ -131,10 +156,9 @@ static struct tpmfe_device *upperlayer_tpmfe;
|
||||
/*
|
||||
* Send data via this module by calling this function
|
||||
*/
|
||||
int tpm_fe_send(const u8 * buf, size_t count, void *ptr)
|
||||
int tpm_fe_send(struct tpm_private *tp, const u8 * buf, size_t count, void *ptr)
|
||||
{
|
||||
int sent = 0;
|
||||
struct tpm_private *tp = &my_private;
|
||||
|
||||
down(&suspend_lock);
|
||||
sent = tpm_xmit(tp, buf, count, 0, ptr);
|
||||
@@ -155,6 +179,7 @@ int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
|
||||
if (NULL == upperlayer_tpmfe) {
|
||||
upperlayer_tpmfe = tpmfe_dev;
|
||||
tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
|
||||
tpmfe_dev->tpm_private = tpm_private_get();
|
||||
} else {
|
||||
rc = -EBUSY;
|
||||
}
|
||||
@@ -197,10 +222,9 @@ static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
|
||||
**************************************************************/
|
||||
|
||||
static int setup_tpmring(struct xenbus_device *dev,
|
||||
struct tpmfront_info * info)
|
||||
struct tpm_private *tp)
|
||||
{
|
||||
tpmif_tx_interface_t *sring;
|
||||
struct tpm_private *tp = &my_private;
|
||||
int err;
|
||||
|
||||
sring = (void *)__get_free_page(GFP_KERNEL);
|
||||
@@ -219,13 +243,13 @@ static int setup_tpmring(struct xenbus_device *dev,
|
||||
xenbus_dev_fatal(dev, err, "allocating grant reference");
|
||||
goto fail;
|
||||
}
|
||||
info->ring_ref = err;
|
||||
tp->ring_ref = err;
|
||||
|
||||
err = xenbus_alloc_evtchn(dev, &tp->evtchn);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
tpmif_connect(tp->evtchn, dev->otherend_id);
|
||||
tpmif_connect(tp, dev->otherend_id);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
@@ -233,11 +257,11 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
|
||||
static void destroy_tpmring(struct tpm_private *tp)
|
||||
{
|
||||
tpmif_set_connected_state(tp, 0);
|
||||
if (tp->tx != NULL) {
|
||||
gnttab_end_foreign_access(info->ring_ref, 0,
|
||||
gnttab_end_foreign_access(tp->ring_ref, 0,
|
||||
(unsigned long)tp->tx);
|
||||
tp->tx = NULL;
|
||||
}
|
||||
@@ -249,13 +273,13 @@ static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
|
||||
|
||||
|
||||
static int talk_to_backend(struct xenbus_device *dev,
|
||||
struct tpmfront_info *info)
|
||||
struct tpm_private *tp)
|
||||
{
|
||||
const char *message = NULL;
|
||||
int err;
|
||||
xenbus_transaction_t xbt;
|
||||
|
||||
err = setup_tpmring(dev, info);
|
||||
err = setup_tpmring(dev, tp);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err, "setting up ring");
|
||||
goto out;
|
||||
@@ -269,14 +293,14 @@ again:
|
||||
}
|
||||
|
||||
err = xenbus_printf(xbt, dev->nodename,
|
||||
"ring-ref","%u", info->ring_ref);
|
||||
"ring-ref","%u", tp->ring_ref);
|
||||
if (err) {
|
||||
message = "writing ring-ref";
|
||||
goto abort_transaction;
|
||||
}
|
||||
|
||||
err = xenbus_printf(xbt, dev->nodename,
|
||||
"event-channel", "%u", my_private.evtchn);
|
||||
"event-channel", "%u", tp->evtchn);
|
||||
if (err) {
|
||||
message = "writing event-channel";
|
||||
goto abort_transaction;
|
||||
@@ -301,7 +325,7 @@ abort_transaction:
|
||||
if (message)
|
||||
xenbus_dev_error(dev, err, "%s", message);
|
||||
destroy_tpmring:
|
||||
destroy_tpmring(info, &my_private);
|
||||
destroy_tpmring(tp);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
@@ -312,7 +336,7 @@ out:
|
||||
static void backend_changed(struct xenbus_device *dev,
|
||||
XenbusState backend_state)
|
||||
{
|
||||
struct tpm_private *tp = &my_private;
|
||||
struct tpm_private *tp = dev->data;
|
||||
DPRINTK("\n");
|
||||
|
||||
switch (backend_state) {
|
||||
@@ -343,8 +367,8 @@ static int tpmfront_probe(struct xenbus_device *dev,
|
||||
const struct xenbus_device_id *id)
|
||||
{
|
||||
int err;
|
||||
struct tpmfront_info *info;
|
||||
int handle;
|
||||
struct tpm_private *tp = tpm_private_get();
|
||||
|
||||
err = xenbus_scanf(XBT_NULL, dev->nodename,
|
||||
"handle", "%i", &handle);
|
||||
@@ -356,20 +380,12 @@ static int tpmfront_probe(struct xenbus_device *dev,
|
||||
return err;
|
||||
}
|
||||
|
||||
info = kmalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info) {
|
||||
err = -ENOMEM;
|
||||
xenbus_dev_fatal(dev,err,"allocating info structure");
|
||||
return err;
|
||||
}
|
||||
memset(info, 0x0, sizeof(*info));
|
||||
tp->dev = dev;
|
||||
dev->data = tp;
|
||||
|
||||
info->dev = dev;
|
||||
dev->data = info;
|
||||
|
||||
err = talk_to_backend(dev, info);
|
||||
err = talk_to_backend(dev, tp);
|
||||
if (err) {
|
||||
kfree(info);
|
||||
tpm_private_free(tp);
|
||||
dev->data = NULL;
|
||||
return err;
|
||||
}
|
||||
@@ -379,18 +395,15 @@ static int tpmfront_probe(struct xenbus_device *dev,
|
||||
|
||||
static int tpmfront_remove(struct xenbus_device *dev)
|
||||
{
|
||||
struct tpmfront_info *info = dev->data;
|
||||
|
||||
destroy_tpmring(info, &my_private);
|
||||
|
||||
kfree(info);
|
||||
struct tpm_private *tp = dev->data;
|
||||
destroy_tpmring(tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tpmfront_suspend(struct xenbus_device *dev)
|
||||
{
|
||||
struct tpm_private *tp = &my_private;
|
||||
struct tpm_private *tp = dev->data;
|
||||
u32 ctr;
|
||||
|
||||
/* lock, so no app can send */
|
||||
@@ -420,17 +433,15 @@ tpmfront_suspend(struct xenbus_device *dev)
|
||||
static int
|
||||
tpmfront_resume(struct xenbus_device *dev)
|
||||
{
|
||||
struct tpmfront_info *info = dev->data;
|
||||
return talk_to_backend(dev, info);
|
||||
struct tpm_private *tp = dev->data;
|
||||
return talk_to_backend(dev, tp);
|
||||
}
|
||||
|
||||
static void
|
||||
tpmif_connect(u16 evtchn, domid_t domid)
|
||||
tpmif_connect(struct tpm_private *tp, domid_t domid)
|
||||
{
|
||||
int err;
|
||||
struct tpm_private *tp = &my_private;
|
||||
|
||||
tp->evtchn = evtchn;
|
||||
tp->backend_id = domid;
|
||||
|
||||
err = bind_evtchn_to_irqhandler(tp->evtchn,
|
||||
@@ -477,9 +488,9 @@ tpm_allocate_buffers(struct tpm_private *tp)
|
||||
}
|
||||
|
||||
static void
|
||||
tpmif_rx_action(unsigned long unused)
|
||||
tpmif_rx_action(unsigned long priv)
|
||||
{
|
||||
struct tpm_private *tp = &my_private;
|
||||
struct tpm_private *tp = (struct tpm_private *)priv;
|
||||
|
||||
int i = 0;
|
||||
unsigned int received;
|
||||
@@ -529,6 +540,7 @@ tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tp->tx_lock, flags);
|
||||
tpmif_rx_tasklet.data = (unsigned long)tp;
|
||||
tasklet_schedule(&tpmif_rx_tasklet);
|
||||
spin_unlock_irqrestore(&tp->tx_lock, flags);
|
||||
|
||||
@@ -678,12 +690,6 @@ tpmif_init(void)
|
||||
&gref_head ) < 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
/*
|
||||
* Only don't send the driver status when we are in the
|
||||
* INIT domain.
|
||||
*/
|
||||
spin_lock_init(&my_private.tx_lock);
|
||||
init_waitqueue_head(&my_private.wait_q);
|
||||
|
||||
init_tpm_xenbus();
|
||||
|
||||
|
||||
@@ -17,9 +17,6 @@ struct tpm_private {
|
||||
domid_t backend_id;
|
||||
wait_queue_head_t wait_q;
|
||||
|
||||
};
|
||||
|
||||
struct tpmfront_info {
|
||||
struct xenbus_device *dev;
|
||||
int ring_ref;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef TPM_FE_H
|
||||
#define TPM_FE_H
|
||||
|
||||
struct tpm_private;
|
||||
|
||||
struct tpmfe_device {
|
||||
/*
|
||||
* Let upper layer receive data from front-end
|
||||
@@ -19,6 +21,11 @@ struct tpmfe_device {
|
||||
* for allocation of buffers.
|
||||
*/
|
||||
unsigned int max_tx_size;
|
||||
/*
|
||||
* The following is a private structure of the underlying
|
||||
* driver. It's expected as first parameter in the send function.
|
||||
*/
|
||||
struct tpm_private *tpm_private;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -26,7 +33,7 @@ enum {
|
||||
TPMFE_STATUS_CONNECTED = 0x1
|
||||
};
|
||||
|
||||
int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
|
||||
int tpm_fe_send(struct tpm_private * tp, const u8 * buf, size_t count, void *ptr);
|
||||
int tpm_fe_register_receiver(struct tpmfe_device *);
|
||||
void tpm_fe_unregister_receiver(void);
|
||||
|
||||
|
||||