# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1289916996 0
# Node ID e1a6a9ab7ef52ac17a873ad99037803640301491
# Parent a6f9006a1d70a3d8654d07313862c2c982c95875
x86_64: Make 32-bit-hypercall translate area per-vcpu.
This is a prerequisite for allowing guest descheduling within a
hypercall.
Signed-off-by: Keir Fraser <keir@xxxxxxx>
---
xen/arch/x86/domain.c | 9 ++++++++
xen/arch/x86/hvm/hvm.c | 15 +++++++++++++-
xen/arch/x86/smpboot.c | 9 --------
xen/arch/x86/x86_64/mm.c | 37 +++++++++++++++++------------------
xen/include/asm-x86/domain.h | 4 +++
xen/include/asm-x86/x86_64/uaccess.h | 9 ++++----
6 files changed, 50 insertions(+), 33 deletions(-)
diff -r a6f9006a1d70 -r e1a6a9ab7ef5 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Tue Nov 16 14:09:13 2010 +0000
+++ b/xen/arch/x86/domain.c Tue Nov 16 14:16:36 2010 +0000
@@ -214,10 +214,18 @@ static int setup_compat_l4(struct vcpu *
{
struct page_info *pg;
l4_pgentry_t *l4tab;
+ int rc;
pg = alloc_domheap_page(NULL, MEMF_node(vcpu_to_node(v)));
if ( pg == NULL )
return -ENOMEM;
+
+ rc = setup_compat_arg_xlat(v);
+ if ( rc )
+ {
+ free_domheap_page(pg);
+ return rc;
+ }
/* This page needs to look like a pagetable so that it can be shadowed */
pg->u.inuse.type_info = PGT_l4_page_table|PGT_validated|1;
@@ -239,6 +247,7 @@ static int setup_compat_l4(struct vcpu *
static void release_compat_l4(struct vcpu *v)
{
+ free_compat_arg_xlat(v);
free_domheap_page(pagetable_get_page(v->arch.guest_table));
v->arch.guest_table = pagetable_null();
v->arch.guest_table_user = pagetable_null();
diff -r a6f9006a1d70 -r e1a6a9ab7ef5 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Nov 16 14:09:13 2010 +0000
+++ b/xen/arch/x86/hvm/hvm.c Tue Nov 16 14:16:36 2010 +0000
@@ -944,9 +944,15 @@ int hvm_vcpu_initialise(struct vcpu *v)
spin_lock_init(&v->arch.hvm_vcpu.tm_lock);
INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
+#ifdef CONFIG_COMPAT
+ rc = setup_compat_arg_xlat(v);
+ if ( rc != 0 )
+ goto fail3;
+#endif
+
rc = hvm_vcpu_cacheattr_init(v);
if ( rc != 0 )
- goto fail3;
+ goto fail4;
tasklet_init(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet,
(void(*)(unsigned long))hvm_assert_evtchn_irq,
@@ -971,6 +977,10 @@ int hvm_vcpu_initialise(struct vcpu *v)
return 0;
+ fail4:
+#ifdef CONFIG_COMPAT
+ free_compat_arg_xlat(v);
+#endif
fail3:
hvm_funcs.vcpu_destroy(v);
fail2:
@@ -981,6 +991,9 @@ int hvm_vcpu_initialise(struct vcpu *v)
void hvm_vcpu_destroy(struct vcpu *v)
{
+#ifdef CONFIG_COMPAT
+ free_compat_arg_xlat(v);
+#endif
tasklet_kill(&v->arch.hvm_vcpu.assert_evtchn_irq_tasklet);
hvm_vcpu_cacheattr_destroy(v);
vlapic_destroy(v);
diff -r a6f9006a1d70 -r e1a6a9ab7ef5 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Tue Nov 16 14:09:13 2010 +0000
+++ b/xen/arch/x86/smpboot.c Tue Nov 16 14:16:36 2010 +0000
@@ -627,10 +627,6 @@ static void cpu_smpboot_free(unsigned in
xfree(idt_tables[cpu]);
idt_tables[cpu] = NULL;
-#ifdef __x86_64__
- free_compat_arg_xlat(cpu);
-#endif
-
order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
#ifdef __x86_64__
if ( per_cpu(compat_gdt_table, cpu) )
@@ -690,11 +686,6 @@ static int cpu_smpboot_alloc(unsigned in
BUILD_BUG_ON(NR_CPUS > 0x10000);
gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
-#ifdef __x86_64__
- if ( setup_compat_arg_xlat(cpu, cpu_to_node[cpu]) )
- goto oom;
-#endif
-
idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
if ( idt_tables[cpu] == NULL )
goto oom;
diff -r a6f9006a1d70 -r e1a6a9ab7ef5 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c Tue Nov 16 14:09:13 2010 +0000
+++ b/xen/arch/x86/x86_64/mm.c Tue Nov 16 14:16:36 2010 +0000
@@ -46,8 +46,6 @@ unsigned int __read_mostly pfn_pdx_hole_
unsigned int __read_mostly pfn_pdx_hole_shift = 0;
unsigned int __read_mostly m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START;
-
-DEFINE_PER_CPU_READ_MOSTLY(void *, compat_arg_xlat);
/* Top-level master (and idle-domain) page directory. */
l4_pgentry_t __attribute__ ((__section__ (".bss.page_aligned")))
@@ -819,25 +817,30 @@ void __init zap_low_mappings(void)
0x10, __PAGE_HYPERVISOR);
}
-int __cpuinit setup_compat_arg_xlat(unsigned int cpu, int node)
+void *compat_arg_xlat_virt_base(void)
+{
+ return current->arch.compat_arg_xlat;
+}
+
+int setup_compat_arg_xlat(struct vcpu *v)
{
unsigned int order = get_order_from_bytes(COMPAT_ARG_XLAT_SIZE);
- unsigned int memflags = node != NUMA_NO_NODE ? MEMF_node(node) : 0;
struct page_info *pg;
- BUG_ON((PAGE_SIZE << order) != COMPAT_ARG_XLAT_SIZE);
-
- pg = alloc_domheap_pages(NULL, order, memflags);
- per_cpu(compat_arg_xlat, cpu) = pg ? page_to_virt(pg) : NULL;
- return pg ? 0 : -ENOMEM;
-}
-
-void __cpuinit free_compat_arg_xlat(unsigned int cpu)
+ pg = alloc_domheap_pages(NULL, order, 0);
+ if ( pg == NULL )
+ return -ENOMEM;
+
+ v->arch.compat_arg_xlat = page_to_virt(pg);
+ return 0;
+}
+
+void free_compat_arg_xlat(struct vcpu *v)
{
unsigned int order = get_order_from_bytes(COMPAT_ARG_XLAT_SIZE);
- if ( per_cpu(compat_arg_xlat, cpu) != NULL )
- free_domheap_pages(virt_to_page(per_cpu(compat_arg_xlat, cpu)), order);
- per_cpu(compat_arg_xlat, cpu) = NULL;
+ if ( v->arch.compat_arg_xlat != NULL )
+ free_domheap_pages(virt_to_page(v->arch.compat_arg_xlat), order);
+ v->arch.compat_arg_xlat = NULL;
}
void cleanup_frame_table(struct mem_hotadd_info *info)
@@ -1009,10 +1012,6 @@ void __init subarch_init_memory(void)
share_xen_page_with_privileged_guests(page, XENSHARE_readonly);
}
}
-
- if ( setup_compat_arg_xlat(smp_processor_id(),
- cpu_to_node[0]) )
- panic("Could not setup argument translation area");
}
long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
diff -r a6f9006a1d70 -r e1a6a9ab7ef5 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h Tue Nov 16 14:09:13 2010 +0000
+++ b/xen/include/asm-x86/domain.h Tue Nov 16 14:16:36 2010 +0000
@@ -436,6 +436,10 @@ struct arch_vcpu
/* A secondary copy of the vcpu time info. */
XEN_GUEST_HANDLE(vcpu_time_info_t) time_info_guest;
+#ifdef CONFIG_COMPAT
+ void *compat_arg_xlat;
+#endif
+
} __cacheline_aligned;
/* Shorthands to improve code legibility. */
diff -r a6f9006a1d70 -r e1a6a9ab7ef5 xen/include/asm-x86/x86_64/uaccess.h
--- a/xen/include/asm-x86/x86_64/uaccess.h Tue Nov 16 14:09:13 2010 +0000
+++ b/xen/include/asm-x86/x86_64/uaccess.h Tue Nov 16 14:16:36 2010 +0000
@@ -1,11 +1,12 @@
#ifndef __X86_64_UACCESS_H
#define __X86_64_UACCESS_H
-#define COMPAT_ARG_XLAT_VIRT_BASE this_cpu(compat_arg_xlat)
+#define COMPAT_ARG_XLAT_VIRT_BASE compat_arg_xlat_virt_base()
#define COMPAT_ARG_XLAT_SIZE (2*PAGE_SIZE)
-DECLARE_PER_CPU(void *, compat_arg_xlat);
-int setup_compat_arg_xlat(unsigned int cpu, int node);
-void free_compat_arg_xlat(unsigned int cpu);
+struct vcpu;
+void *compat_arg_xlat_virt_base(void);
+int setup_compat_arg_xlat(struct vcpu *v);
+void free_compat_arg_xlat(struct vcpu *v);
#define is_compat_arg_xlat_range(addr, size) ({ \
unsigned long __off; \
__off = (unsigned long)(addr) - (unsigned long)COMPAT_ARG_XLAT_VIRT_BASE; \
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|