[Xen-devel] [PATCH v4] x86/cpu: Add supports for zhaoxin x86 platform
From: DavidWang <davidw...@zhaoxin.com> Zhaoxin is a x86 IC designer. Its SOC products support both CPU virtualization and I/O virtualization, which are compatible with Intel VMX and VT-d respectively. Zhaoxin has 'Shanghai' CPU vendor ID. Signed-off-by: DavidWang <davidw...@zhaoxin.com> --- Delete an unnecessary variable. xen/arch/x86/cpu/Makefile | 1 + xen/arch/x86/cpu/common.c | 1 + xen/arch/x86/cpu/intel_cacheinfo.c | 4 +++- xen/arch/x86/cpu/shanghai.c| 28 xen/include/asm-x86/setup.h| 1 + xen/include/asm-x86/x86-vendors.h | 3 ++- 6 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 xen/arch/x86/cpu/shanghai.c diff --git a/xen/arch/x86/cpu/Makefile b/xen/arch/x86/cpu/Makefile index 74f23ae..34a01ca 100644 --- a/xen/arch/x86/cpu/Makefile +++ b/xen/arch/x86/cpu/Makefile @@ -7,4 +7,5 @@ obj-y += common.o obj-y += intel.o obj-y += intel_cacheinfo.o obj-y += mwait-idle.o +obj-y += shanghai.o obj-y += vpmu.o vpmu_amd.o vpmu_intel.o diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 0a452ae..02863c9 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -709,6 +709,7 @@ void __init early_cpu_init(void) intel_cpu_init(); amd_init_cpu(); centaur_init_cpu(); + shanghai_init_cpu(); early_cpu_detect(); } diff --git a/xen/arch/x86/cpu/intel_cacheinfo.c b/xen/arch/x86/cpu/intel_cacheinfo.c index 101e297..1843c2e 100644 --- a/xen/arch/x86/cpu/intel_cacheinfo.c +++ b/xen/arch/x86/cpu/intel_cacheinfo.c @@ -176,7 +176,9 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for * trace cache */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + if ( (num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1 && + c->x86_vendor != X86_VENDOR_SHANGHAI ) + { /* supports eax=2 call */ int i, j, n; int regs[4]; diff --git a/xen/arch/x86/cpu/shanghai.c b/xen/arch/x86/cpu/shanghai.c new file mode 100644 index 000..9156c85 --- /dev/null +++ b/xen/arch/x86/cpu/shanghai.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include "cpu.h" + +static void init_shanghai(struct cpuinfo_x86 *c) +{ +if ( cpu_has(c, X86_FEATURE_ITSC) ) +{ +__set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); +__set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability); +__set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability); +} + +init_intel_cacheinfo(c); +} + +static const struct cpu_dev shanghai_cpu_dev = { +.c_vendor = " Shang", +.c_ident= {" Shanghai "}, +.c_init = init_shanghai, +}; + +int __init shanghai_init_cpu(void) +{ +cpu_devs[X86_VENDOR_SHANGHAI] = _cpu_dev; +return 0; +} diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h index 19232af..2c2d9fd 100644 --- a/xen/include/asm-x86/setup.h +++ b/xen/include/asm-x86/setup.h @@ -23,6 +23,7 @@ int cyrix_init_cpu(void); int nsc_init_cpu(void); int centaur_init_cpu(void); int transmeta_init_cpu(void); +int shanghai_init_cpu(void); void set_nr_cpu_ids(unsigned int max_cpus); diff --git a/xen/include/asm-x86/x86-vendors.h b/xen/include/asm-x86/x86-vendors.h index cae5507..c53d0b9 100644 --- a/xen/include/asm-x86/x86-vendors.h +++ b/xen/include/asm-x86/x86-vendors.h @@ -7,7 +7,8 @@ #define X86_VENDOR_INTEL 0 #define X86_VENDOR_AMD 1 #define X86_VENDOR_CENTAUR 2 -#define X86_VENDOR_NUM 3 +#define X86_VENDOR_SHANGHAI 3 +#define X86_VENDOR_NUM 4 #define X86_VENDOR_UNKNOWN 0xff #endif /* __XEN_X86_VENDORS_H__ */ -- 1.8.3.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3] x86/cpu: Add supports for zhaoxin x86 platform
From: DavidWang <davidw...@zhaoxin.com> Zhaoxin is a x86 IC designer. Its SOC products support both CPU virtualization and I/O virtualization, which are compatible with Intel VMX and VT-d respectively. Zhaoxin has 'Shanghai' CPU vendor ID. Signed-off-by: DavidWang <davidw...@zhaoxin.com> --- xen/arch/x86/cpu/Makefile | 1 + xen/arch/x86/cpu/common.c | 1 + xen/arch/x86/cpu/intel_cacheinfo.c | 4 +++- xen/arch/x86/cpu/shanghai.c| 30 ++ xen/include/asm-x86/setup.h| 1 + xen/include/asm-x86/x86-vendors.h | 3 ++- 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 xen/arch/x86/cpu/shanghai.c diff --git a/xen/arch/x86/cpu/Makefile b/xen/arch/x86/cpu/Makefile index 74f23ae..34a01ca 100644 --- a/xen/arch/x86/cpu/Makefile +++ b/xen/arch/x86/cpu/Makefile @@ -7,4 +7,5 @@ obj-y += common.o obj-y += intel.o obj-y += intel_cacheinfo.o obj-y += mwait-idle.o +obj-y += shanghai.o obj-y += vpmu.o vpmu_amd.o vpmu_intel.o diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 0a452ae..02863c9 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -709,6 +709,7 @@ void __init early_cpu_init(void) intel_cpu_init(); amd_init_cpu(); centaur_init_cpu(); + shanghai_init_cpu(); early_cpu_detect(); } diff --git a/xen/arch/x86/cpu/intel_cacheinfo.c b/xen/arch/x86/cpu/intel_cacheinfo.c index 101e297..5f92254 100644 --- a/xen/arch/x86/cpu/intel_cacheinfo.c +++ b/xen/arch/x86/cpu/intel_cacheinfo.c @@ -176,7 +176,9 @@ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c) * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for * trace cache */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + if ( (num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1 && + c->x86_vendor != X86_VENDOR_SHANGHAI ) + { /* supports eax=2 call */ int i, j, n; int regs[4]; diff --git a/xen/arch/x86/cpu/shanghai.c b/xen/arch/x86/cpu/shanghai.c new file mode 100644 index 000..4f424ed --- /dev/null +++ b/xen/arch/x86/cpu/shanghai.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include "cpu.h" + +static void init_shanghai(struct cpuinfo_x86 *c) +{ +unsigned int l2 = 0; + +if ( cpu_has(c, X86_FEATURE_ITSC) ) +{ +__set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); +__set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability); +__set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability); +} + +l2 = init_intel_cacheinfo(c); +} + +static const struct cpu_dev shanghai_cpu_dev = { +.c_vendor = " Shang", +.c_ident= {" Shanghai "}, +.c_init = init_shanghai, +}; + +int __init shanghai_init_cpu(void) +{ +cpu_devs[X86_VENDOR_SHANGHAI] = _cpu_dev; +return 0; +} diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h index 19232af..2c2d9fd 100644 --- a/xen/include/asm-x86/setup.h +++ b/xen/include/asm-x86/setup.h @@ -23,6 +23,7 @@ int cyrix_init_cpu(void); int nsc_init_cpu(void); int centaur_init_cpu(void); int transmeta_init_cpu(void); +int shanghai_init_cpu(void); void set_nr_cpu_ids(unsigned int max_cpus); diff --git a/xen/include/asm-x86/x86-vendors.h b/xen/include/asm-x86/x86-vendors.h index cae5507..c53d0b9 100644 --- a/xen/include/asm-x86/x86-vendors.h +++ b/xen/include/asm-x86/x86-vendors.h @@ -7,7 +7,8 @@ #define X86_VENDOR_INTEL 0 #define X86_VENDOR_AMD 1 #define X86_VENDOR_CENTAUR 2 -#define X86_VENDOR_NUM 3 +#define X86_VENDOR_SHANGHAI 3 +#define X86_VENDOR_NUM 4 #define X86_VENDOR_UNKNOWN 0xff #endif /* __XEN_X86_VENDORS_H__ */ -- 1.8.3.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v2] x86/cpu: Add supports for zhaoxin x86 platform
From: DavidWang <davidw...@zhaoxin.com> Zhaoxin is a x86 IC designer. Its SOC products support both CPU virtualization and I/O virtualization, which are compatible with Intel VMX and VT-d respectively. Zhaoxin has 'Shanghai' CPU vendor ID. Signed-off-by: DavidWang <davidw...@zhaoxin.com> --- xen/arch/x86/cpu/Makefile | 1 + xen/arch/x86/cpu/common.c | 1 + xen/arch/x86/cpu/intel_cacheinfo.c | 2 +- xen/arch/x86/cpu/shanghai.c| 90 ++ xen/include/asm-x86/cpufeature.h | 1 + xen/include/asm-x86/iommu.h| 2 + xen/include/asm-x86/setup.h| 1 + xen/include/asm-x86/x86-vendors.h | 3 +- 8 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 xen/arch/x86/cpu/shanghai.c diff --git a/xen/arch/x86/cpu/Makefile b/xen/arch/x86/cpu/Makefile index 74f23ae..34a01ca 100644 --- a/xen/arch/x86/cpu/Makefile +++ b/xen/arch/x86/cpu/Makefile @@ -7,4 +7,5 @@ obj-y += common.o obj-y += intel.o obj-y += intel_cacheinfo.o obj-y += mwait-idle.o +obj-y += shanghai.o obj-y += vpmu.o vpmu_amd.o vpmu_intel.o diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 0a452ae..02863c9 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -709,6 +709,7 @@ void __init early_cpu_init(void) intel_cpu_init(); amd_init_cpu(); centaur_init_cpu(); + shanghai_init_cpu(); early_cpu_detect(); } diff --git a/xen/arch/x86/cpu/intel_cacheinfo.c b/xen/arch/x86/cpu/intel_cacheinfo.c index 101e297..a3aec13 100644 --- a/xen/arch/x86/cpu/intel_cacheinfo.c +++ b/xen/arch/x86/cpu/intel_cacheinfo.c @@ -103,7 +103,7 @@ int cpuid4_cache_lookup(int index, struct cpuid4_info *this_leaf) return 0; } -static int find_num_cache_leaves(void) +int find_num_cache_leaves(void) { unsigned inteax, ebx, ecx, edx; union _cpuid4_leaf_eax cache_eax; diff --git a/xen/arch/x86/cpu/shanghai.c b/xen/arch/x86/cpu/shanghai.c new file mode 100644 index 000..ac12ba3 --- /dev/null +++ b/xen/arch/x86/cpu/shanghai.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include "cpu.h" + +void init_shanghai_cache(struct cpuinfo_x86 *c) +{ + unsigned int i = 0, l1d = 0, l1i = 0, l2 = 0, l3 = 0; +struct cpuid4_info leaf; + static bool is_initialized = false; + static unsigned int cache_leaves = 0; + + if ( (!is_initialized) && (c->cpuid_level > 0x0003) ) +{ + /* Init cache_leaves from boot CPU */ + cache_leaves = find_num_cache_leaves(); + is_initialized = true; + } + + /* Use cpuid:0x0004 to find the cache details */ + for (i = 0; i < cache_leaves; i++) +{ + if( c->cpuid_level <= 0x0003 ) + break; + + if ( !cpuid4_cache_lookup(i, ) ) +{ + switch( leaf.eax.split.level ) + { + case 1: + if ( leaf.eax.split.type == CACHE_TYPE_DATA ) + l1d = leaf.size/1024; + else if ( leaf.eax.split.type == CACHE_TYPE_INST ) + l1i = leaf.size/1024; + break; + case 2: + l2 = leaf.size/1024; + break; + case 3: + l3 = leaf.size/1024; + break; + default: + break; + } + } + } + + if ( opt_cpu_info ) + { + if ( l1i ) + printk("CPU: L1 I cache: %dK", l1i); + + if ( l1d ) + printk(", L1 D cache: %dK\n", l1d); + else + printk("\n"); + + if ( l2 ) + printk("CPU: L2 cache: %dK\n", l2); + + if ( l3 ) + printk("CPU: L3 cache: %dK\n", l3); + } + + c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i + l1d)); +} + +static void init_shanghai(struct cpuinfo_x86 *c) +{ + if ( cpu_has(c, X86_FEATURE_ITSC) ) + { + __set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); + __set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability); + __set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability); + } + + init_shanghai_cache(c); +} + +static const struct cpu_dev shanghai_cpu_dev = { + .c_vendor = " Shang", + .c_ident= {" Shanghai "}, + .c_init =
[Xen-devel] [PATCH v4] x86: Fix possible ASSERT(cpu < nr_cpu_ids)
From: David WangCPUs may share an in-use channel. Hence clearing of a bit from the cpumask (in hpet_broadcast_exit()) as well as setting one (in hpet_broadcast_enter()) must not race evaluation of that same cpumask. Therefore avoid evaluating the cpumask twice in hpet_detach_channel(). Otherwise cpumask_empty() may e.g.return false while the subsequent cpumask_first() could return nr_cpu_ids, which then triggers the assertion in cpumask_of() reached through set_channel_irq_affinity(). Signed-off-by: David Wang --- xen/arch/x86/hpet.c | 24 +++- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index bc7a851..18447db 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -509,6 +509,8 @@ static void hpet_attach_channel(unsigned int cpu, static void hpet_detach_channel(unsigned int cpu, struct hpet_event_channel *ch) { +unsigned int next; + spin_lock_irq(>lock); ASSERT(ch == per_cpu(cpu_bc_channel, cpu)); @@ -517,17 +519,21 @@ static void hpet_detach_channel(unsigned int cpu, if ( cpu != ch->cpu ) spin_unlock_irq(>lock); -else if ( cpumask_empty(ch->cpumask) ) -{ -ch->cpu = -1; -clear_bit(HPET_EVT_USED_BIT, >flags); -spin_unlock_irq(>lock); -} else { -ch->cpu = cpumask_first(ch->cpumask); -set_channel_irq_affinity(ch); -local_irq_enable(); +next = cpumask_first(ch->cpumask); +if( next >= nr_cpu_ids ) +{ +ch->cpu = -1; +clear_bit(HPET_EVT_USED_BIT, >flags); +spin_unlock_irq(>lock); +} +else +{ +ch->cpu = next; +set_channel_irq_affinity(ch); +local_irq_enable(); +} } } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3] x86: Fix possible ASSERT(cpu < nr_cpu_ids)
From: David WangCPUs may share an in-use channel. Hence clearing of a bit from the cpumask (in hpet_broadcast_exit()) as well as setting one (in hpet_broadcast_enter()) must not race evaluation of that same cpumask. Therefore avoid evaluating the cpumask twice in hpet_detach_channel(). Otherwise cpumask_empty() may e.g.return false while the subsequent cpumask_first() could return nr_cpu_ids, which then triggers the assertion in cpumask_of() reached through set_channel_irq_affinity(). Sign-off-by: David Wang --- xen/arch/x86/hpet.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index bc7a851..fda0431 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -509,15 +509,18 @@ static void hpet_attach_channel(unsigned int cpu, static void hpet_detach_channel(unsigned int cpu, struct hpet_event_channel *ch) { +unsigned int next; + spin_lock_irq(>lock); ASSERT(ch == per_cpu(cpu_bc_channel, cpu)); per_cpu(cpu_bc_channel, cpu) = NULL; +next = cpumask_first(ch->cpumask); if ( cpu != ch->cpu ) spin_unlock_irq(>lock); -else if ( cpumask_empty(ch->cpumask) ) +else if ( next == nr_cpu_ids ) { ch->cpu = -1; clear_bit(HPET_EVT_USED_BIT, >flags); @@ -525,7 +528,7 @@ static void hpet_detach_channel(unsigned int cpu, } else { -ch->cpu = cpumask_first(ch->cpumask); +ch->cpu = next; set_channel_irq_affinity(ch); local_irq_enable(); } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v2] x86/hpet: Fix possible ASSERT(cpu < nr_cpu_ids)
From: David WangFor the ch->cpumask be cleared by other cpu, cpumask_first() called by hpet_detach_channel() return nr_cpu_ids. That lead an assertion in set_channel_irq_affinity() when cpumask_of() check cpu. Fix this by using a local variable. Signed-off-by: David Wang --- xen/arch/x86/hpet.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index bc7a851..6b3587a 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -509,15 +509,18 @@ static void hpet_attach_channel(unsigned int cpu, static void hpet_detach_channel(unsigned int cpu, struct hpet_event_channel *ch) { +cpumask_t cpumask; + spin_lock_irq(>lock); ASSERT(ch == per_cpu(cpu_bc_channel, cpu)); per_cpu(cpu_bc_channel, cpu) = NULL; +cpumask_copy(, ch->cpumask); if ( cpu != ch->cpu ) spin_unlock_irq(>lock); -else if ( cpumask_empty(ch->cpumask) ) +else if ( cpumask_empty() ) { ch->cpu = -1; clear_bit(HPET_EVT_USED_BIT, >flags); @@ -525,7 +528,7 @@ static void hpet_detach_channel(unsigned int cpu, } else { -ch->cpu = cpumask_first(ch->cpumask); +ch->cpu = cpumask_first(); set_channel_irq_affinity(ch); local_irq_enable(); } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH] x86/hpet: add a lock when cpu clear cpumask in hpet_broadcast_exit();
From: David WangBy the hpet_get_channel(), cpus share an in-use channel somtime. So, core shouldn't clear cpumask while others are getting first cpumask. If core zero and core one share an channel, the cpumask is 0x3. Core zero clear cpumask between core one executing cpumask_empty() and cpumask_first(). The return of cpumask_first() is nr_cpu_ids. That would lead to ASSERT(cpu < nr_cpu_ids). Signed-off-by: David Wang --- xen/arch/x86/hpet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index bc7a851..69a7b3a 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -740,7 +740,9 @@ void hpet_broadcast_exit(void) if ( !reprogram_timer(deadline) ) raise_softirq(TIMER_SOFTIRQ); +spin_lock_irq(>lock); cpumask_clear_cpu(cpu, ch->cpumask); +spin_unlock_irq(>lock); if ( !(ch->flags & HPET_EVT_LEGACY) ) hpet_detach_channel(cpu, ch); -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel