[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86_64: Make 32-bit-hypercall translate area per-vcpu.



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.