Accepting request 94175 from Virtualization

- 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

- submit fixes for bnc#649209 and bnc#711892
  xl-create-pv-with-qcow2-img.patch
  update suspend_evtchn_lock.patch
 

- 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

OBS-URL: https://build.opensuse.org/request/show/94175
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=151
This commit is contained in:
Stephan Kulow 2011-12-06 12:54:07 +00:00 committed by Git OBS Bridge
commit 0be4fbb36d
67 changed files with 5098 additions and 495 deletions

View File

@ -1,21 +1,21 @@
changeset: 23050:4ebba54b666f
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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(-)

View File

@ -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 <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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 <xen/init.h>
#include <xen/mm.h>
#include <xen/percpu.h>
+#include <xen/pfn.h>
#include <xen/cpu.h>
#include <asm/atomic.h>
#include <public/sysctl.h>
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+
#ifdef CONFIG_COMPAT
#include <compat/trace.h>
#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;
}

View File

@ -1,12 +1,16 @@
changeset: 23092:45dafa422812
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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);

View File

@ -1,9 +1,13 @@
changeset: 23093:4b784605b089
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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) )
{

View File

@ -1,11 +1,15 @@
changeset: 23094:d09e8885bc82
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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;
/*

View File

@ -1,9 +1,13 @@
changeset: 23095:941119d58655
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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) )
{

View File

@ -1,13 +1,18 @@
changeset: 23128:4a335f1000ea
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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;
}

View File

@ -1,10 +1,16 @@
changeset: 23129:219ba19aedeb
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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;

View File

@ -1,12 +1,16 @@
changeset: 23173:94cef9aaf0cd
user: Keir Fraser <keir@xen.org>
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 <keir@xen.org>
---
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)
{

View File

@ -1,18 +1,22 @@
changeset: 23239:51d89366c859
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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.

View File

@ -1,13 +1,17 @@
changeset: 23308:fb5313e64335
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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 */

View File

@ -1,9 +1,13 @@
changeset: 23309:0ddcc8063690
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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);

View File

@ -1,12 +1,16 @@
changeset: 23310:b7ca55907bd3
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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;

View File

@ -0,0 +1,61 @@
changeset: 23404:dd0eb070ee44
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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 "

View File

@ -0,0 +1,52 @@
changeset: 23405:3057b531d905
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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);

View File

@ -0,0 +1,153 @@
changeset: 23406:956438803307
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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;

View File

@ -0,0 +1,155 @@
changeset: 23407:b19898ac3e32
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
Acked-by: George Dunlap <george.dunlap@eu.citrix.com>
---
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");

View File

@ -0,0 +1,58 @@
changeset: 23643:335e96664589
user: George Dunlap <george.dunlap@eu.citrix.com>
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 <george.dunlap@eu.citrix.com>
---
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;
+ }
}
}

View File

@ -0,0 +1,37 @@
changeset: 23719:c2888876abd3
user: Olaf Hering <olaf@aepfle.de>
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 <olaf@aepfle.de>
---
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)

View File

@ -0,0 +1,147 @@
References: bnc#713503
# HG changeset patch
# User George Dunlap <george.dunlap@eu.citrix.com>
# 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 <george.dunlap@eu.citrix.com>
# HG changeset patch
# User George Dunlap <george.dunlap@eu.citrix.com>
# 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 <george.dunlap@eu.citrix.com>
--- 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;
};

View File

@ -0,0 +1,361 @@
References: bnc#713503
# HG changeset patch
# User George Dunlap <george.dunlap@eu.citrix.com>
# 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 <george.dunlap@eu.citrix.com>
# HG changeset patch
# User George Dunlap <george.dunlap@eu.citrix.com>
# 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 <george.dunlap@eu.citrix.com>
# HG changeset patch
# User George Dunlap <george.dunlap@eu.citrix.com>
# 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 <george.dunlap@eu.citrix.com>
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- 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 <asm/mach-generic/mach_apic.h>
#include <public/physdev.h>
+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 <xen/types.h>
#include <xen/list.h>
#include <xen/spinlock.h>
+#include <xen/irq.h>
/*
* 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 {

22
23819-make-docs.patch Normal file
View File

@ -0,0 +1,22 @@
# HG changeset patch
# User Keir Fraser <keir@xen.org>
# Date 1315320580 -3600
# Node ID 5fe770c8a8a35c58893816ee6335a90ed43f3bbd
# Parent 0268e73809532a4a3ca18a075efcee3c62caf458
docs: Fix 'make docs'
Signed-off-by: Keir Fraser <keir@xen.org>
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.

89
23900-xzalloc.patch Normal file
View File

@ -0,0 +1,89 @@
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- 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.
*/

View File

@ -1,3 +1,5 @@
References: bnc#725169
# HG changeset patch
# User Jan Beulich <jbeulich@novell.com>
# Date 1319475620 -3600

View File

@ -0,0 +1,67 @@
# HG changeset patch
# User Jean Guyader <jean.guyader@eu.citrix.com>
# 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 <jean.guyader@eu.citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
Committed-by: Jan Beulich <jbeulich@suse.com>
--- 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 = &current->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()) | \

View File

@ -0,0 +1,64 @@
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- 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;
}
/*

View File

@ -0,0 +1,62 @@
References: bnc#719700
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- 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 )

77
24137-revert-23666.patch Normal file
View File

@ -0,0 +1,77 @@
# HG changeset patch
# User Andrew Cooper <andrew.cooper3@citrix.com>
# 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 <andrew.cooper3@citrix.com>
Signed-off-by: Keir Fraser <keir@xen.org>
Committed-by: Keir Fraser <keir@xen.org>
--- a/xen/arch/x86/crash.c
+++ b/xen/arch/x86/crash.c
@@ -28,7 +28,6 @@
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <xen/iommu.h>
-#include <xen/pci.h>
#include <asm/hpet.h>
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(

View File

@ -0,0 +1,95 @@
# HG changeset patch
# User Ian Campbell <ian.campbell@citrix.com>
# 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:[<ffff82c48013ceed>] 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) [<ffff82c48013ceed>] cpufreq_enable_turbo+0x1d/0x29
(XEN) [<ffff82c48014c427>] do_pm_op+0x884/0x8e7
(XEN) [<ffff82c480124fd8>] do_sysctl+0x6d8/0x9f0
(XEN) [<ffff82c48021511e>] 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 <ian.campbell@citrix.com>
Committed-by: Jan Beulich <jbeulich@suse.com>
--- 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;
}
/*********************************************************************

View File

@ -0,0 +1,29 @@
References: bnc#726332
# HG changeset patch
# User Gianluca Guida <gianluca.guida@citrix.com>
# 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 <gianluca.guida@citrix.com>
Tested-by: Jan Beulich <jbeulich@suse.com>
Committed-by: Keir Fraser <keir@xen.org>
--- 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 */ );

View File

@ -0,0 +1,130 @@
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
--- 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));

View File

@ -0,0 +1,159 @@
References: bnc#713503
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
--- 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;

View File

@ -0,0 +1,96 @@
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Tested-by: Charles Arnold <carnold@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
--- 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;

View File

@ -0,0 +1,30 @@
References: bnc#694863
# HG changeset patch
# User Jan Beulich <jbeulich@suse.com>
# 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 <jbeulich@suse.com>
Tested-by: Olaf Hering <olaf@aepfle.de>
--- 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] )
{

29
2XXXX-vif-bridge.patch Normal file
View File

@ -0,0 +1,29 @@
# HG changeset patch
# User Jim Fehlig <jfehlig@suse.com>
# 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 <jfehlig@suse.com>
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")

View File

@ -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 <cyliu@suse.com>
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 <sys/file.h>
+#include <sys/fcntl.h>
+#include <signal.h>
+#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;
}

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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

198
xen.spec
View File

@ -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

View File

@ -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 <olaf@aepfle.de>
---
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) )

View File

@ -0,0 +1,51 @@
xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path()
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
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)

View File

@ -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 <olaf@aepfle.de>
---
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
{

View File

@ -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 <olaf@aepfle.de>
---
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/<domain_name>.<domaind_id>.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' : ('<Domain> <Mem>',
'Set the current memory usage for a domain.'),
+ 'mem-swap-target' : ('<Domain> <Mem>',
+ 'Set the memory usage for a domain.'),
'migrate' : ('<Domain> <Host>',
'Migrate a domain to another machine.'),
'pause' : ('<Domain>', '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',

View File

@ -0,0 +1,34 @@
# HG changeset patch
# Parent 2ac53905d95e6d02f53c99f6e2fa38f7306b8800
libxc: add bitmap_clear function
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
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 <stdlib.h>
+#include <string.h>
#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;

View File

@ -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 <pagefile> -d <domain_id>
options:
-d <domid> --domain=<domid> numerical domain_id of guest. This option is required.
-f <file> --pagefile=<file> pagefile to use. This option is required.
-m <max_memkb> --max_memkb=<max_memkb> maximum amount of memory to handle.
-r <num> --mru_size=<num> number of paged-in pages to keep in memory.
-d --debug enable debug output.
-h --help this output.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
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 <poll.h>
#include <xc_private.h>
#include <xs.h>
+#include <getopt.h>
#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 <pagefile> -d <domain_id>\n\n");
+
+ printf("options:\n");
+ printf(" -d <domid> --domain=<domid> numerical domain_id of guest. This option is required.\n");
+ printf(" -f <file> --pagefile=<file> pagefile to use. This option is required.\n");
+ printf(" -m <max_memkb> --max_memkb=<max_memkb> maximum amount of memory to handle.\n");
+ printf(" -r <num> --mru_size=<num> 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 <domain_id> 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 <domain_id> <tot_pages>\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;

View File

@ -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 <olaf@aepfle.de>
---
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];

View File

@ -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 <olaf@aepfle.de>
---
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 <unistd.h>
-#include <stdarg.h>
#include <xc_private.h>
-
-#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);
}

View File

@ -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 <stdio.h>
+#include <xc_private.h>
+
+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;
+}

View File

@ -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 <olaf@aepfle.de>
---
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)

View File

@ -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 <olaf@aepfle.de>
---
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
{

View File

@ -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 <olaf@aepfle.de>
---
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);

View File

@ -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 <olaf@aepfle.de>
---
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 */

View File

@ -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 <olaf@aepfle.de>
---
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);

95
xenpaging.print-gfn.patch Normal file
View File

@ -0,0 +1,95 @@
# HG changeset patch
# Parent 9c7e82499e983ad11b13dd41d2fa5f12072adecf
xenpaging: print gfn in failure case
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
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;
}
}

View File

@ -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 <olaf@aepfle.de>
---
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];

View File

@ -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 <olaf@aepfle.de>
---
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;
}

View File

@ -0,0 +1,42 @@
# HG changeset patch
# Parent 401247fe2a24c4923a0106c5d8230fb16de0bb96
xenpaging: remove filename from comment
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
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)

View File

@ -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 <olaf@aepfle.de>
---
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 <domain_id> <num_pages>\n", argv[0]);
+ fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\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;

281
xenpaging.use-PERROR.patch Normal file
View File

@ -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 <olaf@aepfle.de>
---
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;
}
}

View File

@ -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 <olaf@aepfle.de>
---
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 <inttypes.h>
+#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
@@ -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 */

View File

@ -0,0 +1,22 @@
# HG changeset patch
# Parent 5b764d6fc1e8165d9012cc8866ba08332fb13021
xenpaging: add debug to show received watch event.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
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 */

View File

@ -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 <olaf@aepfle.de>
---
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;
}

View File

@ -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 <cyliu@suse.com>
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)