diff options
author | Keir Fraser <keir@xen.org> | 2010-11-16 14:16:36 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2010-11-16 14:16:36 +0000 |
commit | 106f2288c2a71e4f6438d5e2571a78720e659d34 (patch) | |
tree | 085fb5fd0943b5fd21d2bbdfbebf622eb0ee8362 | |
parent | 561e9179370c6927160eb797e1dccc5351d13eb3 (diff) | |
download | xen-106f2288c2a71e4f6438d5e2571a78720e659d34.tar.gz xen-106f2288c2a71e4f6438d5e2571a78720e659d34.tar.bz2 xen-106f2288c2a71e4f6438d5e2571a78720e659d34.zip |
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@xen.org>
-rw-r--r-- | xen/arch/x86/domain.c | 9 | ||||
-rw-r--r-- | xen/arch/x86/hvm/hvm.c | 15 | ||||
-rw-r--r-- | xen/arch/x86/smpboot.c | 9 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/mm.c | 31 | ||||
-rw-r--r-- | xen/include/asm-x86/domain.h | 4 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/uaccess.h | 9 |
6 files changed, 47 insertions, 30 deletions
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 6cdb6d85c6..13ff475555 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -214,11 +214,19 @@ static int setup_compat_l4(struct vcpu *v) { 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 *v) 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 --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index ba0481a133..6bd92ce61c 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -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); - rc = hvm_vcpu_cacheattr_init(v); +#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 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 --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 365d70a4c4..90b4bfb56c 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -627,10 +627,6 @@ static void cpu_smpboot_free(unsigned int cpu) 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 int cpu) 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 --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 883d23fa84..1de4e8b03d 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -47,8 +47,6 @@ 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"))) idle_pg_table[L4_PAGETABLE_ENTRIES]; @@ -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, 0); + if ( pg == NULL ) + return -ENOMEM; - pg = alloc_domheap_pages(NULL, order, memflags); - per_cpu(compat_arg_xlat, cpu) = pg ? page_to_virt(pg) : NULL; - return pg ? 0 : -ENOMEM; + v->arch.compat_arg_xlat = page_to_virt(pg); + return 0; } -void __cpuinit free_compat_arg_xlat(unsigned int cpu) +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 --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 6b4222abed..5ff0a06e98 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -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 --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index c5cb386d2b..e35ce28e03 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -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; \ |