diff --git a/xen-unstable.xentrace.dynamic_tbuf.patch b/23050-xentrace_dynamic_tracebuffer_allocation.patch similarity index 98% rename from xen-unstable.xentrace.dynamic_tbuf.patch rename to 23050-xentrace_dynamic_tracebuffer_allocation.patch index 0404917..0f7971b 100644 --- a/xen-unstable.xentrace.dynamic_tbuf.patch +++ b/23050-xentrace_dynamic_tracebuffer_allocation.patch @@ -1,21 +1,21 @@ +changeset: 23050:4ebba54b666f +user: Olaf Hering +date: Thu Mar 17 13:29:01 2011 +0000 +files: xen/common/trace.c +description: xentrace: dynamic tracebuffer allocation -(xen-unstable changeset 23050:4ebba54b666f) - Allocate tracebuffers dynamically, based on the requested buffer size. Calculate t_info_size from requested t_buf size. Fix allocation failure path, free pages outside the spinlock. -Remove casts for rawbuf, it can be a void pointer since no math is done. +Remove casts for rawbuf, it can be a void pointer since no math is +done. Signed-off-by: Olaf Hering +Acked-by: George Dunlap + --- -v3: - add comments to calculate_tbuf_size for side effects and max value -v2: - if per_cpu allocation fails, free also t_info to allow a retry with a - smaller tbuf_size - xen/common/trace.c | 249 ++++++++++++++++++++++------------------------------- 1 file changed, 104 insertions(+), 145 deletions(-) diff --git a/xen-unstable.xentrace.empty_t_info_pages.patch b/23091-xentrace_fix_t_info_pages_calculation..patch similarity index 57% rename from xen-unstable.xentrace.empty_t_info_pages.patch rename to 23091-xentrace_fix_t_info_pages_calculation..patch index f15e487..55f31bc 100644 --- a/xen-unstable.xentrace.empty_t_info_pages.patch +++ b/23091-xentrace_fix_t_info_pages_calculation..patch @@ -1,32 +1,30 @@ -xentrace: fix t_info_pages calculation for the default case - -(xen-unstable changeset 23091:67632e5cf652) - -The default tracebuffer size of 32 pages was not tested with the previous patch. -As a result, t_info_pages will become zero and alloc_xenheap_pages() fails. -Catch this case and allocate at least one page. +changeset: 23091:67632e5cf652 +user: Olaf Hering +date: Fri Mar 25 08:56:33 2011 +0000 +files: xen/common/trace.c +description: +xentrace: fix t_info_pages calculation. Signed-off-by: Olaf Hering ---- - xen/common/trace.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - +--- + xen/common/trace.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -33,6 +33,8 @@ +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include #include #include - -+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -+ - #ifdef CONFIG_COMPAT - #include - #define xen_t_buf t_buf -@@ -109,6 +111,7 @@ static int calculate_tbuf_size(unsigned +@@ -109,6 +110,7 @@ static int calculate_tbuf_size(unsigned { struct t_buf dummy; typeof(dummy.prod) size; @@ -34,7 +32,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c /* force maximum value for an unsigned type */ size = -1; -@@ -122,11 +125,9 @@ static int calculate_tbuf_size(unsigned +@@ -122,11 +124,9 @@ static int calculate_tbuf_size(unsigned pages = size; } diff --git a/xen-unstable.xentrace.verbose.patch b/23092-xentrace_print_calculated_numbers_in_calculate_tbuf_size.patch similarity index 78% rename from xen-unstable.xentrace.verbose.patch rename to 23092-xentrace_print_calculated_numbers_in_calculate_tbuf_size.patch index 26e1962..e16980d 100644 --- a/xen-unstable.xentrace.verbose.patch +++ b/23092-xentrace_print_calculated_numbers_in_calculate_tbuf_size.patch @@ -1,12 +1,16 @@ +changeset: 23092:45dafa422812 +user: Olaf Hering +date: Fri Mar 25 08:57:28 2011 +0000 +files: xen/common/trace.c +description: xentrace: print calculated numbers in calculate_tbuf_size() -(xen-unstable changeset 23092:45dafa422812) - Print number of pages to allocate for per-cpu tracebuffer and metadata to ease debugging when allocation fails. Signed-off-by: Olaf Hering + --- xen/common/trace.c | 2 ++ 1 file changed, 2 insertions(+) @@ -15,7 +19,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -128,6 +128,8 @@ static int calculate_tbuf_size(unsigned +@@ -127,6 +127,8 @@ static int calculate_tbuf_size(unsigned t_info_words = num_online_cpus() * pages + t_info_first_offset; t_info_bytes = t_info_words * sizeof(uint32_t); t_info_pages = PFN_UP(t_info_bytes); diff --git a/xen-unstable.xentrace.no_gdprintk.patch b/23093-xentrace_remove_gdprintk_usage_since_they_are_not_in_guest_context.patch similarity index 79% rename from xen-unstable.xentrace.no_gdprintk.patch rename to 23093-xentrace_remove_gdprintk_usage_since_they_are_not_in_guest_context.patch index 5297809..3b1195d 100644 --- a/xen-unstable.xentrace.no_gdprintk.patch +++ b/23093-xentrace_remove_gdprintk_usage_since_they_are_not_in_guest_context.patch @@ -1,9 +1,13 @@ +changeset: 23093:4b784605b089 +user: Olaf Hering +date: Fri Mar 25 08:57:47 2011 +0000 +files: xen/common/trace.c +description: xentrace: remove gdprintk usage since they are not in guest context -(xen-unstable changeset 23093:4b784605b089) - Signed-off-by: Olaf Hering + --- xen/common/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) @@ -12,7 +16,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -120,7 +120,7 @@ static int calculate_tbuf_size(unsigned +@@ -119,7 +119,7 @@ static int calculate_tbuf_size(unsigned size /= PAGE_SIZE; if ( pages > size ) { @@ -21,7 +25,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c __func__, pages, (unsigned int)size); pages = size; } -@@ -266,7 +266,7 @@ static int tb_set_size(unsigned int page +@@ -265,7 +265,7 @@ static int tb_set_size(unsigned int page */ if ( opt_tbuf_size && pages != opt_tbuf_size ) { @@ -30,7 +34,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c opt_tbuf_size, pages); return -EINVAL; } -@@ -311,7 +311,7 @@ void __init init_trace_bufs(void) +@@ -310,7 +310,7 @@ void __init init_trace_bufs(void) { if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) ) { diff --git a/xen-unstable.xentrace.comments.patch b/23094-xentrace_update_comments.patch similarity index 79% rename from xen-unstable.xentrace.comments.patch rename to 23094-xentrace_update_comments.patch index a2ce174..517b921 100644 --- a/xen-unstable.xentrace.comments.patch +++ b/23094-xentrace_update_comments.patch @@ -1,11 +1,15 @@ +changeset: 23094:d09e8885bc82 +user: Olaf Hering +date: Fri Mar 25 08:58:04 2011 +0000 +files: xen/common/trace.c +description: xentrace: update comments -(xen-unstable changeset 23094:d09e8885bc82) - Fix a typo, remove redundant comment. Signed-off-by: Olaf Hering + --- xen/common/trace.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) @@ -14,7 +18,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -197,12 +197,11 @@ static int alloc_trace_bufs(unsigned int +@@ -196,12 +196,11 @@ static int alloc_trace_bufs(unsigned int t_info->tbuf_size = pages; /* diff --git a/xen-unstable.xentrace.printk_prefix.patch b/23095-xentrace_use_consistent_printk_prefix.patch similarity index 85% rename from xen-unstable.xentrace.printk_prefix.patch rename to 23095-xentrace_use_consistent_printk_prefix.patch index 905ff87..a89677e 100644 --- a/xen-unstable.xentrace.printk_prefix.patch +++ b/23095-xentrace_use_consistent_printk_prefix.patch @@ -1,9 +1,13 @@ +changeset: 23095:941119d58655 +user: Olaf Hering +date: Fri Mar 25 09:01:37 2011 +0000 +files: xen/common/trace.c +description: xentrace: use consistent printk prefix -(xen-unstable changeset 23095:941119d58655) - Signed-off-by: Olaf Hering + --- xen/common/trace.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) @@ -12,7 +16,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -120,16 +120,18 @@ static int calculate_tbuf_size(unsigned +@@ -119,16 +119,18 @@ static int calculate_tbuf_size(unsigned size /= PAGE_SIZE; if ( pages > size ) { @@ -35,7 +39,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c return pages; } -@@ -178,7 +180,8 @@ static int alloc_trace_bufs(unsigned int +@@ -177,7 +179,8 @@ static int alloc_trace_bufs(unsigned int if ( (rawbuf = alloc_xenheap_pages( order, MEMF_bits(32 + PAGE_SHIFT))) == NULL ) { @@ -45,7 +49,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c goto out_dealloc; } -@@ -213,7 +216,7 @@ static int alloc_trace_bufs(unsigned int +@@ -212,7 +215,7 @@ static int alloc_trace_bufs(unsigned int t_info_mfn_list[offset + i]=mfn + i; } t_info->mfn_offset[cpu]=offset; @@ -54,7 +58,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c cpu, mfn, offset); offset+=i; -@@ -226,7 +229,7 @@ static int alloc_trace_bufs(unsigned int +@@ -225,7 +228,7 @@ static int alloc_trace_bufs(unsigned int register_cpu_notifier(&cpu_nfb); @@ -63,7 +67,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c wmb(); /* above must be visible before tb_init_done flag set */ tb_init_done = 1; -@@ -237,7 +240,7 @@ out_dealloc: +@@ -236,7 +239,7 @@ out_dealloc: { void *rawbuf = per_cpu(t_bufs, cpu); per_cpu(t_bufs, cpu) = NULL; @@ -72,7 +76,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c if ( rawbuf ) { ASSERT(!(virt_to_page(rawbuf)->count_info & PGC_allocated)); -@@ -246,7 +249,7 @@ out_dealloc: +@@ -245,7 +248,7 @@ out_dealloc: } free_xenheap_pages(t_info, get_order_from_pages(t_info_pages)); t_info = NULL; @@ -81,7 +85,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c return -ENOMEM; } -@@ -265,8 +268,9 @@ static int tb_set_size(unsigned int page +@@ -264,8 +267,9 @@ static int tb_set_size(unsigned int page */ if ( opt_tbuf_size && pages != opt_tbuf_size ) { @@ -93,7 +97,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c return -EINVAL; } -@@ -310,9 +314,8 @@ void __init init_trace_bufs(void) +@@ -309,9 +313,8 @@ void __init init_trace_bufs(void) { if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) ) { diff --git a/xen-unstable.xentrace.t_info_pages-formula.patch b/23128-xentrace_correct_formula_to_calculate_t_info_pages.patch similarity index 76% rename from xen-unstable.xentrace.t_info_pages-formula.patch rename to 23128-xentrace_correct_formula_to_calculate_t_info_pages.patch index c94f4ff..417442b 100644 --- a/xen-unstable.xentrace.t_info_pages-formula.patch +++ b/23128-xentrace_correct_formula_to_calculate_t_info_pages.patch @@ -1,13 +1,18 @@ +changeset: 23128:4a335f1000ea +user: Olaf Hering +date: Sat Apr 02 15:50:19 2011 +0100 +files: xen/common/trace.c +description: xentrace: correct formula to calculate t_info_pages -(xen-unstable changeset 23128:4a335f1000ea) - The current formula to calculate t_info_pages, based on the initial code, is slightly incorrect. It may allocate more than needed. Each cpu has some pages/mfns stored as uint32_t. -That list is stored with an offset at tinfo. +That list is stored with an offset at tinfo. Signed-off-by: Olaf Hering +Acked-by: George Dunlap + --- xen/common/trace.c | 7 +++---- @@ -17,7 +22,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -111,7 +111,7 @@ static int calculate_tbuf_size(unsigned +@@ -110,7 +110,7 @@ static int calculate_tbuf_size(unsigned { struct t_buf dummy; typeof(dummy.prod) size; @@ -26,7 +31,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c /* force maximum value for an unsigned type */ size = -1; -@@ -126,9 +126,8 @@ static int calculate_tbuf_size(unsigned +@@ -125,9 +125,8 @@ static int calculate_tbuf_size(unsigned pages = size; } diff --git a/xen-unstable.xentrace.remove_debug_printk.patch b/23129-xentrace_remove_unneeded_debug_printk.patch similarity index 65% rename from xen-unstable.xentrace.remove_debug_printk.patch rename to 23129-xentrace_remove_unneeded_debug_printk.patch index 74647c7..69ac2b6 100644 --- a/xen-unstable.xentrace.remove_debug_printk.patch +++ b/23129-xentrace_remove_unneeded_debug_printk.patch @@ -1,10 +1,16 @@ +changeset: 23129:219ba19aedeb +user: Olaf Hering +date: Sat Apr 02 15:50:47 2011 +0100 +files: xen/common/trace.c +description: xentrace: remove unneeded debug printk -(xen-unstable changeset 23129:219ba19aedeb) - -The pointer value in case of an allocation failure is rather uninteresting. +The pointer value in case of an allocation failure is rather +uninteresting. Signed-off-by: Olaf Hering +Acked-by: George Dunlap + --- xen/common/trace.c | 1 - @@ -14,7 +20,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -240,7 +240,6 @@ out_dealloc: +@@ -238,7 +238,6 @@ out_dealloc: { void *rawbuf = per_cpu(t_bufs, cpu); per_cpu(t_bufs, cpu) = NULL; diff --git a/xen-unstable.xentrace.register_cpu_notifier-boot_time.patch b/23173-xentrace_Move_register_cpu_notifier_call_into_boot-time_init..patch similarity index 78% rename from xen-unstable.xentrace.register_cpu_notifier-boot_time.patch rename to 23173-xentrace_Move_register_cpu_notifier_call_into_boot-time_init..patch index 667feb7..8ee85df 100644 --- a/xen-unstable.xentrace.register_cpu_notifier-boot_time.patch +++ b/23173-xentrace_Move_register_cpu_notifier_call_into_boot-time_init..patch @@ -1,12 +1,16 @@ +changeset: 23173:94cef9aaf0cd +user: Keir Fraser +date: Wed Apr 06 15:52:50 2011 +0100 +files: xen/common/trace.c +description: xentrace: Move register_cpu_notifier() call into boot-time init. -(xen-unstable changeset 23173:94cef9aaf0cd) - We can't do it lazily from alloc_trace_bufs() as that gets called later if tracing is enabled later by dom0. Signed-off-by: Keir Fraser + --- xen/common/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) @@ -15,7 +19,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -226,8 +226,6 @@ static int alloc_trace_bufs(unsigned int +@@ -225,8 +225,6 @@ static int alloc_trace_bufs(unsigned int t_buf_highwater = data_size >> 1; /* 50% high water */ opt_tbuf_size = pages; @@ -24,7 +28,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c printk("xentrace: initialised\n"); wmb(); /* above must be visible before tb_init_done flag set */ tb_init_done = 1; -@@ -310,6 +308,8 @@ int trace_will_trace_event(u32 event) +@@ -309,6 +307,8 @@ int trace_will_trace_event(u32 event) */ void __init init_trace_bufs(void) { diff --git a/xen-unstable.xentrace.t_info_page-overflow.patch b/23239-xentrace_correct_overflow_check_for_number_of_per-cpu_trace_pages.patch similarity index 73% rename from xen-unstable.xentrace.t_info_page-overflow.patch rename to 23239-xentrace_correct_overflow_check_for_number_of_per-cpu_trace_pages.patch index e57b612..f06ed2e 100644 --- a/xen-unstable.xentrace.t_info_page-overflow.patch +++ b/23239-xentrace_correct_overflow_check_for_number_of_per-cpu_trace_pages.patch @@ -1,18 +1,22 @@ +changeset: 23239:51d89366c859 +user: Olaf Hering +date: Mon Apr 18 15:12:04 2011 +0100 +files: xen/common/trace.c +description: xentrace: correct overflow check for number of per-cpu trace pages -(xen-unstable changeset 23239:51d89366c859) - The calculated number of per-cpu trace pages is stored in t_info and -shared with tools like xentrace. Since its an u16 the value may overflow -because the current check is based on u32. -Using the u16 means each cpu could in theory use up to 256MB as trace +shared with tools like xentrace. Since its an u16 the value may +overflow because the current check is based on u32. Using the u16 +means each cpu could in theory use up to 256MB as trace buffer. However such a large allocation will currently fail on x86 due -to the MAX_ORDER limit. -Check both max theoretical number of pages per cpu and max number of -pages reachable by struct t_buf->prod/cons variables with requested -number of pages. +to the MAX_ORDER limit. Check both max theoretical number of pages +per cpu and max number of pages reachable by struct t_buf->prod/cons +variables with requested number of pages. Signed-off-by: Olaf Hering +Acked-by: George Dunlap + --- xen/common/trace.c | 22 +++++++++++++++------- @@ -22,7 +26,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -105,25 +105,33 @@ static void calc_tinfo_first_offset(void +@@ -104,25 +104,33 @@ static void calc_tinfo_first_offset(void * calculate_tbuf_size - check to make sure that the proposed size will fit * in the currently sized struct t_info and allows prod and cons to * reach double the value without overflow. diff --git a/xen-unstable.xentrace.t_info_first_offset.patch b/23308-xentrace_Move_the_global_variable_t_info_first_offset_into_calculate_tbuf_size.patch similarity index 82% rename from xen-unstable.xentrace.t_info_first_offset.patch rename to 23308-xentrace_Move_the_global_variable_t_info_first_offset_into_calculate_tbuf_size.patch index 769ca89..ac398a1 100644 --- a/xen-unstable.xentrace.t_info_first_offset.patch +++ b/23308-xentrace_Move_the_global_variable_t_info_first_offset_into_calculate_tbuf_size.patch @@ -1,13 +1,17 @@ +changeset: 23308:fb5313e64335 +user: Olaf Hering +date: Mon May 09 09:58:36 2011 +0100 +files: xen/common/trace.c +description: xentrace: Move the global variable t_info_first_offset into calculate_tbuf_size() -(xen-unstable changeset 23308:fb5313e64335) - Move the global variable t_info_first_offset into calculate_tbuf_size() because it is only used there. Change the type from u32 to uint32_t to match type in other places. Signed-off-by: Olaf Hering + --- xen/common/trace.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) @@ -16,7 +20,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -56,7 +56,6 @@ static DEFINE_PER_CPU_READ_MOSTLY(struct +@@ -55,7 +55,6 @@ static DEFINE_PER_CPU_READ_MOSTLY(struct static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data); static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock); static u32 data_size; @@ -24,7 +28,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c /* High water mark for trace buffers; */ /* Send virtual interrupt when buffer level reaches this point */ -@@ -95,10 +94,10 @@ static struct notifier_block cpu_nfb = { +@@ -94,10 +93,10 @@ static struct notifier_block cpu_nfb = { .notifier_call = cpu_callback }; @@ -37,7 +41,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c } /** -@@ -108,7 +107,7 @@ static void calc_tinfo_first_offset(void +@@ -107,7 +106,7 @@ static void calc_tinfo_first_offset(void * The t_info layout is fixed and cant be changed without breaking xentrace. * Initialize t_info_pages based on number of trace pages. */ @@ -46,7 +50,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c { struct t_buf dummy_size; typeof(dummy_size.prod) max_size; -@@ -157,6 +156,7 @@ static int alloc_trace_bufs(unsigned int +@@ -156,6 +155,7 @@ static int alloc_trace_bufs(unsigned int int i, cpu, order; /* Start after a fixed-size array of NR_CPUS */ uint32_t *t_info_mfn_list; @@ -54,7 +58,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c int offset; if ( t_info ) -@@ -166,9 +166,9 @@ static int alloc_trace_bufs(unsigned int +@@ -165,9 +165,9 @@ static int alloc_trace_bufs(unsigned int return -EINVAL; /* Calculate offset in u32 of first mfn */ diff --git a/xen-unstable.xentrace.data_size__read_mostly.patch b/23309-xentrace_Mark_data_size___read_mostly_because_its_only_written_once.patch similarity index 77% rename from xen-unstable.xentrace.data_size__read_mostly.patch rename to 23309-xentrace_Mark_data_size___read_mostly_because_its_only_written_once.patch index 6acf6e7..75720f5 100644 --- a/xen-unstable.xentrace.data_size__read_mostly.patch +++ b/23309-xentrace_Mark_data_size___read_mostly_because_its_only_written_once.patch @@ -1,9 +1,13 @@ +changeset: 23309:0ddcc8063690 +user: Olaf Hering +date: Mon May 09 09:59:13 2011 +0100 +files: xen/common/trace.c +description: xentrace: Mark data_size __read_mostly because it's only written once -(xen-unstable changeset: 23309:0ddcc8063690) - Signed-off-by: Olaf Hering + --- xen/common/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) @@ -12,7 +16,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -55,7 +55,7 @@ static unsigned int t_info_pages; +@@ -54,7 +54,7 @@ static unsigned int t_info_pages; static DEFINE_PER_CPU_READ_MOSTLY(struct t_buf *, t_bufs); static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data); static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock); diff --git a/xen-unstable.xentrace.__insert_record-dst-type.patch b/23310-xentrace_Remove_unneeded_cast_when_assigning_pointer_value_to_dst.patch similarity index 81% rename from xen-unstable.xentrace.__insert_record-dst-type.patch rename to 23310-xentrace_Remove_unneeded_cast_when_assigning_pointer_value_to_dst.patch index 7725309..08d5bf0 100644 --- a/xen-unstable.xentrace.__insert_record-dst-type.patch +++ b/23310-xentrace_Remove_unneeded_cast_when_assigning_pointer_value_to_dst.patch @@ -1,12 +1,16 @@ +changeset: 23310:b7ca55907bd3 +user: Olaf Hering +date: Mon May 09 09:59:50 2011 +0100 +files: xen/common/trace.c +description: xentrace: Remove unneeded cast when assigning pointer value to dst -(xen-unstable changeset: 23310:b7ca55907bd3) - Remove unneeded cast when assigning pointer value to dst. Both arrays are uint32_t and memcpy takes a void pointer. Signed-off-by: Olaf Hering + --- xen/common/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) @@ -15,7 +19,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c =================================================================== --- xen-4.1.2-testing.orig/xen/common/trace.c +++ xen-4.1.2-testing/xen/common/trace.c -@@ -484,7 +484,7 @@ static inline void __insert_record(struc +@@ -483,7 +483,7 @@ static inline void __insert_record(struc const void *extra_data) { struct t_rec *rec; @@ -24,7 +28,7 @@ Index: xen-4.1.2-testing/xen/common/trace.c unsigned int extra_word = extra / sizeof(u32); unsigned int local_rec_size = calc_rec_size(cycles, extra); uint32_t next; -@@ -509,13 +509,13 @@ static inline void __insert_record(struc +@@ -508,13 +508,13 @@ static inline void __insert_record(struc rec->event = event; rec->extra_u32 = extra_word; diff --git a/23404-xentrace_reduce_trace_buffer_size_to_something_mfn_offset_can_reach.patch b/23404-xentrace_reduce_trace_buffer_size_to_something_mfn_offset_can_reach.patch new file mode 100644 index 0000000..3a5c848 --- /dev/null +++ b/23404-xentrace_reduce_trace_buffer_size_to_something_mfn_offset_can_reach.patch @@ -0,0 +1,61 @@ +changeset: 23404:dd0eb070ee44 +user: Olaf Hering +date: Thu May 26 12:34:44 2011 +0100 +files: xen/common/trace.c +description: +xentrace: reduce trace buffer size to something mfn_offset can reach + +The start of the array which holds the list of mfns for each cpus +tracebuffer is stored in an unsigned short. This limits the total +amount of pages for each cpu as the number of active cpus increases. + +Update the math in calculate_tbuf_size() to apply also this rule to +the max number of trace pages. Without this change the index can +overflow. + +Signed-off-by: Olaf Hering +Acked-by: George Dunlap + + +--- + xen/common/trace.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +Index: xen-4.1.2-testing/xen/common/trace.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/trace.c ++++ xen-4.1.2-testing/xen/common/trace.c +@@ -112,11 +112,14 @@ static int calculate_tbuf_size(unsigned + typeof(dummy_size.prod) max_size; + struct t_info dummy_pages; + typeof(dummy_pages.tbuf_size) max_pages; ++ typeof(dummy_pages.mfn_offset[0]) max_mfn_offset; ++ unsigned int max_cpus = num_online_cpus(); + unsigned int t_info_words; + + /* force maximum value for an unsigned type */ + max_size = -1; + max_pages = -1; ++ max_mfn_offset = -1; + + /* max size holds up to n pages */ + max_size /= PAGE_SIZE; +@@ -124,6 +127,18 @@ static int calculate_tbuf_size(unsigned + if ( max_size < max_pages ) + max_pages = max_size; + ++ /* ++ * max mfn_offset holds up to n pages per cpu ++ * 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_cpus--; ++ if ( max_cpus ) ++ max_mfn_offset /= max_cpus; ++ if ( max_mfn_offset < max_pages ) ++ max_pages = max_mfn_offset; ++ + if ( pages > max_pages ) + { + printk(XENLOG_INFO "xentrace: requested number of %u pages " diff --git a/23405-xentrace_fix_type_of_offset_to_avoid_ouf-of-bounds_access.patch b/23405-xentrace_fix_type_of_offset_to_avoid_ouf-of-bounds_access.patch new file mode 100644 index 0000000..08d4c8d --- /dev/null +++ b/23405-xentrace_fix_type_of_offset_to_avoid_ouf-of-bounds_access.patch @@ -0,0 +1,52 @@ +changeset: 23405:3057b531d905 +user: Olaf Hering +date: Thu May 26 12:35:30 2011 +0100 +files: xen/common/trace.c +description: +xentrace: fix type of offset to avoid ouf-of-bounds access + +Update the type of the local offset variable to match the type where +this variable is stored. Also update the type of t_info_first_offset +because it has also a limited range. + +Signed-off-by: Olaf Hering +Acked-by: George Dunlap + + +--- + xen/common/trace.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +Index: xen-4.1.2-testing/xen/common/trace.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/trace.c ++++ xen-4.1.2-testing/xen/common/trace.c +@@ -106,7 +106,7 @@ static uint32_t calc_tinfo_first_offset( + * The t_info layout is fixed and cant be changed without breaking xentrace. + * Initialize t_info_pages based on number of trace pages. + */ +-static int calculate_tbuf_size(unsigned int pages, uint32_t t_info_first_offset) ++static int calculate_tbuf_size(unsigned int pages, uint16_t t_info_first_offset) + { + struct t_buf dummy_size; + typeof(dummy_size.prod) max_size; +@@ -170,8 +170,8 @@ static int alloc_trace_bufs(unsigned int + int i, cpu, order; + /* Start after a fixed-size array of NR_CPUS */ + uint32_t *t_info_mfn_list; +- uint32_t t_info_first_offset; +- int offset; ++ uint16_t t_info_first_offset; ++ uint16_t offset; + + if ( t_info ) + return -EBUSY; +@@ -179,7 +179,7 @@ static int alloc_trace_bufs(unsigned int + if ( pages == 0 ) + return -EINVAL; + +- /* Calculate offset in u32 of first mfn */ ++ /* Calculate offset in units of u32 of first mfn */ + t_info_first_offset = calc_tinfo_first_offset(); + + pages = calculate_tbuf_size(pages, t_info_first_offset); diff --git a/23406-xentrace_update___insert_record_to_copy_the_trace_record_to_individual_mfns.patch b/23406-xentrace_update___insert_record_to_copy_the_trace_record_to_individual_mfns.patch new file mode 100644 index 0000000..05a526c --- /dev/null +++ b/23406-xentrace_update___insert_record_to_copy_the_trace_record_to_individual_mfns.patch @@ -0,0 +1,153 @@ +changeset: 23406:956438803307 +user: Olaf Hering +date: Thu May 26 12:36:03 2011 +0100 +files: xen/common/trace.c +description: +xentrace: update __insert_record() to copy the trace record to individual mfns + +Update __insert_record() to copy the trace record to individual mfns. +This is a prereq before changing the per-cpu allocation from +contiguous to non-contiguous allocation. + +v2: + update offset calculation to use shift and mask + update type of mfn_offset to match type of data source + +Signed-off-by: Olaf Hering +Acked-by: George Dunlap + + +--- + xen/common/trace.c | 71 +++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 55 insertions(+), 16 deletions(-) + +Index: xen-4.1.2-testing/xen/common/trace.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/trace.c ++++ xen-4.1.2-testing/xen/common/trace.c +@@ -52,7 +52,6 @@ static struct t_info *t_info; + static unsigned int t_info_pages; + + static DEFINE_PER_CPU_READ_MOSTLY(struct t_buf *, t_bufs); +-static DEFINE_PER_CPU_READ_MOSTLY(unsigned char *, t_data); + static DEFINE_PER_CPU_READ_MOSTLY(spinlock_t, t_lock); + static u32 data_size __read_mostly; + +@@ -208,7 +207,6 @@ static int alloc_trace_bufs(unsigned int + + per_cpu(t_bufs, cpu) = buf = rawbuf; + buf->cons = buf->prod = 0; +- per_cpu(t_data, cpu) = (unsigned char *)(buf + 1); + } + + offset = t_info_first_offset; +@@ -472,10 +470,16 @@ static inline u32 calc_bytes_avail(const + return data_size - calc_unconsumed_bytes(buf); + } + +-static inline struct t_rec *next_record(const struct t_buf *buf, +- uint32_t *next) ++static unsigned char *next_record(const struct t_buf *buf, uint32_t *next, ++ unsigned char **next_page, ++ uint32_t *offset_in_page) + { + u32 x = buf->prod, cons = buf->cons; ++ uint16_t per_cpu_mfn_offset; ++ uint32_t per_cpu_mfn_nr; ++ uint32_t *mfn_list; ++ uint32_t mfn; ++ unsigned char *this_page; + + barrier(); /* must read buf->prod and buf->cons only once */ + *next = x; +@@ -487,7 +491,27 @@ static inline struct t_rec *next_record( + + ASSERT(x < data_size); + +- return (struct t_rec *)&this_cpu(t_data)[x]; ++ /* add leading header to get total offset of next record */ ++ x += sizeof(struct t_buf); ++ *offset_in_page = x & ~PAGE_MASK; ++ ++ /* offset into array of mfns */ ++ per_cpu_mfn_nr = x >> PAGE_SHIFT; ++ per_cpu_mfn_offset = t_info->mfn_offset[smp_processor_id()]; ++ mfn_list = (uint32_t *)t_info; ++ mfn = mfn_list[per_cpu_mfn_offset + per_cpu_mfn_nr]; ++ this_page = mfn_to_virt(mfn); ++ if (per_cpu_mfn_nr + 1 >= opt_tbuf_size) ++ { ++ /* reached end of buffer? */ ++ *next_page = NULL; ++ } ++ else ++ { ++ mfn = mfn_list[per_cpu_mfn_offset + per_cpu_mfn_nr + 1]; ++ *next_page = mfn_to_virt(mfn); ++ } ++ return this_page; + } + + static inline void __insert_record(struct t_buf *buf, +@@ -497,28 +521,37 @@ static inline void __insert_record(struc + unsigned int rec_size, + const void *extra_data) + { +- struct t_rec *rec; ++ struct t_rec split_rec, *rec; + uint32_t *dst; ++ unsigned char *this_page, *next_page; + unsigned int extra_word = extra / sizeof(u32); + unsigned int local_rec_size = calc_rec_size(cycles, extra); + uint32_t next; ++ uint32_t offset; ++ uint32_t remaining; + + BUG_ON(local_rec_size != rec_size); + BUG_ON(extra & 3); + +- rec = next_record(buf, &next); +- if ( !rec ) ++ this_page = next_record(buf, &next, &next_page, &offset); ++ if ( !this_page ) + return; +- /* Double-check once more that we have enough space. +- * Don't bugcheck here, in case the userland tool is doing +- * something stupid. */ +- if ( (unsigned char *)rec + rec_size > this_cpu(t_data) + data_size ) ++ ++ remaining = PAGE_SIZE - offset; ++ ++ if ( unlikely(rec_size > remaining) ) + { +- if ( printk_ratelimit() ) ++ if ( next_page == NULL ) ++ { ++ /* access beyond end of buffer */ + printk(XENLOG_WARNING +- "%s: size=%08x prod=%08x cons=%08x rec=%u\n", +- __func__, data_size, next, buf->cons, rec_size); +- return; ++ "%s: size=%08x prod=%08x cons=%08x rec=%u remaining=%u\n", ++ __func__, data_size, next, buf->cons, rec_size, remaining); ++ return; ++ } ++ rec = &split_rec; ++ } else { ++ rec = (struct t_rec*)(this_page + offset); + } + + rec->event = event; +@@ -535,6 +568,12 @@ static inline void __insert_record(struc + if ( extra_data && extra ) + memcpy(dst, extra_data, extra); + ++ if ( unlikely(rec_size > remaining) ) ++ { ++ memcpy(this_page + offset, rec, remaining); ++ memcpy(next_page, (char *)rec + remaining, rec_size - remaining); ++ } ++ + wmb(); + + next += rec_size; diff --git a/23407-xentrace_allocate_non-contiguous_per-cpu_trace_buffers.patch b/23407-xentrace_allocate_non-contiguous_per-cpu_trace_buffers.patch new file mode 100644 index 0000000..000a9da --- /dev/null +++ b/23407-xentrace_allocate_non-contiguous_per-cpu_trace_buffers.patch @@ -0,0 +1,155 @@ +changeset: 23407:b19898ac3e32 +user: Olaf Hering +date: Thu May 26 12:36:27 2011 +0100 +files: xen/common/trace.c +description: +xentrace: allocate non-contiguous per-cpu trace buffers + +Signed-off-by: Olaf Hering +Acked-by: George Dunlap + + +--- + xen/common/trace.c | 92 ++++++++++++++++++++++++++++------------------------- + 1 file changed, 50 insertions(+), 42 deletions(-) + +Index: xen-4.1.2-testing/xen/common/trace.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/trace.c ++++ xen-4.1.2-testing/xen/common/trace.c +@@ -166,7 +166,7 @@ static int calculate_tbuf_size(unsigned + */ + static int alloc_trace_bufs(unsigned int pages) + { +- int i, cpu, order; ++ int i, cpu; + /* Start after a fixed-size array of NR_CPUS */ + uint32_t *t_info_mfn_list; + uint16_t t_info_first_offset; +@@ -182,34 +182,11 @@ static int alloc_trace_bufs(unsigned int + t_info_first_offset = calc_tinfo_first_offset(); + + pages = calculate_tbuf_size(pages, t_info_first_offset); +- order = get_order_from_pages(pages); + + t_info = alloc_xenheap_pages(get_order_from_pages(t_info_pages), 0); + if ( t_info == NULL ) +- goto out_dealloc; ++ goto out_dealloc_t_info; + +- /* +- * First, allocate buffers for all of the cpus. If any +- * fails, deallocate what you have so far and exit. +- */ +- for_each_online_cpu(cpu) +- { +- void *rawbuf; +- struct t_buf *buf; +- +- if ( (rawbuf = alloc_xenheap_pages( +- order, MEMF_bits(32 + PAGE_SHIFT))) == NULL ) +- { +- printk(XENLOG_INFO "xentrace: memory allocation failed " +- "on cpu %d\n", cpu); +- goto out_dealloc; +- } +- +- per_cpu(t_bufs, cpu) = buf = rawbuf; +- buf->cons = buf->prod = 0; +- } +- +- offset = t_info_first_offset; + t_info_mfn_list = (uint32_t *)t_info; + + for(i = 0; i < t_info_pages; i++) +@@ -219,27 +196,53 @@ static int alloc_trace_bufs(unsigned int + t_info->tbuf_size = pages; + + /* +- * Now share the pages so xentrace can map them, and write them in +- * the global t_info structure. ++ * Allocate buffers for all of the cpus. ++ * If any fails, deallocate what you have so far and exit. + */ + for_each_online_cpu(cpu) + { +- void *rawbuf = per_cpu(t_bufs, cpu); +- struct page_info *p = virt_to_page(rawbuf); +- uint32_t mfn = virt_to_mfn(rawbuf); ++ offset = t_info_first_offset + (cpu * pages); ++ t_info->mfn_offset[cpu] = offset; + + for ( i = 0; i < pages; i++ ) + { +- share_xen_page_with_privileged_guests(p + i, XENSHARE_writable); +- +- t_info_mfn_list[offset + i]=mfn + i; ++ void *p = alloc_xenheap_pages(0, MEMF_bits(32 + PAGE_SHIFT)); ++ if ( !p ) ++ { ++ printk(XENLOG_INFO "xentrace: memory allocation failed " ++ "on cpu %d after %d pages\n", cpu, i); ++ t_info_mfn_list[offset + i] = 0; ++ goto out_dealloc; ++ } ++ t_info_mfn_list[offset + i] = virt_to_mfn(p); + } +- t_info->mfn_offset[cpu]=offset; +- printk(XENLOG_INFO "xentrace: p%d mfn %"PRIx32" offset %d\n", +- cpu, mfn, offset); +- offset+=i; ++ } ++ ++ /* ++ * Initialize buffers for all of the cpus. ++ */ ++ for_each_online_cpu(cpu) ++ { ++ struct t_buf *buf; ++ struct page_info *pg; + + spin_lock_init(&per_cpu(t_lock, cpu)); ++ ++ offset = t_info->mfn_offset[cpu]; ++ ++ /* Initialize the buffer metadata */ ++ per_cpu(t_bufs, cpu) = buf = mfn_to_virt(t_info_mfn_list[offset]); ++ buf->cons = buf->prod = 0; ++ ++ printk(XENLOG_INFO "xentrace: p%d mfn %x offset %u\n", ++ cpu, t_info_mfn_list[offset], offset); ++ ++ /* Now share the trace pages */ ++ for ( i = 0; i < pages; i++ ) ++ { ++ pg = mfn_to_page(t_info_mfn_list[offset + i]); ++ share_xen_page_with_privileged_guests(pg, XENSHARE_writable); ++ } + } + + data_size = (pages * PAGE_SIZE - sizeof(struct t_buf)); +@@ -255,14 +258,19 @@ static int alloc_trace_bufs(unsigned int + out_dealloc: + for_each_online_cpu(cpu) + { +- void *rawbuf = per_cpu(t_bufs, cpu); +- per_cpu(t_bufs, cpu) = NULL; +- if ( rawbuf ) ++ offset = t_info->mfn_offset[cpu]; ++ if ( !offset ) ++ continue; ++ for ( i = 0; i < pages; i++ ) + { +- ASSERT(!(virt_to_page(rawbuf)->count_info & PGC_allocated)); +- free_xenheap_pages(rawbuf, order); ++ uint32_t mfn = t_info_mfn_list[offset + i]; ++ if ( !mfn ) ++ break; ++ ASSERT(!(mfn_to_page(mfn)->count_info & PGC_allocated)); ++ 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; + printk(XENLOG_WARNING "xentrace: allocation failed! Tracing disabled.\n"); diff --git a/23643-xentrace_Allow_tracing_to_be_enabled_at_boot.patch b/23643-xentrace_Allow_tracing_to_be_enabled_at_boot.patch new file mode 100644 index 0000000..4368bc2 --- /dev/null +++ b/23643-xentrace_Allow_tracing_to_be_enabled_at_boot.patch @@ -0,0 +1,58 @@ +changeset: 23643:335e96664589 +user: George Dunlap +date: Fri Jul 01 20:31:18 2011 +0100 +files: xen/common/trace.c +description: +xentrace: Allow tracing to be enabled at boot + +Add a "tevt_mask" parameter to the xen command-line, allowing +trace records to be gathered early in boot. They will be placed +into the trace buffers, and read when the user runs "xentrace". + +Signed-off-by: George Dunlap + + +--- + xen/common/trace.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +Index: xen-4.1.2-testing/xen/common/trace.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/trace.c ++++ xen-4.1.2-testing/xen/common/trace.c +@@ -45,7 +45,9 @@ CHECK_t_buf; + + /* opt_tbuf_size: trace buffer size (in pages) for each cpu */ + static unsigned int opt_tbuf_size; ++static unsigned int opt_tevt_mask; + integer_param("tbuf_size", opt_tbuf_size); ++integer_param("tevt_mask", opt_tevt_mask); + + /* Pointers to the meta-data objects for all system trace buffers */ + static struct t_info *t_info; +@@ -338,11 +340,21 @@ void __init init_trace_bufs(void) + { + register_cpu_notifier(&cpu_nfb); + +- if ( opt_tbuf_size && alloc_trace_bufs(opt_tbuf_size) ) ++ if ( opt_tbuf_size ) + { +- printk(XENLOG_INFO "xentrace: allocation size %d failed, disabling\n", +- opt_tbuf_size); +- opt_tbuf_size = 0; ++ if ( alloc_trace_bufs(opt_tbuf_size) ) ++ { ++ printk("xentrace: allocation size %d failed, disabling\n", ++ opt_tbuf_size); ++ opt_tbuf_size = 0; ++ } ++ else if ( opt_tevt_mask ) ++ { ++ printk("xentrace: Starting tracing, enabling mask %x\n", ++ opt_tevt_mask); ++ tb_event_mask = opt_tevt_mask; ++ tb_init_done=1; ++ } + } + } + diff --git a/23719-xentrace_update___trace_var_comment.patch b/23719-xentrace_update___trace_var_comment.patch new file mode 100644 index 0000000..93d8d34 --- /dev/null +++ b/23719-xentrace_update___trace_var_comment.patch @@ -0,0 +1,37 @@ +changeset: 23719:c2888876abd3 +user: Olaf Hering +date: Tue Jul 19 08:22:19 2011 +0100 +files: xen/common/trace.c +description: +xentrace: update __trace_var comment + +Signed-off-by: Olaf Hering + + +--- + xen/common/trace.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +Index: xen-4.1.2-testing/xen/common/trace.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/trace.c ++++ xen-4.1.2-testing/xen/common/trace.c +@@ -657,13 +657,13 @@ static DECLARE_SOFTIRQ_TASKLET(trace_not + trace_notify_dom0, 0); + + /** +- * trace - Enters a trace tuple into the trace buffer for the current CPU. ++ * __trace_var - Enters a trace tuple into the trace buffer for the current CPU. + * @event: the event type being logged +- * @d1...d5: the data items for the event being logged ++ * @cycles: include tsc timestamp into trace record ++ * @extra: size of additional trace data in bytes ++ * @extra_data: pointer to additional trace data + * +- * Logs a trace record into the appropriate buffer. Returns nonzero on +- * failure, otherwise 0. Failure occurs only if the trace buffers are not yet +- * initialised. ++ * Logs a trace record into the appropriate buffer. + */ + void __trace_var(u32 event, bool_t cycles, unsigned int extra, + const void *extra_data) diff --git a/23752-x86-shared-IRQ-vector-maps.patch b/23752-x86-shared-IRQ-vector-maps.patch new file mode 100644 index 0000000..5841eee --- /dev/null +++ b/23752-x86-shared-IRQ-vector-maps.patch @@ -0,0 +1,147 @@ +References: bnc#713503 + +# HG changeset patch +# User George Dunlap +# Date 1311701818 -3600 +# Node ID ef9ed3d2aa870a37ed5e611be9c524d526a2d604 +# Parent 590aadf7c46ae979da3552332f592f9492ce6d8b +xen: Infrastructure to allow irqs to share vector maps + +Laying the groundwork for per-device vector maps. This generic +code allows any irq to point to a vector map; all irqs sharing the +same vector map will avoid sharing vectors. + +Signed-off-by: George Dunlap + +# HG changeset patch +# User George Dunlap +# Date 1314026133 -3600 +# Node ID 3a05da2dc7c0a5fc0fcfc40c535d1fcb71203625 +# Parent d1cd78a73a79e0e648937322cdb8d92a7f86327a +x86: Fix up irq vector map logic + +We need to make sure that cfg->used_vector is only cleared once; +otherwise there may be a race condition that allows the same vector to +be assigned twice, defeating the whole purpose of the map. + +This makes two changes: +* __clear_irq_vector() only clears the vector if the irq is not being +moved +* smp_iqr_move_cleanup_interrupt() only clears used_vector if this +is the last place it's being used (move_cleanup_count==0 after +decrement). + +Also make use of asserts more consistent, to catch this kind of logic +bug in the future. + +Signed-off-by: George Dunlap + +--- a/xen/arch/x86/io_apic.c ++++ b/xen/arch/x86/io_apic.c +@@ -548,6 +548,13 @@ fastcall void smp_irq_move_cleanup_inter + } + __get_cpu_var(vector_irq)[vector] = -1; + cfg->move_cleanup_count--; ++ ++ if ( cfg->move_cleanup_count == 0 ++ && cfg->used_vectors ) ++ { ++ ASSERT(test_bit(vector, cfg->used_vectors)); ++ clear_bit(vector, cfg->used_vectors); ++ } + unlock: + spin_unlock(&desc->lock); + } +--- a/xen/arch/x86/irq.c ++++ b/xen/arch/x86/irq.c +@@ -94,6 +94,11 @@ static int __init __bind_irq_vector(int + per_cpu(vector_irq, cpu)[vector] = irq; + cfg->vector = vector; + cfg->cpu_mask = online_mask; ++ if ( cfg->used_vectors ) ++ { ++ ASSERT(!test_bit(vector, cfg->used_vectors)); ++ set_bit(vector, cfg->used_vectors); ++ } + irq_status[irq] = IRQ_USED; + if (IO_APIC_IRQ(irq)) + irq_vector[irq] = vector; +@@ -159,6 +164,7 @@ static void dynamic_irq_cleanup(unsigned + desc->depth = 1; + desc->msi_desc = NULL; + desc->handler = &no_irq_type; ++ desc->chip_data->used_vectors=NULL; + cpus_setall(desc->affinity); + spin_unlock_irqrestore(&desc->lock, flags); + +@@ -191,6 +197,7 @@ static void __clear_irq_vector(int irq) + + if (likely(!cfg->move_in_progress)) + return; ++ + cpus_and(tmp_mask, cfg->old_cpu_mask, cpu_online_map); + for_each_cpu_mask(cpu, tmp_mask) { + for (vector = FIRST_DYNAMIC_VECTOR; vector <= LAST_DYNAMIC_VECTOR; +@@ -202,6 +209,12 @@ static void __clear_irq_vector(int irq) + } + } + ++ if ( cfg->used_vectors ) ++ { ++ ASSERT(test_bit(vector, cfg->used_vectors)); ++ clear_bit(vector, cfg->used_vectors); ++ } ++ + cfg->move_in_progress = 0; + } + +@@ -261,6 +274,7 @@ static void init_one_irq_cfg(struct irq_ + cfg->vector = IRQ_VECTOR_UNASSIGNED; + cpus_clear(cfg->cpu_mask); + cpus_clear(cfg->old_cpu_mask); ++ cfg->used_vectors = NULL; + } + + int init_irq_data(void) +@@ -387,6 +401,10 @@ next: + if (test_bit(vector, used_vectors)) + goto next; + ++ if (cfg->used_vectors ++ && test_bit(vector, cfg->used_vectors) ) ++ goto next; ++ + for_each_cpu_mask(new_cpu, tmp_mask) + if (per_cpu(vector_irq, new_cpu)[vector] != -1) + goto next; +@@ -402,6 +420,11 @@ next: + per_cpu(vector_irq, new_cpu)[vector] = irq; + cfg->vector = vector; + cpus_copy(cfg->cpu_mask, tmp_mask); ++ if ( cfg->used_vectors ) ++ { ++ ASSERT(!test_bit(vector, cfg->used_vectors)); ++ set_bit(vector, cfg->used_vectors); ++ } + + irq_status[irq] = IRQ_USED; + if (IO_APIC_IRQ(irq)) +--- a/xen/include/asm-x86/irq.h ++++ b/xen/include/asm-x86/irq.h +@@ -23,11 +23,16 @@ + #define irq_to_desc(irq) (&irq_desc[irq]) + #define irq_cfg(irq) (&irq_cfg[irq]) + ++typedef struct { ++ DECLARE_BITMAP(_bits,NR_VECTORS); ++} vmask_t; ++ + struct irq_cfg { + int vector; + cpumask_t cpu_mask; + cpumask_t old_cpu_mask; + unsigned move_cleanup_count; ++ vmask_t *used_vectors; + u8 move_in_progress : 1; + }; + diff --git a/23754-AMD-perdev-vector-map.patch b/23754-AMD-perdev-vector-map.patch new file mode 100644 index 0000000..67c0a9e --- /dev/null +++ b/23754-AMD-perdev-vector-map.patch @@ -0,0 +1,361 @@ +References: bnc#713503 + +# HG changeset patch +# User George Dunlap +# Date 1311701836 -3600 +# Node ID 2e0cf9428554da666616982cd0074024ff85b221 +# Parent ef9ed3d2aa870a37ed5e611be9c524d526a2d604 +xen: Option to allow per-device vector maps for MSI IRQs + +Add a vector-map to pci_dev, and add an option to point MSI-related +IRQs to the vector-map of the device. + +This prevents irqs from the same device from being assigned +the same vector on different pcpus. This is required for systems +using an AMD IOMMU, since the intremap tables on AMD only look at +vector, and not destination ID. + +Signed-off-by: George Dunlap + +# HG changeset patch +# User George Dunlap +# Date 1311701852 -3600 +# Node ID fa4e2ca9ecffbc432b451f495ad0a403644a6be8 +# Parent 2e0cf9428554da666616982cd0074024ff85b221 +xen: AMD IOMMU: Automatically enable per-device vector maps + +Automatically enable per-device vector maps when using IOMMU, +unless disabled specifically by an IOMMU parameter. + +Signed-off-by: George Dunlap + +# HG changeset patch +# User George Dunlap +# Date 1315231215 -3600 +# Node ID 32814ad7458dc842a7c588eee13e5c4ee11709a3 +# Parent f1349a968a5ac5577d67ad4a3f3490c580dbe264 +xen: Add global irq_vector_map option, set if using AMD global intremap tables + +As mentioned in previous changesets, AMD IOMMU interrupt +remapping tables only look at the vector, not the destination +id of an interrupt. This means that all IRQs going through +the same interrupt remapping table need to *not* share vectors. + +The irq "vector map" functionality was originally introduced +after a patch which disabled global AMD IOMMUs entirely. That +patch has since been reverted, meaning that AMD intremap tables +can either be per-device or global. + +This patch therefore introduces a global irq vector map option, +and enables it if we're using an AMD IOMMU with a global +interrupt remapping table. + +This patch removes the "irq-perdev-vector-map" boolean +command-line optino and replaces it with "irq_vector_map", +which can have one of three values: none, global, or per-device. + +Setting the irq_vector_map to any value will override the +default that the AMD code sets. + +Signed-off-by: George Dunlap + +# HG changeset patch +# User Jan Beulich +# Date 1317730316 -7200 +# Node ID a99d75671a911f9c0d5d11e0fe88a0a65863cb44 +# Parent 3d1664cc9e458809e399320204aca8536e401ee1 +AMD-IOMMU: remove dead variable references + +These got orphaned up by recent changes. + +Signed-off-by: Jan Beulich +Acked-by: Keir Fraser + +--- a/docs/src/user.tex ++++ b/docs/src/user.tex +@@ -4197,6 +4197,10 @@ writing to the VGA console after domain + \item [ vcpu\_migration\_delay=$<$minimum\_time$>$] Set minimum time of + vcpu migration in microseconds (default 0). This parameter avoids agressive + vcpu migration. For example, the linux kernel uses 0.5ms by default. ++\item [ irq_vector_map=xxx ] Enable irq vector non-sharing maps. Setting 'global' ++ will ensure that no IRQs will share vectors. Setting 'per-device' will ensure ++ that no IRQs from the same device will share vectors. Setting to 'none' will ++ disable it entirely, overriding any defaults the IOMMU code may set. + \end{description} + + In addition, the following options may be specified on the Xen command +--- a/xen/arch/x86/irq.c ++++ b/xen/arch/x86/irq.c +@@ -24,6 +24,8 @@ + #include + #include + ++static void parse_irq_vector_map_param(char *s); ++ + /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */ + bool_t __read_mostly opt_noirqbalance = 0; + boolean_param("noirqbalance", opt_noirqbalance); +@@ -32,6 +34,12 @@ unsigned int __read_mostly nr_irqs_gsi = + unsigned int __read_mostly nr_irqs; + integer_param("nr_irqs", nr_irqs); + ++/* This default may be changed by the AMD IOMMU code */ ++int __read_mostly opt_irq_vector_map = OPT_IRQ_VECTOR_MAP_DEFAULT; ++custom_param("irq_vector_map", parse_irq_vector_map_param); ++ ++vmask_t global_used_vector_map; ++ + u8 __read_mostly *irq_vector; + struct irq_desc __read_mostly *irq_desc = NULL; + +@@ -60,6 +68,26 @@ static struct timer irq_ratelimit_timer; + static unsigned int __read_mostly irq_ratelimit_threshold = 10000; + integer_param("irq_ratelimit", irq_ratelimit_threshold); + ++static void __init parse_irq_vector_map_param(char *s) ++{ ++ char *ss; ++ ++ do { ++ ss = strchr(s, ','); ++ if ( ss ) ++ *ss = '\0'; ++ ++ if ( !strcmp(s, "none")) ++ opt_irq_vector_map=OPT_IRQ_VECTOR_MAP_NONE; ++ else if ( !strcmp(s, "global")) ++ opt_irq_vector_map=OPT_IRQ_VECTOR_MAP_GLOBAL; ++ else if ( !strcmp(s, "per-device")) ++ opt_irq_vector_map=OPT_IRQ_VECTOR_MAP_PERDEV; ++ ++ s = ss + 1; ++ } while ( ss ); ++} ++ + /* Must be called when irq disabled */ + void lock_vector_lock(void) + { +@@ -344,6 +372,41 @@ hw_irq_controller no_irq_type = { + end_none + }; + ++static vmask_t *irq_get_used_vector_mask(int irq) ++{ ++ vmask_t *ret = NULL; ++ ++ if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_GLOBAL ) ++ { ++ struct irq_desc *desc = irq_to_desc(irq); ++ ++ ret = &global_used_vector_map; ++ ++ if ( desc->chip_data->used_vectors ) ++ { ++ printk(XENLOG_INFO "%s: Strange, unassigned irq %d already has used_vectors!\n", ++ __func__, irq); ++ } ++ else ++ { ++ int vector; ++ ++ vector = irq_to_vector(irq); ++ if ( vector > 0 ) ++ { ++ printk(XENLOG_INFO "%s: Strange, irq %d already assigned vector %d!\n", ++ __func__, irq, vector); ++ ++ ASSERT(!test_bit(vector, ret)); ++ ++ set_bit(vector, ret); ++ } ++ } ++ } ++ ++ return ret; ++} ++ + int __assign_irq_vector(int irq, struct irq_cfg *cfg, const cpumask_t *mask) + { + /* +@@ -362,6 +425,7 @@ int __assign_irq_vector(int irq, struct + int cpu, err; + unsigned long flags; + cpumask_t tmp_mask; ++ vmask_t *irq_used_vectors = NULL; + + old_vector = irq_to_vector(irq); + if (old_vector) { +@@ -376,6 +440,17 @@ int __assign_irq_vector(int irq, struct + return -EAGAIN; + + err = -ENOSPC; ++ ++ /* This is the only place normal IRQs are ever marked ++ * as "in use". If they're not in use yet, check to see ++ * if we need to assign a global vector mask. */ ++ if ( irq_status[irq] == IRQ_USED ) ++ { ++ irq_used_vectors = cfg->used_vectors; ++ } ++ else ++ irq_used_vectors = irq_get_used_vector_mask(irq); ++ + for_each_cpu_mask(cpu, *mask) { + int new_cpu; + int vector, offset; +@@ -401,8 +476,8 @@ next: + if (test_bit(vector, used_vectors)) + goto next; + +- if (cfg->used_vectors +- && test_bit(vector, cfg->used_vectors) ) ++ if (irq_used_vectors ++ && test_bit(vector, irq_used_vectors) ) + goto next; + + for_each_cpu_mask(new_cpu, tmp_mask) +@@ -420,15 +495,22 @@ next: + per_cpu(vector_irq, new_cpu)[vector] = irq; + cfg->vector = vector; + cpus_copy(cfg->cpu_mask, tmp_mask); ++ ++ irq_status[irq] = IRQ_USED; ++ ASSERT((cfg->used_vectors == NULL) ++ || (cfg->used_vectors == irq_used_vectors)); ++ cfg->used_vectors = irq_used_vectors; ++ ++ if (IO_APIC_IRQ(irq)) ++ irq_vector[irq] = vector; ++ + if ( cfg->used_vectors ) + { + ASSERT(!test_bit(vector, cfg->used_vectors)); ++ + set_bit(vector, cfg->used_vectors); + } + +- irq_status[irq] = IRQ_USED; +- if (IO_APIC_IRQ(irq)) +- irq_vector[irq] = vector; + err = 0; + local_irq_restore(flags); + break; +@@ -1523,7 +1605,7 @@ int map_domain_pirq( + + if ( !IS_PRIV(current->domain) && + !(IS_PRIV_FOR(current->domain, d) && +- irq_access_permitted(current->domain, pirq))) ++ irq_access_permitted(current->domain, pirq))) + return -EPERM; + + if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs ) +@@ -1571,8 +1653,22 @@ int map_domain_pirq( + + if ( desc->handler != &no_irq_type ) + dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n", +- d->domain_id, irq); ++ d->domain_id, irq); + desc->handler = &pci_msi_type; ++ ++ if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV ++ && !desc->chip_data->used_vectors ) ++ { ++ desc->chip_data->used_vectors = &pdev->info.used_vectors; ++ if ( desc->chip_data->vector != IRQ_VECTOR_UNASSIGNED ) ++ { ++ int vector = desc->chip_data->vector; ++ ASSERT(!test_bit(vector, desc->chip_data->used_vectors)); ++ ++ set_bit(vector, desc->chip_data->used_vectors); ++ } ++ } ++ + d->arch.pirq_irq[pirq] = irq; + d->arch.irq_pirq[irq] = pirq; + setup_msi_irq(pdev, msi_desc, irq); +@@ -1583,9 +1679,12 @@ int map_domain_pirq( + d->arch.pirq_irq[pirq] = irq; + d->arch.irq_pirq[irq] = pirq; + spin_unlock_irqrestore(&desc->lock, flags); ++ ++ if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_PERDEV ) ++ printk(XENLOG_INFO "Per-device vector maps for GSIs not implemented yet.\n"); + } + +- done: ++done: + return ret; + } + +--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c ++++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c +@@ -166,6 +166,35 @@ int __init amd_iov_detect(void) + return -ENODEV; + } + ++ /* ++ * AMD IOMMUs don't distinguish between vectors destined for ++ * different cpus when doing interrupt remapping. This means ++ * that interrupts going through the same intremap table ++ * can't share the same vector. ++ * ++ * If irq_vector_map isn't specified, choose a sensible default: ++ * - If we're using per-device interemap tables, per-device ++ * vector non-sharing maps ++ * - If we're using a global interemap table, global vector ++ * non-sharing map ++ */ ++ if ( opt_irq_vector_map == OPT_IRQ_VECTOR_MAP_DEFAULT ) ++ { ++ if ( amd_iommu_perdev_intremap ) ++ { ++ printk("AMD-Vi: Enabling per-device vector maps\n"); ++ opt_irq_vector_map = OPT_IRQ_VECTOR_MAP_PERDEV; ++ } ++ else ++ { ++ printk("AMD-Vi: Enabling global vector map\n"); ++ opt_irq_vector_map = OPT_IRQ_VECTOR_MAP_GLOBAL; ++ } ++ } ++ else ++ { ++ printk("AMD-Vi: Not overriding irq_vector_map setting\n"); ++ } + return scan_pci_devices(); + } + +--- a/xen/include/asm-x86/irq.h ++++ b/xen/include/asm-x86/irq.h +@@ -45,6 +45,13 @@ extern u8 *irq_vector; + + extern bool_t opt_noirqbalance; + ++#define OPT_IRQ_VECTOR_MAP_DEFAULT 0 /* Do the default thing */ ++#define OPT_IRQ_VECTOR_MAP_NONE 1 /* None */ ++#define OPT_IRQ_VECTOR_MAP_GLOBAL 2 /* One global vector map (no vector sharing) */ ++#define OPT_IRQ_VECTOR_MAP_PERDEV 3 /* Per-device vetor map (no vector sharing w/in a device) */ ++ ++extern int opt_irq_vector_map; ++ + /* + * Per-cpu current frame pointer - the location of the last exception frame on + * the stack +--- a/xen/include/xen/pci.h ++++ b/xen/include/xen/pci.h +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + /* + * The PCI interface treats multi-function devices as independent +@@ -38,6 +39,7 @@ struct pci_dev_info { + u8 bus; + u8 devfn; + } physfn; ++ vmask_t used_vectors; + }; + + struct pci_dev { diff --git a/23819-make-docs.patch b/23819-make-docs.patch new file mode 100644 index 0000000..c0f1e89 --- /dev/null +++ b/23819-make-docs.patch @@ -0,0 +1,22 @@ +# HG changeset patch +# User Keir Fraser +# Date 1315320580 -3600 +# Node ID 5fe770c8a8a35c58893816ee6335a90ed43f3bbd +# Parent 0268e73809532a4a3ca18a075efcee3c62caf458 +docs: Fix 'make docs' + +Signed-off-by: Keir Fraser + +Index: xen-4.1.2-testing/docs/src/user.tex +=================================================================== +--- xen-4.1.2-testing.orig/docs/src/user.tex ++++ xen-4.1.2-testing/docs/src/user.tex +@@ -4197,7 +4197,7 @@ writing to the VGA console after domain + \item [ vcpu\_migration\_delay=$<$minimum\_time$>$] Set minimum time of + vcpu migration in microseconds (default 0). This parameter avoids agressive + vcpu migration. For example, the linux kernel uses 0.5ms by default. +-\item [ irq_vector_map=xxx ] Enable irq vector non-sharing maps. Setting 'global' ++\item [ irq\_vector\_map=xxx ] Enable irq vector non-sharing maps. Setting 'global' + will ensure that no IRQs will share vectors. Setting 'per-device' will ensure + that no IRQs from the same device will share vectors. Setting to 'none' will + disable it entirely, overriding any defaults the IOMMU code may set. diff --git a/23900-xzalloc.patch b/23900-xzalloc.patch new file mode 100644 index 0000000..a035f59 --- /dev/null +++ b/23900-xzalloc.patch @@ -0,0 +1,89 @@ +# HG changeset patch +# User Jan Beulich +# Date 1317730526 -7200 +# Node ID e09ebf7a31f55bb26c3cce7695a435ed20adf05b +# Parent a99d75671a911f9c0d5d11e0fe88a0a65863cb44 +introduce xzalloc() & Co + +Rather than having to match a call to one of the xmalloc() flavors with +a subsequent memset(), introduce a zeroing variant of each of those +flavors. + +Signed-off-by: Jan Beulich +Acked-by: Keir Fraser + +--- a/xen/common/xmalloc_tlsf.c ++++ b/xen/common/xmalloc_tlsf.c +@@ -585,6 +585,13 @@ void *_xmalloc(unsigned long size, unsig + return p; + } + ++void *_xzalloc(unsigned long size, unsigned long align) ++{ ++ void *p = _xmalloc(size, align); ++ ++ return p ? memset(p, 0, size) : p; ++} ++ + void xfree(void *p) + { + struct bhdr *b; +--- a/xen/include/acpi/platform/aclinux.h ++++ b/xen/include/acpi/platform/aclinux.h +@@ -77,10 +77,7 @@ + #define acpi_thread_id struct vcpu * + + #define ACPI_ALLOCATE(a) xmalloc_bytes(a) +-#define ACPI_ALLOCATE_ZEROED(a) ({ \ +- void *p = xmalloc_bytes(a); \ +- if ( p ) memset(p, 0, a); \ +- p; }) ++#define ACPI_ALLOCATE_ZEROED(a) xzalloc_bytes(a) + #define ACPI_FREE(a) xfree(a) + + #endif /* __ACLINUX_H__ */ +--- a/xen/include/xen/xmalloc.h ++++ b/xen/include/xen/xmalloc.h +@@ -8,19 +8,25 @@ + + /* Allocate space for typed object. */ + #define xmalloc(_type) ((_type *)_xmalloc(sizeof(_type), __alignof__(_type))) ++#define xzalloc(_type) ((_type *)_xzalloc(sizeof(_type), __alignof__(_type))) + + /* Allocate space for array of typed objects. */ + #define xmalloc_array(_type, _num) \ + ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num)) ++#define xzalloc_array(_type, _num) \ ++ ((_type *)_xzalloc_array(sizeof(_type), __alignof__(_type), _num)) + + /* Allocate untyped storage. */ +-#define xmalloc_bytes(_bytes) (_xmalloc(_bytes, SMP_CACHE_BYTES)) ++#define xmalloc_bytes(_bytes) _xmalloc(_bytes, SMP_CACHE_BYTES) ++#define xzalloc_bytes(_bytes) _xzalloc(_bytes, SMP_CACHE_BYTES) + + /* Free any of the above. */ + extern void xfree(void *); + + /* Underlying functions */ + extern void *_xmalloc(unsigned long size, unsigned long align); ++extern void *_xzalloc(unsigned long size, unsigned long align); ++ + static inline void *_xmalloc_array( + unsigned long size, unsigned long align, unsigned long num) + { +@@ -30,6 +36,15 @@ static inline void *_xmalloc_array( + return _xmalloc(size * num, align); + } + ++static inline void *_xzalloc_array( ++ unsigned long size, unsigned long align, unsigned long num) ++{ ++ /* Check for overflow. */ ++ if (size && num > UINT_MAX / size) ++ return NULL; ++ return _xzalloc(size * num, align); ++} ++ + /* + * Pooled allocator interface. + */ diff --git a/23993-x86-microcode-amd-fix-23871.patch b/23993-x86-microcode-amd-fix-23871.patch index 8d45851..5367621 100644 --- a/23993-x86-microcode-amd-fix-23871.patch +++ b/23993-x86-microcode-amd-fix-23871.patch @@ -1,3 +1,5 @@ +References: bnc#725169 + # HG changeset patch # User Jan Beulich # Date 1319475620 -3600 diff --git a/24116-x86-continuation-cancel.patch b/24116-x86-continuation-cancel.patch new file mode 100644 index 0000000..e8067f3 --- /dev/null +++ b/24116-x86-continuation-cancel.patch @@ -0,0 +1,67 @@ +# HG changeset patch +# User Jean Guyader +# Date 1321002862 -3600 +# Node ID a095cf28f2b6eeb8f5873c18eb18d4d7e5544e2c +# Parent 6534da595d695a4f2af12a64e46fb06219a0e4bc +Hypercall continuation cancelation in compat mode for XENMEM_get/set_pod_target + +If copy_to_guest failed in the compat code after a continuation as been +done in the native code we need to cancel it so we won't reexecute the +hypercall but return from the hypercall with the appropriate error. + +Signed-off-by: Jean Guyader +Acked-by: Jan Beulich +Acked-by: Keir Fraser +Committed-by: Jan Beulich + +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c +@@ -1585,6 +1585,24 @@ void sync_vcpu_execstate(struct vcpu *v) + __arg; \ + }) + ++void hypercall_cancel_continuation(void) ++{ ++ struct cpu_user_regs *regs = guest_cpu_user_regs(); ++ struct mc_state *mcs = ¤t->mc_state; ++ ++ if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) ++ { ++ __clear_bit(_MCSF_call_preempted, &mcs->flags); ++ } ++ else ++ { ++ if ( !is_hvm_vcpu(current) ) ++ regs->eip += 2; /* skip re-execute 'syscall' / 'int $xx' */ ++ else ++ current->arch.hvm_vcpu.hcall_preempted = 0; ++ } ++} ++ + unsigned long hypercall_create_continuation( + unsigned int op, const char *format, ...) + { +--- a/xen/arch/x86/x86_64/compat/mm.c ++++ b/xen/arch/x86/x86_64/compat/mm.c +@@ -133,7 +133,11 @@ int compat_arch_memory_op(int op, XEN_GU + XLAT_pod_target(&cmp, nat); + + if ( copy_to_guest(arg, &cmp, 1) ) ++ { ++ if ( rc == __HYPERVISOR_memory_op ) ++ hypercall_cancel_continuation(); + rc = -EFAULT; ++ } + + break; + } +--- a/xen/include/xen/sched.h ++++ b/xen/include/xen/sched.h +@@ -560,6 +560,7 @@ void startup_cpu_idle_loop(void); + */ + unsigned long hypercall_create_continuation( + unsigned int op, const char *format, ...); ++void hypercall_cancel_continuation(void); + + #define hypercall_preempt_check() (unlikely( \ + softirq_pending(smp_processor_id()) | \ diff --git a/24123-x86-cpuidle-quiesce.patch b/24123-x86-cpuidle-quiesce.patch new file mode 100644 index 0000000..eae9cd6 --- /dev/null +++ b/24123-x86-cpuidle-quiesce.patch @@ -0,0 +1,64 @@ +# HG changeset patch +# User Jan Beulich +# Date 1321017916 -3600 +# Node ID 8b08b2166aa82e7df0b1fa620ed57078810f8c12 +# Parent 4699decb8424a00447c466205be3cb4d0fb95a76 +x86: quiesce cpuidle code + +So far these messages got pointlessly (as the code in other places +assumes symmetric configuration) emitted once per CPU. Hide the debug +one behind opt_cpu_info, and issue the info one just once (if the code +gets adjusted to support assymtric configurations, this would need to +be revisited, but ideally without producing per-CPU messages again). + +Signed-off-by: Jan Beulich +Acked-by: Keir Fraser + +--- a/xen/arch/x86/acpi/cpu_idle.c ++++ b/xen/arch/x86/acpi/cpu_idle.c +@@ -659,6 +659,8 @@ static int acpi_processor_ffh_cstate_pro + unsigned int edx_part; + unsigned int cstate_type; /* C-state type and not ACPI C-state type */ + unsigned int num_cstate_subtype; ++ int ret = 0; ++ static unsigned long printed; + + if ( c->cpuid_level < CPUID_MWAIT_LEAF ) + { +@@ -667,8 +669,9 @@ static int acpi_processor_ffh_cstate_pro + } + + cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); +- printk(XENLOG_DEBUG "cpuid.MWAIT[.eax=%x, .ebx=%x, .ecx=%x, .edx=%x]\n", +- eax, ebx, ecx, edx); ++ if ( opt_cpu_info ) ++ printk(XENLOG_DEBUG "cpuid.MWAIT[eax=%x ebx=%x ecx=%x edx=%x]\n", ++ eax, ebx, ecx, edx); + + /* Check whether this particular cx_type (in CST) is supported or not */ + cstate_type = (cx->reg.address >> MWAIT_SUBSTATE_SIZE) + 1; +@@ -676,15 +679,16 @@ static int acpi_processor_ffh_cstate_pro + num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK; + + if ( num_cstate_subtype < (cx->reg.address & MWAIT_SUBSTATE_MASK) ) +- return -EFAULT; +- ++ ret = -ERANGE; + /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */ +- if ( !(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || +- !(ecx & CPUID5_ECX_INTERRUPT_BREAK) ) +- return -EFAULT; +- +- printk(XENLOG_INFO "Monitor-Mwait will be used to enter C-%d state\n", cx->type); +- return 0; ++ else if ( !(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || ++ !(ecx & CPUID5_ECX_INTERRUPT_BREAK) ) ++ ret = -ENODEV; ++ else if ( opt_cpu_info || cx->type >= BITS_PER_LONG || ++ !test_and_set_bit(cx->type, &printed) ) ++ printk(XENLOG_INFO "Monitor-Mwait will be used to enter C%d state\n", ++ cx->type); ++ return ret; + } + + /* diff --git a/24124-x86-microcode-amd-quiesce.patch b/24124-x86-microcode-amd-quiesce.patch new file mode 100644 index 0000000..8d6ccc3 --- /dev/null +++ b/24124-x86-microcode-amd-quiesce.patch @@ -0,0 +1,62 @@ +References: bnc#719700 + +# HG changeset patch +# User Jan Beulich +# Date 1321018008 -3600 +# Node ID 69f8b6f4c29cb2fb2d11e27c391090f543e6b393 +# Parent 8b08b2166aa82e7df0b1fa620ed57078810f8c12 +x86/amd-ucode: further turn down verbosity + +Turn up the log level on various (mostly debug-only) messages. + +Signed-off-by: Jan Beulich +Acked-by: Keir Fraser + +--- a/xen/arch/x86/microcode_amd.c ++++ b/xen/arch/x86/microcode_amd.c +@@ -59,7 +59,7 @@ static int collect_cpu_info(int cpu, str + + rdmsrl(MSR_AMD_PATCHLEVEL, csig->rev); + +- printk(KERN_INFO "microcode: collect_cpu_info: patch_id=0x%x\n", ++ printk(KERN_DEBUG "microcode: collect_cpu_info: patch_id=0x%x\n", + csig->rev); + + return 0; +@@ -92,7 +92,7 @@ static int microcode_fits(void *mc, int + + if ( (mc_header->processor_rev_id) != equiv_cpu_id ) + { +- printk(KERN_INFO "microcode: CPU%d patch does not match " ++ printk(KERN_DEBUG "microcode: CPU%d patch does not match " + "(patch is %x, cpu base id is %x) \n", + cpu, mc_header->processor_rev_id, equiv_cpu_id); + return -EINVAL; +@@ -101,7 +101,7 @@ static int microcode_fits(void *mc, int + if ( mc_header->patch_id <= uci->cpu_sig.rev ) + return -EINVAL; + +- printk(KERN_INFO "microcode: CPU%d found a matching microcode " ++ printk(KERN_DEBUG "microcode: CPU%d found a matching microcode " + "update with version 0x%x (current=0x%x)\n", + cpu, mc_header->patch_id, uci->cpu_sig.rev); + +@@ -139,8 +139,7 @@ static int apply_microcode(int cpu) + return -EIO; + } + +- printk("microcode: CPU%d updated from revision " +- "0x%x to 0x%x \n", ++ printk(KERN_INFO "microcode: CPU%d updated from revision %#x to %#x\n", + cpu, uci->cpu_sig.rev, mc_amd->hdr.patch_id); + + uci->cpu_sig.rev = rev; +@@ -173,7 +172,7 @@ static int get_next_ucode_from_buffer_am + + total_size = (unsigned long) (bufp[off+4] + (bufp[off+5] << 8)); + +- printk(KERN_INFO "microcode: size %lu, total_size %lu, offset %ld\n", ++ printk(KERN_DEBUG "microcode: size %lu, total_size %lu, offset %ld\n", + (unsigned long)size, total_size, off); + + if ( (off + total_size) > size ) diff --git a/24137-revert-23666.patch b/24137-revert-23666.patch new file mode 100644 index 0000000..7bc0b91 --- /dev/null +++ b/24137-revert-23666.patch @@ -0,0 +1,77 @@ +# HG changeset patch +# User Andrew Cooper +# Date 1321035275 0 +# Node ID 0844b17df7a9dd885e98e505f14fc99c1951b483 +# Parent 3622d7fae14dfc2d00f378738ace3b65ee65b6cc +Revert c/s 23666:b96f8bdcaa15 KEXEC: disconnect all PCI devices from the PCI bus on crash + +It turns out that this causes all mannor of problems on certain +motherboards (so far with no pattern I can discern) + +Problems include: +* Hanging forever checking hlt instruction. +* Panics when trying to change switch root device +* Drivers hanging when trying to check for interrupts. + +From: Andrew Cooper +Signed-off-by: Keir Fraser +Committed-by: Keir Fraser + +--- a/xen/arch/x86/crash.c ++++ b/xen/arch/x86/crash.c +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + #include + + static atomic_t waiting_for_crash_ipi; +@@ -83,8 +82,6 @@ static void nmi_shootdown_cpus(void) + msecs--; + } + +- disconnect_pci_devices(); +- + /* Crash shutdown any IOMMU functionality as the crashdump kernel is not + * happy when booting if interrupt/dma remapping is still enabled */ + iommu_crash_shutdown(); +--- a/xen/drivers/passthrough/pci.c ++++ b/xen/drivers/passthrough/pci.c +@@ -518,25 +518,6 @@ int __init scan_pci_devices(void) + return 0; + } + +-/* Disconnect all PCI devices from the PCI buses. From the PCI spec: +- * "When a 0 is written to [the COMMAND] register, the device is +- * logically disconnected from the PCI bus for all accesses except +- * configuration accesses. All devices are required to support +- * this base level of functionality." +- */ +-void disconnect_pci_devices(void) +-{ +- struct pci_dev *pdev; +- +- spin_lock(&pcidevs_lock); +- +- list_for_each_entry ( pdev, &alldevs_list, alldevs_list ) +- pci_conf_write16(pdev->bus, PCI_SLOT(pdev->devfn), +- PCI_FUNC(pdev->devfn), PCI_COMMAND, 0); +- +- spin_unlock(&pcidevs_lock); +-} +- + #ifdef SUPPORT_MSI_REMAPPING + static void dump_pci_devices(unsigned char ch) + { +--- a/xen/include/xen/pci.h ++++ b/xen/include/xen/pci.h +@@ -94,8 +94,6 @@ int pci_remove_device(u8 bus, u8 devfn); + struct pci_dev *pci_get_pdev(int bus, int devfn); + struct pci_dev *pci_get_pdev_by_domain(struct domain *d, int bus, int devfn); + +-void disconnect_pci_devices(void); +- + uint8_t pci_conf_read8( + unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg); + uint16_t pci_conf_read16( diff --git a/24144-cpufreq-turbo-crash.patch b/24144-cpufreq-turbo-crash.patch new file mode 100644 index 0000000..4991b63 --- /dev/null +++ b/24144-cpufreq-turbo-crash.patch @@ -0,0 +1,95 @@ +# HG changeset patch +# User Ian Campbell +# Date 1321363478 -3600 +# Node ID cd3ef25f207a3925f1f8650c227e24f839da13ad +# Parent 848049b14ec7fbd28bd4cd756e01609698b60c7a +xen: avoid crash enabling turbo mode + +On a system which has not had P-state information pushed down into the +hypervisor running "xenpm enable-turbo-mode" will reliably crash the host. + +(XEN) PM OP 38 on CPU0 +(XEN) ----[ Xen-4.2-unstable x86_64 debug=y Not tainted ]---- +(XEN) CPU: 0 +(XEN) RIP: e008:[] cpufreq_enable_turbo+0x1d/0x29 +(XEN) RFLAGS: 0000000000010297 CONTEXT: hypervisor +(XEN) rax: 0000000000000000 rbx: ffff82c48029fe40 rcx: 0000000000000000 +(XEN) rdx: 0000000000000000 rsi: 000000000000000a rdi: 0000000000000000 +(XEN) rbp: ffff82c48029fd08 rsp: ffff82c48029fd08 r8: 0000000000000004 +(XEN) r9: 0000000000000000 r10: 00000000fffffffd r11: ffff82c480218f20 +(XEN) r12: ffff830106e720b0 r13: 0000000000000000 r14: ffff82c4802bff80 +(XEN) r15: ffff82c48025c0e4 cr0: 000000008005003b cr4: 00000000000026f0 +(XEN) cr3: 000000011f459000 cr2: 0000000000000051 +(XEN) ds: 007b es: 007b fs: 00d8 gs: 0033 ss: 0000 cs: e008 +(XEN) Xen stack trace from rsp=ffff82c48029fd08: +(XEN) ffff82c48029fdb8 ffff82c48014c427 ffff82c48029fd98 ffff82c48016b2d6 +(XEN) ffff82c48029fdb8 ffff82c48029fd60 00000000001196c5 0000000116bbe025 +(XEN) 0000000116bbe025 ffff8301196c5338 ffff82f6022d77c0 0000000000000000 +(XEN) ffff82f60205edf0 0000000000000000 0000000000000000 ffff8300dffba000 +(XEN) ffff82c48029fdb8 ffff82c48029ff18 0000000008050004 0000000000000000 +(XEN) ffff82c4802bff80 ffff82c48025c0e4 ffff82c48029fef8 ffff82c480124fd8 +(XEN) 0000000000000000 ffff83011f48c000 0000000116bbe025 0000000000000025 +(XEN) ffff82c48029fe28 0000000080167722 ffff82c48029ff08 ffff83011f48c000 +(XEN) ffff82f60232d8a0 ffff8300dffba000 ffff83011f48c000 ffff82f60232d8a0 +(XEN) ffff82c48029fed8 ffff82c48017296a 000000080000000c 0000000000000026 +(XEN) bfb338b000000000 bfb33874bfb33868 b78988f800000000 0000008800000000 +(XEN) b787a6e0b78533a0 ffffffff00000001 080487aeb7897ff4 bfb3389000000001 +(XEN) b7898ab0b7889626 0000000100000000 0000000000000001 0804867800000001 +(XEN) 000000000804e998 00000000b78533a0 bfb33e70bfb33a7c 0000000000000000 +(XEN) 0000000000000000 ffff8300dffba000 0000000000000000 0000000000000000 +(XEN) 0000000000000000 0000000000000000 00007d3b7fd600c7 ffff82c48021511e +(XEN) 00000000c1002467 0000000000000023 0000000000000000 0000000000000000 +(XEN) 0000000000000000 0000000000000000 00000000dbf5bef8 0000000008050004 +(XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +(XEN) 0000000000000023 00000000bfb33874 00000000bfb33868 0000000000000000 +(XEN) Xen call trace: +(XEN) [] cpufreq_enable_turbo+0x1d/0x29 +(XEN) [] do_pm_op+0x884/0x8e7 +(XEN) [] do_sysctl+0x6d8/0x9f0 +(XEN) [] compat_hypercall+0xae/0x107 +(XEN) +(XEN) Pagetable walk from 0000000000000051: +(XEN) L4[0x000] = 0000000116dbc027 000000000001bd22 +(XEN) L3[0x000] = 0000000119ba8027 000000000001eb36 +(XEN) L2[0x000] = 0000000000000000 ffffffffffffffff +(XEN) +(XEN) **************************************** +(XEN) Panic on CPU 0: +(XEN) FATAL PAGE FAULT +(XEN) [error_code=0000] +(XEN) Faulting linear address: 0000000000000051 +(XEN) **************************************** +(XEN) + +Signed-off-by: Ian Campbell +Committed-by: Jan Beulich + +--- a/xen/drivers/cpufreq/utility.c ++++ b/xen/drivers/cpufreq/utility.c +@@ -400,7 +400,7 @@ void cpufreq_enable_turbo(int cpuid) + struct cpufreq_policy *policy; + + policy = per_cpu(cpufreq_cpu_policy, cpuid); +- if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED) ++ if (policy && policy->turbo != CPUFREQ_TURBO_UNSUPPORTED) + policy->turbo = CPUFREQ_TURBO_ENABLED; + } + +@@ -409,7 +409,7 @@ void cpufreq_disable_turbo(int cpuid) + struct cpufreq_policy *policy; + + policy = per_cpu(cpufreq_cpu_policy, cpuid); +- if (policy->turbo != CPUFREQ_TURBO_UNSUPPORTED) ++ if (policy && policy->turbo != CPUFREQ_TURBO_UNSUPPORTED) + policy->turbo = CPUFREQ_TURBO_DISABLED; + } + +@@ -418,7 +418,7 @@ int cpufreq_get_turbo_status(int cpuid) + struct cpufreq_policy *policy; + + policy = per_cpu(cpufreq_cpu_policy, cpuid); +- return policy->turbo; ++ return policy && policy->turbo; + } + + /********************************************************************* diff --git a/24148-shadow-pgt-dying-op-performance.patch b/24148-shadow-pgt-dying-op-performance.patch new file mode 100644 index 0000000..f73a4ed --- /dev/null +++ b/24148-shadow-pgt-dying-op-performance.patch @@ -0,0 +1,29 @@ +References: bnc#726332 + +# HG changeset patch +# User Gianluca Guida +# Date 1321456773 0 +# Node ID 3ecc8fef428138e4304ef11b47498981e63626b3 +# Parent a5f1d3b1612bb48e1cb09dc66b0909e3613dc855 +[shadow] Disable higher level pagetables early unshadow only when the "process dying" hypercall is used. + +This patch fixes a performance problem in fully virtualized guests. + +Signed-off-by: Gianluca Guida +Tested-by: Jan Beulich +Committed-by: Keir Fraser + +--- a/xen/arch/x86/mm/shadow/multi.c ++++ b/xen/arch/x86/mm/shadow/multi.c +@@ -2743,8 +2743,9 @@ static inline void check_for_early_unsha + || ( !v->domain->arch.paging.shadow.pagetable_dying_op + && v->arch.paging.shadow.last_emulated_mfn_for_unshadow == mfn_x(gmfn) ) ) + && sh_mfn_is_a_page_table(gmfn) +- && !(mfn_to_page(gmfn)->shadow_flags +- & (SHF_L2_32|SHF_L2_PAE|SHF_L2H_PAE|SHF_L4_64)) ) ++ && (!v->domain->arch.paging.shadow.pagetable_dying_op || ++ !(mfn_to_page(gmfn)->shadow_flags ++ & (SHF_L2_32|SHF_L2_PAE|SHF_L2H_PAE|SHF_L4_64))) ) + { + perfc_incr(shadow_early_unshadow); + sh_remove_shadows(v, gmfn, 1, 0 /* Fast, can fail to unshadow */ ); diff --git a/24155-x86-ioapic-EOI-after-migration.patch b/24155-x86-ioapic-EOI-after-migration.patch new file mode 100644 index 0000000..ee5e966 --- /dev/null +++ b/24155-x86-ioapic-EOI-after-migration.patch @@ -0,0 +1,130 @@ +# HG changeset patch +# User Jan Beulich +# Date 1321604321 -3600 +# Node ID 0d50e704834fb53c6c86b8b0badd19d88e73c4ed +# Parent dbdc840f8f62db58321b5009e5e0f7833066386f +x86/IO-APIC: refine EOI-ing of migrating level interrupts + +Rather than going through all IO-APICs and calling io_apic_eoi_vector() +for the vector in question, just use eoi_IO_APIC_irq(). + +This in turn allows to eliminate quite a bit of other code. + +Signed-off-by: Jan Beulich +Tested-by: Andrew Cooper +Acked-by: Andrew Cooper + +--- a/xen/arch/x86/io_apic.c ++++ b/xen/arch/x86/io_apic.c +@@ -69,10 +69,6 @@ int __read_mostly nr_ioapics; + + #define ioapic_has_eoi_reg(apic) (mp_ioapics[(apic)].mpc_apicver >= 0x20) + +-#define io_apic_eoi_vector(apic, vector) io_apic_eoi((apic), (vector), -1) +-#define io_apic_eoi_pin(apic, pin) io_apic_eoi((apic), -1, (pin)) +- +- + /* + * This is performance-critical, we want to do it O(1) + * +@@ -208,21 +204,18 @@ static void ioapic_write_entry(int apic, + spin_unlock_irqrestore(&ioapic_lock, flags); + } + +-/* EOI an IO-APIC entry. One of vector or pin may be -1, indicating that +- * it should be worked out using the other. This function expect that the +- * ioapic_lock is taken, and interrupts are disabled (or there is a good reason +- * not to), and that if both pin and vector are passed, that they refer to the ++/* EOI an IO-APIC entry. Vector may be zero, indicating that it should be ++ * worked out using the pin. This function expects that the ioapic_lock is ++ * being held, and interrupts are disabled (or there is a good reason not ++ * to), and that if both pin and vector are passed, that they refer to the + * same redirection entry in the IO-APIC. */ + static void __io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin) + { +- /* Ensure some useful information is passed in */ +- BUG_ON( (vector == -1 && pin == -1) ); +- + /* Prefer the use of the EOI register if available */ + if ( ioapic_has_eoi_reg(apic) ) + { + /* If vector is unknown, read it from the IO-APIC */ +- if ( vector == -1 ) ++ if ( !vector ) + vector = __ioapic_read_entry(apic, pin, TRUE).vector; + + *(IO_APIC_BASE(apic)+16) = vector; +@@ -234,42 +227,6 @@ static void __io_apic_eoi(unsigned int a + struct IO_APIC_route_entry entry; + bool_t need_to_unmask = 0; + +- /* If pin is unknown, search for it */ +- if ( pin == -1 ) +- { +- unsigned int p; +- for ( p = 0; p < nr_ioapic_registers[apic]; ++p ) +- { +- entry = __ioapic_read_entry(apic, p, TRUE); +- if ( entry.vector == vector ) +- { +- pin = p; +- /* break; */ +- +- /* Here should be a break out of the loop, but at the +- * Xen code doesn't actually prevent multiple IO-APIC +- * entries being assigned the same vector, so EOI all +- * pins which have the correct vector. +- * +- * Remove the following code when the above assertion +- * is fulfilled. */ +- __io_apic_eoi(apic, vector, p); +- } +- } +- +- /* If search fails, nothing to do */ +- +- /* if ( pin == -1 ) */ +- +- /* Because the loop wasn't broken out of (see comment above), +- * all relevant pins have been EOI, so we can always return. +- * +- * Re-instate the if statement above when the Xen logic has been +- * fixed.*/ +- +- return; +- } +- + entry = __ioapic_read_entry(apic, pin, TRUE); + + if ( ! entry.mask ) +@@ -296,17 +253,6 @@ static void __io_apic_eoi(unsigned int a + } + } + +-/* EOI an IO-APIC entry. One of vector or pin may be -1, indicating that +- * it should be worked out using the other. This function disables interrupts +- * and takes the ioapic_lock */ +-static void io_apic_eoi(unsigned int apic, unsigned int vector, unsigned int pin) +-{ +- unsigned int flags; +- spin_lock_irqsave(&ioapic_lock, flags); +- __io_apic_eoi(apic, vector, pin); +- spin_unlock_irqrestore(&ioapic_lock, flags); +-} +- + /* + * Saves all the IO-APIC RTE's + */ +@@ -1830,11 +1776,7 @@ static void end_level_ioapic_irq (unsign + + /* Manually EOI the old vector if we are moving to the new */ + if ( vector && i != vector ) +- { +- int ioapic; +- for (ioapic = 0; ioapic < nr_ioapics; ioapic++) +- io_apic_eoi_vector(ioapic, i); +- } ++ eoi_IO_APIC_irq(irq); + + v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); + diff --git a/24156-x86-ioapic-shared-vectors.patch b/24156-x86-ioapic-shared-vectors.patch new file mode 100644 index 0000000..793c751 --- /dev/null +++ b/24156-x86-ioapic-shared-vectors.patch @@ -0,0 +1,159 @@ +References: bnc#713503 + +# HG changeset patch +# User Jan Beulich +# Date 1321604484 -3600 +# Node ID f29b5bd6e25fd78409baa5461914c67065f7579f +# Parent 0d50e704834fb53c6c86b8b0badd19d88e73c4ed +x86/IRQ: prevent vector sharing within IO-APICs + +Following the prevention of vector sharing for MSIs, this change +enforces the same within IO-APICs: Pin based interrupts use the IO-APIC +as their identifying device under the AMD IOMMU (and just like for +MSIs, only the identifying device is used to remap interrupts here, +with no regard to an interrupt's destination). + +Additionally, LAPIC initiated EOIs (for level triggered interrupts) too +use only the vector for identifying which interrupts to end. While this +generally causes no significant problem (at worst an interrupt would be +re-raised without a new interrupt event actually having occurred), it +still seems better to avoid the situation. + +For this second aspect, a distinction is being made between the +traditional and the directed-EOI cases: In the former, vectors should +not be shared throughout all IO-APICs in the system, while in the +latter case only individual IO-APICs need to be contrained (or, if the +firmware indicates so, sub- groups of them having the same GSI appear +at multiple pins). + +Signed-off-by: Jan Beulich +Acked-by: Andrew Cooper + +--- a/xen/arch/x86/io_apic.c ++++ b/xen/arch/x86/io_apic.c +@@ -69,6 +69,34 @@ int __read_mostly nr_ioapics; + + #define ioapic_has_eoi_reg(apic) (mp_ioapics[(apic)].mpc_apicver >= 0x20) + ++static int apic_pin_2_gsi_irq(int apic, int pin); ++ ++static vmask_t *__read_mostly vector_map[MAX_IO_APICS]; ++ ++static void share_vector_maps(unsigned int src, unsigned int dst) ++{ ++ unsigned int pin; ++ ++ if (vector_map[src] == vector_map[dst]) ++ return; ++ ++ bitmap_or(vector_map[src]->_bits, vector_map[src]->_bits, ++ vector_map[dst]->_bits, NR_VECTORS); ++ ++ for (pin = 0; pin < nr_ioapic_registers[dst]; ++pin) { ++ int irq = apic_pin_2_gsi_irq(dst, pin); ++ struct irq_cfg *cfg; ++ ++ if (irq < 0) ++ continue; ++ cfg = irq_cfg(irq); ++ if (cfg->used_vectors == vector_map[dst]) ++ cfg->used_vectors = vector_map[src]; ++ } ++ ++ vector_map[dst] = vector_map[src]; ++} ++ + /* + * This is performance-critical, we want to do it O(1) + * +@@ -109,6 +137,7 @@ static void add_pin_to_irq(unsigned int + } + entry->apic = apic; + entry->pin = pin; ++ share_vector_maps(irq_2_pin[irq].apic, apic); + } + + /* +@@ -124,6 +153,7 @@ static void __init replace_pin_at_irq(un + if (entry->apic == oldapic && entry->pin == oldpin) { + entry->apic = newapic; + entry->pin = newpin; ++ share_vector_maps(oldapic, newapic); + } + if (!entry->next) + break; +@@ -131,6 +161,16 @@ static void __init replace_pin_at_irq(un + } + } + ++vmask_t *io_apic_get_used_vector_map(unsigned int irq) ++{ ++ struct irq_pin_list *entry = irq_2_pin + irq; ++ ++ if (entry->pin == -1) ++ return NULL; ++ ++ return vector_map[entry->apic]; ++} ++ + struct IO_APIC_route_entry **alloc_ioapic_entries(void) + { + int apic; +@@ -1314,6 +1354,18 @@ static void __init enable_IO_APIC(void) + for (i = irq_2_pin_free_entry = nr_irqs_gsi; i < PIN_MAP_SIZE; i++) + irq_2_pin[i].next = i + 1; + ++ if (directed_eoi_enabled) { ++ for (apic = 0; apic < nr_ioapics; apic++) { ++ vector_map[apic] = xzalloc(vmask_t); ++ BUG_ON(!vector_map[apic]); ++ } ++ } else { ++ vector_map[0] = xzalloc(vmask_t); ++ BUG_ON(!vector_map[0]); ++ for (apic = 1; apic < nr_ioapics; apic++) ++ vector_map[apic] = vector_map[0]; ++ } ++ + for(apic = 0; apic < nr_ioapics; apic++) { + int pin; + /* See if any of the pins is in ExtINT mode */ +@@ -2479,13 +2531,12 @@ int ioapic_guest_write(unsigned long phy + } + + if ( cfg->vector <= 0 || cfg->vector > LAST_DYNAMIC_VECTOR ) { ++ add_pin_to_irq(irq, apic, pin); + vector = assign_irq_vector(irq); + if ( vector < 0 ) + return vector; + + printk(XENLOG_INFO "allocated vector %02x for irq %d\n", vector, irq); +- +- add_pin_to_irq(irq, apic, pin); + } + spin_lock(&pcidevs_lock); + spin_lock(&dom0->event_lock); +--- a/xen/arch/x86/irq.c ++++ b/xen/arch/x86/irq.c +@@ -403,6 +403,11 @@ static vmask_t *irq_get_used_vector_mask + } + } + } ++ else if ( IO_APIC_IRQ(irq) && ++ opt_irq_vector_map != OPT_IRQ_VECTOR_MAP_NONE ) ++ { ++ ret = io_apic_get_used_vector_map(irq); ++ } + + return ret; + } +--- a/xen/include/asm-x86/irq.h ++++ b/xen/include/asm-x86/irq.h +@@ -113,6 +113,7 @@ void setup_IO_APIC(void); + void disable_IO_APIC(void); + void print_IO_APIC(void); + void setup_ioapic_dest(void); ++vmask_t *io_apic_get_used_vector_map(unsigned int irq); + + extern unsigned long io_apic_irqs; + diff --git a/24157-x86-xstate-init.patch b/24157-x86-xstate-init.patch new file mode 100644 index 0000000..e1e0170 --- /dev/null +++ b/24157-x86-xstate-init.patch @@ -0,0 +1,96 @@ +# HG changeset patch +# User Jan Beulich +# Date 1321604565 -3600 +# Node ID 7b5e1cb94bfa43a9268479b9a255fb88c07e4ce2 +# Parent f29b5bd6e25fd78409baa5461914c67065f7579f +x86/xsave: provide guests with finit-like environment + +Without the use of xsave, guests get their initial floating point +environment set up with finit. At least NetWare actually depends on +this (in particular on all exceptions being masked), so to be +consistent set the same environment also when using xsave. This is +also in line with all SSE exceptions getting masked initially. + +To avoid further fragile casts in xstate_alloc_save_area() the patch +also changes xsave_struct's fpu_see member to have actually usable +fields. + +The patch was tested in its technically identical, but modified-file- +wise different 4.1.2 version. + +Signed-off-by: Jan Beulich +Tested-by: Charles Arnold +Acked-by: Keir Fraser + +--- a/xen/arch/x86/i387.c ++++ b/xen/arch/x86/i387.c +@@ -92,11 +92,14 @@ void setup_fpu(struct vcpu *v) + v->fpu_dirtied = 1; + } + ++#define FCW_DEFAULT 0x037f ++#define MXCSR_DEFAULT 0x1f80 ++ + static void init_fpu(void) + { + asm volatile ( "fninit" ); + if ( cpu_has_xmm ) +- load_mxcsr(0x1f80); ++ load_mxcsr(MXCSR_DEFAULT); + } + + void save_init_fpu(struct vcpu *v) +@@ -287,7 +290,7 @@ void xsave_init(void) + + int xsave_alloc_save_area(struct vcpu *v) + { +- void *save_area; ++ struct xsave_struct *save_area; + + if ( !cpu_has_xsave || is_idle_vcpu(v) ) + return 0; +@@ -300,8 +303,9 @@ int xsave_alloc_save_area(struct vcpu *v + return -ENOMEM; + + memset(save_area, 0, xsave_cntxt_size); +- ((u32 *)save_area)[6] = 0x1f80; /* MXCSR */ +- *(uint64_t *)(save_area + 512) = XSTATE_FP_SSE; /* XSETBV */ ++ save_area->fpu_sse.fcw = FCW_DEFAULT; ++ save_area->fpu_sse.mxcsr = MXCSR_DEFAULT; ++ save_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE; + + v->arch.xsave_area = save_area; + v->arch.xcr0 = XSTATE_FP_SSE; +--- a/xen/include/asm-x86/i387.h ++++ b/xen/include/asm-x86/i387.h +@@ -37,7 +37,29 @@ bool_t xsave_enabled(const struct vcpu * + + struct xsave_struct + { +- struct { char x[512]; } fpu_sse; /* FPU/MMX, SSE */ ++ union { /* FPU/MMX, SSE */ ++ char x[512]; ++ struct { ++ uint16_t fcw; ++ uint16_t fsw; ++ uint8_t ftw; ++ uint8_t rsvd1; ++ uint16_t fop; ++ union { ++#ifdef __x86_64__ ++ uint64_t addr; ++#endif ++ struct { ++ uint32_t offs; ++ uint16_t sel; ++ uint16_t rsvd; ++ }; ++ } fip, fdp; ++ uint32_t mxcsr; ++ uint32_t mxcsr_mask; ++ /* data registers follow here */ ++ }; ++ } fpu_sse; + + struct { + u64 xstate_bv; diff --git a/24168-x86-vioapic-clear-remote_irr.patch b/24168-x86-vioapic-clear-remote_irr.patch new file mode 100644 index 0000000..a2b9c6d --- /dev/null +++ b/24168-x86-vioapic-clear-remote_irr.patch @@ -0,0 +1,30 @@ +References: bnc#694863 + +# HG changeset patch +# User Jan Beulich +# Date 1321864171 -3600 +# Node ID 9c350ab8d3ea64866421de756ab2bf3daaf63187 +# Parent 335e8273a3f34a5e2972643a028f83684609f1c1 +x86/vioapic: clear remote IRR when switching RTE to edge triggered mode + +Xen itself (as much as Linux) relies on this behavior, so it should +also emulate it properly. Not doing so reportedly gets in the way of +kexec inside a HVM guest. + +Signed-off-by: Jan Beulich +Tested-by: Olaf Hering + +--- a/xen/arch/x86/hvm/vioapic.c ++++ b/xen/arch/x86/hvm/vioapic.c +@@ -154,8 +154,9 @@ static void vioapic_write_redirent( + { + vlapic_adjust_i8259_target(d); + } +- else if ( (ent.fields.trig_mode == VIOAPIC_LEVEL_TRIG) && +- !ent.fields.mask && ++ else if ( ent.fields.trig_mode == VIOAPIC_EDGE_TRIG ) ++ pent->fields.remote_irr = 0; ++ else if ( !ent.fields.mask && + !ent.fields.remote_irr && + hvm_irq->gsi_assert_count[idx] ) + { diff --git a/2XXXX-vif-bridge.patch b/2XXXX-vif-bridge.patch new file mode 100644 index 0000000..0d480b0 --- /dev/null +++ b/2XXXX-vif-bridge.patch @@ -0,0 +1,29 @@ +# HG changeset patch +# User Jim Fehlig +# Date 1319581952 21600 +# Node ID 74da2a3a1db1476d627f42e4a99e9e720cc6774d +# Parent 6c583d35d76dda2236c81d9437ff9d57ab02c006 +Prevent vif-bridge from adding user-created tap interfaces to a bridge + +Exit vif-bridge script if there is no device info in xenstore, preventing +it from adding user-created taps to bridges. + + Signed-off-by: Jim Fehlig + +diff -r 6c583d35d76d -r 74da2a3a1db1 tools/hotplug/Linux/vif-bridge +--- a/tools/hotplug/Linux/vif-bridge Thu Oct 20 15:36:01 2011 +0100 ++++ b/tools/hotplug/Linux/vif-bridge Tue Oct 25 16:32:32 2011 -0600 +@@ -31,6 +31,13 @@ + + dir=$(dirname "$0") + . "$dir/vif-common.sh" ++ ++domu=$(xenstore_read_default "$XENBUS_PATH/domain" "") ++if [ -z "$domu" ] ++then ++ log debug "No device details in $XENBUS_PATH, exiting." ++ exit 0 ++fi + + bridge=${bridge:-} + bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge") diff --git a/suspend_evtchn_lock.patch b/suspend_evtchn_lock.patch index 9ed5749..7d05d4c 100644 --- a/suspend_evtchn_lock.patch +++ b/suspend_evtchn_lock.patch @@ -1,87 +1,84 @@ -Improve suspend eventchn lock, use flock instead of exclusive lock -file to avoid that sometimes the lock file is not removed cleanly -and affacts later getting lock. -http://lists.xensource.com/archives/html/xen-devel/2010-11/msg01559.html +Fix problems that suspend eventchannel lock file might be obselete for some reason +like segment fault or other abnormal exit, and once obselete lock file exists, +it might affact latter save process. +Have discussed with upstream, for some reason not accepted. +http://xen.1045712.n5.nabble.com/Re-PATCH-improve-suspend-evtchn-lock-processing-td3395229.html -Signed-off-by cyliu@novell.com +Signed-off-by: Chunyan Liu -Index: xen-4.0.1-testing/tools/libxc/xc_suspend.c +Index: xen-4.1.2-testing/tools/libxc/xc_suspend.c =================================================================== ---- xen-4.0.1-testing.orig/tools/libxc/xc_suspend.c -+++ xen-4.0.1-testing/tools/libxc/xc_suspend.c -@@ -6,25 +6,25 @@ +--- xen-4.1.2-testing.orig/tools/libxc/xc_suspend.c ++++ xen-4.1.2-testing/tools/libxc/xc_suspend.c +@@ -16,8 +16,43 @@ #include "xc_private.h" #include "xenguest.h" -+#include -+#include ++#include ++#ifdef __MINIOS__ ++extern int kill (__pid_t __pid, int __sig); ++#endif - #define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn_lock.d" - static int lock_suspend_event(void) + #define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn" ++/* cleanup obsolete suspend lock file which is unlinked for any reason, ++so that current process can get lock */ ++static void clean_obsolete_lock(int domid) ++{ ++ int fd, pid, n; ++ char buf[128]; ++ char suspend_file[256]; ++ ++ snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d", ++ SUSPEND_LOCK_FILE, domid); ++ fd = open(suspend_file, O_RDWR); ++ ++ if (fd < 0) ++ return; ++ ++ n = read(fd, buf, 127); ++ ++ close(fd); ++ ++ if (n > 0) ++ { ++ sscanf(buf, "%d", &pid); ++ /* pid does not exist, this lock file is obsolete, just delete it */ ++ if ( kill(pid,0) ) ++ { ++ unlink(suspend_file); ++ return; ++ } ++ } ++} ++ + static int lock_suspend_event(xc_interface *xch, int domid) { int fd, rc; - mode_t mask; -- char buf[128]; +@@ -27,6 +62,7 @@ static int lock_suspend_event(xc_interfa + snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d", + SUSPEND_LOCK_FILE, domid); ++ clean_obsolete_lock(domid); mask = umask(022); -- fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0666); -+ fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_RDWR, 0666); + fd = open(suspend_file, O_CREAT | O_EXCL | O_RDWR, 0666); if (fd < 0) - { - ERROR("Can't create lock file for suspend event channel\n"); - return -EINVAL; - } - umask(mask); -- snprintf(buf, sizeof(buf), "%10ld", (long)getpid()); -+ rc = flock(fd, LOCK_EX | LOCK_NB); - -- rc = write_exact(fd, buf, strlen(buf)); +@@ -41,6 +77,9 @@ static int lock_suspend_event(xc_interfa + rc = write_exact(fd, buf, strlen(buf)); close(fd); ++ if(rc) ++ unlink(suspend_file); ++ return rc; -@@ -32,30 +32,21 @@ static int lock_suspend_event(void) - - static int unlock_suspend_event(void) - { -- int fd, pid, n; -- char buf[128]; -+ int fd, rc; - - fd = open(SUSPEND_LOCK_FILE, O_RDWR); - - if (fd < 0) - return -EINVAL; - -- n = read(fd, buf, 127); -+ rc = flock(fd, LOCK_UN | LOCK_NB); - - close(fd); - -- if (n > 0) -- { -- sscanf(buf, "%d", &pid); -- /* We are the owner, so we can simply delete the file */ -- if (pid == getpid()) -- { -- unlink(SUSPEND_LOCK_FILE); -- return 0; -- } -- } -+ if(!rc) -+ unlink(SUSPEND_LOCK_FILE); - -- return -EPERM; -+ return rc; } - int xc_await_suspend(int xce, int suspend_evtchn) -@@ -110,8 +101,7 @@ int xc_suspend_evtchn_init(int xc, int x +@@ -127,8 +166,7 @@ int xc_suspend_evtchn_init(xc_interface return suspend_evtchn; cleanup: - if (suspend_evtchn != -1) -- xc_suspend_evtchn_release(xce, suspend_evtchn); -+ xc_suspend_evtchn_release(xce, suspend_evtchn); +- xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn); ++ xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn); return -1; } diff --git a/tmp-initscript-modprobe.patch b/tmp-initscript-modprobe.patch index 62810d0..303215e 100644 --- a/tmp-initscript-modprobe.patch +++ b/tmp-initscript-modprobe.patch @@ -2,7 +2,7 @@ Index: xen-4.1.2-testing/tools/hotplug/Linux/init.d/xencommons =================================================================== --- xen-4.1.2-testing.orig/tools/hotplug/Linux/init.d/xencommons +++ xen-4.1.2-testing/tools/hotplug/Linux/init.d/xencommons -@@ -57,6 +57,18 @@ do_start () { +@@ -57,6 +57,20 @@ do_start () { local time=0 local timeout=30 @@ -17,6 +17,8 @@ Index: xen-4.1.2-testing/tools/hotplug/Linux/init.d/xencommons + modprobe usbbk 2>/dev/null || true + # xenblk (frontend module) is needed in dom0, allowing it to use vbds + modprobe xenblk 2>/dev/null || true ++ # support xl create pv guest with qcow/qcow2 disk image ++ modprobe nbd max_part=8 2>/dev/null || true + if ! `xenstore-read -s / >/dev/null 2>&1` then diff --git a/vif-bridge.mtu.patch b/vif-bridge.mtu.patch index e6ddc0b..e455b78 100644 --- a/vif-bridge.mtu.patch +++ b/vif-bridge.mtu.patch @@ -19,7 +19,7 @@ Index: xen-4.1.2-testing/tools/hotplug/Linux/vif-bridge =================================================================== --- xen-4.1.2-testing.orig/tools/hotplug/Linux/vif-bridge +++ xen-4.1.2-testing/tools/hotplug/Linux/vif-bridge -@@ -97,6 +97,11 @@ case "$command" in +@@ -104,6 +104,11 @@ case "$command" in add) setup_virtual_bridge_port "$dev" diff --git a/x86-ioapic-ack-default.patch b/x86-ioapic-ack-default.patch index dfa0f01..852362b 100644 --- a/x86-ioapic-ack-default.patch +++ b/x86-ioapic-ack-default.patch @@ -2,7 +2,7 @@ Change default IO-APIC ack mode for single IO-APIC systems to old-style. --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c -@@ -1674,7 +1674,7 @@ static unsigned int startup_level_ioapic +@@ -1679,7 +1679,7 @@ static unsigned int startup_level_ioapic return 0; /* don't check for pending */ } @@ -11,7 +11,7 @@ Change default IO-APIC ack mode for single IO-APIC systems to old-style. static void setup_ioapic_ack(char *s) { if ( !strcmp(s, "old") ) -@@ -2179,6 +2179,8 @@ void __init setup_IO_APIC(void) +@@ -2180,6 +2180,8 @@ void __init setup_IO_APIC(void) else io_apic_irqs = ~PIC_IRQS; diff --git a/xen-cpupool-xl-config-format.patch b/xen-cpupool-xl-config-format.patch new file mode 100644 index 0000000..2c79c8f --- /dev/null +++ b/xen-cpupool-xl-config-format.patch @@ -0,0 +1,25 @@ +Index: xen-4.1.2-testing/tools/python/xen/xm/cpupool.py +=================================================================== +--- xen-4.1.2-testing.orig/tools/python/xen/xm/cpupool.py ++++ xen-4.1.2-testing/tools/python/xen/xm/cpupool.py +@@ -157,9 +157,17 @@ def make_cpus_config(cfg_cpus): + # ["0,2","1,3"] -> [[0,2],[1,3]] + # ["0-3,^1","1-4,^2"] -> [[0,2,3],[1,3,4]] + try: +- for c in cfg_cpus: +- cpus = cnv(c) +- cpus_list.append(cpus) ++ cpus_str = "" ++ list_len = len(cfg_cpus) ++ n = 0 ++ while n < list_len: ++ if type(cfg_cpus[n]) != str: ++ raise SyntaxError('cpus = %s' % cfg_cpus) ++ cpus_str += cfg_cpus[n] ++ n += 1 ++ if n < list_len: ++ cpus_str += ', ' ++ cpus_list = cnv(cpus_str) + except ValueError, e: + raise err('cpus = %s: %s' % (cfg_cpus, e)) + else: diff --git a/xen-warnings-unused.diff b/xen-warnings-unused.diff index 7784cc5..696a8e0 100644 --- a/xen-warnings-unused.diff +++ b/xen-warnings-unused.diff @@ -1,7 +1,5 @@ -Index: xen-4.1.2-testing/tools/libxc/xc_tmem.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxc/xc_tmem.c -+++ xen-4.1.2-testing/tools/libxc/xc_tmem.c +--- a/tools/libxc/xc_tmem.c ++++ b/tools/libxc/xc_tmem.c @@ -390,7 +390,8 @@ static int xc_tmem_restore_new_pool( int xc_tmem_restore(xc_interface *xch, int dom, int io_fd) @@ -12,10 +10,8 @@ Index: xen-4.1.2-testing/tools/libxc/xc_tmem.c uint32_t this_max_pools, this_version; uint32_t pool_id; uint32_t minusone; -Index: xen-4.1.2-testing/tools/libxc/xc_domain_restore.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxc/xc_domain_restore.c -+++ xen-4.1.2-testing/tools/libxc/xc_domain_restore.c +--- a/tools/libxc/xc_domain_restore.c ++++ b/tools/libxc/xc_domain_restore.c @@ -1087,7 +1087,6 @@ int xc_domain_restore(xc_interface *xch, int vcpuextstate = 0; uint32_t vcpuextstate_size = 0; @@ -32,10 +28,8 @@ Index: xen-4.1.2-testing/tools/libxc/xc_domain_restore.c n = m = 0; loadpages: -Index: xen-4.1.2-testing/tools/misc/gtraceview.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/misc/gtraceview.c -+++ xen-4.1.2-testing/tools/misc/gtraceview.c +--- a/tools/misc/gtraceview.c ++++ b/tools/misc/gtraceview.c @@ -622,7 +622,8 @@ void crt_init(void) void nr_addch(int nr, int ch) { @@ -46,10 +40,8 @@ Index: xen-4.1.2-testing/tools/misc/gtraceview.c getyx(stdscr, y, x); for (i = 0; i < nr; i++) { if (x == COLS-1) -Index: xen-4.1.2-testing/tools/xcutils/xc_restore.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/xcutils/xc_restore.c -+++ xen-4.1.2-testing/tools/xcutils/xc_restore.c +--- a/tools/xcutils/xc_restore.c ++++ b/tools/xcutils/xc_restore.c @@ -19,7 +19,8 @@ int main(int argc, char **argv) { @@ -60,10 +52,8 @@ Index: xen-4.1.2-testing/tools/xcutils/xc_restore.c xc_interface *xch; int io_fd, ret; int superpages; -Index: xen-4.1.2-testing/tools/firmware/rombios/32bit/tcgbios/tcgbios.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/firmware/rombios/32bit/tcgbios/tcgbios.c -+++ xen-4.1.2-testing/tools/firmware/rombios/32bit/tcgbios/tcgbios.c +--- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c ++++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c @@ -1064,7 +1064,7 @@ uint32_t HashLogEvent32(struct hlei *hle uint32_t rc = 0; uint16_t size; @@ -73,10 +63,8 @@ Index: xen-4.1.2-testing/tools/firmware/rombios/32bit/tcgbios/tcgbios.c uint32_t hashdataptr; uint32_t hashdatalen; -Index: xen-4.1.2-testing/tools/console/client/main.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/console/client/main.c -+++ xen-4.1.2-testing/tools/console/client/main.c +--- a/tools/console/client/main.c ++++ b/tools/console/client/main.c @@ -277,7 +277,8 @@ int main(int argc, char **argv) }; @@ -87,10 +75,8 @@ Index: xen-4.1.2-testing/tools/console/client/main.c struct xs_handle *xs; char *end; console_type type = CONSOLE_INVAL; -Index: xen-4.1.2-testing/tools/xenstat/xentop/xentop.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/xenstat/xentop/xentop.c -+++ xen-4.1.2-testing/tools/xenstat/xentop/xentop.c +--- a/tools/xenstat/xentop/xentop.c ++++ b/tools/xenstat/xentop/xentop.c @@ -272,7 +272,8 @@ static void fail(const char *str) /* Return the row containing the cursor. */ static int current_row(void) @@ -111,11 +97,9 @@ Index: xen-4.1.2-testing/tools/xenstat/xentop/xentop.c getmaxyx(stdscr, y, x); return y; } -Index: xen-4.1.2-testing/tools/libxl/libxlu_cfg.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxl/libxlu_cfg.c -+++ xen-4.1.2-testing/tools/libxl/libxlu_cfg.c -@@ -348,7 +348,7 @@ char *xlu__cfgl_dequote(CfgParseContext +--- a/tools/libxl/libxlu_cfg.c ++++ b/tools/libxl/libxlu_cfg.c +@@ -348,7 +348,7 @@ char *xlu__cfgl_dequote(CfgParseContext #define NUMERIC_CHAR(minlen,maxlen,base,basetext) do{ \ char numbuf[(maxlen)+1], *ep; \ @@ -124,11 +108,9 @@ Index: xen-4.1.2-testing/tools/libxl/libxlu_cfg.c \ strncpy(numbuf,p,(maxlen)); \ numbuf[(maxlen)]= 0; \ -Index: xen-4.1.2-testing/tools/libxl/libxl.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxl/libxl.c -+++ xen-4.1.2-testing/tools/libxl/libxl.c -@@ -221,7 +221,7 @@ int libxl_domain_rename(libxl_ctx *ctx, +--- a/tools/libxl/libxl.c ++++ b/tools/libxl/libxl.c +@@ -221,7 +221,7 @@ int libxl_domain_rename(libxl_ctx *ctx, int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) { libxl__gc gc = LIBXL_INIT_GC(ctx); @@ -155,10 +137,8 @@ Index: xen-4.1.2-testing/tools/libxl/libxl.c libxl__sprintf(&gc, "%s/device/vif", dompath), &nb_nics); if (!l) goto err; -Index: xen-4.1.2-testing/tools/libxl/libxl_pci.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxl/libxl_pci.c -+++ xen-4.1.2-testing/tools/libxl/libxl_pci.c +--- a/tools/libxl/libxl_pci.c ++++ b/tools/libxl/libxl_pci.c @@ -240,7 +240,7 @@ static int libxl_create_pci_backend(libx flexarray_t *front = NULL; flexarray_t *back = NULL; @@ -177,10 +157,8 @@ Index: xen-4.1.2-testing/tools/libxl/libxl_pci.c LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Creating pci backend"); /* add pci device */ -Index: xen-4.1.2-testing/tools/libxl/libxl_dom.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxl/libxl_dom.c -+++ xen-4.1.2-testing/tools/libxl/libxl_dom.c +--- a/tools/libxl/libxl_dom.c ++++ b/tools/libxl/libxl_dom.c @@ -265,14 +265,13 @@ int libxl__build_hvm(libxl_ctx *ctx, uin libxl_domain_build_info *info, libxl_domain_build_state *state) { @@ -205,10 +183,8 @@ Index: xen-4.1.2-testing/tools/libxl/libxl_dom.c out: libxl__free_all(&gc); return 0; -Index: xen-4.1.2-testing/tools/libxl/libxl_utils.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxl/libxl_utils.c -+++ xen-4.1.2-testing/tools/libxl/libxl_utils.c +--- a/tools/libxl/libxl_utils.c ++++ b/tools/libxl/libxl_utils.c @@ -531,7 +531,7 @@ int libxl_devid_to_device_disk(libxl_ctx libxl__gc gc = LIBXL_INIT_GC(ctx); char *val; @@ -218,10 +194,8 @@ Index: xen-4.1.2-testing/tools/libxl/libxl_utils.c int rc = ERROR_INVAL; devid_n = libxl__device_disk_dev_number(devid); -Index: xen-4.1.2-testing/tools/libxl/xl_cmdimpl.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/libxl/xl_cmdimpl.c -+++ xen-4.1.2-testing/tools/libxl/xl_cmdimpl.c +--- a/tools/libxl/xl_cmdimpl.c ++++ b/tools/libxl/xl_cmdimpl.c @@ -5448,7 +5448,7 @@ int main_cpupoollist(int argc, char **ar {"cpus", 0, 0, 'c'}, {0, 0, 0, 0} @@ -231,10 +205,8 @@ Index: xen-4.1.2-testing/tools/libxl/xl_cmdimpl.c int opt_cpus = 0; const char *pool = NULL; libxl_cpupoolinfo *poolinfo; -Index: xen-4.1.2-testing/tools/debugger/gdbsx/gx/gx_comm.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/debugger/gdbsx/gx/gx_comm.c -+++ xen-4.1.2-testing/tools/debugger/gdbsx/gx/gx_comm.c +--- a/tools/debugger/gdbsx/gx/gx_comm.c ++++ b/tools/debugger/gdbsx/gx/gx_comm.c @@ -163,7 +163,7 @@ readchar(void) static char buf[BUFSIZ]; static int bufcnt = 0; @@ -244,10 +216,8 @@ Index: xen-4.1.2-testing/tools/debugger/gdbsx/gx/gx_comm.c if (bufcnt-- > 0) return *bufp++ & 0x7f; -Index: xen-4.1.2-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c -+++ xen-4.1.2-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c +--- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c ++++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c @@ -820,7 +820,7 @@ static int create_suspend_thread(checkpo static void stop_suspend_thread(checkpoint_state* s) @@ -257,10 +227,8 @@ Index: xen-4.1.2-testing/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c s->done = 1; -Index: xen-4.1.2-testing/tools/python/xen/lowlevel/netlink/libnetlink.c -=================================================================== ---- xen-4.1.2-testing.orig/tools/python/xen/lowlevel/netlink/libnetlink.c -+++ xen-4.1.2-testing/tools/python/xen/lowlevel/netlink/libnetlink.c +--- a/tools/python/xen/lowlevel/netlink/libnetlink.c ++++ b/tools/python/xen/lowlevel/netlink/libnetlink.c @@ -433,7 +433,8 @@ int rtnl_from_file(FILE *rtnl, rtnl_filt nladdr.nl_groups = 0; @@ -271,10 +239,8 @@ Index: xen-4.1.2-testing/tools/python/xen/lowlevel/netlink/libnetlink.c int l; status = fread(&buf, 1, sizeof(*h), rtnl); -Index: xen-4.1.2-testing/xen/arch/x86/msi.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/msi.c -+++ xen-4.1.2-testing/xen/arch/x86/msi.c +--- a/xen/arch/x86/msi.c ++++ b/xen/arch/x86/msi.c @@ -799,7 +799,7 @@ static void __pci_disable_msi(struct msi { struct pci_dev *dev; @@ -284,11 +250,9 @@ Index: xen-4.1.2-testing/xen/arch/x86/msi.c u8 bus, slot, func; dev = entry->dev; -Index: xen-4.1.2-testing/xen/arch/x86/microcode_amd.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/microcode_amd.c -+++ xen-4.1.2-testing/xen/arch/x86/microcode_amd.c -@@ -151,7 +151,7 @@ static int apply_microcode(int cpu) +--- a/xen/arch/x86/microcode_amd.c ++++ b/xen/arch/x86/microcode_amd.c +@@ -150,7 +150,7 @@ static int apply_microcode(int cpu) static int get_next_ucode_from_buffer_amd(void *mc, const void *buf, size_t size, unsigned long *offset) { @@ -297,10 +261,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/microcode_amd.c size_t total_size; const uint8_t *bufp = buf; unsigned long off; -Index: xen-4.1.2-testing/xen/common/cpupool.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/cpupool.c -+++ xen-4.1.2-testing/xen/common/cpupool.c +--- a/xen/common/cpupool.c ++++ b/xen/common/cpupool.c @@ -356,7 +356,7 @@ int cpupool_add_domain(struct domain *d, { struct cpupool *c; @@ -321,10 +283,8 @@ Index: xen-4.1.2-testing/xen/common/cpupool.c if ( d->cpupool == NULL ) return; -Index: xen-4.1.2-testing/xen/common/grant_table.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/grant_table.c -+++ xen-4.1.2-testing/xen/common/grant_table.c +--- a/xen/common/grant_table.c ++++ b/xen/common/grant_table.c @@ -765,7 +765,7 @@ __gnttab_unmap_common( struct domain *ld, *rd; struct active_grant_entry *act; @@ -334,10 +294,8 @@ Index: xen-4.1.2-testing/xen/common/grant_table.c ld = current->domain; -Index: xen-4.1.2-testing/xen/common/kexec.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/kexec.c -+++ xen-4.1.2-testing/xen/common/kexec.c +--- a/xen/common/kexec.c ++++ b/xen/common/kexec.c @@ -569,7 +569,8 @@ static int kexec_exec(XEN_GUEST_HANDLE(v { xen_kexec_exec_t exec; @@ -348,10 +306,8 @@ Index: xen-4.1.2-testing/xen/common/kexec.c if ( unlikely(copy_from_guest(&exec, uarg, 1)) ) return -EFAULT; -Index: xen-4.1.2-testing/xen/drivers/passthrough/vtd/intremap.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/drivers/passthrough/vtd/intremap.c -+++ xen-4.1.2-testing/xen/drivers/passthrough/vtd/intremap.c +--- a/xen/drivers/passthrough/vtd/intremap.c ++++ b/xen/drivers/passthrough/vtd/intremap.c @@ -367,7 +367,7 @@ unsigned int io_apic_read_remap_rte( unsigned int ioapic_pin = (reg - 0x10) / 2; int index; @@ -370,10 +326,8 @@ Index: xen-4.1.2-testing/xen/drivers/passthrough/vtd/intremap.c iommu = drhd->iommu; qi_ctrl = iommu_qi_ctrl(iommu); -Index: xen-4.1.2-testing/xen/common/sched_credit2.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/sched_credit2.c -+++ xen-4.1.2-testing/xen/common/sched_credit2.c +--- a/xen/common/sched_credit2.c ++++ b/xen/common/sched_credit2.c @@ -1854,7 +1854,8 @@ static void deactivate_runqueue(struct c static void init_pcpu(const struct scheduler *ops, int cpu) @@ -384,11 +338,9 @@ Index: xen-4.1.2-testing/xen/common/sched_credit2.c struct csched_private *prv = CSCHED_PRIV(ops); struct csched_runqueue_data *rqd; spinlock_t *old_lock; -Index: xen-4.1.2-testing/xen/common/unlzo.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/unlzo.c -+++ xen-4.1.2-testing/xen/common/unlzo.c -@@ -68,7 +68,7 @@ static int INIT parse_header(u8 *input, +--- a/xen/common/unlzo.c ++++ b/xen/common/unlzo.c +@@ -68,7 +68,7 @@ static int INIT parse_header(u8 *input, { int l; u8 *parse = input; @@ -397,10 +349,8 @@ Index: xen-4.1.2-testing/xen/common/unlzo.c u16 version; /* read magic: 9 first bits */ -Index: xen-4.1.2-testing/xen/arch/x86/time.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/time.c -+++ xen-4.1.2-testing/xen/arch/x86/time.c +--- a/xen/arch/x86/time.c ++++ b/xen/arch/x86/time.c @@ -1009,7 +1009,8 @@ static void local_time_calibration(void) * System timestamps, extrapolated from local and master oscillators, * taken during this calibration and the previous calibration. @@ -411,10 +361,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/time.c s_time_t prev_master_stime, curr_master_stime; /* TSC timestamps taken during this calibration and prev calibration. */ -Index: xen-4.1.2-testing/xen/arch/x86/cpu/amd.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/cpu/amd.c -+++ xen-4.1.2-testing/xen/arch/x86/cpu/amd.c +--- a/xen/arch/x86/cpu/amd.c ++++ b/xen/arch/x86/cpu/amd.c @@ -391,7 +391,7 @@ static void __devinit init_amd(struct cp { u32 l, h; @@ -424,11 +372,9 @@ Index: xen-4.1.2-testing/xen/arch/x86/cpu/amd.c #ifdef CONFIG_SMP unsigned long long value; -Index: xen-4.1.2-testing/xen/arch/x86/mm/p2m.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/mm/p2m.c -+++ xen-4.1.2-testing/xen/arch/x86/mm/p2m.c -@@ -2338,7 +2338,7 @@ p2m_remove_page(struct p2m_domain *p2m, +--- a/xen/arch/x86/mm/p2m.c ++++ b/xen/arch/x86/mm/p2m.c +@@ -2338,7 +2338,7 @@ p2m_remove_page(struct p2m_domain *p2m, unsigned int page_order) { unsigned long i; @@ -446,10 +392,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/mm/p2m.c int pod_count = 0; int rc = 0; -Index: xen-4.1.2-testing/xen/arch/x86/hvm/emulate.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/hvm/emulate.c -+++ xen-4.1.2-testing/xen/arch/x86/hvm/emulate.c +--- a/xen/arch/x86/hvm/emulate.c ++++ b/xen/arch/x86/hvm/emulate.c @@ -59,7 +59,7 @@ static int hvmemul_do_io( ioreq_t *p = get_ioreq(curr); unsigned long ram_gfn = paddr_to_pfn(ram_gpa); @@ -459,10 +403,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/hvm/emulate.c int rc; /* Check for paged out page */ -Index: xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/hvm/hvm.c -+++ xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c +--- a/xen/arch/x86/hvm/hvm.c ++++ b/xen/arch/x86/hvm/hvm.c @@ -253,7 +253,8 @@ void hvm_migrate_timers(struct vcpu *v) void hvm_migrate_pirqs(struct vcpu *v) @@ -482,10 +424,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c mfn = gfn_to_mfn_unshare(p2m, pfn, &t, 0); if ( p2m_is_paging(t) ) { -Index: xen-4.1.2-testing/xen/arch/x86/acpi/cpu_idle.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/acpi/cpu_idle.c -+++ xen-4.1.2-testing/xen/arch/x86/acpi/cpu_idle.c +--- a/xen/arch/x86/acpi/cpu_idle.c ++++ b/xen/arch/x86/acpi/cpu_idle.c @@ -275,7 +275,7 @@ static void acpi_processor_ffh_cstate_en static void acpi_idle_do_entry(struct acpi_processor_cx *cx) @@ -495,10 +435,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/acpi/cpu_idle.c switch ( cx->entry_method ) { -Index: xen-4.1.2-testing/xen/arch/x86/cpu/intel_cacheinfo.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/cpu/intel_cacheinfo.c -+++ xen-4.1.2-testing/xen/arch/x86/cpu/intel_cacheinfo.c +--- a/xen/arch/x86/cpu/intel_cacheinfo.c ++++ b/xen/arch/x86/cpu/intel_cacheinfo.c @@ -170,7 +170,8 @@ unsigned int __cpuinit init_intel_cachei unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ @@ -509,11 +447,9 @@ Index: xen-4.1.2-testing/xen/arch/x86/cpu/intel_cacheinfo.c if (c->cpuid_level > 3) { static int is_initialized; -Index: xen-4.1.2-testing/xen/arch/x86/mm/mem_sharing.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/mm/mem_sharing.c -+++ xen-4.1.2-testing/xen/arch/x86/mm/mem_sharing.c -@@ -375,7 +375,7 @@ int mem_sharing_debug_gfn(struct domain +--- a/xen/arch/x86/mm/mem_sharing.c ++++ b/xen/arch/x86/mm/mem_sharing.c +@@ -375,7 +375,7 @@ int mem_sharing_debug_gfn(struct domain { p2m_type_t p2mt; mfn_t mfn; @@ -522,10 +458,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/mm/mem_sharing.c mfn = gfn_to_mfn(p2m_get_hostp2m(d), gfn, &p2mt); page = mfn_to_page(mfn); -Index: xen-4.1.2-testing/xen/arch/x86/hvm/viridian.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/hvm/viridian.c -+++ xen-4.1.2-testing/xen/arch/x86/hvm/viridian.c +--- a/xen/arch/x86/hvm/viridian.c ++++ b/xen/arch/x86/hvm/viridian.c @@ -270,7 +270,7 @@ int rdmsr_viridian_regs(uint32_t idx, ui int viridian_hypercall(struct cpu_user_regs *regs) { @@ -535,10 +469,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/hvm/viridian.c uint16_t status = HV_STATUS_SUCCESS; union hypercall_input { -Index: xen-4.1.2-testing/xen/arch/x86/mm.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/mm.c -+++ xen-4.1.2-testing/xen/arch/x86/mm.c +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c @@ -4906,7 +4906,7 @@ static int ptwr_emulated_update( { unsigned long mfn; @@ -548,10 +480,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/mm.c l1_pgentry_t pte, ol1e, nl1e, *pl1e; struct vcpu *v = current; struct domain *d = v->domain; -Index: xen-4.1.2-testing/xen/arch/x86/x86_64/mm.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/x86_64/mm.c -+++ xen-4.1.2-testing/xen/arch/x86/x86_64/mm.c +--- a/xen/arch/x86/x86_64/mm.c ++++ b/xen/arch/x86/x86_64/mm.c @@ -436,7 +436,8 @@ void destroy_m2p_mapping(struct mem_hota static int setup_compat_m2p_table(struct mem_hotadd_info *info) { @@ -562,10 +492,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/x86_64/mm.c l3_pgentry_t *l3_ro_mpt = NULL; l2_pgentry_t *l2_ro_mpt = NULL; struct page_info *l1_pg; -Index: xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/mce.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/cpu/mcheck/mce.c -+++ xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/mce.c +--- a/xen/arch/x86/cpu/mcheck/mce.c ++++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -151,7 +151,6 @@ static struct mcinfo_bank *mca_init_bank struct mc_info *mi, int bank) { @@ -582,7 +510,7 @@ Index: xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/mce.c if (mib->mc_status & MCi_STATUS_MISCV) mib->mc_misc = mca_rdmsr(MSR_IA32_MCx_MISC(bank)); -@@ -281,7 +279,7 @@ mctelem_cookie_t mcheck_mca_logout(enum +@@ -281,7 +279,7 @@ mctelem_cookie_t mcheck_mca_logout(enum recover = (mc_recoverable_scan)? 1: 0; for (i = 0; i < 32 && i < nr_mce_banks; i++) { @@ -600,10 +528,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/mce.c uint64_t hwcr = 0; int intpose; int i; -Index: xen-4.1.2-testing/xen/common/tmem.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/tmem.c -+++ xen-4.1.2-testing/xen/common/tmem.c +--- a/xen/common/tmem.c ++++ b/xen/common/tmem.c @@ -1351,7 +1351,8 @@ obj_unlock: static int tmem_evict(void) { @@ -624,10 +550,8 @@ Index: xen-4.1.2-testing/xen/common/tmem.c client_t *client = pool->client; int ret = client->frozen ? -EFROZEN : -ENOMEM; -Index: xen-4.1.2-testing/xen/common/tmem_xen.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/common/tmem_xen.c -+++ xen-4.1.2-testing/xen/common/tmem_xen.c +--- a/xen/common/tmem_xen.c ++++ b/xen/common/tmem_xen.c @@ -177,7 +177,7 @@ EXPORT int tmh_copy_from_client(pfp_t *p EXPORT int tmh_compress_from_client(tmem_cli_mfn_t cmfn, void **out_va, size_t *out_len, void *cli_va) @@ -665,10 +589,8 @@ Index: xen-4.1.2-testing/xen/common/tmem_xen.c tmh->persistent_pool = xmem_pool_create(name, tmh_persistent_pool_page_get, tmh_persistent_pool_page_put, PAGE_SIZE, 0, PAGE_SIZE); if ( tmh->persistent_pool == NULL ) -Index: xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/vmce.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/cpu/mcheck/vmce.c -+++ xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/vmce.c +--- a/xen/arch/x86/cpu/mcheck/vmce.c ++++ b/xen/arch/x86/cpu/mcheck/vmce.c @@ -574,7 +574,7 @@ int is_vmce_ready(struct mcinfo_bank *ba */ int unmmap_broken_page(struct domain *d, mfn_t mfn, unsigned long gfn) @@ -678,11 +600,9 @@ Index: xen-4.1.2-testing/xen/arch/x86/cpu/mcheck/vmce.c struct p2m_domain *p2m; p2m_type_t pt; -Index: xen-4.1.2-testing/xen/arch/x86/mm/shadow/multi.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/mm/shadow/multi.c -+++ xen-4.1.2-testing/xen/arch/x86/mm/shadow/multi.c -@@ -124,7 +124,7 @@ set_shadow_status(struct vcpu *v, mfn_t +--- a/xen/arch/x86/mm/shadow/multi.c ++++ b/xen/arch/x86/mm/shadow/multi.c +@@ -124,7 +124,7 @@ set_shadow_status(struct vcpu *v, mfn_t /* Put a shadow into the hash table */ { struct domain *d = v->domain; @@ -691,7 +611,7 @@ Index: xen-4.1.2-testing/xen/arch/x86/mm/shadow/multi.c SHADOW_PRINTK("d=%d, v=%d, gmfn=%05lx, type=%08x, smfn=%05lx\n", d->domain_id, v->vcpu_id, mfn_x(gmfn), -@@ -4446,7 +4446,7 @@ sh_update_cr3(struct vcpu *v, int do_loc +@@ -4447,7 +4447,7 @@ sh_update_cr3(struct vcpu *v, int do_loc int sh_rm_write_access_from_sl1p(struct vcpu *v, mfn_t gmfn, mfn_t smfn, unsigned long off) { @@ -700,10 +620,8 @@ Index: xen-4.1.2-testing/xen/arch/x86/mm/shadow/multi.c shadow_l1e_t *sl1p, sl1e; struct page_info *sp; -Index: xen-4.1.2-testing/xen/arch/x86/domain_build.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/domain_build.c -+++ xen-4.1.2-testing/xen/arch/x86/domain_build.c +--- a/xen/arch/x86/domain_build.c ++++ b/xen/arch/x86/domain_build.c @@ -378,8 +378,7 @@ int __init construct_dom0( return rc; @@ -714,11 +632,9 @@ Index: xen-4.1.2-testing/xen/arch/x86/domain_build.c machine = elf_uval(&elf, elf.ehdr, e_machine); switch (CONFIG_PAGING_LEVELS) { case 3: /* x86_32p */ -Index: xen-4.1.2-testing/xen/arch/x86/traps.c -=================================================================== ---- xen-4.1.2-testing.orig/xen/arch/x86/traps.c -+++ xen-4.1.2-testing/xen/arch/x86/traps.c -@@ -1854,7 +1854,11 @@ static int emulate_privileged_op(struct +--- a/xen/arch/x86/traps.c ++++ b/xen/arch/x86/traps.c +@@ -1854,7 +1854,11 @@ static int emulate_privileged_op(struct struct vcpu *v = current; unsigned long *reg, eip = regs->eip; u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0; diff --git a/xen.changes b/xen.changes index 7d7bca0..0db7b82 100644 --- a/xen.changes +++ b/xen.changes @@ -1,3 +1,136 @@ +------------------------------------------------------------------- +Tue Nov 22 17:57:07 MST 2011 - carnold@novell.com + +- Upstream patches from Jan + 23900-xzalloc.patch + 24144-cpufreq-turbo-crash.patch + 24148-shadow-pgt-dying-op-performance.patch + 24155-x86-ioapic-EOI-after-migration.patch + 24156-x86-ioapic-shared-vectors.patch + 24157-x86-xstate-init.patch + 24168-x86-vioapic-clear-remote_irr.patch + +------------------------------------------------------------------- +Sun Nov 22 12:45:13 CST 2011 - cyliu@suse.com +- submit fixes for bnc#649209 and bnc#711892 + xl-create-pv-with-qcow2-img.patch + update suspend_evtchn_lock.patch + +------------------------------------------------------------------- +Sun Nov 20 20:45:13 CET 2011 - ohering@suse.de + +- Update trace.c, merge patches from upstream + 23050-xentrace_dynamic_tracebuffer_allocation.patch + 23091-xentrace_fix_t_info_pages_calculation..patch + 23092-xentrace_print_calculated_numbers_in_calculate_tbuf_size.patch + 23093-xentrace_remove_gdprintk_usage_since_they_are_not_in_guest_context.patch + 23094-xentrace_update_comments.patch + 23095-xentrace_use_consistent_printk_prefix.patch + 23128-xentrace_correct_formula_to_calculate_t_info_pages.patch + 23129-xentrace_remove_unneeded_debug_printk.patch + 23173-xentrace_Move_register_cpu_notifier_call_into_boot-time_init..patch + 23239-xentrace_correct_overflow_check_for_number_of_per-cpu_trace_pages.patch + 23308-xentrace_Move_the_global_variable_t_info_first_offset_into_calculate_tbuf_size.patch + 23309-xentrace_Mark_data_size___read_mostly_because_its_only_written_once.patch + 23310-xentrace_Remove_unneeded_cast_when_assigning_pointer_value_to_dst.patch + 23404-xentrace_reduce_trace_buffer_size_to_something_mfn_offset_can_reach.patch + 23405-xentrace_fix_type_of_offset_to_avoid_ouf-of-bounds_access.patch + 23406-xentrace_update___insert_record_to_copy_the_trace_record_to_individual_mfns.patch + 23407-xentrace_allocate_non-contiguous_per-cpu_trace_buffers.patch + 23643-xentrace_Allow_tracing_to_be_enabled_at_boot.patch + 23719-xentrace_update___trace_var_comment.patch + Remove old patches: + xen-unstable.xentrace.dynamic_tbuf.patch + xen-unstable.xentrace.empty_t_info_pages.patch + xen-unstable.xentrace.verbose.patch + xen-unstable.xentrace.no_gdprintk.patch + xen-unstable.xentrace.comments.patch + xen-unstable.xentrace.printk_prefix.patch + xen-unstable.xentrace.remove_debug_printk.patch + xen-unstable.xentrace.t_info_pages-formula.patch + xen-unstable.xentrace.register_cpu_notifier-boot_time.patch + xen-unstable.xentrace.t_info_page-overflow.patch + xen-unstable.xentrace.t_info_first_offset.patch + xen-unstable.xentrace.data_size__read_mostly.patch + xen-unstable.xentrace.__insert_record-dst-type.patch + +------------------------------------------------------------------- +Mon Nov 14 09:41:46 MST 2011 - carnold@novell.com + +- Upstream patches from Jan + 24116-x86-continuation-cancel.patch + 24123-x86-cpuidle-quiesce.patch + 24124-x86-microcode-amd-quiesce.patch + 24137-revert-23666.patch + 24xxx-shadow-pgt-dying-op-performance.patch + +------------------------------------------------------------------- +Thu Nov 10 17:03:18 MST 2011 - carnold@novell.com + +- bnc#722738 - xm cpupool-create errors out + xen-cpupool-xl-config-format.patch + +------------------------------------------------------------------- +Fri Nov 4 15:14:09 MDT 2011 - carnold@novell.com + +- Fix broken build when building docs + 23819-make-docs.patch + +------------------------------------------------------------------- +Fri Nov 4 11:52:22 MDT 2011 - jfehlig@suse.com + +- bnc#720054 - Prevent vif-bridge from adding user-created tap + interfaces to a bridge + 2XXXX-vif-bridge.patch + +------------------------------------------------------------------- +Fri Nov 4 10:11:04 MDT 2011 - carnold@novell.com + +- bnc#713503 - DOM0 filesystem commit + 23752-x86-shared-IRQ-vector-maps.patch + 23754-AMD-perdev-vector-map.patch + +------------------------------------------------------------------- +Thu Nov 3 23:50:31 CET 2011 - ohering@suse.de + +- fate#310510 - fix xenpaging + This change reverses the task of xenpaging. Before this change a + fixed number of pages was paged out. With this change the guest + will not have access to more than the given number of pages at + the same time. + The xenpaging= config option is replaced by actmem= + A new xm mem-swap-target is added. + The xenpaging binary is moved to /usr/lib/xen/bin/ + xenpaging.HVMCOPY_gfn_paged_out.patch + xenpaging.XEN_PAGING_DIR.patch + xenpaging.add_evict_pages.patch + xenpaging.bitmap_clear.patch + xenpaging.cmdline-interface.patch + xenpaging.encapsulate_domain_info.patch + xenpaging.file_op-return-code.patch + xenpaging.guest-memusage.patch + xenpaging.install-to-libexec.patch + xenpaging.low_target_policy_nomru.patch + xenpaging.main-loop-exit-handling.patch + xenpaging.misleading-comment.patch + xenpaging.page_in-munmap-size.patch + xenpaging.print-gfn.patch + xenpaging.record-numer-paged-out-pages.patch + xenpaging.reset-uncomsumed.patch + xenpaging.stale-comments.patch + xenpaging.target-tot_pages.patch + xenpaging.use-PERROR.patch + xenpaging.watch-target-tot_pages.patch + xenpaging.watch_event-DPRINTF.patch + xenpaging.xc_interface_open-comment.patch + +------------------------------------------------------------------- +Thu Nov 3 23:32:12 CET 2011 - ohering@suse.de + +- xen.spec: update filelist + package /usr/lib*/xen with wildcard to pickup new files + remove duplicate /usr/sbin/xen-list from filelist + ------------------------------------------------------------------- Wed Oct 26 10:13:04 MDT 2011 - carnold@novell.com diff --git a/xen.spec b/xen.spec index d94fbf8..52f6c88 100644 --- a/xen.spec +++ b/xen.spec @@ -96,7 +96,7 @@ BuildRequires: glibc-devel %if %{?with_kmp}0 BuildRequires: kernel-source kernel-syms module-init-tools xorg-x11 %endif -Version: 4.1.2_05 +Version: 4.1.2_08 Release: 1 License: GPLv2+ Group: System/Kernel @@ -145,24 +145,41 @@ Source20000: xenalyze.hg.tar.bz2 Patch22998: 22998-x86-get_page_from_l1e-retcode.patch Patch22999: 22999-x86-mod_l1_entry-retcode.patch Patch23000: 23000-x86-mod_l2_entry-retcode.patch +Patch23050: 23050-xentrace_dynamic_tracebuffer_allocation.patch Patch23074: 23074-pfn.h.patch +Patch23091: 23091-xentrace_fix_t_info_pages_calculation..patch +Patch23092: 23092-xentrace_print_calculated_numbers_in_calculate_tbuf_size.patch +Patch23093: 23093-xentrace_remove_gdprintk_usage_since_they_are_not_in_guest_context.patch +Patch23094: 23094-xentrace_update_comments.patch +Patch23095: 23095-xentrace_use_consistent_printk_prefix.patch Patch23096: 23096-x86-hpet-no-cpumask_lock.patch Patch23099: 23099-x86-rwlock-scalability.patch Patch23103: 23103-x86-pirq-guest-eoi-check.patch Patch23127: 23127-vtd-bios-settings.patch +Patch23128: 23128-xentrace_correct_formula_to_calculate_t_info_pages.patch +Patch23129: 23129-xentrace_remove_unneeded_debug_printk.patch +Patch23173: 23173-xentrace_Move_register_cpu_notifier_call_into_boot-time_init..patch Patch23199: 23199-amd-iommu-unmapped-intr-fault.patch Patch23233: 23233-hvm-cr-access.patch Patch23234: 23234-svm-decode-assist-base.patch Patch23235: 23235-svm-decode-assist-crs.patch Patch23236: 23236-svm-decode-assist-invlpg.patch Patch23238: 23238-svm-decode-assist-insn-fetch.patch +Patch23239: 23239-xentrace_correct_overflow_check_for_number_of_per-cpu_trace_pages.patch Patch23246: 23246-x86-xsave-enable.patch Patch23303: 23303-cpufreq-misc.patch Patch23304: 23304-amd-oprofile-strings.patch Patch23305: 23305-amd-fam15-xenoprof.patch Patch23306: 23306-amd-fam15-vpmu.patch +Patch23308: 23308-xentrace_Move_the_global_variable_t_info_first_offset_into_calculate_tbuf_size.patch +Patch23309: 23309-xentrace_Mark_data_size___read_mostly_because_its_only_written_once.patch +Patch23310: 23310-xentrace_Remove_unneeded_cast_when_assigning_pointer_value_to_dst.patch Patch23334: 23334-amd-fam12+14-vpmu.patch Patch23383: 23383-libxc-rm-static-vars.patch +Patch23404: 23404-xentrace_reduce_trace_buffer_size_to_something_mfn_offset_can_reach.patch +Patch23405: 23405-xentrace_fix_type_of_offset_to_avoid_ouf-of-bounds_access.patch +Patch23406: 23406-xentrace_update___insert_record_to_copy_the_trace_record_to_individual_mfns.patch +Patch23407: 23407-xentrace_allocate_non-contiguous_per-cpu_trace_buffers.patch Patch23437: 23437-amd-fam15-TSC-scaling.patch Patch23462: 23462-libxc-cpu-feature.patch Patch23506: 23506-x86_Disable_set_gpfn_from_mfn_until_m2p_table_is_allocated..patch @@ -203,13 +220,17 @@ Patch23613: 23613-EFI-headers.patch Patch23614: 23614-x86_64-EFI-boot.patch Patch23615: 23615-x86_64-EFI-runtime.patch Patch23616: 23616-x86_64-EFI-MPS.patch +Patch23643: 23643-xentrace_Allow_tracing_to_be_enabled_at_boot.patch Patch23676: 23676-x86_64-image-map-bounds.patch +Patch23719: 23719-xentrace_update___trace_var_comment.patch Patch23723: 23723-x86-CMOS-lock.patch Patch23724: 23724-x86-smpboot-x2apic.patch Patch23726: 23726-x86-intel-flexmigration-v2.patch Patch23735: 23735-guest-dom0-cap.patch Patch23747: 23747-mmcfg-base-address.patch Patch23749: 23749-mmcfg-reservation.patch +Patch23752: 23752-x86-shared-IRQ-vector-maps.patch +Patch23754: 23754-AMD-perdev-vector-map.patch Patch23771: 23771-x86-ioapic-clear-pin.patch Patch23772: 23772-x86-trampoline.patch Patch23774: 23774-x86_64-EFI-EDD.patch @@ -221,12 +242,14 @@ Patch23800: 23800-x86_64-guest-addr-range.patch Patch23804: 23804-x86-IPI-counts.patch Patch23817: 23817-mem_event_add_ref_counting_for_free_requestslots.patch Patch23818: 23818-mem_event_use_mem_event_mark_and_pause_in_mem_event_check_ring.patch +Patch23819: 23819-make-docs.patch Patch23827: 23827-xenpaging_use_batch_of_pages_during_final_page-in.patch Patch23841: 23841-mem_event_pass_mem_event_domain_pointer_to_mem_event_functions.patch Patch23842: 23842-mem_event_use_different_ringbuffers_for_share_paging_and_access.patch Patch23853: 23853-x86-pv-cpuid-xsave.patch Patch23874: 23874-xenpaging_track_number_of_paged_pages_in_struct_domain.patch Patch23897: 23897-x86-mce-offline-again.patch +Patch23900: 23900-xzalloc.patch Patch23904: 23904-xenpaging_use_p2m-get_entry_in_p2m_mem_paging_functions.patch Patch23905: 23905-xenpaging_fix_locking_in_p2m_mem_paging_functions.patch Patch23906: 23906-xenpaging_remove_confusing_comment_from_p2m_mem_paging_populate.patch @@ -241,6 +264,16 @@ Patch23978: 23978-xenpaging_check_p2mt_in_p2m_mem_paging_functions.patch Patch23979: 23979-xenpaging_document_p2m_mem_paging_functions.patch Patch23980: 23980-xenpaging_disallow_paging_in_a_PoD_guest.patch Patch23993: 23993-x86-microcode-amd-fix-23871.patch +Patch24116: 24116-x86-continuation-cancel.patch +Patch24123: 24123-x86-cpuidle-quiesce.patch +Patch24124: 24124-x86-microcode-amd-quiesce.patch +Patch24137: 24137-revert-23666.patch +Patch24144: 24144-cpufreq-turbo-crash.patch +Patch24148: 24148-shadow-pgt-dying-op-performance.patch +Patch24155: 24155-x86-ioapic-EOI-after-migration.patch +Patch24156: 24156-x86-ioapic-shared-vectors.patch +Patch24157: 24157-x86-xstate-init.patch +Patch24168: 24168-x86-vioapic-clear-remote_irr.patch # Upstream qemu patches # Our patches Patch300: xen-config.diff @@ -298,6 +331,8 @@ Patch376: xend-devid-or-name.patch Patch377: suspend_evtchn_lock.patch Patch378: log-guest-console.patch Patch379: xend-migration-domname-fix.patch +# Sent upstream and tentatively ACK'ed, but not yet committed +Patch380: 2XXXX-vif-bridge.patch # Patches for snapshot support Patch400: snapshot-ioemu-save.patch Patch401: snapshot-ioemu-restore.patch @@ -336,7 +371,7 @@ Patch445: hotplug.losetup.patch Patch446: xend-disable-internal-logrotate.patch Patch447: xend-config-enable-dump-comment.patch Patch448: change-vnc-passwd.patch -Patch449: kernel-boot-hvm.patch +Patch449: kernel-boot-hvm.patch Patch450: ioemu-watchdog-support.patch Patch451: ioemu-watchdog-linkage.patch Patch452: ioemu-watchdog-ib700-timer.patch @@ -345,6 +380,8 @@ Patch454: xend-console-port-restore.patch Patch455: xencommons-proc-xen.patch Patch456: xend-vcpu-affinity-fix.patch Patch457: xenstored.XS_RESET_WATCHES.patch +Patch458: xen-cpupool-xl-config-format.patch +Patch459: xl-create-pv-with-qcow2-img.patch # Jim's domain lock patch Patch480: xend-domain-lock.patch Patch481: xend-domain-lock-sfex.patch @@ -366,22 +403,30 @@ Patch650: disable_emulated_device.diff Patch651: ioemu-disable-scsi.patch Patch652: ioemu-disable-emulated-ide-if-pv.patch Patch700: hv_extid_compatibility.patch -# xentrace / xenalyze -Patch1000: xen-unstable.xentrace.dynamic_tbuf.patch -Patch1001: xen-unstable.xentrace.empty_t_info_pages.patch -Patch1002: xen-unstable.xentrace.verbose.patch -Patch1003: xen-unstable.xentrace.no_gdprintk.patch -Patch1004: xen-unstable.xentrace.comments.patch -Patch1005: xen-unstable.xentrace.printk_prefix.patch -Patch1006: xen-unstable.xentrace.remove_debug_printk.patch -Patch1007: xen-unstable.xentrace.t_info_pages-formula.patch -Patch1008: xen-unstable.xentrace.register_cpu_notifier-boot_time.patch -Patch1009: xen-unstable.xentrace.t_info_page-overflow.patch -Patch1010: xen-unstable.xentrace.t_info_first_offset.patch -Patch1011: xen-unstable.xentrace.data_size__read_mostly.patch -Patch1012: xen-unstable.xentrace.__insert_record-dst-type.patch # FATE 310510 -Patch1106: xenpaging.autostart.patch +Patch1107: xenpaging.stale-comments.patch +Patch1108: xenpaging.misleading-comment.patch +Patch1109: xenpaging.use-PERROR.patch +Patch1110: xenpaging.file_op-return-code.patch +Patch1111: xenpaging.print-gfn.patch +Patch1112: xenpaging.xc_interface_open-comment.patch +Patch1113: xenpaging.encapsulate_domain_info.patch +Patch1114: xenpaging.record-numer-paged-out-pages.patch +Patch1115: xenpaging.add_evict_pages.patch +Patch1116: xenpaging.main-loop-exit-handling.patch +Patch1117: xenpaging.bitmap_clear.patch +Patch1118: xenpaging.reset-uncomsumed.patch +Patch1119: xenpaging.install-to-libexec.patch +Patch1120: xenpaging.XEN_PAGING_DIR.patch +Patch1121: xenpaging.target-tot_pages.patch +Patch1122: xenpaging.watch-target-tot_pages.patch +Patch1123: xenpaging.cmdline-interface.patch +Patch1125: xenpaging.watch_event-DPRINTF.patch +Patch1126: xenpaging.guest-memusage.patch +Patch1127: xenpaging.page_in-munmap-size.patch +Patch1128: xenpaging.low_target_policy_nomru.patch +Patch1129: xenpaging.autostart.patch +Patch1130: xenpaging.HVMCOPY_gfn_paged_out.patch # xenalyze Patch20000: xenalyze.gcc46.patch # Build patch @@ -729,24 +774,41 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch22998 -p1 %patch22999 -p1 %patch23000 -p1 +%patch23050 -p1 %patch23074 -p1 +%patch23091 -p1 +%patch23092 -p1 +%patch23093 -p1 +%patch23094 -p1 +%patch23095 -p1 %patch23096 -p1 %patch23099 -p1 %patch23103 -p1 %patch23127 -p1 +%patch23128 -p1 +%patch23129 -p1 +%patch23173 -p1 %patch23199 -p1 %patch23233 -p1 %patch23234 -p1 %patch23235 -p1 %patch23236 -p1 %patch23238 -p1 +%patch23239 -p1 %patch23246 -p1 %patch23303 -p1 %patch23304 -p1 %patch23305 -p1 %patch23306 -p1 +%patch23308 -p1 +%patch23309 -p1 +%patch23310 -p1 %patch23334 -p1 %patch23383 -p1 +%patch23404 -p1 +%patch23405 -p1 +%patch23406 -p1 +%patch23407 -p1 %patch23437 -p1 %patch23462 -p1 %patch23506 -p1 @@ -787,13 +849,17 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch23614 -p1 %patch23615 -p1 %patch23616 -p1 +%patch23643 -p1 %patch23676 -p1 +%patch23719 -p1 %patch23723 -p1 %patch23724 -p1 %patch23726 -p1 %patch23735 -p1 %patch23747 -p1 %patch23749 -p1 +%patch23752 -p1 +%patch23754 -p1 %patch23771 -p1 %patch23772 -p1 %patch23774 -p1 @@ -805,12 +871,14 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch23804 -p1 %patch23817 -p1 %patch23818 -p1 +%patch23819 -p1 %patch23827 -p1 %patch23841 -p1 %patch23842 -p1 %patch23853 -p1 %patch23874 -p1 %patch23897 -p1 +%patch23900 -p1 %patch23904 -p1 %patch23905 -p1 %patch23906 -p1 @@ -825,6 +893,16 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch23979 -p1 %patch23980 -p1 %patch23993 -p1 +%patch24116 -p1 +%patch24123 -p1 +%patch24124 -p1 +%patch24137 -p1 +%patch24144 -p1 +%patch24148 -p1 +%patch24155 -p1 +%patch24156 -p1 +%patch24157 -p1 +%patch24168 -p1 # Upstream patches %patch300 -p1 %patch301 -p1 @@ -877,9 +955,10 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch374 -p1 %patch375 -p1 %patch376 -p1 -#%patch377 -p1 suspend_evtchn_lock, buildservice build problem +%patch377 -p1 %patch378 -p1 %patch379 -p1 +%patch380 -p1 %patch400 -p1 %patch401 -p1 %patch402 -p1 @@ -924,6 +1003,8 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch455 -p1 %patch456 -p1 %patch457 -p1 +%patch458 -p1 +%patch459 -p1 %patch480 -p1 %patch481 -p1 %patch500 -p1 @@ -943,22 +1024,30 @@ tar xfj %{SOURCE2} -C $RPM_BUILD_DIR/%{xen_build_dir}/tools %patch651 -p1 %patch652 -p1 %patch700 -p1 -# xentrace / xenalyze -%patch1000 -p1 -%patch1001 -p1 -%patch1002 -p1 -%patch1003 -p1 -%patch1004 -p1 -%patch1005 -p1 -%patch1006 -p1 -%patch1007 -p1 -%patch1008 -p1 -%patch1009 -p1 -%patch1010 -p1 -%patch1011 -p1 -%patch1012 -p1 # FATE 310510 -%patch1106 -p1 +%patch1107 -p1 +%patch1108 -p1 +%patch1109 -p1 +%patch1110 -p1 +%patch1111 -p1 +%patch1112 -p1 +%patch1113 -p1 +%patch1114 -p1 +%patch1115 -p1 +%patch1116 -p1 +%patch1117 -p1 +%patch1118 -p1 +%patch1119 -p1 +%patch1120 -p1 +%patch1121 -p1 +%patch1122 -p1 +%patch1123 -p1 +%patch1125 -p1 +%patch1126 -p1 +%patch1127 -p1 +%patch1128 -p1 +%patch1129 -p1 +%patch1130 -p1 # %patch99998 -p1 %patch99999 -p1 @@ -1254,24 +1343,14 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons /usr/sbin/td-util /usr/sbin/vhd-update /usr/sbin/vhd-util -/usr/sbin/xen-list /usr/sbin/gdbsx /usr/sbin/xl -/usr/sbin/kdd +/usr/sbin/kdd /usr/sbin/tap-ctl -%dir %{_libdir}/xen -%dir %{_libdir}/xen/bin +%{_libdir}/xen %ifarch x86_64 -%dir /usr/lib/xen -%dir /usr/lib/xen/bin +/usr/lib/xen %endif -%dir /usr/lib/xen/boot -%{_libdir}/xen/bin/readnotes -%{_libdir}/xen/bin/xc_restore -%{_libdir}/xen/bin/xc_save -%{_libdir}/xen/bin/xenconsole -%{_libdir}/xen/bin/xenctx -%{_libdir}/xen/bin/lsevtchn %{_mandir}/man1/*.1.gz %{_mandir}/man5/*.5.gz %{_mandir}/man8/*.8.gz @@ -1330,36 +1409,9 @@ rm -f $RPM_BUILD_ROOT/%{_bindir}/xencons %{_datadir}/xen/qemu/* %{_datadir}/xen/man/man1/* %{_datadir}/xen/man/man8/* -%if %{?with_stubdom}0 -/usr/lib/xen/bin/stubdom-dm -/usr/lib/xen/bin/stubdompath.sh -%ifarch x86_64 -%{_libdir}/xen/bin/stubdom-dm -%{_libdir}/xen/bin/stubdompath.sh -%endif -%endif -%{_libdir}/xen/bin/qemu-dm -%ifarch x86_64 -/usr/lib/xen/bin/qemu-dm -# NEEDS FIXING -##/usr/lib64/xen/bin/xc_kexec -%else -# NEEDS FIXING -#/usr/lib/xen/bin/xc_kexec -%endif -/usr/lib/xen/boot/hvmloader %{_libdir}/python%{pyver}/site-packages/xen/* -/usr/lib/xen/boot/domUloader.py %{_libdir}/python%{pyver}/site-packages/grub/* %{_libdir}/python%{pyver}/site-packages/fsimage.so -%if %{?with_stubdom}0 -/usr/lib/xen/boot/ioemu-stubdom.gz -%ifarch x86_64 -/usr/lib/xen/boot/pv-grub-x86_64.gz -%else -/usr/lib/xen/boot/pv-grub-x86_32.gz -%endif -%endif %config %{_fwdefdir}/xend-relocation-server %endif diff --git a/xenpaging.HVMCOPY_gfn_paged_out.patch b/xenpaging.HVMCOPY_gfn_paged_out.patch new file mode 100644 index 0000000..c17655e --- /dev/null +++ b/xenpaging.HVMCOPY_gfn_paged_out.patch @@ -0,0 +1,151 @@ + +xenpaging: handle HVMCOPY_gfn_paged_out in copy_from/to_user + +copy_from_user_hvm can fail when __hvm_copy returns +HVMCOPY_gfn_paged_out for a referenced gfn, for example during guests +pagetable walk. This has to be handled in some way. + +For the time being, return -EAGAIN for the most common case (xen_balloon +driver crashing in guest) until the recently added waitqueues will be +used. + +Signed-off-by: Olaf Hering + +--- + xen/arch/x86/hvm/hvm.c | 4 ++++ + xen/common/memory.c | 39 ++++++++++++++++++++++++++++++++++----- + 2 files changed, 38 insertions(+), 5 deletions(-) + +Index: xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/arch/x86/hvm/hvm.c ++++ xen-4.1.2-testing/xen/arch/x86/hvm/hvm.c +@@ -2247,6 +2247,8 @@ unsigned long copy_to_user_hvm(void *to, + + rc = hvm_copy_to_guest_virt_nofault((unsigned long)to, (void *)from, + len, 0); ++ if ( unlikely(rc == HVMCOPY_gfn_paged_out) ) ++ return -EAGAIN; + return rc ? len : 0; /* fake a copy_to_user() return code */ + } + +@@ -2264,6 +2266,8 @@ unsigned long copy_from_user_hvm(void *t + #endif + + rc = hvm_copy_from_guest_virt_nofault(to, (unsigned long)from, len, 0); ++ if ( unlikely(rc == HVMCOPY_gfn_paged_out) ) ++ return -EAGAIN; + return rc ? len : 0; /* fake a copy_from_user() return code */ + } + +Index: xen-4.1.2-testing/xen/common/memory.c +=================================================================== +--- xen-4.1.2-testing.orig/xen/common/memory.c ++++ xen-4.1.2-testing/xen/common/memory.c +@@ -48,6 +48,7 @@ static void increase_reservation(struct + { + struct page_info *page; + unsigned long i; ++ unsigned long ctg_ret; + xen_pfn_t mfn; + struct domain *d = a->domain; + +@@ -81,8 +82,13 @@ static void increase_reservation(struct + if ( !guest_handle_is_null(a->extent_list) ) + { + mfn = page_to_mfn(page); +- if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) ++ ctg_ret = __copy_to_guest_offset(a->extent_list, i, &mfn, 1); ++ if ( unlikely(ctg_ret) ) ++ { ++ if ( (long)ctg_ret == -EAGAIN ) ++ a->preempted = 1; + goto out; ++ } + } + } + +@@ -94,6 +100,7 @@ static void populate_physmap(struct memo + { + struct page_info *page; + unsigned long i, j; ++ unsigned long cftg_ret; + xen_pfn_t gpfn, mfn; + struct domain *d = a->domain; + +@@ -112,8 +119,13 @@ static void populate_physmap(struct memo + goto out; + } + +- if ( unlikely(__copy_from_guest_offset(&gpfn, a->extent_list, i, 1)) ) ++ cftg_ret = __copy_from_guest_offset(&gpfn, a->extent_list, i, 1); ++ if ( unlikely(cftg_ret) ) ++ { ++ if ( (long)cftg_ret == -EAGAIN ) ++ a->preempted = 1; + goto out; ++ } + + if ( a->memflags & MEMF_populate_on_demand ) + { +@@ -143,8 +155,13 @@ static void populate_physmap(struct memo + set_gpfn_from_mfn(mfn + j, gpfn + j); + + /* Inform the domain of the new page's machine address. */ +- if ( unlikely(__copy_to_guest_offset(a->extent_list, i, &mfn, 1)) ) ++ cftg_ret = __copy_to_guest_offset(a->extent_list, i, &mfn, 1); ++ if ( unlikely(cftg_ret) ) ++ { ++ if ( (long)cftg_ret == -EAGAIN ) ++ a->preempted = 1; + goto out; ++ } + } + } + } +@@ -213,6 +230,7 @@ int guest_remove_page(struct domain *d, + static void decrease_reservation(struct memop_args *a) + { + unsigned long i, j; ++ unsigned long cfg_ret; + xen_pfn_t gmfn; + + if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, +@@ -227,8 +245,13 @@ static void decrease_reservation(struct + goto out; + } + +- if ( unlikely(__copy_from_guest_offset(&gmfn, a->extent_list, i, 1)) ) ++ cfg_ret = __copy_from_guest_offset(&gmfn, a->extent_list, i, 1); ++ if ( unlikely(cfg_ret) ) ++ { ++ if ( (long)cfg_ret == -EAGAIN ) ++ a->preempted = 1; + goto out; ++ } + + if ( tb_init_done ) + { +@@ -509,6 +532,7 @@ long do_memory_op(unsigned long cmd, XEN + int rc, op; + unsigned int address_bits; + unsigned long start_extent; ++ unsigned long cfg_ret; + struct xen_memory_reservation reservation; + struct memop_args args; + domid_t domid; +@@ -522,8 +546,13 @@ long do_memory_op(unsigned long cmd, XEN + case XENMEM_populate_physmap: + start_extent = cmd >> MEMOP_EXTENT_SHIFT; + +- if ( copy_from_guest(&reservation, arg, 1) ) ++ cfg_ret = copy_from_guest(&reservation, arg, 1); ++ if ( unlikely(cfg_ret) ) ++ { ++ if ( (long)cfg_ret == -EAGAIN ) ++ return hypercall_create_continuation(__HYPERVISOR_memory_op, "lh", cmd, arg); + return start_extent; ++ } + + /* Is size too large for us to encode a continuation? */ + if ( reservation.nr_extents > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) ) diff --git a/xenpaging.XEN_PAGING_DIR.patch b/xenpaging.XEN_PAGING_DIR.patch new file mode 100644 index 0000000..b2d9598 --- /dev/null +++ b/xenpaging.XEN_PAGING_DIR.patch @@ -0,0 +1,51 @@ +xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path() + +Signed-off-by: Olaf Hering + +--- + Config.mk | 1 + + config/StdGNU.mk | 2 ++ + tools/xenpaging/Makefile | 2 +- + 3 files changed, 4 insertions(+), 1 deletion(-) + +Index: xen-4.1.2-testing/Config.mk +=================================================================== +--- xen-4.1.2-testing.orig/Config.mk ++++ xen-4.1.2-testing/Config.mk +@@ -124,6 +124,7 @@ define buildmakevars2file-closure + echo "XEN_CONFIG_DIR=\"$(XEN_CONFIG_DIR)\"" >> $(1).tmp; \ + echo "XEN_SCRIPT_DIR=\"$(XEN_SCRIPT_DIR)\"" >> $(1).tmp; \ + echo "XEN_LOCK_DIR=\"$(XEN_LOCK_DIR)\"" >> $(1).tmp; \ ++ echo "XEN_PAGING_DIR=\"$(XEN_PAGING_DIR)\"" >> $(1).tmp; \ + if ! cmp $(1).tmp $(1); then mv -f $(1).tmp $(1); fi + endef + +Index: xen-4.1.2-testing/config/StdGNU.mk +=================================================================== +--- xen-4.1.2-testing.orig/config/StdGNU.mk ++++ xen-4.1.2-testing/config/StdGNU.mk +@@ -46,9 +46,11 @@ PRIVATE_BINDIR = $(PRIVATE_PREFIX)/bin + ifeq ($(PREFIX),/usr) + CONFIG_DIR = /etc + XEN_LOCK_DIR = /var/lock ++XEN_PAGING_DIR = /var/lib/xen/xenpaging + else + CONFIG_DIR = $(PREFIX)/etc + XEN_LOCK_DIR = $(PREFIX)/var/lock ++XEN_PAGING_DIR = $(PREFIX)/var/lib/xen/xenpaging + endif + + SYSCONFIG_DIR = $(CONFIG_DIR)/$(CONFIG_LEAF_DIR) +Index: xen-4.1.2-testing/tools/xenpaging/Makefile +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile ++++ xen-4.1.2-testing/tools/xenpaging/Makefile +@@ -28,7 +28,7 @@ xenpaging: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) + + install: all +- $(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging ++ $(INSTALL_DIR) $(DESTDIR)$(XEN_PAGING_DIR) + $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC) + $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC) + diff --git a/xenpaging.add_evict_pages.patch b/xenpaging.add_evict_pages.patch new file mode 100644 index 0000000..38914ac --- /dev/null +++ b/xenpaging.add_evict_pages.patch @@ -0,0 +1,165 @@ +xenpaging: move page add/resume loops into its own function. + +Move page resume loop into its own function. +Move page eviction loop into its own function. +Allocate all possible slots in a paging file to allow growing and +shrinking of the number of paged-out pages. Adjust other places to +iterate over all slots. + +This change is required by subsequent patches. + +v2: + - check if victims allocation succeeded + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 94 ++++++++++++++++++++++++++++---------------- + 1 file changed, 61 insertions(+), 33 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -553,6 +553,27 @@ static int xenpaging_populate_page(xenpa + return ret; + } + ++/* Trigger a page-in for a batch of pages */ ++static void resume_pages(xenpaging_t *paging, int num_pages) ++{ ++ xc_interface *xch = paging->xc_handle; ++ int i, num = 0; ++ ++ for ( i = 0; i < paging->max_pages && num < num_pages; i++ ) ++ { ++ if ( test_bit(i, paging->bitmap) ) ++ { ++ paging->pagein_queue[num] = i; ++ num++; ++ if ( num == XENPAGING_PAGEIN_QUEUE_SIZE ) ++ break; ++ } ++ } ++ /* num may be less than num_pages, caller has to try again */ ++ if ( num ) ++ page_in_trigger(); ++} ++ + static int evict_victim(xenpaging_t *paging, + xenpaging_victim_t *victim, int fd, int i) + { +@@ -596,6 +617,30 @@ static int evict_victim(xenpaging_t *pag + return ret; + } + ++/* Evict a batch of pages and write them to a free slot in the paging file */ ++static int evict_pages(xenpaging_t *paging, int fd, xenpaging_victim_t *victims, int num_pages) ++{ ++ xc_interface *xch = paging->xc_handle; ++ int rc, slot, num = 0; ++ ++ for ( slot = 0; slot < paging->max_pages && num < num_pages; slot++ ) ++ { ++ /* Slot is allocated */ ++ if ( victims[slot].gfn != INVALID_MFN ) ++ continue; ++ ++ rc = evict_victim(paging, &victims[slot], fd, slot); ++ if ( rc == -ENOSPC ) ++ break; ++ if ( rc == -EINTR ) ++ break; ++ if ( num && num % 100 == 0 ) ++ DPRINTF("%d pages evicted\n", num); ++ num++; ++ } ++ return num; ++} ++ + int main(int argc, char *argv[]) + { + struct sigaction act; +@@ -638,7 +683,14 @@ int main(int argc, char *argv[]) + return 2; + } + +- victims = calloc(paging->num_pages, sizeof(xenpaging_victim_t)); ++ /* Allocate upper limit of pages to allow growing and shrinking */ ++ victims = calloc(paging->max_pages, sizeof(xenpaging_victim_t)); ++ if ( !victims ) ++ goto out; ++ ++ /* Mark all slots as unallocated */ ++ for ( i = 0; i < paging->max_pages; i++ ) ++ victims[i].gfn = INVALID_MFN; + + /* ensure that if we get a signal, we'll do cleanup, then exit */ + act.sa_handler = close_handler; +@@ -652,18 +704,7 @@ int main(int argc, char *argv[]) + /* listen for page-in events to stop pager */ + create_page_in_thread(paging); + +- /* Evict pages */ +- for ( i = 0; i < paging->num_pages; i++ ) +- { +- rc = evict_victim(paging, &victims[i], fd, i); +- if ( rc == -ENOSPC ) +- break; +- if ( rc == -EINTR ) +- break; +- if ( i % 100 == 0 ) +- DPRINTF("%d pages evicted\n", i); +- } +- ++ i = evict_pages(paging, fd, victims, paging->num_pages); + DPRINTF("%d pages evicted. Done.\n", i); + + /* Swap pages in and out */ +@@ -689,13 +730,13 @@ int main(int argc, char *argv[]) + if ( test_and_clear_bit(req.gfn, paging->bitmap) ) + { + /* Find where in the paging file to read from */ +- for ( i = 0; i < paging->num_pages; i++ ) ++ for ( i = 0; i < paging->max_pages; i++ ) + { + if ( victims[i].gfn == req.gfn ) + break; + } + +- if ( i >= paging->num_pages ) ++ if ( i >= paging->max_pages ) + { + DPRINTF("Couldn't find page %"PRIx64"\n", req.gfn); + goto out; +@@ -767,25 +808,12 @@ int main(int argc, char *argv[]) + /* Write all pages back into the guest */ + if ( interrupted == SIGTERM || interrupted == SIGINT ) + { +- int num = 0; +- for ( i = 0; i < paging->max_pages; i++ ) +- { +- if ( test_bit(i, paging->bitmap) ) +- { +- paging->pagein_queue[num] = i; +- num++; +- if ( num == XENPAGING_PAGEIN_QUEUE_SIZE ) +- break; +- } +- } +- /* +- * One more round if there are still pages to process. +- * If no more pages to process, exit loop. +- */ +- if ( num ) +- page_in_trigger(); +- else if ( i == paging->max_pages ) ++ /* If no more pages to process, exit loop. */ ++ if ( !paging->num_paged_out ) + break; ++ ++ /* One more round if there are still pages to process. */ ++ resume_pages(paging, paging->num_paged_out); + } + else + { diff --git a/xenpaging.autostart.patch b/xenpaging.autostart.patch index 096634e..e516ef1 100644 --- a/xenpaging.autostart.patch +++ b/xenpaging.autostart.patch @@ -1,4 +1,7 @@ -xenpaging: start xenpaging via config option +# HG changeset patch +# Parent 659ee31faec91ac543578db7c9b2849fb7367419 + +xenpaging: xend: start xenpaging via config option Start xenpaging via config option. @@ -8,10 +11,14 @@ TODO: parse config values like 42K, 42M, 42G, 42% Signed-off-by: Olaf Hering --- +v5: + use actmem=, xenpaging_file=, xenpaging_extra= + add xm mem-swap-target + v4: add config option for pagefile directory add config option to enable debug - add config option to set polic mru_size + add config option to set policy mru_size fail if chdir fails force self.xenpaging* variables to be strings because a xm new may turn some of them into type int and later os.execve fails with a TypeError @@ -26,35 +33,34 @@ v2: allows hardlinking for further inspection --- - tools/examples/xmexample.hvm | 12 ++++ - tools/python/README.XendConfig | 4 + - tools/python/README.sxpcfg | 4 + - tools/python/xen/xend/XendConfig.py | 12 ++++ - tools/python/xen/xend/XendDomainInfo.py | 12 ++++ - tools/python/xen/xend/image.py | 87 ++++++++++++++++++++++++++++++++ - tools/python/xen/xm/create.py | 20 +++++++ - tools/python/xen/xm/xenapi_create.py | 4 + - 8 files changed, 155 insertions(+) + tools/examples/xmexample.hvm | 9 +++ + tools/python/README.XendConfig | 3 + + tools/python/README.sxpcfg | 3 + + tools/python/xen/xend/XendConfig.py | 9 +++ + tools/python/xen/xend/XendDomain.py | 15 +++++ + tools/python/xen/xend/XendDomainInfo.py | 22 ++++++++ + tools/python/xen/xend/image.py | 85 ++++++++++++++++++++++++++++++++ + tools/python/xen/xm/create.py | 15 +++++ + tools/python/xen/xm/main.py | 14 +++++ + tools/python/xen/xm/xenapi_create.py | 3 + + 10 files changed, 178 insertions(+) Index: xen-4.1.2-testing/tools/examples/xmexample.hvm =================================================================== --- xen-4.1.2-testing.orig/tools/examples/xmexample.hvm +++ xen-4.1.2-testing/tools/examples/xmexample.hvm -@@ -127,6 +127,18 @@ disk = [ 'file:/var/lib/xen/images/disk. +@@ -127,6 +127,15 @@ disk = [ 'file:/var/lib/xen/images/disk. # Device Model to be used device_model = 'qemu-dm' -+# number of guest pages to page-out, or -1 for entire guest memory range -+xenpaging=42 ++# the amount of memory in MiB for the guest ++#actmem=42 + -+# directory to store guest page file -+#xenpaging_workdir="/var/lib/xen/xenpaging" ++# Optional: guest page file ++#xenpaging_file="/var/lib/xen/xenpaging/..paging" + -+# enable debug output in pager -+#xenpaging_debug=0 -+ -+# number of paged-in pages to keep in memory -+#xenpaging_policy_mru_size=1024 ++# Optional: extra cmdline options for xenpaging ++#xenpaging_extra=[ 'string', 'string' ] + #----------------------------------------------------------------------------- # boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d) @@ -63,14 +69,13 @@ Index: xen-4.1.2-testing/tools/python/README.XendConfig =================================================================== --- xen-4.1.2-testing.orig/tools/python/README.XendConfig +++ xen-4.1.2-testing/tools/python/README.XendConfig -@@ -120,6 +120,10 @@ otherConfig +@@ -120,6 +120,9 @@ otherConfig image.vncdisplay image.vncunused image.hvm.device_model -+ image.hvm.xenpaging -+ image.hvm.xenpaging_workdir -+ image.hvm.xenpaging_debug -+ image.hvm.xenpaging_policy_mru_size ++ image.hvm.actmem ++ image.hvm.xenpaging_file ++ image.hvm.xenpaging_extra image.hvm.display image.hvm.xauthority image.hvm.vncconsole @@ -78,14 +83,13 @@ Index: xen-4.1.2-testing/tools/python/README.sxpcfg =================================================================== --- xen-4.1.2-testing.orig/tools/python/README.sxpcfg +++ xen-4.1.2-testing/tools/python/README.sxpcfg -@@ -51,6 +51,10 @@ image +@@ -51,6 +51,9 @@ image - vncunused (HVM) - device_model -+ - xenpaging -+ - xenpaging_workdir -+ - xenpaging_debug -+ - xenpaging_policy_mru_size ++ - actmem ++ - xenpaging_file ++ - xenpaging_extra - display - xauthority - vncconsole @@ -93,37 +97,77 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendConfig.py =================================================================== --- xen-4.1.2-testing.orig/tools/python/xen/xend/XendConfig.py +++ xen-4.1.2-testing/tools/python/xen/xend/XendConfig.py -@@ -147,6 +147,10 @@ XENAPI_PLATFORM_CFG_TYPES = { +@@ -147,6 +147,9 @@ XENAPI_PLATFORM_CFG_TYPES = { 'apic': int, 'boot': str, 'device_model': str, -+ 'xenpaging': str, -+ 'xenpaging_workdir': str, -+ 'xenpaging_debug': str, -+ 'xenpaging_policy_mru_size': str, ++ 'actmem': str, ++ 'xenpaging_file': str, ++ 'xenpaging_extra': str, 'loader': str, 'display' : str, 'fda': str, -@@ -516,6 +520,14 @@ class XendConfig(dict): +@@ -516,6 +519,12 @@ class XendConfig(dict): self['platform']['nomigrate'] = 0 if self.is_hvm(): -+ if 'xenpaging' not in self['platform']: -+ self['platform']['xenpaging'] = "0" -+ if 'xenpaging_workdir' not in self['platform']: -+ self['platform']['xenpaging_workdir'] = "/var/lib/xen/xenpaging" -+ if 'xenpaging_debug' not in self['platform']: -+ self['platform']['xenpaging_debug'] = "0" -+ if 'xenpaging_policy_mru_size' not in self['platform']: -+ self['platform']['xenpaging_policy_mru_size'] = "0" ++ if 'actmem' not in self['platform']: ++ self['platform']['actmem'] = "0" ++ if 'xenpaging_file' not in self['platform']: ++ self['platform']['xenpaging_file'] = "" ++ if 'xenpaging_extra' not in self['platform']: ++ self['platform']['xenpaging_extra'] = [] if 'timer_mode' not in self['platform']: self['platform']['timer_mode'] = 1 if 'extid' in self['platform'] and int(self['platform']['extid']) == 1: +Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomain.py +=================================================================== +--- xen-4.1.2-testing.orig/tools/python/xen/xend/XendDomain.py ++++ xen-4.1.2-testing/tools/python/xen/xend/XendDomain.py +@@ -2022,6 +2022,21 @@ class XendDomain: + log.exception(ex) + raise XendError(str(ex)) + ++ def domain_swaptarget_set(self, domid, mem): ++ """Set the memory limit for a domain. ++ ++ @param domid: Domain ID or Name ++ @type domid: int or string. ++ @param mem: memory limit (in MiB) ++ @type mem: int ++ @raise XendError: fail to set memory ++ @rtype: 0 ++ """ ++ dominfo = self.domain_lookup_nr(domid) ++ if not dominfo: ++ raise XendInvalidDomain(str(domid)) ++ dominfo.setSwapTarget(mem) ++ + def domain_maxmem_set(self, domid, mem): + """Set the memory limit for a domain. + Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-4.1.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -2291,6 +2291,8 @@ class XendDomainInfo: +@@ -1503,6 +1503,16 @@ class XendDomainInfo: + break + xen.xend.XendDomain.instance().managed_config_save(self) + ++ def setSwapTarget(self, target): ++ """Set the swap target of this domain. ++ @param target: In MiB. ++ """ ++ log.debug("Setting swap target of domain %s (%s) to %d MiB.", ++ self.info['name_label'], str(self.domid), target) ++ ++ if self.domid > 0: ++ self.storeDom("memory/target-tot_pages", target * 1024) ++ + def setMemoryTarget(self, target): + """Set the memory target of this domain. + @param target: In MiB. +@@ -2291,6 +2301,8 @@ class XendDomainInfo: self.info['name_label'], self.domid, self.info['uuid'], new_name, new_uuid) self._unwatchVm() @@ -132,7 +176,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py self._releaseDevices() # Remove existing vm node in xenstore self._removeVm() -@@ -2965,6 +2967,9 @@ class XendDomainInfo: +@@ -2965,6 +2977,9 @@ class XendDomainInfo: self._createDevices() @@ -142,7 +186,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py self.image.cleanupTmpImages() self.info['start_time'] = time.time() -@@ -2989,6 +2994,8 @@ class XendDomainInfo: +@@ -2989,6 +3004,8 @@ class XendDomainInfo: self.refresh_shutdown_lock.acquire() try: self.unwatchShutdown() @@ -151,7 +195,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py self._releaseDevices() bootloader_tidy(self) -@@ -3073,6 +3080,7 @@ class XendDomainInfo: +@@ -3073,6 +3090,7 @@ class XendDomainInfo: self.image = image.create(self, self.info) if self.image: self._createDevices(True) @@ -159,7 +203,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py self.console_port = console_port self._storeDomDetails() self._registerWatches() -@@ -3214,6 +3222,8 @@ class XendDomainInfo: +@@ -3214,6 +3232,8 @@ class XendDomainInfo: # could also fetch a parsed note from xenstore fast = self.info.get_notes().get('SUSPEND_CANCEL') and 1 or 0 if not fast: @@ -168,7 +212,7 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/XendDomainInfo.py self._releaseDevices() self.testDeviceComplete() self.testvifsComplete() -@@ -3229,6 +3239,8 @@ class XendDomainInfo: +@@ -3229,6 +3249,8 @@ class XendDomainInfo: self._storeDomDetails() self._createDevices() @@ -181,38 +225,34 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/image.py =================================================================== --- xen-4.1.2-testing.orig/tools/python/xen/xend/image.py +++ xen-4.1.2-testing/tools/python/xen/xend/image.py -@@ -122,6 +122,11 @@ class ImageHandler: +@@ -122,6 +122,10 @@ class ImageHandler: self.vm.permissionsVm("image/cmdline", { 'dom': self.vm.getDomid(), 'read': True } ) self.device_model = vmConfig['platform'].get('device_model') -+ self.xenpaging = str(vmConfig['platform'].get('xenpaging')) -+ self.xenpaging_workdir = str(vmConfig['platform'].get('xenpaging_workdir')) -+ self.xenpaging_debug = str(vmConfig['platform'].get('xenpaging_debug')) -+ self.xenpaging_policy_mru_size = str(vmConfig['platform'].get('xenpaging_policy_mru_size')) ++ self.actmem = str(vmConfig['platform'].get('actmem')) ++ self.xenpaging_file = str(vmConfig['platform'].get('xenpaging_file')) ++ self.xenpaging_extra = vmConfig['platform'].get('xenpaging_extra') + self.xenpaging_pid = None self.display = vmConfig['platform'].get('display') self.xauthority = vmConfig['platform'].get('xauthority') -@@ -392,6 +397,88 @@ class ImageHandler: +@@ -392,6 +396,87 @@ class ImageHandler: sentinel_fifos_inuse[sentinel_path_fifo] = 1 self.sentinel_path_fifo = sentinel_path_fifo + def createXenPaging(self): + if not self.vm.info.is_hvm(): + return -+ if self.xenpaging == "0": ++ if self.actmem == "0": + return + if self.xenpaging_pid: + return + xenpaging_bin = auxbin.pathTo("xenpaging") + args = [xenpaging_bin] -+ args = args + ([ "%d" % self.vm.getDomid()]) -+ args = args + ([ "%s" % self.xenpaging]) -+ env = dict(os.environ) -+ if not self.xenpaging_debug == "0": -+ env['XENPAGING_DEBUG'] = self.xenpaging_debug -+ if not self.xenpaging_policy_mru_size == "0": -+ env['XENPAGING_POLICY_MRU_SIZE'] = self.xenpaging_policy_mru_size ++ args = args + ([ "-f", "/var/lib/xen/xenpaging/%s.%d.paging" % (str(self.vm.info['name_label']), self.vm.getDomid())]) ++ if self.xenpaging_extra: ++ args = args + (self.xenpaging_extra) ++ args = args + ([ "-d", "%d" % self.vm.getDomid()]) + self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" % str(self.vm.info['name_label']) + logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC + null = os.open("/dev/null", os.O_RDONLY) @@ -230,24 +270,26 @@ Index: xen-4.1.2-testing/tools/python/xen/xend/image.py + os.dup2(null, 0) + os.dup2(logfd, 1) + os.dup2(logfd, 2) -+ os.chdir(self.xenpaging_workdir) + try: ++ env = dict(os.environ) + log.info("starting %s" % args) + os.execve(xenpaging_bin, args, env) + except Exception, e: + log.warn('failed to execute xenpaging: %s' % utils.exception_string(e)) + os._exit(126) + except: -+ log.warn("starting xenpaging in %s failed" % self.xenpaging_workdir) ++ log.warn("starting xenpaging failed") + os._exit(127) + else: + osdep.postfork(contract, abandon=True) + self.xenpaging_pid = xenpaging_pid + os.close(null) + os.close(logfd) ++ self.vm.storeDom("xenpaging/xenpaging-pid", self.xenpaging_pid) ++ self.vm.storeDom("memory/target-tot_pages", int(self.actmem) * 1024) + + def destroyXenPaging(self): -+ if self.xenpaging == "0": ++ if self.actmem == "0": + return + if self.xenpaging_pid: + try: @@ -286,52 +328,85 @@ Index: xen-4.1.2-testing/tools/python/xen/xm/create.py =================================================================== --- xen-4.1.2-testing.orig/tools/python/xen/xm/create.py +++ xen-4.1.2-testing/tools/python/xen/xm/create.py -@@ -495,6 +495,22 @@ gopts.var('nfs_root', val="PATH", +@@ -495,6 +495,18 @@ gopts.var('nfs_root', val="PATH", fn=set_value, default=None, use="Set the path of the root NFS directory.") -+gopts.var('xenpaging', val='NUM', ++gopts.var('actmem', val='NUM', + fn=set_value, default='0', + use="Number of pages to swap.") + -+gopts.var('xenpaging_workdir', val='PATH', -+ fn=set_value, default='/var/lib/xen/xenpaging', -+ use="Number of pages to swap.") ++gopts.var('xenpaging_file', val='PATH', ++ fn=set_value, default=None, ++ use="pagefile to use (optional)") + -+gopts.var('xenpaging_debug', val='NUM', -+ fn=set_value, default='0', -+ use="Number of pages to swap.") -+ -+gopts.var('xenpaging_policy_mru_size', val='NUM', -+ fn=set_value, default='0', -+ use="Number of pages to swap.") ++gopts.var('xenpaging_extra', val='string1,string2', ++ fn=append_value, default=[], ++ use="additional args for xenpaging (optional)") + gopts.var('device_model', val='FILE', fn=set_value, default=None, use="Path to device model program.") -@@ -1095,6 +1111,10 @@ def configure_hvm(config_image, vals): +@@ -1095,6 +1107,9 @@ def configure_hvm(config_image, vals): args = [ 'acpi', 'apic', 'boot', 'cpuid', 'cpuid_check', -+ 'xenpaging', -+ 'xenpaging_workdir', -+ 'xenpaging_debug', -+ 'xenpaging_policy_mru_size', ++ 'actmem', ++ 'xenpaging_file', ++ 'xenpaging_extra', 'device_model', 'display', 'fda', 'fdb', 'gfx_passthru', 'guest_os_type', +Index: xen-4.1.2-testing/tools/python/xen/xm/main.py +=================================================================== +--- xen-4.1.2-testing.orig/tools/python/xen/xm/main.py ++++ xen-4.1.2-testing/tools/python/xen/xm/main.py +@@ -115,6 +115,8 @@ SUBCOMMAND_HELP = { + 'Set the maximum amount reservation for a domain.'), + 'mem-set' : (' ', + 'Set the current memory usage for a domain.'), ++ 'mem-swap-target' : (' ', ++ 'Set the memory usage for a domain.'), + 'migrate' : (' ', + 'Migrate a domain to another machine.'), + 'pause' : ('', 'Pause execution of a domain.'), +@@ -1667,6 +1669,17 @@ def xm_mem_set(args): + mem_target = int_unit(args[1], 'm') + server.xend.domain.setMemoryTarget(dom, mem_target) + ++def xm_mem_swap_target(args): ++ arg_check(args, "mem-swap-target", 2) ++ ++ dom = args[0] ++ ++ if serverType == SERVER_XEN_API: ++ err("xenapi not supported") ++ else: ++ swap_target = int_unit(args[1], 'm') ++ server.xend.domain.swaptarget_set(dom, swap_target) ++ + def xm_usb_add(args): + arg_check(args, "usb-add", 2) + server.xend.domain.usb_add(args[0],args[1]) +@@ -3926,6 +3939,7 @@ commands = { + # memory commands + "mem-max": xm_mem_max, + "mem-set": xm_mem_set, ++ "mem-swap-target": xm_mem_swap_target, + # cpu commands + "vcpu-pin": xm_vcpu_pin, + "vcpu-list": xm_vcpu_list, Index: xen-4.1.2-testing/tools/python/xen/xm/xenapi_create.py =================================================================== --- xen-4.1.2-testing.orig/tools/python/xen/xm/xenapi_create.py +++ xen-4.1.2-testing/tools/python/xen/xm/xenapi_create.py -@@ -1085,6 +1085,10 @@ class sxp2xml: +@@ -1085,6 +1085,9 @@ class sxp2xml: 'acpi', 'apic', 'boot', -+ 'xenpaging', -+ 'xenpaging_workdir', -+ 'xenpaging_debug', -+ 'xenpaging_policy_mru_size', ++ 'actmem', ++ 'xenpaging_file', ++ 'xenpaging_extra', 'device_model', 'loader', 'fda', diff --git a/xenpaging.bitmap_clear.patch b/xenpaging.bitmap_clear.patch new file mode 100644 index 0000000..01fb7b1 --- /dev/null +++ b/xenpaging.bitmap_clear.patch @@ -0,0 +1,34 @@ +# HG changeset patch +# Parent 2ac53905d95e6d02f53c99f6e2fa38f7306b8800 +libxc: add bitmap_clear function + +Signed-off-by: Olaf Hering + +--- + tools/libxc/xc_bitops.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: xen-4.1.2-testing/tools/libxc/xc_bitops.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/libxc/xc_bitops.h ++++ xen-4.1.2-testing/tools/libxc/xc_bitops.h +@@ -4,6 +4,7 @@ + /* bitmap operations for single threaded access */ + + #include ++#include + + #define BITS_PER_LONG (sizeof(unsigned long) * 8) + #define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6) +@@ -25,6 +26,11 @@ static inline unsigned long *bitmap_allo + return calloc(1, bitmap_size(nr_bits)); + } + ++static inline void bitmap_clear(unsigned long *addr, int nr_bits) ++{ ++ memset(addr, 0, bitmap_size(nr_bits)); ++} ++ + static inline int test_bit(int nr, volatile unsigned long *addr) + { + return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1; diff --git a/xenpaging.cmdline-interface.patch b/xenpaging.cmdline-interface.patch new file mode 100644 index 0000000..8a965e9 --- /dev/null +++ b/xenpaging.cmdline-interface.patch @@ -0,0 +1,268 @@ +# HG changeset patch +# Parent 434f0b4da9148b101e184e0108be6c31f67038f4 +xenpaging: add cmdline interface for pager + +Introduce a cmdline handling for the pager. This simplifies libxl support, +debug and mru_size are not passed via the environment anymore. +The new interface looks like this: + +xenpaging [options] -f -d +options: + -d --domain= numerical domain_id of guest. This option is required. + -f --pagefile= pagefile to use. This option is required. + -m --max_memkb= maximum amount of memory to handle. + -r --mru_size= number of paged-in pages to keep in memory. + -d --debug enable debug output. + -h --help this output. + + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 139 ++++++++++++++++++++++++++++++++------------ + tools/xenpaging/xenpaging.h | 1 + 2 files changed, 103 insertions(+), 37 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "xc_bitops.h" + #include "file_ops.h" +@@ -42,12 +43,12 @@ + static char *watch_target_tot_pages; + static char *dom_path; + static char watch_token[16]; +-static char filename[80]; ++static char *filename; + static int interrupted; + + static void unlink_pagefile(void) + { +- if ( filename[0] ) ++ if ( filename && filename[0] ) + { + unlink(filename); + filename[0] = '\0'; +@@ -201,11 +202,85 @@ static void *init_page(void) + return NULL; + } + +-static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages) ++static void usage(void) ++{ ++ printf("usage:\n\n"); ++ ++ printf(" xenpaging [options] -f -d \n\n"); ++ ++ printf("options:\n"); ++ printf(" -d --domain= numerical domain_id of guest. This option is required.\n"); ++ printf(" -f --pagefile= pagefile to use. This option is required.\n"); ++ printf(" -m --max_memkb= maximum amount of memory to handle.\n"); ++ printf(" -r --mru_size= number of paged-in pages to keep in memory.\n"); ++ printf(" -v --verbose enable debug output.\n"); ++ printf(" -h --help this output.\n"); ++} ++ ++static int xenpaging_getopts(xenpaging_t *paging, int argc, char *argv[]) ++{ ++ int ch; ++ static const char sopts[] = "hvd:f:m:r:"; ++ static const struct option lopts[] = { ++ {"help", 0, NULL, 'h'}, ++ {"verbose", 0, NULL, 'v'}, ++ {"domain", 1, NULL, 'd'}, ++ {"pagefile", 1, NULL, 'f'}, ++ {"mru_size", 1, NULL, 'm'}, ++ { } ++ }; ++ ++ while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) ++ { ++ switch(ch) { ++ case 'd': ++ paging->mem_event.domain_id = atoi(optarg); ++ break; ++ case 'f': ++ filename = strdup(optarg); ++ break; ++ case 'm': ++ /* KiB to pages */ ++ paging->max_pages = atoi(optarg) >> 2; ++ break; ++ case 'r': ++ paging->policy_mru_size = atoi(optarg); ++ break; ++ case 'v': ++ paging->debug = 1; ++ break; ++ case 'h': ++ case '?': ++ usage(); ++ return 1; ++ } ++ } ++ ++ argv += optind; argc -= optind; ++ ++ /* Path to pagefile is required */ ++ if ( !filename ) ++ { ++ printf("Filename for pagefile missing!\n"); ++ usage(); ++ return 1; ++ } ++ ++ /* Set domain id */ ++ if ( !paging->mem_event.domain_id ) ++ { ++ printf("Numerical missing!\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static xenpaging_t *xenpaging_init(int argc, char *argv[]) + { + xenpaging_t *paging; + xc_domaininfo_t domain_info; +- xc_interface *xch; ++ xc_interface *xch = NULL; + xentoollog_logger *dbg = NULL; + char *p; + int rc; +@@ -215,7 +290,12 @@ static xenpaging_t *xenpaging_init(domid + if ( !paging ) + goto err; + +- if ( getenv("XENPAGING_DEBUG") ) ++ /* Get cmdline options and domain_id */ ++ if ( xenpaging_getopts(paging, argc, argv) ) ++ goto err; ++ ++ /* Enable debug output */ ++ if ( paging->debug ) + dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0); + + /* Open connection to xen */ +@@ -234,7 +314,7 @@ static xenpaging_t *xenpaging_init(domid + } + + /* write domain ID to watch so we can ignore other domain shutdowns */ +- snprintf(watch_token, sizeof(watch_token), "%u", domain_id); ++ snprintf(watch_token, sizeof(watch_token), "%u", paging->mem_event.domain_id); + if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false ) + { + PERROR("Could not bind to shutdown watch\n"); +@@ -242,7 +322,7 @@ static xenpaging_t *xenpaging_init(domid + } + + /* Watch xenpagings working target */ +- dom_path = xs_get_domain_path(paging->xs_handle, domain_id); ++ dom_path = xs_get_domain_path(paging->xs_handle, paging->mem_event.domain_id); + if ( !dom_path ) + { + PERROR("Could not find domain path\n"); +@@ -260,16 +340,6 @@ static xenpaging_t *xenpaging_init(domid + goto err; + } + +- p = getenv("XENPAGING_POLICY_MRU_SIZE"); +- if ( p && *p ) +- { +- paging->policy_mru_size = atoi(p); +- DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size); +- } +- +- /* Set domain id */ +- paging->mem_event.domain_id = domain_id; +- + /* Initialise shared page */ + paging->mem_event.shared_page = init_page(); + if ( paging->mem_event.shared_page == NULL ) +@@ -335,16 +405,20 @@ static xenpaging_t *xenpaging_init(domid + + paging->mem_event.port = rc; + +- rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, +- &domain_info); +- if ( rc != 1 ) ++ /* Get max_pages from guest if not provided via cmdline */ ++ if ( !paging->max_pages ) + { +- PERROR("Error getting domain info"); +- goto err; +- } ++ rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, ++ &domain_info); ++ if ( rc != 1 ) ++ { ++ PERROR("Error getting domain info"); ++ goto err; ++ } + +- /* Record number of max_pages */ +- paging->max_pages = domain_info.max_pages; ++ /* Record number of max_pages */ ++ paging->max_pages = domain_info.max_pages; ++ } + + /* Allocate bitmap for tracking pages that have been paged out */ + paging->bitmap = bitmap_alloc(paging->max_pages); +@@ -355,8 +429,6 @@ static xenpaging_t *xenpaging_init(domid + } + DPRINTF("max_pages = %d\n", paging->max_pages); + +- paging->target_tot_pages = target_tot_pages; +- + /* Initialise policy */ + rc = policy_init(paging); + if ( rc != 0 ) +@@ -718,25 +790,18 @@ int main(int argc, char *argv[]) + mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH; + int fd; + +- if ( argc != 3 ) +- { +- fprintf(stderr, "Usage: %s \n", argv[0]); +- return -1; +- } +- + /* Initialise domain paging */ +- paging = xenpaging_init(atoi(argv[1]), atoi(argv[2])); ++ paging = xenpaging_init(argc, argv); + if ( paging == NULL ) + { +- fprintf(stderr, "Error initialising paging"); ++ fprintf(stderr, "Error initialising paging\n"); + return 1; + } + xch = paging->xc_handle; + +- DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages); ++ DPRINTF("starting %s for domain_id %u with pagefile %s\n", argv[0], paging->mem_event.domain_id, filename); + + /* Open file */ +- sprintf(filename, "page_cache_%u", paging->mem_event.domain_id); + fd = open(filename, open_flags, open_mode); + if ( fd < 0 ) + { +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h +@@ -52,6 +52,7 @@ typedef struct xenpaging { + int num_paged_out; + int target_tot_pages; + int policy_mru_size; ++ int debug; + unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; + } xenpaging_t; + diff --git a/xenpaging.encapsulate_domain_info.patch b/xenpaging.encapsulate_domain_info.patch new file mode 100644 index 0000000..b730cab --- /dev/null +++ b/xenpaging.encapsulate_domain_info.patch @@ -0,0 +1,140 @@ +# HG changeset patch +# Parent f665912bc70e0b12e194cf1dd1d37bd22b29c54f +xenpaging: remove xc_dominfo_t from paging_t + +Remove xc_dominfo_t from paging_t, record only max_pages. +This value is used to setup internal data structures. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/policy_default.c | 8 ++++---- + tools/xenpaging/xenpaging.c | 27 +++++++++++---------------- + tools/xenpaging/xenpaging.h | 4 ++-- + 3 files changed, 17 insertions(+), 22 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c ++++ xen-4.1.2-testing/tools/xenpaging/policy_default.c +@@ -41,17 +41,17 @@ int policy_init(xenpaging_t *paging) + int i; + int rc = -ENOMEM; + ++ max_pages = paging->max_pages; ++ + /* Allocate bitmap for pages not to page out */ +- bitmap = bitmap_alloc(paging->domain_info->max_pages); ++ bitmap = bitmap_alloc(max_pages); + if ( !bitmap ) + goto out; + /* Allocate bitmap to track unusable pages */ +- unconsumed = bitmap_alloc(paging->domain_info->max_pages); ++ unconsumed = bitmap_alloc(max_pages); + if ( !unconsumed ) + goto out; + +- max_pages = paging->domain_info->max_pages; +- + /* Initialise MRU list of paged in pages */ + if ( paging->policy_mru_size > 0 ) + mru_size = paging->policy_mru_size; +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -164,6 +164,7 @@ static void *init_page(void) + static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages) + { + xenpaging_t *paging; ++ xc_domaininfo_t domain_info; + xc_interface *xch; + xentoollog_logger *dbg = NULL; + char *p; +@@ -275,34 +276,29 @@ static xenpaging_t *xenpaging_init(domid + + paging->mem_event.port = rc; + +- /* Get domaininfo */ +- paging->domain_info = malloc(sizeof(xc_domaininfo_t)); +- if ( paging->domain_info == NULL ) +- { +- PERROR("Error allocating memory for domain info"); +- goto err; +- } +- + rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, +- paging->domain_info); ++ &domain_info); + if ( rc != 1 ) + { + PERROR("Error getting domain info"); + goto err; + } + ++ /* Record number of max_pages */ ++ paging->max_pages = domain_info.max_pages; ++ + /* Allocate bitmap for tracking pages that have been paged out */ +- paging->bitmap = bitmap_alloc(paging->domain_info->max_pages); ++ paging->bitmap = bitmap_alloc(paging->max_pages); + if ( !paging->bitmap ) + { + PERROR("Error allocating bitmap"); + goto err; + } +- DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages); ++ DPRINTF("max_pages = %d\n", paging->max_pages); + +- if ( num_pages < 0 || num_pages > paging->domain_info->max_pages ) ++ if ( num_pages < 0 || num_pages > paging->max_pages ) + { +- num_pages = paging->domain_info->max_pages; ++ num_pages = paging->max_pages; + DPRINTF("setting num_pages to %d\n", num_pages); + } + paging->num_pages = num_pages; +@@ -337,7 +333,6 @@ static xenpaging_t *xenpaging_init(domid + } + + free(paging->bitmap); +- free(paging->domain_info); + free(paging); + } + +@@ -765,7 +760,7 @@ int main(int argc, char *argv[]) + if ( interrupted == SIGTERM || interrupted == SIGINT ) + { + int num = 0; +- for ( i = 0; i < paging->domain_info->max_pages; i++ ) ++ for ( i = 0; i < paging->max_pages; i++ ) + { + if ( test_bit(i, paging->bitmap) ) + { +@@ -781,7 +776,7 @@ int main(int argc, char *argv[]) + */ + if ( num ) + page_in_trigger(); +- else if ( i == paging->domain_info->max_pages ) ++ else if ( i == paging->max_pages ) + break; + } + else +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h +@@ -44,11 +44,11 @@ typedef struct xenpaging { + xc_interface *xc_handle; + struct xs_handle *xs_handle; + +- xc_domaininfo_t *domain_info; +- + unsigned long *bitmap; + + mem_event_t mem_event; ++ /* number of pages for which data structures were allocated */ ++ int max_pages; + int num_pages; + int policy_mru_size; + unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; diff --git a/xenpaging.file_op-return-code.patch b/xenpaging.file_op-return-code.patch new file mode 100644 index 0000000..811b967 --- /dev/null +++ b/xenpaging.file_op-return-code.patch @@ -0,0 +1,85 @@ +# HG changeset patch +# Parent 7a4a6935bfa145b24d5183cbf43ce8cc140d9183 +xenpaging: simplify file_op + +Use -1 as return value and let caller read errno. +Remove const casts from buffer pointers, the page is writeable. +Use wrapper for write() which matches the read() prototype. +Remove unused stdarg.h inclusion. +Remove unused macro. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/file_ops.c | 29 +++++++++-------------------- + 1 file changed, 9 insertions(+), 20 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/file_ops.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/file_ops.c ++++ xen-4.1.2-testing/tools/xenpaging/file_ops.c +@@ -21,55 +21,44 @@ + + + #include +-#include + #include + +- +-#define page_offset(_pfn) (((off_t)(_pfn)) << PAGE_SHIFT) +- +- + static int file_op(int fd, void *page, int i, +- ssize_t (*fn)(int, const void *, size_t)) ++ ssize_t (*fn)(int, void *, size_t)) + { + off_t seek_ret; +- int total; ++ int total = 0; + int bytes; +- int ret; + + seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET); ++ if ( seek_ret == (off_t)-1 ) ++ return -1; + +- total = 0; + while ( total < PAGE_SIZE ) + { + bytes = fn(fd, page + total, PAGE_SIZE - total); + if ( bytes <= 0 ) +- { +- ret = -errno; +- goto err; +- } ++ return -1; + + total += bytes; + } + + return 0; +- +- err: +- return ret; + } + +-static ssize_t my_read(int fd, const void *buf, size_t count) ++static ssize_t my_write(int fd, void *buf, size_t count) + { +- return read(fd, (void *)buf, count); ++ return write(fd, buf, count); + } + + int read_page(int fd, void *page, int i) + { +- return file_op(fd, page, i, &my_read); ++ return file_op(fd, page, i, &read); + } + + int write_page(int fd, void *page, int i) + { +- return file_op(fd, page, i, &write); ++ return file_op(fd, page, i, &my_write); + } + + diff --git a/xenpaging.guest-memusage.patch b/xenpaging.guest-memusage.patch new file mode 100644 index 0000000..807003a --- /dev/null +++ b/xenpaging.guest-memusage.patch @@ -0,0 +1,80 @@ +--- + tools/xenpaging/Makefile | 2 - + tools/xenpaging/xenmem.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 58 insertions(+), 1 deletion(-) + +Index: xen-4.1.2-testing/tools/xenpaging/Makefile +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile ++++ xen-4.1.2-testing/tools/xenpaging/Makefile +@@ -20,7 +20,7 @@ CFLAGS += -Wp,-MD,.$(@F).d + DEPS = .*.d + + OBJS = $(SRCS:.c=.o) +-IBINS = xenpaging ++IBINS = xenpaging xenmem + + all: $(IBINS) + +Index: xen-4.1.2-testing/tools/xenpaging/xenmem.c +=================================================================== +--- /dev/null ++++ xen-4.1.2-testing/tools/xenpaging/xenmem.c +@@ -0,0 +1,57 @@ ++#include ++#include ++ ++static void dump_mem(const char *domid) ++{ ++ xc_interface *xch; ++ xc_dominfo_t info; ++ unsigned char handle[16]; ++ char uuid[16 * 2 + 1]; ++ int i; ++ ++ xch = xc_interface_open(NULL, NULL, 0); ++ if (!xch) ++ perror("xc_interface_open"); ++ else { ++ i = xc_domain_getinfo(xch, atoi(domid), 1, &info); ++ if (i != 1) ++ perror("xc_domain_getinfo"); ++ else { ++ printf("domid\t%u\n", info.domid); ++ printf("ssidref\t%u\n", info.ssidref); ++ printf("dying\t%u\n", info.dying); ++ printf("crashed\t%u\n", info.crashed); ++ printf("shutdown\t%u\n", info.shutdown); ++ printf("paused\t%u\n", info.paused); ++ printf("blocked\t%u\n", info.blocked); ++ printf("running\t%u\n", info.running); ++ printf("hvm\t%u\n", info.hvm); ++ printf("debugged\t%u\n", info.debugged); ++ printf("shutdown_reason\t%u\n", info.shutdown_reason); ++ printf("nr_pages\t%lu\t%lu KiB\t%lu MiB\n", info.nr_pages, info.nr_pages * 4, info.nr_pages * 4 / 1024); ++ printf("nr_shared_pages\t%lu\t%lu KiB\t%lu MiB\n", info.nr_shared_pages, info.nr_shared_pages * 4, info.nr_shared_pages * 4 / 1024); ++ printf("nr_paged_pages\t%lu\t%lu KiB\t%lu MiB\n", info.nr_paged_pages, info.nr_paged_pages * 4, info.nr_paged_pages * 4 / 1024); ++ printf("max_memkb\t%lu KiB\t%lu MiB\n", info.max_memkb, info.max_memkb / 1024); ++ printf("shared_info_frame\t%lu\t%lx\n", info.shared_info_frame, info.shared_info_frame); ++ printf("cpu_time\t%llu\t%016llx\n", (unsigned long long)info.cpu_time, (unsigned long long)info.cpu_time); ++ printf("nr_online_vcpus\t%u\n", info.nr_online_vcpus); ++ printf("max_vcpu_id\t%u\n", info.max_vcpu_id); ++ printf("cpupool\t%u\n", info.cpupool); ++ ++ memcpy(&handle, &info.handle, sizeof(handle)); ++ uuid[0] = '\0'; ++ for (i = 0; i < sizeof(handle); i++) ++ snprintf(&uuid[i * 2], sizeof(uuid) - strlen(uuid), "%02x", handle[i]); ++ printf("handle\t%s\n", uuid); ++ } ++ if (xc_interface_close(xch) < 0) ++ perror("xc_interface_close"); ++ } ++} ++ ++int main(int argc, char **argv) ++{ ++ if (argv[1]) ++ dump_mem(argv[1]); ++ return 0; ++} diff --git a/xenpaging.install-to-libexec.patch b/xenpaging.install-to-libexec.patch new file mode 100644 index 0000000..79b69d2 --- /dev/null +++ b/xenpaging.install-to-libexec.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# Parent a30ec96cbaa43bc7abd90b7d974a8033265409c1 +xenpaging: install into LIBEXEC dir + +In preparation of upcoming libxl integration, +move xenpaging binary from /usr/sbin/ to /usr/lib/xen/bin/ + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/Makefile +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/Makefile ++++ xen-4.1.2-testing/tools/xenpaging/Makefile +@@ -29,8 +29,8 @@ xenpaging: $(OBJS) + + install: all + $(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging +- $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) +- $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(SBINDIR) ++ $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC) ++ $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC) + + clean: + rm -f *.o *~ $(DEPS) xen TAGS $(IBINS) $(LIB) diff --git a/xenpaging.low_target_policy_nomru.patch b/xenpaging.low_target_policy_nomru.patch new file mode 100644 index 0000000..b873595 --- /dev/null +++ b/xenpaging.low_target_policy_nomru.patch @@ -0,0 +1,122 @@ +# HG changeset patch +# Parent 79677f532a2406ca501250b50fa8b33965a8d7d7 +xenpaging: improve policy mru list handling + +Without this change it is not possible to page-out all guest pages, then +trigger a page-in for all pages, and then page-out everything once +again. All pages in the mru list can not be paged out because they +remain active in the internal bitmap of paged pages. + +Use the mru list only if the number of paged-out pages is larger than +the mru list. If the number is smaller, start to clear the mru list. In +case the number of paged-out pages drops to zero the mru list and the +internal bitmap will be empty as well. + +Also add a new interface for dropped pages. If a gfn was dropped there +is no need to adjust the mru list because dropping a page is not usage +of a page. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/policy.h | 2 ++ + tools/xenpaging/policy_default.c | 27 ++++++++++++++++++++++++--- + tools/xenpaging/xenpaging.c | 11 +++++++++-- + 3 files changed, 35 insertions(+), 5 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/policy.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/policy.h ++++ xen-4.1.2-testing/tools/xenpaging/policy.h +@@ -32,6 +32,8 @@ int policy_init(xenpaging_t *paging); + int policy_choose_victim(xenpaging_t *paging, xenpaging_victim_t *victim); + void policy_notify_paged_out(unsigned long gfn); + void policy_notify_paged_in(unsigned long gfn); ++void policy_notify_paged_in_nomru(unsigned long gfn); ++void policy_notify_dropped(unsigned long gfn); + + #endif // __XEN_PAGING_POLICY_H__ + +Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c ++++ xen-4.1.2-testing/tools/xenpaging/policy_default.c +@@ -57,7 +57,7 @@ int policy_init(xenpaging_t *paging) + if ( paging->policy_mru_size > 0 ) + mru_size = paging->policy_mru_size; + else +- mru_size = DEFAULT_MRU_SIZE; ++ mru_size = paging->policy_mru_size = DEFAULT_MRU_SIZE; + + mru = malloc(sizeof(*mru) * mru_size); + if ( mru == NULL ) +@@ -120,17 +120,38 @@ void policy_notify_paged_out(unsigned lo + clear_bit(gfn, unconsumed); + } + +-void policy_notify_paged_in(unsigned long gfn) ++static void policy_handle_paged_in(unsigned long gfn, int do_mru) + { + unsigned long old_gfn = mru[i_mru & (mru_size - 1)]; + + if ( old_gfn != INVALID_MFN ) + clear_bit(old_gfn, bitmap); + +- mru[i_mru & (mru_size - 1)] = gfn; ++ if (do_mru) { ++ mru[i_mru & (mru_size - 1)] = gfn; ++ } else { ++ clear_bit(gfn, bitmap); ++ mru[i_mru & (mru_size - 1)] = INVALID_MFN; ++ } ++ + i_mru++; + } + ++void policy_notify_paged_in(unsigned long gfn) ++{ ++ policy_handle_paged_in(gfn, 1); ++} ++ ++void policy_notify_paged_in_nomru(unsigned long gfn) ++{ ++ policy_handle_paged_in(gfn, 0); ++} ++ ++void policy_notify_dropped(unsigned long gfn) ++{ ++ clear_bit(gfn, bitmap); ++} ++ + + /* + * Local variables: +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -616,7 +616,14 @@ static int xenpaging_resume_page(xenpagi + /* Notify policy of page being paged in */ + if ( notify_policy ) + { +- policy_notify_paged_in(rsp->gfn); ++ /* ++ * Do not add gfn to mru list if the target is lower than mru size. ++ * This allows page-out of these gfns if the target grows again. ++ */ ++ if (paging->num_paged_out > paging->policy_mru_size) ++ policy_notify_paged_in(rsp->gfn); ++ else ++ policy_notify_paged_in_nomru(rsp->gfn); + + /* Record number of resumed pages */ + paging->num_paged_out--; +@@ -870,7 +877,7 @@ int main(int argc, char *argv[]) + { + DPRINTF("drop_page ^ gfn %"PRIx64" pageslot %d\n", req.gfn, i); + /* Notify policy of page being dropped */ +- policy_notify_paged_in(req.gfn); ++ policy_notify_dropped(req.gfn); + } + else + { diff --git a/xenpaging.main-loop-exit-handling.patch b/xenpaging.main-loop-exit-handling.patch new file mode 100644 index 0000000..6f3e512 --- /dev/null +++ b/xenpaging.main-loop-exit-handling.patch @@ -0,0 +1,48 @@ +# HG changeset patch +# Parent f08959fb7528e1724e26365973914ae3e0af78ea +xenpaging: improve mainloop exit handling + +Remove the if/else logic to exit from the in case a signal arrives. +Update comments. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -805,7 +805,7 @@ int main(int argc, char *argv[]) + } + } + +- /* Write all pages back into the guest */ ++ /* If interrupted, write all pages back into the guest */ + if ( interrupted == SIGTERM || interrupted == SIGINT ) + { + /* If no more pages to process, exit loop. */ +@@ -814,13 +814,15 @@ int main(int argc, char *argv[]) + + /* One more round if there are still pages to process. */ + resume_pages(paging, paging->num_paged_out); ++ ++ /* Resume main loop */ ++ continue; + } +- else +- { +- /* Exit on any other signal */ +- if ( interrupted ) +- break; +- } ++ ++ /* Exit main loop on any other signal */ ++ if ( interrupted ) ++ break; ++ + } + DPRINTF("xenpaging got signal %d\n", interrupted); + diff --git a/xenpaging.misleading-comment.patch b/xenpaging.misleading-comment.patch new file mode 100644 index 0000000..7a591b5 --- /dev/null +++ b/xenpaging.misleading-comment.patch @@ -0,0 +1,26 @@ +# HG changeset patch +# Parent 138406814b338c07af349a477dd7602ecca8be70 +xenpaging: remove obsolete comment in resume path + +Remove stale comment. +If a page was populated several times the vcpu is paused and +xenpaging has to unpause it again. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 1 - + 1 file changed, 1 deletion(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -744,7 +744,6 @@ int main(int argc, char *argv[]) + !!(req.flags & MEM_EVENT_FLAG_EVICT_FAIL) ); + + /* Tell Xen to resume the vcpu */ +- /* XXX: Maybe just check if the vcpu was paused? */ + if ( req.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) + { + /* Prepare the response */ diff --git a/xenpaging.page_in-munmap-size.patch b/xenpaging.page_in-munmap-size.patch new file mode 100644 index 0000000..391ddd8 --- /dev/null +++ b/xenpaging.page_in-munmap-size.patch @@ -0,0 +1,28 @@ +# HG changeset patch +# Parent 951a9879c34bee1dd2fa0329a541ae089f271c11 +xenpaging: munmap all pages after page-in + +Do munmap() on all mapped pages, not just the first one. Without this +change the gfns backing the remaining pages can not be paged out again +because the page count does not go down to 1. This change was missing +from changeset 23827:d1d6abc1db20. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/pagein.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: xen-4.1.2-testing/tools/xenpaging/pagein.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/pagein.c ++++ xen-4.1.2-testing/tools/xenpaging/pagein.c +@@ -44,7 +44,7 @@ static void *page_in(void *arg) + /* Ignore errors */ + page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, gfns, num); + if (page) +- munmap(page, PAGE_SIZE); ++ munmap(page, PAGE_SIZE * num); + } + page_in_possible = 0; + pthread_exit(NULL); diff --git a/xenpaging.print-gfn.patch b/xenpaging.print-gfn.patch new file mode 100644 index 0000000..906bd82 --- /dev/null +++ b/xenpaging.print-gfn.patch @@ -0,0 +1,95 @@ +# HG changeset patch +# Parent 9c7e82499e983ad11b13dd41d2fa5f12072adecf +xenpaging: print gfn in failure case + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -444,7 +444,7 @@ static int xenpaging_evict_page(xenpagin + PROT_READ | PROT_WRITE, &gfn, 1); + if ( page == NULL ) + { +- PERROR("Error mapping page"); ++ PERROR("Error mapping page %lx", victim->gfn); + goto out; + } + +@@ -452,7 +452,7 @@ static int xenpaging_evict_page(xenpagin + ret = write_page(fd, page, i); + if ( ret != 0 ) + { +- PERROR("Error copying page"); ++ PERROR("Error copying page %lx", victim->gfn); + munmap(page, PAGE_SIZE); + goto out; + } +@@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin + victim->gfn); + if ( ret != 0 ) + { +- PERROR("Error evicting page"); ++ PERROR("Error evicting page %lx", victim->gfn); + goto out; + } + +@@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa + sleep(1); + continue; + } +- PERROR("Error preparing for page in"); ++ PERROR("Error preparing %"PRI_xen_pfn" for page-in", gfn); + goto out_map; + } + } +@@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa + PROT_READ | PROT_WRITE, &gfn, 1); + if ( page == NULL ) + { +- PERROR("Error mapping page: page is null"); ++ PERROR("Error mapping page %"PRI_xen_pfn": page is null", gfn); + goto out_map; + } + +@@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa + ret = read_page(fd, page, i); + if ( ret != 0 ) + { +- PERROR("Error reading page"); ++ PERROR("Error reading page %"PRI_xen_pfn"", gfn); + goto out; + } + +@@ -710,7 +710,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_populate_page(paging, req.gfn, fd, i); + if ( rc != 0 ) + { +- PERROR("Error populating page"); ++ PERROR("Error populating page %"PRIx64"", req.gfn); + goto out; + } + } +@@ -723,7 +723,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_resume_page(paging, &rsp, 1); + if ( rc != 0 ) + { +- PERROR("Error resuming page"); ++ PERROR("Error resuming page %"PRIx64"", req.gfn); + goto out; + } + +@@ -754,7 +754,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_resume_page(paging, &rsp, 0); + if ( rc != 0 ) + { +- PERROR("Error resuming"); ++ PERROR("Error resuming page %"PRIx64"", req.gfn); + goto out; + } + } diff --git a/xenpaging.record-numer-paged-out-pages.patch b/xenpaging.record-numer-paged-out-pages.patch new file mode 100644 index 0000000..6de62d9 --- /dev/null +++ b/xenpaging.record-numer-paged-out-pages.patch @@ -0,0 +1,53 @@ +# HG changeset patch +# Parent 8e31f3194c87e1cdb41621caa5a41810ef787293 +xenpaging: track the number of paged-out pages + +This change is required by subsequent changes. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 8 ++++++++ + tools/xenpaging/xenpaging.h | 1 + + 2 files changed, 9 insertions(+) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -467,6 +467,9 @@ static int xenpaging_evict_page(xenpagin + /* Notify policy of page being paged out */ + policy_notify_paged_out(victim->gfn); + ++ /* Record number of evicted pages */ ++ paging->num_paged_out++; ++ + out: + return ret; + } +@@ -480,8 +483,13 @@ static int xenpaging_resume_page(xenpagi + + /* Notify policy of page being paged in */ + if ( notify_policy ) ++ { + policy_notify_paged_in(rsp->gfn); + ++ /* Record number of resumed pages */ ++ paging->num_paged_out--; ++ } ++ + /* Tell Xen page is ready */ + ret = xc_mem_paging_resume(paging->xc_handle, paging->mem_event.domain_id, + rsp->gfn); +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h +@@ -49,6 +49,7 @@ typedef struct xenpaging { + mem_event_t mem_event; + /* number of pages for which data structures were allocated */ + int max_pages; ++ int num_paged_out; + int num_pages; + int policy_mru_size; + unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; diff --git a/xenpaging.reset-uncomsumed.patch b/xenpaging.reset-uncomsumed.patch new file mode 100644 index 0000000..036d5fb --- /dev/null +++ b/xenpaging.reset-uncomsumed.patch @@ -0,0 +1,50 @@ +# HG changeset patch +# Parent 5d87917314c0b4f13c987575d5329dfa215c5698 +xenpaging: retry unpageable gfns + +Nomination of gfns can fail, but may succeed later. +Thats the case for a guest that starts ballooned. + +v2: + - print debug when clearing uncosumed happens + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/policy_default.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c ++++ xen-4.1.2-testing/tools/xenpaging/policy_default.c +@@ -32,6 +32,7 @@ static unsigned int i_mru; + static unsigned int mru_size; + static unsigned long *bitmap; + static unsigned long *unconsumed; ++static unsigned int unconsumed_cleared; + static unsigned long current_gfn; + static unsigned long max_pages; + +@@ -87,8 +88,21 @@ int policy_choose_victim(xenpaging_t *pa + current_gfn++; + if ( current_gfn >= max_pages ) + current_gfn = 0; ++ /* Could not nominate any gfn */ + if ( wrap == current_gfn ) + { ++ /* Count wrap arounds */ ++ unconsumed_cleared++; ++ /* Force retry every few seconds (depends on poll() timeout) */ ++ if ( unconsumed_cleared > 123) ++ { ++ /* Force retry of unconsumed gfns */ ++ bitmap_clear(unconsumed, max_pages); ++ unconsumed_cleared = 0; ++ DPRINTF("clearing unconsumed, wrap %lx", wrap); ++ /* One more round before returning ENOSPC */ ++ continue; ++ } + victim->gfn = INVALID_MFN; + return -ENOSPC; + } diff --git a/xenpaging.stale-comments.patch b/xenpaging.stale-comments.patch new file mode 100644 index 0000000..fe0ac10 --- /dev/null +++ b/xenpaging.stale-comments.patch @@ -0,0 +1,42 @@ +# HG changeset patch +# Parent 401247fe2a24c4923a0106c5d8230fb16de0bb96 +xenpaging: remove filename from comment + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/file_ops.c | 1 - + tools/xenpaging/policy_default.c | 1 - + tools/xenpaging/xenpaging.c | 1 - + 3 files changed, 3 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/file_ops.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/file_ops.c ++++ xen-4.1.2-testing/tools/xenpaging/file_ops.c +@@ -1,5 +1,4 @@ + /****************************************************************************** +- * tools/xenpaging/file_ops.c + * + * Common file operations. + * +Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c ++++ xen-4.1.2-testing/tools/xenpaging/policy_default.c +@@ -1,5 +1,4 @@ + /****************************************************************************** +- * tools/xenpaging/policy.c + * + * Xen domain paging default policy. + * +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -1,5 +1,4 @@ + /****************************************************************************** +- * tools/xenpaging/xenpaging.c + * + * Domain paging. + * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp) diff --git a/xenpaging.target-tot_pages.patch b/xenpaging.target-tot_pages.patch new file mode 100644 index 0000000..038ea9b --- /dev/null +++ b/xenpaging.target-tot_pages.patch @@ -0,0 +1,187 @@ +# HG changeset patch +# Parent f057eb06706e2bacaadb41cf80fa45001e786e69 +xenpaging: use guests tot_pages as working target + +This change reverses the task of xenpaging. Before this change a fixed number +of pages was paged out. With this change the guest will not have access to +more than the given number of pages at the same time. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/policy_default.c | 1 + tools/xenpaging/xenpaging.c | 78 ++++++++++++++++++++++++++++++--------- + tools/xenpaging/xenpaging.h | 2 - + 3 files changed, 61 insertions(+), 20 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c ++++ xen-4.1.2-testing/tools/xenpaging/policy_default.c +@@ -71,7 +71,6 @@ int policy_init(xenpaging_t *paging) + + /* Start in the middle to avoid paging during BIOS startup */ + current_gfn = max_pages / 2; +- current_gfn -= paging->num_pages / 2; + + rc = 0; + out: +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -136,6 +136,21 @@ err: + return rc; + } + ++static int xenpaging_get_tot_pages(xenpaging_t *paging) ++{ ++ xc_interface *xch = paging->xc_handle; ++ xc_domaininfo_t domain_info; ++ int rc; ++ ++ rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, &domain_info); ++ if ( rc != 1 ) ++ { ++ PERROR("Error getting domain info"); ++ return -1; ++ } ++ return domain_info.tot_pages; ++} ++ + static void *init_page(void) + { + void *buffer; +@@ -161,7 +176,7 @@ static void *init_page(void) + return NULL; + } + +-static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages) ++static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages) + { + xenpaging_t *paging; + xc_domaininfo_t domain_info; +@@ -296,12 +311,7 @@ static xenpaging_t *xenpaging_init(domid + } + DPRINTF("max_pages = %d\n", paging->max_pages); + +- if ( num_pages < 0 || num_pages > paging->max_pages ) +- { +- num_pages = paging->max_pages; +- DPRINTF("setting num_pages to %d\n", num_pages); +- } +- paging->num_pages = num_pages; ++ paging->target_tot_pages = target_tot_pages; + + /* Initialise policy */ + rc = policy_init(paging); +@@ -648,7 +658,9 @@ int main(int argc, char *argv[]) + xenpaging_victim_t *victims; + mem_event_request_t req; + mem_event_response_t rsp; ++ int num, prev_num = 0; + int i; ++ int tot_pages; + int rc = -1; + int rc1; + xc_interface *xch; +@@ -659,7 +671,7 @@ int main(int argc, char *argv[]) + + if ( argc != 3 ) + { +- fprintf(stderr, "Usage: %s \n", argv[0]); ++ fprintf(stderr, "Usage: %s \n", argv[0]); + return -1; + } + +@@ -672,7 +684,7 @@ int main(int argc, char *argv[]) + } + xch = paging->xc_handle; + +- DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->num_pages); ++ DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages); + + /* Open file */ + sprintf(filename, "page_cache_%u", paging->mem_event.domain_id); +@@ -704,9 +716,6 @@ int main(int argc, char *argv[]) + /* listen for page-in events to stop pager */ + create_page_in_thread(paging); + +- i = evict_pages(paging, fd, victims, paging->num_pages); +- DPRINTF("%d pages evicted. Done.\n", i); +- + /* Swap pages in and out */ + while ( 1 ) + { +@@ -771,12 +780,8 @@ int main(int argc, char *argv[]) + goto out; + } + +- /* Evict a new page to replace the one we just paged in, +- * or clear this pagefile slot on exit */ +- if ( interrupted ) +- victims[i].gfn = INVALID_MFN; +- else +- evict_victim(paging, &victims[i], fd, i); ++ /* Clear this pagefile slot */ ++ victims[i].gfn = INVALID_MFN; + } + else + { +@@ -823,6 +828,43 @@ int main(int argc, char *argv[]) + if ( interrupted ) + break; + ++ /* Check if the target has been reached already */ ++ tot_pages = xenpaging_get_tot_pages(paging); ++ if ( tot_pages < 0 ) ++ goto out; ++ ++ /* Resume all pages if paging is disabled or no target was set */ ++ if ( paging->target_tot_pages == 0 ) ++ { ++ if ( paging->num_paged_out ) ++ resume_pages(paging, paging->num_paged_out); ++ } ++ /* Evict more pages if target not reached */ ++ else if ( tot_pages > paging->target_tot_pages ) ++ { ++ num = tot_pages - paging->target_tot_pages; ++ if ( num != prev_num ) ++ { ++ DPRINTF("Need to evict %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages); ++ prev_num = num; ++ } ++ /* Limit the number of evicts to be able to process page-in requests */ ++ if ( num > 42 ) ++ num = 42; ++ evict_pages(paging, fd, victims, num); ++ } ++ /* Resume some pages if target not reached */ ++ else if ( tot_pages < paging->target_tot_pages && paging->num_paged_out ) ++ { ++ num = paging->target_tot_pages - tot_pages; ++ if ( num != prev_num ) ++ { ++ DPRINTF("Need to resume %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages); ++ prev_num = num; ++ } ++ resume_pages(paging, num); ++ } ++ + } + DPRINTF("xenpaging got signal %d\n", interrupted); + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h +@@ -50,7 +50,7 @@ typedef struct xenpaging { + /* number of pages for which data structures were allocated */ + int max_pages; + int num_paged_out; +- int num_pages; ++ int target_tot_pages; + int policy_mru_size; + unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; + } xenpaging_t; diff --git a/xenpaging.use-PERROR.patch b/xenpaging.use-PERROR.patch new file mode 100644 index 0000000..d8411a7 --- /dev/null +++ b/xenpaging.use-PERROR.patch @@ -0,0 +1,281 @@ +# HG changeset patch +# Parent 5eb76b80baa127278e0fc1574bef22a79d9513f5 +xenpaging: use PERROR to print errno + +v3: + - adjust arguments for xc_mem_paging_enable() failures + +v2: + - move changes to file_op() to different patch + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 58 ++++++++++++++++++++++---------------------- + 1 file changed, 29 insertions(+), 29 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -90,7 +90,7 @@ static int xenpaging_wait_for_event_or_t + if (errno == EINTR) + return 0; + +- ERROR("Poll exited with an error"); ++ PERROR("Poll exited with an error"); + return -errno; + } + +@@ -121,7 +121,7 @@ static int xenpaging_wait_for_event_or_t + port = xc_evtchn_pending(xce); + if ( port == -1 ) + { +- ERROR("Failed to read port from event channel"); ++ PERROR("Failed to read port from event channel"); + rc = -1; + goto err; + } +@@ -129,7 +129,7 @@ static int xenpaging_wait_for_event_or_t + rc = xc_evtchn_unmask(xce, port); + if ( rc < 0 ) + { +- ERROR("Failed to unmask event channel port"); ++ PERROR("Failed to unmask event channel port"); + } + } + err: +@@ -185,7 +185,7 @@ static xenpaging_t *xenpaging_init(domid + paging->xs_handle = xs_open(0); + if ( paging->xs_handle == NULL ) + { +- ERROR("Error initialising xenstore connection"); ++ PERROR("Error initialising xenstore connection"); + goto err; + } + +@@ -193,7 +193,7 @@ static xenpaging_t *xenpaging_init(domid + snprintf(watch_token, sizeof(watch_token), "%u", domain_id); + if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false ) + { +- ERROR("Could not bind to shutdown watch\n"); ++ PERROR("Could not bind to shutdown watch\n"); + goto err; + } + +@@ -214,7 +214,7 @@ static xenpaging_t *xenpaging_init(domid + paging->mem_event.shared_page = init_page(); + if ( paging->mem_event.shared_page == NULL ) + { +- ERROR("Error initialising shared page"); ++ PERROR("Error initialising shared page"); + goto err; + } + +@@ -222,7 +222,7 @@ static xenpaging_t *xenpaging_init(domid + paging->mem_event.ring_page = init_page(); + if ( paging->mem_event.ring_page == NULL ) + { +- ERROR("Error initialising ring page"); ++ PERROR("Error initialising ring page"); + goto err; + } + +@@ -249,7 +249,7 @@ static xenpaging_t *xenpaging_init(domid + ERROR("xenpaging not supported in a PoD guest"); + break; + default: +- ERROR("Error initialising shared page: %s", strerror(errno)); ++ PERROR("Error initialising shared page"); + break; + } + goto err; +@@ -259,7 +259,7 @@ static xenpaging_t *xenpaging_init(domid + paging->mem_event.xce_handle = xc_evtchn_open(NULL, 0); + if ( paging->mem_event.xce_handle == NULL ) + { +- ERROR("Failed to open event channel"); ++ PERROR("Failed to open event channel"); + goto err; + } + +@@ -269,7 +269,7 @@ static xenpaging_t *xenpaging_init(domid + paging->mem_event.shared_page->port); + if ( rc < 0 ) + { +- ERROR("Failed to bind event channel"); ++ PERROR("Failed to bind event channel"); + goto err; + } + +@@ -279,7 +279,7 @@ static xenpaging_t *xenpaging_init(domid + paging->domain_info = malloc(sizeof(xc_domaininfo_t)); + if ( paging->domain_info == NULL ) + { +- ERROR("Error allocating memory for domain info"); ++ PERROR("Error allocating memory for domain info"); + goto err; + } + +@@ -287,7 +287,7 @@ static xenpaging_t *xenpaging_init(domid + paging->domain_info); + if ( rc != 1 ) + { +- ERROR("Error getting domain info"); ++ PERROR("Error getting domain info"); + goto err; + } + +@@ -295,7 +295,7 @@ static xenpaging_t *xenpaging_init(domid + paging->bitmap = bitmap_alloc(paging->domain_info->max_pages); + if ( !paging->bitmap ) + { +- ERROR("Error allocating bitmap"); ++ PERROR("Error allocating bitmap"); + goto err; + } + DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages); +@@ -311,7 +311,7 @@ static xenpaging_t *xenpaging_init(domid + rc = policy_init(paging); + if ( rc != 0 ) + { +- ERROR("Error initialising policy"); ++ PERROR("Error initialising policy"); + goto err; + } + +@@ -358,14 +358,14 @@ static int xenpaging_teardown(xenpaging_ + rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id); + if ( rc != 0 ) + { +- ERROR("Error tearing down domain paging in xen"); ++ PERROR("Error tearing down domain paging in xen"); + } + + /* Unbind VIRQ */ + rc = xc_evtchn_unbind(paging->mem_event.xce_handle, paging->mem_event.port); + if ( rc != 0 ) + { +- ERROR("Error unbinding event port"); ++ PERROR("Error unbinding event port"); + } + paging->mem_event.port = -1; + +@@ -373,7 +373,7 @@ static int xenpaging_teardown(xenpaging_ + rc = xc_evtchn_close(paging->mem_event.xce_handle); + if ( rc != 0 ) + { +- ERROR("Error closing event channel"); ++ PERROR("Error closing event channel"); + } + paging->mem_event.xce_handle = NULL; + +@@ -384,7 +384,7 @@ static int xenpaging_teardown(xenpaging_ + rc = xc_interface_close(xch); + if ( rc != 0 ) + { +- ERROR("Error closing connection to xen"); ++ PERROR("Error closing connection to xen"); + } + + return 0; +@@ -444,7 +444,7 @@ static int xenpaging_evict_page(xenpagin + PROT_READ | PROT_WRITE, &gfn, 1); + if ( page == NULL ) + { +- ERROR("Error mapping page"); ++ PERROR("Error mapping page"); + goto out; + } + +@@ -452,8 +452,8 @@ static int xenpaging_evict_page(xenpagin + ret = write_page(fd, page, i); + if ( ret != 0 ) + { ++ PERROR("Error copying page"); + munmap(page, PAGE_SIZE); +- ERROR("Error copying page"); + goto out; + } + +@@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin + victim->gfn); + if ( ret != 0 ) + { +- ERROR("Error evicting page"); ++ PERROR("Error evicting page"); + goto out; + } + +@@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa + sleep(1); + continue; + } +- ERROR("Error preparing for page in"); ++ PERROR("Error preparing for page in"); + goto out_map; + } + } +@@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa + PROT_READ | PROT_WRITE, &gfn, 1); + if ( page == NULL ) + { +- ERROR("Error mapping page: page is null"); ++ PERROR("Error mapping page: page is null"); + goto out_map; + } + +@@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa + ret = read_page(fd, page, i); + if ( ret != 0 ) + { +- ERROR("Error reading page"); ++ PERROR("Error reading page"); + goto out; + } + +@@ -579,7 +579,7 @@ static int evict_victim(xenpaging_t *pag + { + if ( j++ % 1000 == 0 ) + if ( xenpaging_mem_paging_flush_ioemu_cache(paging) ) +- ERROR("Error flushing ioemu cache"); ++ PERROR("Error flushing ioemu cache"); + } + } + while ( ret ); +@@ -670,7 +670,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_wait_for_event_or_timeout(paging); + if ( rc < 0 ) + { +- ERROR("Error getting event"); ++ PERROR("Error getting event"); + goto out; + } + else if ( rc != 0 ) +@@ -710,7 +710,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_populate_page(paging, req.gfn, fd, i); + if ( rc != 0 ) + { +- ERROR("Error populating page"); ++ PERROR("Error populating page"); + goto out; + } + } +@@ -723,7 +723,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_resume_page(paging, &rsp, 1); + if ( rc != 0 ) + { +- ERROR("Error resuming page"); ++ PERROR("Error resuming page"); + goto out; + } + +@@ -754,7 +754,7 @@ int main(int argc, char *argv[]) + rc = xenpaging_resume_page(paging, &rsp, 0); + if ( rc != 0 ) + { +- ERROR("Error resuming"); ++ PERROR("Error resuming"); + goto out; + } + } diff --git a/xenpaging.watch-target-tot_pages.patch b/xenpaging.watch-target-tot_pages.patch new file mode 100644 index 0000000..7611b77 --- /dev/null +++ b/xenpaging.watch-target-tot_pages.patch @@ -0,0 +1,120 @@ +# HG changeset patch +# Parent 0d872bf1203dd36200477f688908797875035b50 +xenpaging: watch the guests memory/target-tot_pages xenstore value + +Subsequent patches will use xenstored to store the numbers of pages +xenpaging is suppose to page-out. +Remove num_pages and use target_pages instead. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 51 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 50 insertions(+), 1 deletion(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -19,8 +19,10 @@ + */ + + #define _XOPEN_SOURCE 600 ++#define _GNU_SOURCE + + #include ++#include + #include + #include + #include +@@ -35,6 +37,10 @@ + #include "policy.h" + #include "xenpaging.h" + ++/* Defines number of mfns a guest should use at a time, in KiB */ ++#define WATCH_TARGETPAGES "memory/target-tot_pages" ++static char *watch_target_tot_pages; ++static char *dom_path; + static char watch_token[16]; + static char filename[80]; + static int interrupted; +@@ -72,7 +78,7 @@ static int xenpaging_wait_for_event_or_t + { + xc_interface *xch = paging->xc_handle; + xc_evtchn *xce = paging->mem_event.xce_handle; +- char **vec; ++ char **vec, *val; + unsigned int num; + struct pollfd fd[2]; + int port; +@@ -111,6 +117,25 @@ static int xenpaging_wait_for_event_or_t + rc = 0; + } + } ++ else if ( strcmp(vec[XS_WATCH_PATH], watch_target_tot_pages) == 0 ) ++ { ++ int ret, target_tot_pages; ++ val = xs_read(paging->xs_handle, XBT_NULL, vec[XS_WATCH_PATH], NULL); ++ if ( val ) ++ { ++ ret = sscanf(val, "%d", &target_tot_pages); ++ if ( ret > 0 ) ++ { ++ /* KiB to pages */ ++ target_tot_pages >>= 2; ++ if ( target_tot_pages < 0 || target_tot_pages > paging->max_pages ) ++ target_tot_pages = paging->max_pages; ++ paging->target_tot_pages = target_tot_pages; ++ DPRINTF("new target_tot_pages %d\n", target_tot_pages); ++ } ++ free(val); ++ } ++ } + free(vec); + } + } +@@ -216,6 +241,25 @@ static xenpaging_t *xenpaging_init(domid + goto err; + } + ++ /* Watch xenpagings working target */ ++ dom_path = xs_get_domain_path(paging->xs_handle, domain_id); ++ if ( !dom_path ) ++ { ++ PERROR("Could not find domain path\n"); ++ goto err; ++ } ++ if ( asprintf(&watch_target_tot_pages, "%s/%s", dom_path, WATCH_TARGETPAGES) < 0 ) ++ { ++ PERROR("Could not alloc watch path\n"); ++ goto err; ++ } ++ DPRINTF("watching '%s'\n", watch_target_tot_pages); ++ if ( xs_watch(paging->xs_handle, watch_target_tot_pages, "") == false ) ++ { ++ PERROR("Could not bind to xenpaging watch\n"); ++ goto err; ++ } ++ + p = getenv("XENPAGING_POLICY_MRU_SIZE"); + if ( p && *p ) + { +@@ -342,6 +386,8 @@ static xenpaging_t *xenpaging_init(domid + free(paging->mem_event.ring_page); + } + ++ free(dom_path); ++ free(watch_target_tot_pages); + free(paging->bitmap); + free(paging); + } +@@ -357,6 +403,9 @@ static int xenpaging_teardown(xenpaging_ + if ( paging == NULL ) + return 0; + ++ xs_unwatch(paging->xs_handle, watch_target_tot_pages, ""); ++ xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token); ++ + xch = paging->xc_handle; + paging->xc_handle = NULL; + /* Tear down domain paging in Xen */ diff --git a/xenpaging.watch_event-DPRINTF.patch b/xenpaging.watch_event-DPRINTF.patch new file mode 100644 index 0000000..de69a54 --- /dev/null +++ b/xenpaging.watch_event-DPRINTF.patch @@ -0,0 +1,22 @@ +# HG changeset patch +# Parent 5b764d6fc1e8165d9012cc8866ba08332fb13021 +xenpaging: add debug to show received watch event. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 1 + + 1 file changed, 1 insertion(+) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -108,6 +108,7 @@ static int xenpaging_wait_for_event_or_t + vec = xs_read_watch(paging->xs_handle, &num); + if ( vec ) + { ++ DPRINTF("path '%s' token '%s'\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]); + if ( strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 ) + { + /* If our guest disappeared, set interrupt flag and fall through */ diff --git a/xenpaging.xc_interface_open-comment.patch b/xenpaging.xc_interface_open-comment.patch new file mode 100644 index 0000000..727f741 --- /dev/null +++ b/xenpaging.xc_interface_open-comment.patch @@ -0,0 +1,73 @@ +# HG changeset patch +# Parent c6014fd38d1f150dd433985f8388b4858ba5aaca +xenpaging: update xenpaging_init + +Move comment about xc_handle to the right place. +Allocate paging early and use calloc. + +Signed-off-by: Olaf Hering + +--- + tools/xenpaging/xenpaging.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c ++++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c +@@ -169,18 +169,21 @@ static xenpaging_t *xenpaging_init(domid + char *p; + int rc; + ++ /* Allocate memory */ ++ paging = calloc(1, sizeof(xenpaging_t)); ++ if ( !paging ) ++ goto err; ++ + if ( getenv("XENPAGING_DEBUG") ) + dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0); +- xch = xc_interface_open(dbg, NULL, 0); ++ ++ /* Open connection to xen */ ++ paging->xc_handle = xch = xc_interface_open(dbg, NULL, 0); + if ( !xch ) +- goto err_iface; ++ goto err; + + DPRINTF("xenpaging init\n"); + +- /* Allocate memory */ +- paging = malloc(sizeof(xenpaging_t)); +- memset(paging, 0, sizeof(xenpaging_t)); +- + /* Open connection to xenstore */ + paging->xs_handle = xs_open(0); + if ( paging->xs_handle == NULL ) +@@ -204,9 +207,6 @@ static xenpaging_t *xenpaging_init(domid + DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size); + } + +- /* Open connection to xen */ +- paging->xc_handle = xch; +- + /* Set domain id */ + paging->mem_event.domain_id = domain_id; + +@@ -322,7 +322,8 @@ static xenpaging_t *xenpaging_init(domid + { + if ( paging->xs_handle ) + xs_close(paging->xs_handle); +- xc_interface_close(xch); ++ if ( xch ) ++ xc_interface_close(xch); + if ( paging->mem_event.shared_page ) + { + munlock(paging->mem_event.shared_page, PAGE_SIZE); +@@ -340,7 +341,6 @@ static xenpaging_t *xenpaging_init(domid + free(paging); + } + +- err_iface: + return NULL; + } + diff --git a/xl-create-pv-with-qcow2-img.patch b/xl-create-pv-with-qcow2-img.patch new file mode 100644 index 0000000..eded8ed --- /dev/null +++ b/xl-create-pv-with-qcow2-img.patch @@ -0,0 +1,234 @@ +Fix problem that xl cannot create PV guest with qcow/qcow2 disk image by using +pygrub. Have discussed with upstream, but the work is something related to both +qemu and xen upstream, making it accepted may take a long time. Submit first and +will be replaced with upstream patches if it is accepted. +http://xen.1045712.n5.nabble.com/xl-create-PV-guest-with-qcow-qcow2-disk-images-fail-td4909399.html + +Signed-off-by: Chunyan Liu + +Index: xen-4.1.2-testing/tools/libxl/libxl.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/libxl/libxl.c ++++ xen-4.1.2-testing/tools/libxl/libxl.c +@@ -1071,11 +1071,131 @@ int libxl_device_disk_del(libxl_ctx *ctx + return rc; + } + ++static int libxl_forkexec(libxl_ctx *ctx, char *arg0, char **args) ++{ ++ pid_t pid; ++ int status; ++ ++ pid = libxl_fork(ctx); ++ if (pid < 0) ++ return -1; ++ else if (pid == 0){ ++ libxl__exec(-1, -1, -1, arg0, args); ++ exit(127); ++ } ++ while (waitpid(pid, &status, 0) < 0) { ++ if (errno != EINTR) { ++ status = -1; ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++#ifdef __linux__ ++static int is_nbd_used(int minor) ++{ ++ FILE *proc; ++ int NBDMAJOR = 43; ++ char buf[BUFSIZ]; ++ int find = 0; ++ ++ proc = fopen("/proc/partitions", "r"); ++ if (proc != NULL) { ++ while (fgets(buf, sizeof(buf), proc)) { ++ int m, n; ++ unsigned long long sz; ++ char name[16]; ++ char *pname = name; ++ char *end; ++ ++ if (sscanf(buf, " %d %d %llu %128[^\n ]", ++ &m, &n, &sz, name) != 4) ++ continue; ++ if (m != NBDMAJOR) ++ continue; ++ if (strncmp(name, "nbd", 3)) ++ continue; ++ pname += 3; ++ n = strtol(pname, &end, 10); ++ if (end && end != pname && *end == '\0' && n == minor) { ++ find = 1; ++ break; ++ } ++ } ++ fclose(proc); ++ } ++ ++ return find; ++} ++ ++static int find_free_nbd_minor(void) ++{ ++ int i; ++ int nbds_max = 16; ++ int minor = -1; ++ ++ for (i = 0; i < nbds_max; i++) { ++ if (!is_nbd_used(i)) { ++ minor = i; ++ break; ++ } ++ } ++ ++ return minor; ++} ++ ++static char * nbd_mount_disk(libxl__gc *gc, libxl_device_disk *disk) ++{ ++ libxl_ctx *ctx = libxl__gc_owner(gc); ++ int n = -1; ++ char *nbd_dev = NULL; ++ char *args[] = {"qemu-nbd","-c",NULL,NULL,NULL}; ++ char *ret = NULL; ++ ++ n = find_free_nbd_minor(); ++ if (n >= 0) { ++ int i = 0; ++ int retry = 3; ++ ++ nbd_dev = libxl__sprintf(gc, "/dev/nbd%d", n); ++ args[2] = libxl__sprintf(gc, "%s", nbd_dev); ++ args[3] = libxl__sprintf(gc, "%s", disk->pdev_path); ++ libxl_forkexec(ctx, args[0], args); ++ ++ /*check connection*/ ++ while (i < retry) { ++ if (is_nbd_used(n)) { ++ ret = strdup(nbd_dev); ++ break; ++ } ++ i++; ++ sleep(1); ++ } ++ } ++ ++ return ret; ++} ++ ++static int nbd_unmount_disk(libxl__gc *gc, char *diskpath) { ++ libxl_ctx *ctx = libxl__gc_owner(gc); ++ char *args[] = {"qemu-nbd","-d",NULL,NULL}; ++ ++ args[2] = libxl__sprintf(gc, "%s", diskpath); ++ if (libxl_forkexec(ctx, args[0], args)) ++ return 0; ++ else ++ return ERROR_FAIL; ++} ++#endif ++ + char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) + { + libxl__gc gc = LIBXL_INIT_GC(ctx); + const char *dev = NULL; + char *ret = NULL; ++ char *mdev = NULL; + + switch (disk->backend) { + case DISK_BACKEND_PHY: +@@ -1117,8 +1237,17 @@ char * libxl_device_disk_local_attach(li + } + case DISK_BACKEND_QDISK: + if (disk->format != DISK_FORMAT_RAW) { +- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot locally attach a qdisk " +- "image if the format is not raw"); ++#ifdef __linux__ ++ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "attaching a non-raw qdisk image to domain 0\n"); ++ mdev = nbd_mount_disk(&gc, disk); ++ if (mdev) ++ dev = mdev; ++ else ++ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "fail to mount image with qemu-nbd"); ++#else ++ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot locally" ++ " attach a qdisk image if the format is not raw"); ++#endif + break; + } + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "attaching qdisk %s to domain 0\n", +@@ -1134,18 +1263,37 @@ char * libxl_device_disk_local_attach(li + + if (dev != NULL) + ret = strdup(dev); ++ free(mdev); + libxl__free_all(&gc); + return ret; + } + +-int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk) ++int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk, char *diskpath) + { +- /* Nothing to do for PHYSTYPE_PHY. */ ++#ifdef __linux__ ++ libxl__gc gc = LIBXL_INIT_GC(ctx); ++ int ret; ++ ++ switch (disk->backend) { ++ case DISK_BACKEND_QDISK: ++ if (disk->format != DISK_FORMAT_RAW) { ++ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Locally detach a non-raw " ++ "qdisk image"); ++ ret = nbd_unmount_disk(&gc, diskpath); ++ return ret; ++ } ++ default: ++ /* Nothing to do for PHYSTYPE_PHY. */ + +- /* +- * For other device types assume that the blktap2 process is +- * needed by the soon to be started domain and do nothing. +- */ ++ /* ++ * For other device types assume that the blktap2 process is ++ * needed by the soon to be started domain and do nothing. ++ */ ++ break; ++ } ++ ++ libxl__free_all(&gc); ++#endif + + return 0; + } +Index: xen-4.1.2-testing/tools/libxl/libxl.h +=================================================================== +--- xen-4.1.2-testing.orig/tools/libxl/libxl.h ++++ xen-4.1.2-testing/tools/libxl/libxl.h +@@ -429,7 +429,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u + * Make a disk available in this domain. Returns path to a device. + */ + char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); +-int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk); ++int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk, char *diskpath); + + int libxl_device_nic_init(libxl_device_nic *nic, int dev_num); + int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic); +Index: xen-4.1.2-testing/tools/libxl/libxl_bootloader.c +=================================================================== +--- xen-4.1.2-testing.orig/tools/libxl/libxl_bootloader.c ++++ xen-4.1.2-testing/tools/libxl/libxl_bootloader.c +@@ -419,7 +419,7 @@ int libxl_run_bootloader(libxl_ctx *ctx, + rc = 0; + out_close: + if (diskpath) { +- libxl_device_disk_local_detach(ctx, disk); ++ libxl_device_disk_local_detach(ctx, disk, diskpath); + free(diskpath); + } + if (fifo_fd > -1)