[Xen-devel] [PATCH v4] x86/cpu: Add supports for zhaoxin x86 platform

2018-05-06 Thread Davidwang
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

2018-05-02 Thread Davidwang
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

2018-04-25 Thread Davidwang
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)

2018-04-19 Thread Davidwang
From: David Wang 

CPUs 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)

2018-04-19 Thread Davidwang
From: David Wang 

CPUs 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)

2018-04-18 Thread Davidwang
From: David Wang 

For 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();

2018-04-16 Thread Davidwang
From: David Wang 

By 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