[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Hypercall to expose physical CPU information.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1257858222 0 # Node ID d492ebacff21f7f8458bbbbbaa22336a1865487b # Parent 50d33023051db488c5c50b317522b09f824ce7ab Hypercall to expose physical CPU information. It also make some changes to current cpu online/offline logic: 1) Firstly, cpu online/offline will trigger a vIRQ to dom0 for status changes notification. 2) It also add an interface to platform operation to online/offline physical CPU. Currently the cpu online/offline interface is in sysctl, which can't be triggered in kernel. With this change, it is possible to trigger cpu online/offline in dom0 through sysfs interface. Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx> --- xen/arch/x86/platform_hypercall.c | 98 ++++++++++++++++++++++++++++++- xen/arch/x86/smpboot.c | 7 +- xen/arch/x86/x86_64/platform_hypercall.c | 6 + xen/include/asm-x86/smp.h | 1 xen/include/public/platform.h | 53 ++++++++++++++++ xen/include/public/xen.h | 1 6 files changed, 164 insertions(+), 2 deletions(-) diff -r 50d33023051d -r d492ebacff21 xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Tue Nov 10 13:01:09 2009 +0000 +++ b/xen/arch/x86/platform_hypercall.c Tue Nov 10 13:03:42 2009 +0000 @@ -53,6 +53,12 @@ static long cpu_frequency_change_helper( return cpu_frequency_change(this_cpu(freq)); } +static long cpu_down_helper(void *data) +{ + int cpu = (unsigned long)data; + return cpu_down(cpu); +} + ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) { ret_t ret = 0; @@ -385,7 +391,97 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe break; } break; - + + case XENPF_get_cpuinfo: + { + int i; + struct xenpf_pcpu_info *g_info; + struct xen_physical_cpuinfo pcpu; + XEN_GUEST_HANDLE(xen_physical_cpuinfo_t) g_cpus; + + g_info = &op->u.pcpu_info; + if (g_info->info_num <= 0 ) + { + op->u.pcpu_info.max_present = last_cpu(cpu_present_map); + op->u.pcpu_info.max_possible = last_cpu(cpu_possible_map); + goto done; + } + + guest_from_compat_handle(g_cpus, g_info->info); + + spin_lock(&cpu_add_remove_lock); + + ret = -EFAULT; + for (i = 0; i < g_info->info_num; i++) + { + if (copy_from_guest_offset(&pcpu, g_cpus, i, 1) ) + goto out; + + if ( (pcpu.xen_cpuid >= NR_CPUS) || + (pcpu.xen_cpuid < 0) || + !cpu_present(pcpu.xen_cpuid) ) + { + pcpu.flags |= XEN_PCPU_FLAGS_INVALID; + } + else + { + pcpu.apic_id = x86_cpu_to_apicid[pcpu.xen_cpuid]; + pcpu.acpi_id = acpi_get_processor_id(pcpu.xen_cpuid); + ASSERT(pcpu.apic_id != BAD_APICID); + if (cpu_online(pcpu.xen_cpuid)) + pcpu.flags |= XEN_PCPU_FLAGS_ONLINE; + } + + if ( copy_to_guest_offset(g_cpus, i, &pcpu, 1) ) + goto out; + } + op->u.pcpu_info.max_present = last_cpu(cpu_present_map); + op->u.pcpu_info.max_possible = last_cpu(cpu_possible_map); + spin_unlock(&cpu_add_remove_lock); +done: + ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; + } + break; + + case XENPF_resource_hotplug: + { + int cpu; + + switch ( op->u.resource.sub_cmd) + { + case XEN_CPU_online: + cpu = op->u.resource.u.cpu_ol.cpuid; + if (!cpu_present(cpu)) + { + ret = -EINVAL; + break; + } + else if (cpu_online(cpu)) + { + ret = 0; + break; + } + + ret = cpu_up(cpu); + break; + case XEN_CPU_offline: + cpu = op->u.resource.u.cpu_ol.cpuid; + if (!cpu_present(cpu)) + { + ret = -EINVAL; + break; + } else if (!cpu_online(cpu)) + { + ret = 0; + break; + } + ret = continue_hypercall_on_cpu( + 0, cpu_down_helper, (void *)(unsigned long)cpu); + break; + } + } + break; + default: ret = -ENOSYS; break; diff -r 50d33023051d -r d492ebacff21 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Tue Nov 10 13:01:09 2009 +0000 +++ b/xen/arch/x86/smpboot.c Tue Nov 10 13:03:42 2009 +0000 @@ -44,6 +44,7 @@ #include <xen/softirq.h> #include <xen/serial.h> #include <xen/numa.h> +#include <xen/event.h> #include <asm/current.h> #include <asm/mc146818rtc.h> #include <asm/desc.h> @@ -104,7 +105,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 }; DEFINE_PER_CPU(int, cpu_state) = { 0 }; static void *stack_base[NR_CPUS]; -static DEFINE_SPINLOCK(cpu_add_remove_lock); +DEFINE_SPINLOCK(cpu_add_remove_lock); /* * The bootstrap kernel entry code has set these up. Save them for @@ -1342,6 +1343,8 @@ int cpu_down(unsigned int cpu) cpu_mcheck_distribute_cmci(); out: + if (!err) + send_guest_global_virq(dom0, VIRQ_PCPU_STATE); spin_unlock(&cpu_add_remove_lock); return err; } @@ -1362,6 +1365,8 @@ int cpu_up(unsigned int cpu) goto out; out: + if (!err) + send_guest_global_virq(dom0, VIRQ_PCPU_STATE); spin_unlock(&cpu_add_remove_lock); return err; } diff -r 50d33023051d -r d492ebacff21 xen/arch/x86/x86_64/platform_hypercall.c --- a/xen/arch/x86/x86_64/platform_hypercall.c Tue Nov 10 13:01:09 2009 +0000 +++ b/xen/arch/x86/x86_64/platform_hypercall.c Tue Nov 10 13:03:42 2009 +0000 @@ -23,6 +23,12 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_ #define xen_processor_power_t compat_processor_power_t #define set_cx_pminfo compat_set_cx_pminfo +DEFINE_XEN_GUEST_HANDLE(compat_physical_cpuinfo_t); +#define xen_physical_cpuinfo compat_physical_cpuinfo +#define xen_physical_cpuinfo_t compat_physical_cpuinfo_t +#define xenpf_pcpu_info compat_pf_pcpu_info +#define xenpf_pcpu_info_t compat_pf_pcpu_info_t + #define xenpf_enter_acpi_sleep compat_pf_enter_acpi_sleep #define COMPAT diff -r 50d33023051d -r d492ebacff21 xen/include/asm-x86/smp.h --- a/xen/include/asm-x86/smp.h Tue Nov 10 13:01:09 2009 +0000 +++ b/xen/include/asm-x86/smp.h Tue Nov 10 13:03:42 2009 +0000 @@ -56,6 +56,7 @@ extern u32 cpu_2_logical_apicid[]; #define CPU_ONLINE 0x0002 /* CPU is up */ #define CPU_DEAD 0x0004 /* CPU is dead */ DECLARE_PER_CPU(int, cpu_state); +extern spinlock_t(cpu_add_remove_lock); #ifdef CONFIG_HOTPLUG_CPU #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) diff -r 50d33023051d -r d492ebacff21 xen/include/public/platform.h --- a/xen/include/public/platform.h Tue Nov 10 13:01:09 2009 +0000 +++ b/xen/include/public/platform.h Tue Nov 10 13:03:42 2009 +0000 @@ -312,6 +312,57 @@ typedef struct xenpf_set_processor_pminf typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t; DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t); +#define XENPF_get_cpuinfo 55 +struct xen_physical_cpuinfo { + /* IN */ + uint32_t xen_cpuid; + /* OUT */ + uint32_t apic_id; + uint32_t acpi_id; +#define XEN_PCPU_FLAGS_ONLINE 1 + /* Correponding xen_cpuid is not present*/ +#define XEN_PCPU_FLAGS_INVALID 2 + uint32_t flags; + uint8_t pad[128]; +}; +typedef struct xen_physical_cpuinfo xen_physical_cpuinfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_physical_cpuinfo_t); + +/* + * Fetch physical CPUs information + */ +struct xenpf_pcpu_info +{ + /* OUT */ + /* The maxium cpu_id that is present */ + uint32_t max_present; + /* The maxium possible cpus */ + uint32_t max_possible; + + /* IN */ + uint32_t info_num; + + XEN_GUEST_HANDLE(xen_physical_cpuinfo_t) info; +}; +typedef struct xenpf_pcpu_info xenpf_pcpu_info_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_pcpu_info_t); + +struct xenpf_cpu_ol +{ + uint32_t cpuid; +}; + +#define XENPF_resource_hotplug 56 +struct xenpf_resource_hotplug { + uint32_t sub_cmd; +#define XEN_CPU_online 1 +#define XEN_CPU_offline 2 + union { + struct xenpf_cpu_ol cpu_ol; + uint8_t pad[64]; + }u; +}; + struct xen_platform_op { uint32_t cmd; uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ @@ -327,6 +378,8 @@ struct xen_platform_op { struct xenpf_change_freq change_freq; struct xenpf_getidletime getidletime; struct xenpf_set_processor_pminfo set_pminfo; + struct xenpf_pcpu_info pcpu_info; + struct xenpf_resource_hotplug resource; uint8_t pad[128]; } u; }; diff -r 50d33023051d -r d492ebacff21 xen/include/public/xen.h --- a/xen/include/public/xen.h Tue Nov 10 13:01:09 2009 +0000 +++ b/xen/include/public/xen.h Tue Nov 10 13:03:42 2009 +0000 @@ -145,6 +145,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); #define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */ #define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */ #define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console */ +#define VIRQ_PCPU_STATE 9 /* G. (DOM0) PCPU state changed */ /* Architecture-specific VIRQ definitions. */ #define VIRQ_ARCH_0 16 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |