diff options
author | George Dunlap <george.dunlap@eu.citrix.com> | 2012-04-12 14:01:27 +0100 |
---|---|---|
committer | George Dunlap <george.dunlap@eu.citrix.com> | 2012-04-12 14:01:27 +0100 |
commit | 2f9fd22f509da9ab5135c602892712bec07d8631 (patch) | |
tree | dc665f1b3049928651c221aebff87f45d507fedd | |
parent | 498d19e3a652470a1de4d5ebe9bdf3be3aa12375 (diff) | |
download | xen-2f9fd22f509da9ab5135c602892712bec07d8631.tar.gz xen-2f9fd22f509da9ab5135c602892712bec07d8631.tar.bz2 xen-2f9fd22f509da9ab5135c602892712bec07d8631.zip |
xen: Fix failure paths for xentrace
Problems this addresses:
* After the allocation of t_info fails, the path the code takes tries
to free t_info. Jump past that part instead.
* The failure code assumes that unused data is zero; but the structure
is never initialized. Zero the structure before using it.
* The t_info pages are shared with dom0 before we know that the whole
operation will succeed, and not un-shared afterwards. Don't share the
pages until we know the whole thing will succeed.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
-rw-r--r-- | xen/common/trace.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/xen/common/trace.c b/xen/common/trace.c index 58cbf39be9..cacaeb2656 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -187,13 +187,11 @@ static int alloc_trace_bufs(unsigned int pages) t_info = alloc_xenheap_pages(get_order_from_pages(t_info_pages), 0); if ( t_info == NULL ) - goto out_dealloc_t_info; + goto out_fail; - t_info_mfn_list = (uint32_t *)t_info; + memset(t_info, 0, t_info_pages*PAGE_SIZE); - for(i = 0; i < t_info_pages; i++) - share_xen_page_with_privileged_guests( - virt_to_page(t_info) + i, XENSHARE_readonly); + t_info_mfn_list = (uint32_t *)t_info; t_info->tbuf_size = pages; @@ -247,6 +245,11 @@ static int alloc_trace_bufs(unsigned int pages) } } + /* Finally, share the t_info page */ + for(i = 0; i < t_info_pages; i++) + share_xen_page_with_privileged_guests( + virt_to_page(t_info) + i, XENSHARE_readonly); + data_size = (pages * PAGE_SIZE - sizeof(struct t_buf)); t_buf_highwater = data_size >> 1; /* 50% high water */ opt_tbuf_size = pages; @@ -272,9 +275,9 @@ out_dealloc: free_xenheap_pages(mfn_to_virt(mfn), 0); } } -out_dealloc_t_info: free_xenheap_pages(t_info, get_order_from_pages(t_info_pages)); t_info = NULL; +out_fail: printk(XENLOG_WARNING "xentrace: allocation failed! Tracing disabled.\n"); return -ENOMEM; } |