[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v1 49/74] x86/guest: map per-cpu vcpu_info area.
From: Roger Pau Monne <roger.pau@xxxxxxxxxx> So that the limit of XEN_LEGACY_MAX_VCPUS can be lifted. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Should be moved earlier maybe? --- xen/arch/x86/guest/xen.c | 61 +++++++++++++++++++++++++++++++++-- xen/arch/x86/time.c | 11 ++----- xen/include/asm-x86/guest/hypercall.h | 7 ++++ 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/guest/xen.c b/xen/arch/x86/guest/xen.c index a95c36017f..3fa164aba8 100644 --- a/xen/arch/x86/guest/xen.c +++ b/xen/arch/x86/guest/xen.c @@ -38,6 +38,10 @@ static struct rangeset *mem; DEFINE_PER_CPU(unsigned int, vcpu_id); +static struct vcpu_info *vcpu_info; +unsigned long vcpu_info_mapped[BITS_TO_LONGS(NR_CPUS)]; +DEFINE_PER_CPU(struct vcpu_info *, vcpu_info); + static void __init find_xen_leaves(void) { uint32_t eax, ebx, ecx, edx, base; @@ -101,6 +105,38 @@ static void map_shared_info(void) xchg(&XEN_shared_info->evtchn_mask[i], ~0ul); } +static int map_vcpuinfo(void) +{ + unsigned int vcpu = this_cpu(vcpu_id); + struct vcpu_register_vcpu_info info = { }; + long rc; + + if ( !vcpu_info ) + { + this_cpu(vcpu_info) = &XEN_shared_info->vcpu_info[vcpu]; + return 0; + } + + if ( test_bit(vcpu, vcpu_info_mapped) ) + { + this_cpu(vcpu_info) = &vcpu_info[vcpu]; + return 0; + } + + info.mfn = virt_to_mfn(&vcpu_info[vcpu]); + info.offset = (unsigned long)&vcpu_info[vcpu] & ~PAGE_MASK; + rc = xen_hypercall_vcpu_op(VCPUOP_register_vcpu_info, vcpu, &info); + if ( rc ) + this_cpu(vcpu_info) = &XEN_shared_info->vcpu_info[vcpu]; + else + { + this_cpu(vcpu_info) = &vcpu_info[vcpu]; + set_bit(vcpu, vcpu_info_mapped); + } + + return rc; +} + static void set_vcpu_id(void) { uint32_t eax, ebx, ecx, edx; @@ -117,8 +153,7 @@ static void set_vcpu_id(void) static void xen_evtchn_upcall(struct cpu_user_regs *regs) { - struct vcpu_info *vcpu_info = - &XEN_shared_info->vcpu_info[this_cpu(vcpu_id)]; + struct vcpu_info *vcpu_info = this_cpu(vcpu_info); vcpu_info->evtchn_upcall_pending = 0; xchg(&vcpu_info->evtchn_pending_sel, 0); @@ -176,12 +211,34 @@ void __init hypervisor_setup(void) map_shared_info(); set_vcpu_id(); + vcpu_info = xzalloc_array(struct vcpu_info, nr_cpu_ids); + if ( map_vcpuinfo() || !vcpu_info ) + { + if ( vcpu_info ) + { + xfree(vcpu_info); + vcpu_info = NULL; + } + if ( nr_cpu_ids > XEN_LEGACY_MAX_VCPUS ) + { + unsigned int i; + + for ( i = XEN_LEGACY_MAX_VCPUS; i < nr_cpu_ids; i++ ) + __cpumask_clear_cpu(i, &cpu_present_map); + nr_cpu_ids = XEN_LEGACY_MAX_VCPUS; + printk(XENLOG_WARNING + "unable to map vCPU info, limiting vCPUs to: %u\n", + XEN_LEGACY_MAX_VCPUS); + } + } + init_evtchn(); } void hypervisor_ap_setup(void) { set_vcpu_id(); + map_vcpuinfo(); init_evtchn(); } diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 85bcb9b28a..1294c88240 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -533,11 +533,11 @@ static struct platform_timesource __initdata plt_tsc = * Xen clock source is a variant of TSC source. */ -DECLARE_PER_CPU(unsigned int, vcpu_id); +DECLARE_PER_CPU(struct vcpu_info *, vcpu_info); static u64 xen_timer_cpu_frequency(void) { - struct vcpu_time_info *info = &XEN_shared_info->vcpu_info[0].time; + struct vcpu_time_info *info = &this_cpu(vcpu_info)->time; u64 freq; freq = 1000000000ULL << 32; @@ -576,16 +576,11 @@ u64 __read_cycle(const struct vcpu_time_info *info, u64 tsc) static u64 last_value; static u64 read_xen_timer(void) { - struct vcpu_time_info *info; - unsigned int cpu = this_cpu(vcpu_id); + struct vcpu_time_info *info = &this_cpu(vcpu_info)->time; u32 version; u64 ret; u64 last; - /* TODO: lift this restriction */ - ASSERT(cpu < XEN_LEGACY_MAX_VCPUS); - info = &XEN_shared_info->vcpu_info[cpu].time; - do { version = info->version & ~1; /* Make sure version is read before the data */ diff --git a/xen/include/asm-x86/guest/hypercall.h b/xen/include/asm-x86/guest/hypercall.h index 90b4755467..7d11df29fa 100644 --- a/xen/include/asm-x86/guest/hypercall.h +++ b/xen/include/asm-x86/guest/hypercall.h @@ -23,6 +23,7 @@ #include <public/xen.h> #include <public/sched.h> +#include <public/vcpu.h> #include <public/hvm/hvm_op.h> #ifdef CONFIG_XEN_GUEST @@ -107,6 +108,12 @@ static inline long xen_hypercall_hvm_op(unsigned int op, void *arg) return _hypercall64_2(long, __HYPERVISOR_hvm_op, op, arg); } +static inline long xen_hypercall_vcpu_op(unsigned int cmd, unsigned int vcpu, + void *arg) +{ + return _hypercall64_3(long, __HYPERVISOR_vcpu_op, cmd, vcpu, arg); +} + /* * Higher level hypercall helpers */ -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |