arm: Use HTPIDR to point to per-CPU state
authorTim Deegan <tim@xen.org>
Mon, 2 Apr 2012 09:54:05 +0000 (10:54 +0100)
committerTim Deegan <tim@xen.org>
Mon, 2 Apr 2012 09:54:05 +0000 (10:54 +0100)
Rather than having the per-VCPU stack contain a pointer to the
per-PCPU state, use the CPU's hypervisor thread ID register for that.

Signed-off-by: Tim Deegan <tim@xen.org>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
[ s/cpuid/id in set_processor_id -- ijc ]
Committed-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/setup.c
xen/arch/arm/smpboot.c
xen/include/asm-arm/cpregs.h
xen/include/asm-arm/current.h
xen/include/asm-arm/percpu.h

index 551c1496e259a21703f0e9ddfe6493fd19257d5f..4e077cda5e2608d1ee3428c94874ecf3de04e433 100644 (file)
@@ -167,7 +167,7 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     percpu_init_areas();
     set_processor_id(0); /* needed early, for smp_processor_id() */
-    __set_current((struct vcpu *)0xfffff000); /* debug sanity */
+    set_current((struct vcpu *)0xfffff000); /* debug sanity */
     idle_vcpu[0] = current;
 
     smp_prepare_cpus(cpus);
index c7773da35a03d9cea3b04bd6795dd0b1342d8534..bc8b3a2fb87c963ef207cbeceed796335342b30f 100644 (file)
@@ -49,6 +49,9 @@ static bool_t cpu_is_dead = 0;
 /* Number of non-boot CPUs ready to enter C */
 unsigned long __initdata ready_cpus = 0;
 
+/* ID of the PCPU we're running on */
+DEFINE_PER_CPU(unsigned int, cpu_id);
+
 void __init
 smp_prepare_cpus (unsigned int max_cpus)
 {
@@ -102,8 +105,6 @@ void __cpuinit start_secondary(unsigned long boot_phys_offset,
     /* Setup Hyp vector base */
     WRITE_CP32((uint32_t) hyp_traps_vector, HVBAR);
 
-    dprintk(XENLOG_DEBUG, "CPU %li awake.\n", cpuid);
-
     mmu_init_secondary_cpu();
     gic_init_secondary_cpu();
 
@@ -119,7 +120,7 @@ void __cpuinit start_secondary(unsigned long boot_phys_offset,
 
     local_irq_enable();
 
-    dprintk(XENLOG_DEBUG, "CPU %li booted.\n", cpuid);
+    dprintk(XENLOG_DEBUG, "CPU %u booted.\n", smp_processor_id());
 
     startup_cpu_idle_loop();
 }
index f6e71eb8f972b0edee98ad5731c9373a072b2c44..ee8a28708e1ad1547837fd4db2bf1a95197a179b 100644 (file)
 /* CP15 CR13:  */
 #define FCSEIDR         p15,0,c13,c0,0  /* FCSE Process ID Register */
 #define CONTEXTIDR      p15,0,c13,c0,1  /* Context ID Register */
+#define HTPIDR          p15,4,c13,c0,2  /* Hyp. Software Thread ID Register */
 
 /* CP15 CR14:  */
 #define CNTPCT          p15,0,c14       /* Time counter value */
index 36b2be950dce26bee7eee426f9618ac011a1a78d..d20d7a8d7635a27ced39aef6f94fcdb290f66b77 100644 (file)
 
 struct vcpu;
 
-/*
- * Which VCPU is "current" on this PCPU.
- */
+/* Which VCPU is "current" on this PCPU. */
 DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
 
+#define current            (this_cpu(curr_vcpu))
+#define set_current(vcpu)  do { current = (vcpu); } while (0)
+
+/* Per-VCPU state that lives at the top of the stack */
 struct cpu_info {
     struct cpu_user_regs guest_cpu_user_regs;
     unsigned long elr;
-    /* The following are valid iff this VCPU is current */
-    unsigned int processor_id;
-    unsigned long per_cpu_offset;
     unsigned int pad;
 };
 
@@ -31,22 +30,6 @@ static inline struct cpu_info *get_cpu_info(void)
     return (struct cpu_info *)((sp & ~(STACK_SIZE - 1)) + STACK_SIZE - sizeof(struct cpu_info));
 }
 
-#define get_processor_id()    (get_cpu_info()->processor_id)
-#define set_processor_id(id)  do {                                      \
-    struct cpu_info *ci__ = get_cpu_info();                             \
-    ci__->per_cpu_offset = __per_cpu_offset[ci__->processor_id = (id)]; \
-} while (0)
-
-#define get_current()         (this_cpu(curr_vcpu))
-#define __set_current(vcpu)   (this_cpu(curr_vcpu) = (vcpu))
-#define set_current(vcpu)     do {                                      \
-    int cpu = get_processor_id();                                       \
-    vcpu->arch.cpu_info->processor_id = cpu;                            \
-    vcpu->arch.cpu_info->per_cpu_offset = __per_cpu_offset[cpu];        \
-    __set_current(vcpu);                                                \
-} while (0)
-#define current               (get_current())
-
 #define guest_cpu_user_regs() (&get_cpu_info()->guest_cpu_user_regs)
 
 #define switch_stack_and_jump(stack, fn)                                \
index e832d6e426eea512b2ec623b70e8c2e742ddc368..1c1f6159adeb6f6c531cdceb3ba170c9bd5dbe76 100644 (file)
@@ -5,7 +5,6 @@
 extern char __per_cpu_start[], __per_cpu_data_end[];
 extern unsigned long __per_cpu_offset[NR_CPUS];
 void percpu_init_areas(void);
-#endif
 
 /* Separate out the type, so (int[3], foo) works. */
 #define __DEFINE_PER_CPU(type, name, suffix)                    \
@@ -16,10 +15,18 @@ void percpu_init_areas(void);
 #define per_cpu(var, cpu)  \
     (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
 #define __get_cpu_var(var) \
-    (*RELOC_HIDE(&per_cpu__##var, get_cpu_info()->per_cpu_offset))
+    (*RELOC_HIDE(&per_cpu__##var, READ_CP32(HTPIDR)))
 
 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
 
+DECLARE_PER_CPU(unsigned int, cpu_id);
+#define get_processor_id()    (this_cpu(cpu_id))
+#define set_processor_id(id)  do {                      \
+    WRITE_CP32(__per_cpu_offset[id], HTPIDR);           \
+    this_cpu(cpu_id) = (id);                            \
+} while(0)
+#endif
+
 #endif /* __ARM_PERCPU_H__ */
 /*
  * Local variables: