diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-10-05 23:16:21 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-10-05 23:16:21 +0100 |
commit | f58fdb8d020c1b6cce3728986812cdd25eb016fe (patch) | |
tree | 86dfb0d0bf8be44fc7ecdec21d28d2216216d89c | |
parent | 10ac5cd887c5f16823728bd3571959dc0b5a68df (diff) | |
download | xen-f58fdb8d020c1b6cce3728986812cdd25eb016fe.tar.gz xen-f58fdb8d020c1b6cce3728986812cdd25eb016fe.tar.bz2 xen-f58fdb8d020c1b6cce3728986812cdd25eb016fe.zip |
[TPM] back: Allocate pages for foreign mappings individually rather than contiguously.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/tpmback/common.h | 8 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c | 37 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 14 |
3 files changed, 43 insertions, 16 deletions
diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h index 27b8fd283a..b209b4f583 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h @@ -46,11 +46,10 @@ typedef struct tpmif_st { atomic_t refcnt; struct backend_info *bi; - unsigned long mmap_vstart; grant_handle_t shmem_handle; grant_ref_t shmem_ref; - struct page *pagerange; + struct page **mmap_pages; char devname[20]; } tpmif_t; @@ -80,6 +79,9 @@ int vtpm_release_packets(tpmif_t * tpmif, int send_msgs); extern int num_frontends; -#define MMAP_VADDR(t,_req) ((t)->mmap_vstart + ((_req) * PAGE_SIZE)) +static inline unsigned long idx_to_kaddr(tpmif_t *t, unsigned int idx) +{ + return (unsigned long)pfn_to_kaddr(page_to_pfn(t->mmap_pages[idx])); +} #endif /* __TPMIF__BACKEND__COMMON_H__ */ diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c index 0105bd93bf..ce06f7ce58 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c @@ -23,10 +23,11 @@ LIST_HEAD(tpmif_list); static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi) { tpmif_t *tpmif; + int i; tpmif = kmem_cache_alloc(tpmif_cachep, GFP_KERNEL); if (!tpmif) - return ERR_PTR(-ENOMEM); + goto out_of_memory; memset(tpmif, 0, sizeof (*tpmif)); tpmif->domid = domid; @@ -35,22 +36,46 @@ static tpmif_t *alloc_tpmif(domid_t domid, struct backend_info *bi) snprintf(tpmif->devname, sizeof(tpmif->devname), "tpmif%d", domid); atomic_set(&tpmif->refcnt, 1); - tpmif->pagerange = balloon_alloc_empty_page_range(TPMIF_TX_RING_SIZE); - BUG_ON(tpmif->pagerange == NULL); - tpmif->mmap_vstart = (unsigned long)pfn_to_kaddr( - page_to_pfn(tpmif->pagerange)); + tpmif->mmap_pages = kmalloc(sizeof(tpmif->mmap_pages[0]) + * TPMIF_TX_RING_SIZE, GFP_KERNEL); + if (tpmif->mmap_pages == NULL) + goto out_of_memory; + + for (i = 0; i < TPMIF_TX_RING_SIZE; i++) { + tpmif->mmap_pages[i] = balloon_alloc_empty_page(); + if (tpmif->mmap_pages[i] == NULL) { + while (--i >= 0) + balloon_free_empty_page(tpmif->mmap_pages[i]); + goto out_of_memory; + } + } list_add(&tpmif->tpmif_list, &tpmif_list); num_frontends++; return tpmif; + + out_of_memory: + if (tpmif != NULL) { + kfree(tpmif->mmap_pages); + kmem_cache_free(tpmif_cachep, tpmif); + } + printk("%s: out of memory\n", __FUNCTION__); + return ERR_PTR(-ENOMEM); } static void free_tpmif(tpmif_t * tpmif) { + int i; + num_frontends--; + list_del(&tpmif->tpmif_list); - balloon_dealloc_empty_page_range(tpmif->pagerange, TPMIF_TX_RING_SIZE); + + for (i = 0; i < TPMIF_TX_RING_SIZE; i++) + balloon_free_empty_page(tpmif->mmap_pages[i]); + kfree(tpmif->mmap_pages); + kmem_cache_free(tpmif_cachep, tpmif); } diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c index 466c3ee581..701a5ad03e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c @@ -253,7 +253,7 @@ int _packet_write(struct packet *pak, return 0; } - gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i), + gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, tx->ref, tpmif->domid); if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, @@ -270,7 +270,7 @@ int _packet_write(struct packet *pak, tocopy = min_t(size_t, size - offset, PAGE_SIZE); - if (copy_from_buffer((void *)(MMAP_VADDR(tpmif, i) | + if (copy_from_buffer((void *)(idx_to_kaddr(tpmif, i) | (tx->addr & ~PAGE_MASK)), &data[offset], tocopy, isuserbuffer)) { tpmif_put(tpmif); @@ -278,7 +278,7 @@ int _packet_write(struct packet *pak, } tx->size = tocopy; - gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i), + gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, handle); if (unlikely @@ -391,7 +391,7 @@ static int packet_read_shmem(struct packet *pak, tx = &tpmif->tx->ring[i].req; - gnttab_set_map_op(&map_op, MMAP_VADDR(tpmif, i), + gnttab_set_map_op(&map_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, tx->ref, tpmif->domid); if (unlikely(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, @@ -414,10 +414,10 @@ static int packet_read_shmem(struct packet *pak, } DPRINTK("Copying from mapped memory at %08lx\n", - (unsigned long)(MMAP_VADDR(tpmif, i) | + (unsigned long)(idx_to_kaddr(tpmif, i) | (tx->addr & ~PAGE_MASK))); - src = (void *)(MMAP_VADDR(tpmif, i) | + src = (void *)(idx_to_kaddr(tpmif, i) | ((tx->addr & ~PAGE_MASK) + pg_offset)); if (copy_to_buffer(&buffer[offset], src, to_copy, isuserbuffer)) { @@ -428,7 +428,7 @@ static int packet_read_shmem(struct packet *pak, tpmif->domid, buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]); - gnttab_set_unmap_op(&unmap_op, MMAP_VADDR(tpmif, i), + gnttab_set_unmap_op(&unmap_op, idx_to_kaddr(tpmif, i), GNTMAP_host_map, handle); if (unlikely |