diff options
author | Olaf Hering <olaf@aepfle.de> | 2013-03-04 13:42:17 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-03-04 13:42:17 +0100 |
commit | d9fb28ae6d41c8201482948660e52889481830dd (patch) | |
tree | e210485bdbe76aaa9b6543ff6a198f0ccf7b368c /xen/common/trace.c | |
parent | c0704a8a90d3219cbbc607f5b83cd4f60371a47e (diff) | |
download | xen-d9fb28ae6d41c8201482948660e52889481830dd.tar.gz xen-d9fb28ae6d41c8201482948660e52889481830dd.tar.bz2 xen-d9fb28ae6d41c8201482948660e52889481830dd.zip |
xentrace: fix off-by-one in calculate_tbuf_size
Commit "xentrace: reduce trace buffer size to something mfn_offset can
reach" contains an off-by-one bug. max_mfn_offset needs to be reduced by
exactly the value of t_info_first_offset.
If the system has two cpus and the number of requested trace pages is
very large, the final number of trace pages + the offset will not fit
into a short. As a result the variable offset in alloc_trace_bufs() will
wrap while allocating buffers for the second cpu. Later
share_xen_page_with_privileged_guests() will be called with a wrong page
and the ASSERT in this function triggers. If the ASSERT is ignored by
running a non-dbg hypervisor the asserts in xentrace itself trigger
because "cons" is not aligned because the very last trace page for the
second cpu is a random mfn.
Thanks to Jan for the quick analysis.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
Diffstat (limited to 'xen/common/trace.c')
-rw-r--r-- | xen/common/trace.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/xen/common/trace.c b/xen/common/trace.c index 08e5b2024c..506c498985 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -133,7 +133,7 @@ static int calculate_tbuf_size(unsigned int pages, uint16_t t_info_first_offset) * The array of mfns for the highest cpu can start at the maximum value * mfn_offset can hold. So reduce the number of cpus and also the mfn_offset. */ - max_mfn_offset -= t_info_first_offset - 1; + max_mfn_offset -= t_info_first_offset; max_cpus--; if ( max_cpus ) max_mfn_offset /= max_cpus; |