All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains
  2012-06-26 10:29 [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang Ian Campbell
@ 2012-06-26 10:29 ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 02/40] arm: handy function to print a walk of a page table Ian Campbell
                     ` (38 more replies)
  2012-06-26 15:26 ` [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang Ian Campbell
  1 sibling, 39 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Not just dom0.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/domain.c |    3 +++
 xen/arch/arm/p2m.c    |    2 +-
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 5702399..4b38790 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -201,6 +201,9 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
         clear_page(d->shared_info);
         share_xen_page_with_guest(
                 virt_to_page(d->shared_info), d, XENSHARE_writable);
+
+        if ( (rc = p2m_alloc_table(d)) != 0 )
+            goto fail;
     }
 
     d->max_vcpus = 8;
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 051a0e8..4f624d8 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -203,7 +203,7 @@ int p2m_alloc_table(struct domain *d)
     void *p;
 
     /* First level P2M is 2 consecutive pages */
-    page = alloc_domheap_pages(d, 1, 0);
+    page = alloc_domheap_pages(NULL, 1, 0);
     if ( page == NULL )
         return -ENOMEM;
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 02/40] arm: handy function to print a walk of a page table
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 03/40] arm: correct and expand TLB flush CP15 registers Ian Campbell
                     ` (37 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Include helpers for dumping hypervisor walks and guest p2m walks.

Useful for debug but not actually used in this patch.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/mm.c          |   49 +++++++++++++++++++++++++++++++++++++++++++-
 xen/arch/arm/p2m.c         |   15 +++++++++++++
 xen/include/asm-arm/page.h |   26 +++++++++++++++++++++++
 3 files changed, 89 insertions(+), 1 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 10ff883..715a98a 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -26,6 +26,7 @@
 #include <xen/preempt.h>
 #include <xen/errno.h>
 #include <xen/guest_access.h>
+#include <xen/domain_page.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <public/memory.h>
@@ -42,6 +43,8 @@ static lpae_t xen_xenmap[LPAE_ENTRIES] __attribute__((__aligned__(4096)));
 /* Non-boot CPUs use this to find the correct pagetables. */
 uint64_t boot_httbr;
 
+static paddr_t phys_offset;
+
 /* Limits of the Xen heap */
 unsigned long xenheap_mfn_start, xenheap_mfn_end;
 unsigned long xenheap_virt_end;
@@ -53,6 +56,50 @@ unsigned long max_page;
 
 extern char __init_begin[], __init_end[];
 
+void dump_pt_walk(lpae_t *first, paddr_t addr)
+{
+    lpae_t *second = NULL, *third = NULL;
+
+    if ( first_table_offset(addr) >= LPAE_ENTRIES )
+        return;
+
+    printk("1ST[0x%llx] = 0x%"PRIpaddr"\n",
+           first_table_offset(addr),
+           first[first_table_offset(addr)].bits);
+    if ( !first[first_table_offset(addr)].walk.valid ||
+         !first[first_table_offset(addr)].walk.table )
+        goto done;
+
+    second = map_domain_page(first[first_table_offset(addr)].walk.base);
+    printk("2ND[0x%llx] = 0x%"PRIpaddr"\n",
+           second_table_offset(addr),
+           second[second_table_offset(addr)].bits);
+    if ( !second[second_table_offset(addr)].walk.valid ||
+         !second[second_table_offset(addr)].walk.table )
+        goto done;
+
+    third = map_domain_page(second[second_table_offset(addr)].walk.base);
+    printk("3RD[0x%llx] = 0x%"PRIpaddr"\n",
+           third_table_offset(addr),
+           third[third_table_offset(addr)].bits);
+
+done:
+    if (third) unmap_domain_page(third);
+    if (second) unmap_domain_page(second);
+
+}
+
+void dump_hyp_walk(uint32_t addr)
+{
+    uint64_t httbr = READ_CP64(HTTBR);
+
+    printk("Walking Hypervisor VA 0x%08"PRIx32" via HTTBR 0x%016"PRIx64"\n",
+           addr, httbr);
+
+    BUG_ON( (lpae_t *)(unsigned long)(httbr - phys_offset) != xen_pgtable );
+    dump_pt_walk(xen_pgtable, addr);
+}
+
 /* Map a 4k page in a fixmap entry */
 void set_fixmap(unsigned map, unsigned long mfn, unsigned attributes)
 {
@@ -159,7 +206,7 @@ void unmap_domain_page(const void *va)
  * Changes here may need matching changes in head.S */
 void __init setup_pagetables(unsigned long boot_phys_offset)
 {
-    paddr_t xen_paddr, phys_offset;
+    paddr_t xen_paddr;
     unsigned long dest_va;
     lpae_t pte, *p;
     int i;
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 4f624d8..ea385a6 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -5,6 +5,21 @@
 #include <xen/domain_page.h>
 #include <asm/flushtlb.h>
 
+void dump_p2m_lookup(struct domain *d, paddr_t addr)
+{
+    struct p2m_domain *p2m = &d->arch.p2m;
+    lpae_t *first;
+
+    printk("dom%d IPA 0x%"PRIpaddr"\n", d->domain_id, addr);
+
+    printk("P2M @ %p mfn:0x%lx\n",
+           p2m->first_level, page_to_mfn(p2m->first_level));
+
+    first = __map_domain_page(p2m->first_level);
+    dump_pt_walk(first, addr);
+    unmap_domain_page(first);
+}
+
 void p2m_load_VTTBR(struct domain *d)
 {
     struct p2m_domain *p2m = &d->arch.p2m;
diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index b6df64e..183ba5f 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -132,10 +132,28 @@ typedef struct {
     unsigned long sbz1:5;
 } __attribute__((__packed__)) lpae_p2m_t;
 
+/*
+ * Walk is the common bits of p2m and pt entries which are needed to
+ * simply walk the table (e.g. for debug).
+ */
+typedef struct {
+    /* These are used in all kinds of entry. */
+    unsigned long valid:1;      /* Valid mapping */
+    unsigned long table:1;      /* == 1 in 4k map entries too */
+
+    unsigned long pad2:10;
+
+    /* The base address must be approprately aligned for Block entries */
+    unsigned long base:28;      /* Base address of block or next table */
+
+    unsigned long pad1:24;
+} __attribute__((__packed__)) lpae_walk_t;
+
 typedef union {
     uint64_t bits;
     lpae_pt_t pt;
     lpae_p2m_t p2m;
+    lpae_walk_t walk;
 } lpae_t;
 
 /* Standard entry type that we'll use to build Xen's own pagetables.
@@ -252,6 +270,14 @@ static inline void flush_guest_tlb(void)
     WRITE_CP32(r0 /* dummy */, TLBIALLNSNH);
 }
 
+/* Print a walk of an arbitrary page table */
+void dump_pt_walk(lpae_t *table, paddr_t addr);
+
+/* Print a walk of the hypervisor's page tables for a virtual addr. */
+extern void dump_hyp_walk(uint32_t addr);
+/* Print a walk of the p2m for a domain for a physical address. */
+extern void dump_p2m_lookup(struct domain *d, paddr_t addr);
+
 /* Ask the MMU to translate a VA for us */
 static inline uint64_t __va_to_par(uint32_t va)
 {
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 03/40] arm: correct and expand TLB flush CP15 registers
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 02/40] arm: handy function to print a walk of a page table Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 04/40] arm: restore stack on return from trap Ian Campbell
                     ` (36 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Correct spelling of TLBIALLHIS and correct definition of TLBIALLNSNHIS.

Add a few more.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/include/asm-arm/cpregs.h |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index ee8a287..7a0b49a 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -172,12 +172,19 @@
 #define TLBIMVAIS       p15,0,c8,c3,1   /* Invalidate unified TLB entry by MVA inner shareable */
 #define TLBIASIDIS      p15,0,c8,c3,2   /* Invalidate unified TLB by ASID match inner shareable */
 #define TLBIMVAAIS      p15,0,c8,c3,3   /* Invalidate unified TLB entry by MVA all ASID inner shareable */
+#define ITLBIALL        p15,0,c8,c5,0   /* Invalidate instruction TLB */
+#define ITLBIMVA        p15,0,c8,c5,1   /* Invalidate instruction TLB entry by MVA */
+#define ITLBIASID       p15,0,c8,c5,2   /* Invalidate instruction TLB by ASID match */
 #define DTLBIALL        p15,0,c8,c6,0   /* Invalidate data TLB */
 #define DTLBIMVA        p15,0,c8,c6,1   /* Invalidate data TLB entry by MVA */
 #define DTLBIASID       p15,0,c8,c6,2   /* Invalidate data TLB by ASID match */
-#define TLBILLHIS       p15,4,c8,c3,0   /* Invalidate Entire Hyp. Unified TLB inner shareable */
+#define TLBIALL         p15,0,c8,c7,0   /* invalidate unified TLB */
+#define TLBIMVA         p15,0,c8,c7,1   /* invalidate unified TLB entry by MVA */
+#define TLBIASID        p15,0,c8,c7,2   /* invalid unified TLB by ASID match */
+#define TLBIMVAA        p15,0,c8,c7,3   /* invalidate unified TLB entries by MVA all ASID */
+#define TLBIALLHIS      p15,4,c8,c3,0   /* Invalidate Entire Hyp. Unified TLB inner shareable */
 #define TLBIMVAHIS      p15,4,c8,c3,1   /* Invalidate Unified Hyp. TLB by MVA inner shareable */
-#define TLBIALLNSNHIS   p15,4,c8,c7,4   /* Invalidate Entire Non-Secure Non-Hyp. Unified TLB inner shareable */
+#define TLBIALLNSNHIS   p15,4,c8,c3,4   /* Invalidate Entire Non-Secure Non-Hyp. Unified TLB inner shareable */
 #define TLBIALLH        p15,4,c8,c7,0   /* Invalidate Entire Hyp. Unified TLB */
 #define TLBIMVAH        p15,4,c8,c7,1   /* Invalidate Unified Hyp. TLB by MVA */
 #define TLBIALLNSNH     p15,4,c8,c7,4   /* Invalidate Entire Non-Secure Non-Hyp. Unified TLB */
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 04/40] arm: restore stack on return from trap.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 02/40] arm: handy function to print a walk of a page table Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 03/40] arm: correct and expand TLB flush CP15 registers Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 05/40] arm: enable interrupts while handling traps Ian Campbell
                     ` (35 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

We align the stack before calling into C code but we weren't undoing this on
return.

Collapse continue_(non)idle_domain into continue_new_vcpu.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain.c |   16 +++-------------
 xen/arch/arm/entry.S  |    5 ++++-
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 4b38790..9339a11 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -16,17 +16,6 @@
 
 DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
 
-static void continue_idle_domain(struct vcpu *v)
-{
-    reset_stack_and_jump(idle_loop);
-}
-
-static void continue_nonidle_domain(struct vcpu *v)
-{
-    /* check_wakeup_from_wait(); */
-    reset_stack_and_jump(return_from_trap);
-}
-
 void idle_loop(void)
 {
     for ( ; ; )
@@ -72,9 +61,10 @@ static void continue_new_vcpu(struct vcpu *prev)
     schedule_tail(prev);
 
     if ( is_idle_vcpu(current) )
-        continue_idle_domain(current);
+        reset_stack_and_jump(idle_loop);
     else
-        continue_nonidle_domain(current);
+        /* check_wakeup_from_wait(); */
+        reset_stack_and_jump(return_to_new_vcpu);
 }
 
 void context_switch(struct vcpu *prev, struct vcpu *next)
diff --git a/xen/arch/arm/entry.S b/xen/arch/arm/entry.S
index f261a9f..7a22e2d 100644
--- a/xen/arch/arm/entry.S
+++ b/xen/arch/arm/entry.S
@@ -72,7 +72,9 @@ DEFINE_TRAP_ENTRY(hypervisor)
 DEFINE_TRAP_ENTRY(irq)
 DEFINE_TRAP_ENTRY(fiq)
 
-ENTRY(return_from_trap)
+return_from_trap:
+	mov sp, r11
+ENTRY(return_to_new_vcpu)
 	ldr r11, [sp, #UREGS_cpsr]
 	and r11, #PSR_MODE_MASK
 	cmp r11, #PSR_MODE_HYP
@@ -82,6 +84,7 @@ ENTRY(return_to_guest)
 	mov r11, sp
 	bic sp, #7 /* Align the stack pointer */
 	bl leave_hypervisor_tail
+	mov sp, r11
 	RESTORE_ONE_BANKED(SP_usr)
 	/* LR_usr is the same physical register as lr and is restored below */
 	RESTORE_BANKED(svc)
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 05/40] arm: enable interrupts while handling traps
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (2 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 04/40] arm: restore stack on return from trap Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 06/40] arm: hook up domctl and memory_op Ian Campbell
                     ` (34 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

For most traps we can do this as soon as we have saved the necessary state.
For IRQs and FIQs we must wait until we have acked the interrupt with the GIC.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/entry.S |   17 ++++++++++++++---
 xen/arch/arm/gic.c   |    2 ++
 xen/arch/arm/traps.c |    1 -
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/entry.S b/xen/arch/arm/entry.S
index 7a22e2d..5bc3906 100644
--- a/xen/arch/arm/entry.S
+++ b/xen/arch/arm/entry.S
@@ -46,6 +46,17 @@ save_guest_regs:
 	ALIGN;												\
 trap_##trap:												\
 	SAVE_ALL;											\
+	cpsie i; 	/* local_irq_enable */								\
+	adr lr, return_from_trap;									\
+	mov r0, sp;											\
+	mov r11, sp;											\
+	bic sp, #7; /* Align the stack pointer (noop on guest trap) */					\
+	b do_trap_##trap
+
+#define DEFINE_TRAP_ENTRY_NOIRQ(trap)									\
+	ALIGN;												\
+trap_##trap:												\
+	SAVE_ALL;											\
 	adr lr, return_from_trap;									\
 	mov r0, sp;											\
 	mov r11, sp;											\
@@ -69,8 +80,8 @@ DEFINE_TRAP_ENTRY(supervisor_call)
 DEFINE_TRAP_ENTRY(prefetch_abort)
 DEFINE_TRAP_ENTRY(data_abort)
 DEFINE_TRAP_ENTRY(hypervisor)
-DEFINE_TRAP_ENTRY(irq)
-DEFINE_TRAP_ENTRY(fiq)
+DEFINE_TRAP_ENTRY_NOIRQ(irq)
+DEFINE_TRAP_ENTRY_NOIRQ(fiq)
 
 return_from_trap:
 	mov sp, r11
@@ -83,7 +94,7 @@ ENTRY(return_to_new_vcpu)
 ENTRY(return_to_guest)
 	mov r11, sp
 	bic sp, #7 /* Align the stack pointer */
-	bl leave_hypervisor_tail
+	bl leave_hypervisor_tail /* Disables interrupts on return */
 	mov sp, r11
 	RESTORE_ONE_BANKED(SP_usr)
 	/* LR_usr is the same physical register as lr and is restored below */
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index cc9d37b..1a2b95f 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -509,6 +509,8 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
     uint32_t intack = GICC[GICC_IAR];
     unsigned int irq = intack & GICC_IA_IRQ;
 
+    local_irq_enable();
+
     if ( irq == 1023 )
         /* Spurious interrupt */
         return;
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index abc26a3..5ed754f 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -412,7 +412,6 @@ static void do_debug_trap(struct cpu_user_regs *regs, unsigned int code)
 static void do_trap_hypercall(struct cpu_user_regs *regs, unsigned long iss)
 {
     arm_hypercall_t *call = NULL;
-    local_irq_enable();
 
     if ( iss != XEN_HYPERCALL_TAG )
     {
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 06/40] arm: hook up domctl and memory_op
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (3 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 05/40] arm: enable interrupts while handling traps Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 07/40] arm: allocate and setup a guest vcpu Ian Campbell
                     ` (33 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/traps.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 5ed754f..5d8b7f9 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -373,6 +373,8 @@ typedef unsigned long arm_hypercall_t(
     [ __HYPERVISOR_ ## x ] = (arm_hypercall_t *) do_ ## x
 
 static arm_hypercall_t *arm_hypercall_table[] = {
+    HYPERCALL(memory_op),
+    HYPERCALL(domctl),
     HYPERCALL(arch_0),
     HYPERCALL(sched_op),
     HYPERCALL(console_io),
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 07/40] arm: allocate and setup a guest vcpu.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (4 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 06/40] arm: hook up domctl and memory_op Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 08/40] arm: print domid as part of debug trap Ian Campbell
                     ` (32 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain.c         |   67 +++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/dummy.S          |    3 --
 xen/include/public/arch-arm.h |    9 -----
 3 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 9339a11..b099d91 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -144,6 +144,17 @@ void free_vcpu_struct(struct vcpu *v)
     free_xenheap_page(v);
 }
 
+struct vcpu_guest_context *alloc_vcpu_guest_context(void)
+{
+    return xmalloc(struct vcpu_guest_context);
+
+}
+
+void free_vcpu_guest_context(struct vcpu_guest_context *vgc)
+{
+    xfree(vgc);
+}
+
 int vcpu_initialise(struct vcpu *v)
 {
     int rc = 0;
@@ -212,6 +223,62 @@ void arch_domain_destroy(struct domain *d)
     /* domain_vgic_destroy */
 }
 
+static int is_guest_psr(uint32_t psr)
+{
+    switch (psr & PSR_MODE_MASK)
+    {
+    case PSR_MODE_USR:
+    case PSR_MODE_FIQ:
+    case PSR_MODE_IRQ:
+    case PSR_MODE_SVC:
+    case PSR_MODE_ABT:
+    case PSR_MODE_UND:
+    case PSR_MODE_SYS:
+        return 1;
+    case PSR_MODE_MON:
+    case PSR_MODE_HYP:
+    default:
+        return 0;
+    }
+}
+
+/*
+ * Initialise VCPU state. The context can be supplied by either the
+ * toolstack (XEN_DOMCTL_setvcpucontext) or the guest
+ * (VCPUOP_initialise) and therefore must be properly validated.
+ */
+int arch_set_info_guest(
+    struct vcpu *v, vcpu_guest_context_u c)
+{
+    struct cpu_user_regs *regs = &c.nat->user_regs;
+
+    if ( !is_guest_psr(regs->cpsr) )
+        return -EINVAL;
+
+    if ( regs->spsr_svc && !is_guest_psr(regs->spsr_svc) )
+        return -EINVAL;
+    if ( regs->spsr_abt && !is_guest_psr(regs->spsr_abt) )
+        return -EINVAL;
+    if ( regs->spsr_und && !is_guest_psr(regs->spsr_und) )
+        return -EINVAL;
+    if ( regs->spsr_irq && !is_guest_psr(regs->spsr_irq) )
+        return -EINVAL;
+    if ( regs->spsr_fiq && !is_guest_psr(regs->spsr_fiq) )
+        return -EINVAL;
+
+    v->arch.cpu_info->guest_cpu_user_regs = *regs;
+
+    /* XXX other state:
+     * - SCTLR
+     * - TTBR0/1
+     * - TTBCR
+     */
+
+    clear_bit(_VPF_down, &v->pause_flags);
+
+    return 0;
+}
+
 void arch_dump_domain_info(struct domain *d)
 {
 }
diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
index 016340c..3b48917 100644
--- a/xen/arch/arm/dummy.S
+++ b/xen/arch/arm/dummy.S
@@ -20,11 +20,8 @@ DUMMY(pirq_guest_unbind);
 DUMMY(pirq_set_affinity);
 
 /* VCPU */
-DUMMY(alloc_vcpu_guest_context);
 DUMMY(arch_get_info_guest);
-DUMMY(arch_set_info_guest);
 DUMMY(arch_vcpu_reset);
-DUMMY(free_vcpu_guest_context);
 DUMMY(sync_vcpu_execstate);
 NOP(update_vcpu_system_time);
 DUMMY(vcpu_show_execution_state);
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index 1b1bcf3..e439727 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -124,15 +124,6 @@ typedef uint32_t xen_ulong_t;
 
 struct vcpu_guest_context {
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
-    union {
-        uint32_t reg[16];
-        struct {
-            uint32_t __pad[12];
-            uint32_t sp; /* r13 */
-            uint32_t lr; /* r14 */
-            uint32_t pc; /* r15 */
-        };
-    };
 };
 typedef struct vcpu_guest_context vcpu_guest_context_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 08/40] arm: print domid as part of debug trap
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (5 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 07/40] arm: allocate and setup a guest vcpu Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 09/40] arm: remove unnecessarily verbose print from p2m_load_VTTBR Ian Campbell
                     ` (31 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/traps.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 5d8b7f9..40bb375 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -388,25 +388,26 @@ static arm_hypercall_t *arm_hypercall_table[] = {
 static void do_debug_trap(struct cpu_user_regs *regs, unsigned int code)
 {
     uint32_t reg, *r;
-
+    uint32_t domid = current->domain->domain_id;
     switch ( code ) {
     case 0xe0 ... 0xef:
         reg = code - 0xe0;
         r = &regs->r0 + reg;
-        printk("R%d = %#010"PRIx32" at %#010"PRIx32"\n", reg, *r, regs->pc);
+        printk("DOM%d: R%d = %#010"PRIx32" at %#010"PRIx32"\n",
+               domid, reg, *r, regs->pc);
         break;
     case 0xfd:
-        printk("Reached %08"PRIx32"\n", regs->pc);
+        printk("DOM%d: Reached %#010"PRIx32"\n", domid, regs->pc);
         break;
     case 0xfe:
         printk("%c", (char)(regs->r0 & 0xff));
         break;
     case 0xff:
-        printk("DEBUG\n");
+        printk("DOM%d: DEBUG\n", domid);
         show_execution_state(regs);
         break;
     default:
-        panic("Unhandled debug trap %#x\n", code);
+        panic("DOM%d: Unhandled debug trap %#x\n", domid, code);
         break;
     }
 }
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 09/40] arm: remove unnecessarily verbose print from p2m_load_VTTBR
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (6 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 08/40] arm: print domid as part of debug trap Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 10/40] arm: implement p2m lookup Ian Campbell
                     ` (30 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/p2m.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index ea385a6..6df5b62 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -28,8 +28,6 @@ void p2m_load_VTTBR(struct domain *d)
 
     vttbr |= ((uint64_t)p2m->vmid&0xff)<<48;
 
-    printk("VTTBR dom%d = %"PRIx64"\n", d->domain_id, vttbr);
-
     WRITE_CP64(vttbr, VTTBR);
     isb(); /* Ensure update is visible */
 }
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 10/40] arm: implement p2m lookup
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (7 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 09/40] arm: remove unnecessarily verbose print from p2m_load_VTTBR Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 11/40] arm: remove hard tabs from init_idle_domain Ian Campbell
                     ` (29 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/p2m.c        |   45 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h |    3 +++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 6df5b62..ec41d38 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -32,6 +32,51 @@ void p2m_load_VTTBR(struct domain *d)
     isb(); /* Ensure update is visible */
 }
 
+/*
+ * Lookup the MFN corresponding to a domain's PFN.
+ *
+ * There are no processor functions to do a stage 2 only lookup therefore we
+ * do a a software walk.
+ */
+paddr_t p2m_lookup(struct domain *d, paddr_t paddr)
+{
+    struct p2m_domain *p2m = &d->arch.p2m;
+    lpae_t pte, *first = NULL, *second = NULL, *third = NULL;
+    paddr_t maddr = INVALID_PADDR;
+
+    spin_lock(&p2m->lock);
+
+    first = __map_domain_page(p2m->first_level);
+
+    pte = first[first_table_offset(paddr)];
+    if ( !pte.p2m.valid || !pte.p2m.table )
+        goto done;
+
+    second = map_domain_page(pte.p2m.base);
+    pte = second[second_table_offset(paddr)];
+    if ( !pte.p2m.valid || !pte.p2m.table )
+        goto done;
+
+    third = map_domain_page(pte.p2m.base);
+    pte = third[third_table_offset(paddr)];
+
+    /* This bit must be one in the level 3 entry */
+    if ( !pte.p2m.table )
+        pte.bits = 0;
+
+done:
+    if ( pte.p2m.valid )
+        maddr = (pte.bits & PADDR_MASK & PAGE_MASK) | (paddr & ~PAGE_MASK);
+
+    if (third) unmap_domain_page(third);
+    if (second) unmap_domain_page(second);
+    if (first) unmap_domain_page(first);
+
+    spin_unlock(&p2m->lock);
+
+    return maddr;
+}
+
 int guest_physmap_mark_populate_on_demand(struct domain *d,
                                           unsigned long gfn,
                                           unsigned int order)
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 349923a..666bb88 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -32,6 +32,9 @@ int p2m_alloc_table(struct domain *d);
 /* */
 void p2m_load_VTTBR(struct domain *d);
 
+/* Look up the MFN corresponding to a domain's PFN. */
+paddr_t p2m_lookup(struct domain *d, paddr_t gpfn);
+
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
 /* Map MMIO regions in the p2m: start_gaddr and end_gaddr is the range
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang
@ 2012-06-26 10:29 Ian Campbell
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
  2012-06-26 15:26 ` [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang Ian Campbell
  0 siblings, 2 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel

I have (I think) addressed all review comments against non-HACK and
non-toolstack (which I've left till later) patches in this series, as
noted in my various replies to the review.

In the list:
        An "A" in the list below indicates that I think the patch has
        sufficient Acked-by's to be committed (assuming the
        prerequisites can go in).

        An "X" means I don't consider this patch for committing.

        A "!" means I didn't consider review comments yet.

Currently this requires Jan's "arm: fix build after c/s
25477:e12e0b038219" patch, which I have not included here, in order to
build.

I intend to commit those patches which are acked and which do not depend
on non-acked patches shortly.

A     01 arm: allocate top level p2m page for all non-idle domains
A     02 arm: handy function to print a walk of a page table
A     03 arm: correct and expand TLB flush CP15 registers
A     04 arm: restore stack on return from trap.
A     05 arm: enable interrupts while handling traps
A     06 arm: hook up domctl and memory_op
A     07 arm: allocate and setup a guest vcpu.
A     08 arm: print domid as part of debug trap
A     09 arm: remove unnecessarily verbose print from p2m_load_VTTBR
A     10 arm: implement p2m lookup
A     11 arm: remove hard tabs from init_idle_domain
A     12 arm: stub out sync_vcpu_execstate
A     13 arm: implement stub version of flush_tlb_mask.
A     14 arm: do not set max_vcpus = 8 in arch_domain_create.
A     15 arm: Add simple cpu_{sibling,core}_mask
      16 arm: allow p2m to be created with specific MATTR.
      17 arm: implement vpl011 (UART) emulator.
A     18 arm: context switch a bunch of guest state.
A     19 arm: dump a page table walk when va_to_par fails.
A     20 arm: dump guest s1 walk on data abort which is not a stage 2 issue.
      21 arm: implement vcpu_show_execution_state
A     22 arm: use correct attributes for mappings in copy_from_paddr()
A     23 arm: map fixmaps non-executable.
A     24 arm: fix locking in create_p2m_entries
      25 arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU)
      26 arm: use interrupt safe spin locks in vgic_vcpu_inject_irq
A     27 arm: map GICV in all domains, not just dom0.
      28 arm: enable data-cache at the same time as enabling the MMU, not before
A     29 arm: Upgrade guest barriers to Outer-Shareable. Enable Protected Table Walk.
A     30 arm: gic.lock can be taken in interrupt context, so lock appropriately.
A     31 arm: context switch virtual timer registers
A     32 arm: the hyp timer seems to work in newer model versions, default to using it.
      33 arm: unwind allocations etc on arch_domain_create_failure
 X!   34 HACK: arm: initial XENMAPSPACE_gmfn_foreign
A     35 arm: move PSR flag definitions into interface, for tools use.
 X!   36 libxc: add ARM support to xc_dom (PV domain building)
      37 arm: implement VGCF_online
A     38 arm: fix typo s/approprately/appropriately/g
 X!   39 HACK: add simple xcbuild
 X!   40 HACK: arm: disable hypercall continuations.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH V2 11/40] arm: remove hard tabs from init_idle_domain
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (8 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 10/40] arm: implement p2m lookup Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 12/40] arm: stub out sync_vcpu_execstate Ian Campbell
                     ` (28 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/setup.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 0df3c1a..81ababb 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -47,9 +47,9 @@ static __attribute_used__ void init_done(void)
 
 static void __init init_idle_domain(void)
 {
-        scheduler_init();
-        set_current(idle_vcpu[0]);
-        /* TODO: setup_idle_pagetable(); */
+    scheduler_init();
+    set_current(idle_vcpu[0]);
+    /* TODO: setup_idle_pagetable(); */
 }
 
 static void __init processor_id(void)
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 12/40] arm: stub out sync_vcpu_execstate
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (9 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 11/40] arm: remove hard tabs from init_idle_domain Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 13/40] arm: implement stub version of flush_tlb_mask Ian Campbell
                     ` (27 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

We don't do lazy exec state switching so there isn't actually anything to do.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain.c |    5 +++++
 xen/arch/arm/dummy.S  |    1 -
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index b099d91..2c3fc90 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -96,6 +96,11 @@ void sync_local_execstate(void)
     /* Nothing to do -- no lazy switching */
 }
 
+void sync_vcpu_execstate(struct vcpu *v)
+{
+    /* Nothing to do -- no lazy switching */
+}
+
 void startup_cpu_idle_loop(void)
 {
     struct vcpu *v = current;
diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
index 3b48917..8eddd15 100644
--- a/xen/arch/arm/dummy.S
+++ b/xen/arch/arm/dummy.S
@@ -22,7 +22,6 @@ DUMMY(pirq_set_affinity);
 /* VCPU */
 DUMMY(arch_get_info_guest);
 DUMMY(arch_vcpu_reset);
-DUMMY(sync_vcpu_execstate);
 NOP(update_vcpu_system_time);
 DUMMY(vcpu_show_execution_state);
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 13/40] arm: implement stub version of flush_tlb_mask.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (10 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 12/40] arm: stub out sync_vcpu_execstate Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 14/40] arm: do not set max_vcpus = 8 in arch_domain_create Ian Campbell
                     ` (26 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/dummy.S |    1 -
 xen/arch/arm/smp.c   |    9 +++++++++
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
index 8eddd15..c001e8d 100644
--- a/xen/arch/arm/dummy.S
+++ b/xen/arch/arm/dummy.S
@@ -48,7 +48,6 @@ DUMMY(domain_get_maximum_gpfn);
 DUMMY(domain_relinquish_resources);
 DUMMY(domain_set_time_offset);
 DUMMY(dom_cow);
-DUMMY(flush_tlb_mask);
 DUMMY(gmfn_to_mfn);
 DUMMY(hypercall_create_continuation);
 DUMMY(send_timer_event);
diff --git a/xen/arch/arm/smp.c b/xen/arch/arm/smp.c
index cad84f5..824c8c8 100644
--- a/xen/arch/arm/smp.c
+++ b/xen/arch/arm/smp.c
@@ -1,5 +1,14 @@
 #include <xen/config.h>
+#include <asm/system.h>
 #include <asm/smp.h>
+#include <asm/cpregs.h>
+#include <asm/page.h>
+
+void flush_tlb_mask(const cpumask_t *mask)
+{
+    /* XXX IPI other processors */
+    flush_xen_data_tlb();
+}
 
 void smp_call_function(
     void (*func) (void *info),
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 14/40] arm: do not set max_vcpus = 8 in arch_domain_create.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (11 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 13/40] arm: implement stub version of flush_tlb_mask Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 15/40] arm: Add simple cpu_{sibling, core}_mask Ian Campbell
                     ` (25 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

XEN_DOMCTL_max_vcpus cannot reduce max_vcpus and therefore we can't create a
smaller guest.

The limit of 8 (due to GIC limits) should be expressed in MAX_VIRT_CPUS.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain.c        |    2 --
 xen/include/asm-arm/config.h |    2 +-
 2 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 2c3fc90..63bad07 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -212,8 +212,6 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
             goto fail;
     }
 
-    d->max_vcpus = 8;
-
     if ( (rc = domain_vgic_init(d)) != 0 )
         goto fail;
 
diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
index 91e87e1..7d02cc7 100644
--- a/xen/include/asm-arm/config.h
+++ b/xen/include/asm-arm/config.h
@@ -27,7 +27,7 @@
 #define NR_CPUS 128
 #endif
 
-#define MAX_VIRT_CPUS 128 /* XXX */
+#define MAX_VIRT_CPUS 8
 #define MAX_HVM_VCPUS MAX_VIRT_CPUS
 
 #define asmlinkage /* Nothing needed */
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 15/40] arm: Add simple cpu_{sibling, core}_mask
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (12 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 14/40] arm: do not set max_vcpus = 8 in arch_domain_create Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR Ian Campbell
                     ` (24 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This needs to be done for all cpus. The allocations require smp_prepare_cpus
to be called a bit later on.

In a previous version of this patch these maps were being zeroed (instead of
setting the CPU itself in them). This in turn causes cpumask_first to return
NR_CPUS, which in turn was causing default_vcpu0_location to misbehave and
read off the end of its cnt array.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/dummy.S   |    2 --
 xen/arch/arm/setup.c   |    4 ++--
 xen/arch/arm/smpboot.c |   21 +++++++++++++++++++++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
index c001e8d..03f7489 100644
--- a/xen/arch/arm/dummy.S
+++ b/xen/arch/arm/dummy.S
@@ -7,8 +7,6 @@ x:	.word 0xe7f000f0 /* Undefined instruction */
 x:	mov pc, lr
 	
 /* SMP support */
-DUMMY(per_cpu__cpu_core_mask);
-DUMMY(per_cpu__cpu_sibling_mask);
 DUMMY(node_online_map);
 DUMMY(smp_send_state_dump);
 
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 81ababb..d6c0178 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -173,8 +173,6 @@ void __init start_xen(unsigned long boot_phys_offset,
     set_current((struct vcpu *)0xfffff000); /* debug sanity */
     idle_vcpu[0] = current;
 
-    smp_prepare_cpus(cpus);
-
     init_xen_time();
 
     setup_mm(atag_paddr, fdt_size);
@@ -214,6 +212,8 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     local_irq_enable();
 
+    smp_prepare_cpus(cpus);
+
     initialize_keytable();
 
     console_init_postirq();
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index ea05afc..6463a8d 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -52,6 +52,23 @@ unsigned long __initdata ready_cpus = 0;
 
 /* ID of the PCPU we're running on */
 DEFINE_PER_CPU(unsigned int, cpu_id);
+/* XXX these seem awfully x86ish... */
+/* representing HT siblings of each logical CPU */
+DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask);
+/* representing HT and core siblings of each logical CPU */
+DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask);
+
+static void setup_cpu_sibling_map(int cpu)
+{
+    if ( !zalloc_cpumask_var(&per_cpu(cpu_sibling_mask, cpu)) ||
+         !zalloc_cpumask_var(&per_cpu(cpu_core_mask, cpu)) )
+        panic("No memory for CPU sibling/core maps\n");
+
+    /* A CPU is a sibling with itself and is always on its own core. */
+    cpumask_set_cpu(cpu, per_cpu(cpu_sibling_mask, cpu));
+    cpumask_set_cpu(cpu, per_cpu(cpu_core_mask, cpu));
+}
+
 
 void __init
 smp_prepare_cpus (unsigned int max_cpus)
@@ -65,6 +82,8 @@ smp_prepare_cpus (unsigned int max_cpus)
     for ( i = 0; i < max_cpus; i++ )
         cpumask_set_cpu(i, &cpu_possible_map);
     cpumask_copy(&cpu_present_map, &cpu_possible_map);
+
+    setup_cpu_sibling_map(0);
 }
 
 void __init
@@ -115,6 +134,8 @@ void __cpuinit start_secondary(unsigned long boot_phys_offset,
 
     set_current(idle_vcpu[cpuid]);
 
+    setup_cpu_sibling_map(cpuid);
+
     /* Run local notifiers */
     notify_cpu_starting(cpuid);
     wmb();
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (13 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 15/40] arm: Add simple cpu_{sibling, core}_mask Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 12:46     ` Ian Campbell
  2012-06-28 13:00     ` Stefano Stabellini
  2012-06-26 10:29   ` [PATCH V2 17/40] arm: implement vpl011 (UART) emulator Ian Campbell
                     ` (23 subsequent siblings)
  38 siblings, 2 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Rename p2m_create_entry to p2m_create_table since it can now only be used to
insert non-leaf entries into the page table.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/p2m.c         |   22 ++++++++++++----------
 xen/include/asm-arm/page.h |    6 ++++--
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index ec41d38..35bfa2f 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -91,7 +91,8 @@ int p2m_pod_decrease_reservation(struct domain *d,
     return -ENOSYS;
 }
 
-static int p2m_create_entry(struct domain *d,
+/* Allocate a new page table page and hook it in via the given entry */
+static int p2m_create_table(struct domain *d,
                             lpae_t *entry)
 {
     struct p2m_domain *p2m = &d->arch.p2m;
@@ -111,7 +112,7 @@ static int p2m_create_entry(struct domain *d,
     clear_page(p);
     unmap_domain_page(p);
 
-    pte = mfn_to_p2m_entry(page_to_mfn(page));
+    pte = mfn_to_p2m_entry(page_to_mfn(page), MATTR_MEM);
 
     write_pte(entry, pte);
 
@@ -122,7 +123,8 @@ static int create_p2m_entries(struct domain *d,
                      int alloc,
                      paddr_t start_gpaddr,
                      paddr_t end_gpaddr,
-                     paddr_t maddr)
+                     paddr_t maddr,
+                     int mattr)
 {
     int rc;
     struct p2m_domain *p2m = &d->arch.p2m;
@@ -140,7 +142,7 @@ static int create_p2m_entries(struct domain *d,
     {
         if ( !first[first_table_offset(addr)].p2m.valid )
         {
-            rc = p2m_create_entry(d, &first[first_table_offset(addr)]);
+            rc = p2m_create_table(d, &first[first_table_offset(addr)]);
             if ( rc < 0 ) {
                 printk("p2m_populate_ram: L1 failed\n");
                 goto out;
@@ -159,7 +161,7 @@ static int create_p2m_entries(struct domain *d,
 
         if ( !second[second_table_offset(addr)].p2m.valid )
         {
-            rc = p2m_create_entry(d, &second[second_table_offset(addr)]);
+            rc = p2m_create_table(d, &second[second_table_offset(addr)]);
             if ( rc < 0 ) {
                 printk("p2m_populate_ram: L2 failed\n");
                 goto out;
@@ -198,11 +200,11 @@ static int create_p2m_entries(struct domain *d,
                 goto out;
             }
 
-            pte = mfn_to_p2m_entry(page_to_mfn(page));
+            pte = mfn_to_p2m_entry(page_to_mfn(page), mattr);
 
             write_pte(&third[third_table_offset(addr)], pte);
         } else {
-            lpae_t pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT);
+            lpae_t pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr);
             write_pte(&third[third_table_offset(addr)], pte);
             maddr += PAGE_SIZE;
         }
@@ -226,7 +228,7 @@ int p2m_populate_ram(struct domain *d,
                      paddr_t start,
                      paddr_t end)
 {
-    return create_p2m_entries(d, 1, start, end, 0);
+    return create_p2m_entries(d, 1, start, end, 0, MATTR_MEM);
 }
 
 int map_mmio_regions(struct domain *d,
@@ -234,7 +236,7 @@ int map_mmio_regions(struct domain *d,
                      paddr_t end_gaddr,
                      paddr_t maddr)
 {
-    return create_p2m_entries(d, 0, start_gaddr, end_gaddr, maddr);
+    return create_p2m_entries(d, 0, start_gaddr, end_gaddr, maddr, MATTR_DEV);
 }
 
 int guest_physmap_add_page(struct domain *d,
@@ -244,7 +246,7 @@ int guest_physmap_add_page(struct domain *d,
 {
     return create_p2m_entries(d, 0, gpfn << PAGE_SHIFT,
                               (gpfn + (1<<page_order)) << PAGE_SHIFT,
-                              mfn << PAGE_SHIFT);
+                              mfn << PAGE_SHIFT, MATTR_MEM);
 }
 
 void guest_physmap_remove_page(struct domain *d,
diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index 183ba5f..2783c30 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -46,6 +46,8 @@
 #define DEV_WC        BUFFERABLE
 #define DEV_CACHED    WRITEBACK
 
+#define MATTR_DEV     0x1
+#define MATTR_MEM     0xf
 
 #ifndef __ASSEMBLY__
 
@@ -187,7 +189,7 @@ static inline lpae_t mfn_to_xen_entry(unsigned long mfn)
     return e;
 }
 
-static inline lpae_t mfn_to_p2m_entry(unsigned long mfn)
+static inline lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr)
 {
     paddr_t pa = ((paddr_t) mfn) << PAGE_SHIFT;
     lpae_t e = (lpae_t) {
@@ -196,7 +198,7 @@ static inline lpae_t mfn_to_p2m_entry(unsigned long mfn)
         .p2m.sh = LPAE_SH_OUTER,
         .p2m.write = 1,
         .p2m.read = 1,
-        .p2m.mattr = 0xf,
+        .p2m.mattr = mattr,
         .p2m.table = 1,
         .p2m.valid = 1,
     };
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 17/40] arm: implement vpl011 (UART) emulator.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (14 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 11:00     ` Tim Deegan
  2012-06-26 10:29   ` [PATCH V2 18/40] arm: context switch a bunch of guest state Ian Campbell
                     ` (22 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This is not interended to provide a full emulation, but rather just enough to
satisfy the use made by Linux' boot time decompressor code (which is too early
for DT etc)

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/Makefile        |    1 +
 xen/arch/arm/domain.c        |    5 ++
 xen/arch/arm/io.c            |    1 +
 xen/arch/arm/io.h            |    1 +
 xen/arch/arm/vpl011.c        |  145 ++++++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/vpl011.h        |   34 ++++++++++
 xen/include/asm-arm/domain.h |    8 ++
 7 files changed, 195 insertions(+), 0 deletions(-)
 create mode 100644 xen/arch/arm/vpl011.c
 create mode 100644 xen/arch/arm/vpl011.h

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 9440a21..5a87ba6 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -25,6 +25,7 @@ obj-y += shutdown.o
 obj-y += traps.o
 obj-y += vgic.o
 obj-y += vtimer.o
+obj-y += vpl011.o
 
 #obj-bin-y += ....o
 
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 63bad07..931261b 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -13,6 +13,7 @@
 
 #include "gic.h"
 #include "vtimer.h"
+#include "vpl011.h"
 
 DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
 
@@ -215,6 +216,10 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
     if ( (rc = domain_vgic_init(d)) != 0 )
         goto fail;
 
+    /* Domain 0 gets a real UART not an emulated one */
+    if ( d->domain_id && (rc = domain_uart0_init(d)) != 0 )
+        goto fail;
+
     rc = 0;
 fail:
     return rc;
diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c
index 4461225..18f6164 100644
--- a/xen/arch/arm/io.c
+++ b/xen/arch/arm/io.c
@@ -25,6 +25,7 @@
 static const struct mmio_handler *const mmio_handlers[] =
 {
     &vgic_distr_mmio_handler,
+    &uart0_mmio_handler,
 };
 #define MMIO_HANDLER_NR ARRAY_SIZE(mmio_handlers)
 
diff --git a/xen/arch/arm/io.h b/xen/arch/arm/io.h
index 8cc5ca7..9a507f5 100644
--- a/xen/arch/arm/io.h
+++ b/xen/arch/arm/io.h
@@ -40,6 +40,7 @@ struct mmio_handler {
 };
 
 extern const struct mmio_handler vgic_distr_mmio_handler;
+extern const struct mmio_handler uart0_mmio_handler;
 
 extern int handle_mmio(mmio_info_t *info);
 
diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
new file mode 100644
index 0000000..5dc8b28
--- /dev/null
+++ b/xen/arch/arm/vpl011.c
@@ -0,0 +1,145 @@
+/*
+ * xen/arch/arm/vpl011.c
+ *
+ * ARM PL011 UART Emulator (DEBUG)
+ *
+ * Ian Campbell <ian.campbell@citrix.com>
+ * Copyright (c) 2012 Citrix Systems.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This is not intended to be a full emulation of a PL011
+ * device. Rather it is intended to provide a sufficient veneer of one
+ * that early code (such as Linux's boot time decompressor) which
+ * hardcodes output directly to such a device are able to make progress.
+ *
+ * This device is not intended to be enumerable or exposed to the OS
+ * (e.g. via Device Tree).
+ */
+
+#include <xen/config.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include <xen/errno.h>
+#include <xen/ctype.h>
+
+#include "io.h"
+
+#define UART0_START 0x1c090000
+#define UART0_END   (UART0_START+65536)
+
+#define UARTDR 0x000
+#define UARTFR 0x018
+
+int domain_uart0_init(struct domain *d)
+{
+    ASSERT( d->domain_id );
+
+    spin_lock_init(&d->arch.uart0.lock);
+    d->arch.uart0.idx = 0;
+
+    d->arch.uart0.buf = xzalloc_array(char, VPL011_BUF_SIZE);
+    if ( !d->arch.uart0.buf )
+        return -ENOMEM;
+
+    return 0;
+
+}
+
+static void uart0_print_char(char c)
+{
+    struct vpl011 *uart = &current->domain->arch.uart0;
+
+    /* Accept only printable characters, newline, and horizontal tab. */
+    if ( !isprint(c) && (c != '\n') && (c != '\t') )
+        return ;
+
+    spin_lock(&uart->lock);
+    uart->buf[uart->idx++] = c;
+    if ( (uart->idx == (VPL011_BUF_SIZE - 2)) || (c == '\n') )
+    {
+        if ( c != '\n' )
+            uart->buf[uart->idx++] = '\n';
+        uart->buf[uart->idx] = '\0';
+        printk(XENLOG_G_DEBUG "DOM%u: %s",
+               current->domain->domain_id, uart->buf);
+        uart->idx = 0;
+    }
+    spin_unlock(&uart->lock);
+}
+
+static int uart0_mmio_check(struct vcpu *v, paddr_t addr)
+{
+    return addr >= UART0_START && addr < UART0_END;
+}
+
+static int uart0_mmio_read(struct vcpu *v, mmio_info_t *info)
+{
+    struct hsr_dabt dabt = info->dabt;
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+    uint32_t *r = &regs->r0 + dabt.reg;
+    int offset = (int)(info->gpa - UART0_START);
+
+    switch ( offset )
+    {
+    case UARTDR:
+        *r = 0;
+        return 1;
+    case UARTFR:
+        *r = 0x87; /* All holding registers empty, ready to send etc */
+        return 1;
+    default:
+        printk("VPL011: unhandled read r%d offset %#08x\n",
+               dabt.reg, offset);
+        domain_crash_synchronous();
+    }
+}
+
+static int uart0_mmio_write(struct vcpu *v, mmio_info_t *info)
+{
+    struct hsr_dabt dabt = info->dabt;
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+    uint32_t *r = &regs->r0 + dabt.reg;
+    int offset = (int)(info->gpa - UART0_START);
+
+    switch ( offset )
+    {
+    case UARTDR:
+        /* ignore any status bits */
+        uart0_print_char((int)((*r) & 0xFF));
+        return 1;
+    case UARTFR:
+        /* Silently ignore */
+        return 1;
+    default:
+        printk("VPL011: unhandled write r%d=%"PRIx32" offset %#08x\n",
+               dabt.reg, *r, offset);
+        domain_crash_synchronous();
+    }
+}
+
+const struct mmio_handler uart0_mmio_handler = {
+    .check_handler = uart0_mmio_check,
+    .read_handler  = uart0_mmio_read,
+    .write_handler = uart0_mmio_write,
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
new file mode 100644
index 0000000..952d812
--- /dev/null
+++ b/xen/arch/arm/vpl011.h
@@ -0,0 +1,34 @@
+/*
+ * xen/arch/arm/vpl011.h
+ *
+ * ARM PL011 Emulation Support
+ *
+ * Ian Campbell <ian.campbell@citrix.com>
+ * Copyright (c) 2012 Citrix Systems.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_VPL011_H__
+#define __ARCH_ARM_VPL011_H__
+
+extern int domain_uart0_init(struct domain *d);
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 10ed540..f295a82 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -48,6 +48,14 @@ struct arch_domain
         struct vgic_irq_rank *shared_irqs;
         struct pending_irq *pending_irqs;
     } vgic;
+
+    struct vpl011 {
+#define VPL011_BUF_SIZE 128
+        char                  *buf;
+        int                    idx;
+        spinlock_t             lock;
+    } uart0;
+
 }  __cacheline_aligned;
 
 struct arch_vcpu
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 18/40] arm: context switch a bunch of guest state.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (15 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 17/40] arm: implement vpl011 (UART) emulator Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 19/40] arm: dump a page table walk when va_to_par fails Ian Campbell
                     ` (21 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

I haven't investigated what if any of this could be done lazily.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain.c         |  122 +++++++++++++++++++++++++++++++++++++++--
 xen/arch/arm/gic.c            |   25 ++++++++-
 xen/arch/arm/gic.h            |    9 ++-
 xen/include/asm-arm/cpregs.h  |   29 +++++++++-
 xen/include/asm-arm/domain.h  |   33 ++++++++++-
 xen/include/public/arch-arm.h |    3 +
 6 files changed, 208 insertions(+), 13 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 931261b..d11be78 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -36,12 +36,124 @@ void idle_loop(void)
 
 static void ctxt_switch_from(struct vcpu *p)
 {
+    /* CP 15 */
+    p->arch.csselr = READ_CP32(CSSELR);
+
+    /* Control Registers */
+    p->arch.actlr = READ_CP32(ACTLR);
+    p->arch.sctlr = READ_CP32(SCTLR);
+    p->arch.cpacr = READ_CP32(CPACR);
+
+    p->arch.contextidr = READ_CP32(CONTEXTIDR);
+    p->arch.tpidrurw = READ_CP32(TPIDRURW);
+    p->arch.tpidruro = READ_CP32(TPIDRURO);
+    p->arch.tpidrprw = READ_CP32(TPIDRPRW);
+
+    /* XXX only save these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
+    p->arch.teecr = READ_CP32(TEECR);
+    p->arch.teehbr = READ_CP32(TEEHBR);
+
+    p->arch.joscr = READ_CP32(JOSCR);
+    p->arch.jmcr = READ_CP32(JMCR);
+
+    isb();
+
+    /* MMU */
+    p->arch.vbar = READ_CP32(VBAR);
+    p->arch.ttbcr = READ_CP32(TTBCR);
+    /* XXX save 64 bit TTBR if guest is LPAE */
+    p->arch.ttbr0 = READ_CP32(TTBR0);
+    p->arch.ttbr1 = READ_CP32(TTBR1);
+
+    p->arch.dacr = READ_CP32(DACR);
+    p->arch.par = READ_CP64(PAR);
+    p->arch.mair0 = READ_CP32(MAIR0);
+    p->arch.mair1 = READ_CP32(MAIR1);
+
+    /* Fault Status */
+    p->arch.dfar = READ_CP32(DFAR);
+    p->arch.ifar = READ_CP32(IFAR);
+    p->arch.dfsr = READ_CP32(DFSR);
+    p->arch.ifsr = READ_CP32(IFSR);
+    p->arch.adfsr = READ_CP32(ADFSR);
+    p->arch.aifsr = READ_CP32(AIFSR);
+
+    /* XXX MPU */
+
+    /* XXX VFP */
+
+    /* XXX VGIC */
+    gic_save_state(p);
+
+    isb();
     context_saved(p);
 }
 
 static void ctxt_switch_to(struct vcpu *n)
 {
+    uint32_t hcr;
+
+    hcr = READ_CP32(HCR);
+    WRITE_CP32(hcr & ~HCR_VM, HCR);
+    isb();
+
     p2m_load_VTTBR(n->domain);
+    isb();
+
+    /* XXX VGIC */
+    gic_restore_state(n);
+
+    /* XXX VFP */
+
+    /* XXX MPU */
+
+    /* Fault Status */
+    WRITE_CP32(n->arch.dfar, DFAR);
+    WRITE_CP32(n->arch.ifar, IFAR);
+    WRITE_CP32(n->arch.dfsr, DFSR);
+    WRITE_CP32(n->arch.ifsr, IFSR);
+    WRITE_CP32(n->arch.adfsr, ADFSR);
+    WRITE_CP32(n->arch.aifsr, AIFSR);
+
+    /* MMU */
+    WRITE_CP32(n->arch.vbar, VBAR);
+    WRITE_CP32(n->arch.ttbcr, TTBCR);
+    /* XXX restore 64 bit TTBR if guest is LPAE */
+    WRITE_CP32(n->arch.ttbr0, TTBR0);
+    WRITE_CP32(n->arch.ttbr1, TTBR1);
+
+    WRITE_CP32(n->arch.dacr, DACR);
+    WRITE_CP64(n->arch.par, PAR);
+    WRITE_CP32(n->arch.mair0, MAIR0);
+    WRITE_CP32(n->arch.mair1, MAIR1);
+    isb();
+
+    /* Control Registers */
+    WRITE_CP32(n->arch.actlr, ACTLR);
+    WRITE_CP32(n->arch.sctlr, SCTLR);
+    WRITE_CP32(n->arch.cpacr, CPACR);
+
+    WRITE_CP32(n->arch.contextidr, CONTEXTIDR);
+    WRITE_CP32(n->arch.tpidrurw, TPIDRURW);
+    WRITE_CP32(n->arch.tpidruro, TPIDRURO);
+    WRITE_CP32(n->arch.tpidrprw, TPIDRPRW);
+
+    /* XXX only restore these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
+    WRITE_CP32(n->arch.teecr, TEECR);
+    WRITE_CP32(n->arch.teehbr, TEEHBR);
+
+    WRITE_CP32(n->arch.joscr, JOSCR);
+    WRITE_CP32(n->arch.jmcr, JMCR);
+
+    isb();
+
+    /* CP 15 */
+    WRITE_CP32(n->arch.csselr, CSSELR);
+
+    isb();
+
+    WRITE_CP32(hcr, HCR);
+    isb();
 }
 
 static void schedule_tail(struct vcpu *prev)
@@ -258,6 +370,7 @@ static int is_guest_psr(uint32_t psr)
 int arch_set_info_guest(
     struct vcpu *v, vcpu_guest_context_u c)
 {
+    struct vcpu_guest_context *ctxt = c.nat;
     struct cpu_user_regs *regs = &c.nat->user_regs;
 
     if ( !is_guest_psr(regs->cpsr) )
@@ -276,11 +389,10 @@ int arch_set_info_guest(
 
     v->arch.cpu_info->guest_cpu_user_regs = *regs;
 
-    /* XXX other state:
-     * - SCTLR
-     * - TTBR0/1
-     * - TTBCR
-     */
+    v->arch.sctlr = ctxt->sctlr;
+    v->arch.ttbr0 = ctxt->ttbr0;
+    v->arch.ttbr1 = ctxt->ttbr1;
+    v->arch.ttbcr = ctxt->ttbcr;
 
     clear_bit(_VPF_down, &v->pause_flags);
 
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 1a2b95f..339c327 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -61,6 +61,30 @@ static struct {
 irq_desc_t irq_desc[NR_IRQS];
 unsigned nr_lrs;
 
+void gic_save_state(struct vcpu *v)
+{
+    int i;
+
+    for ( i=0; i<nr_lrs; i++)
+        v->arch.gic_lr[i] = GICH[GICH_LR + i];
+    /* Disable until next VCPU scheduled */
+    GICH[GICH_HCR] = 0;
+    isb();
+}
+
+void gic_restore_state(struct vcpu *v)
+{
+    int i;
+
+    if ( is_idle_vcpu(v) )
+        return;
+
+    for ( i=0; i<nr_lrs; i++)
+        GICH[GICH_LR + i] = v->arch.gic_lr[i];
+    GICH[GICH_HCR] = GICH_HCR_EN;
+    isb();
+}
+
 static unsigned int gic_irq_startup(struct irq_desc *desc)
 {
     uint32_t enabler;
@@ -263,7 +287,6 @@ static void __cpuinit gic_hyp_init(void)
     vtr = GICH[GICH_VTR];
     nr_lrs  = (vtr & GICH_VTR_NRLRGS) + 1;
 
-    GICH[GICH_HCR] = GICH_HCR_EN;
     GICH[GICH_MISR] = GICH_MISR_EOI;
 }
 
diff --git a/xen/arch/arm/gic.h b/xen/arch/arm/gic.h
index ff8d0a2..ac9cf3a 100644
--- a/xen/arch/arm/gic.h
+++ b/xen/arch/arm/gic.h
@@ -70,8 +70,8 @@
 #define GICH_MISR       (0x10/4)
 #define GICH_EISR0      (0x20/4)
 #define GICH_EISR1      (0x24/4)
-#define GICH_ELRSR0     (0x30/4)
-#define GICH_ELRSR1     (0x34/4)
+#define GICH_ELSR0      (0x30/4)
+#define GICH_ELSR1      (0x34/4)
 #define GICH_APR        (0xF0/4)
 #define GICH_LR         (0x100/4)
 
@@ -149,6 +149,11 @@ extern void gic_init_secondary_cpu(void);
 extern void gic_disable_cpu(void);
 /* setup the gic virtual interface for a guest */
 extern void gicv_setup(struct domain *d);
+
+/* Context switch */
+extern void gic_save_state(struct vcpu *v);
+extern void gic_restore_state(struct vcpu *v);
+
 #endif
 
 /*
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 7a0b49a..bd46942 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -88,6 +88,19 @@
  * arguments, which are cp,opc1,crn,crm,opc2.
  */
 
+/* Coprocessor 14 */
+
+/* CP14 CR0: */
+#define TEECR           p14,6,c0,c0,0   /* ThumbEE Configuration Register */
+
+/* CP14 CR1: */
+#define TEEHBR          p14,6,c1,c0,0   /* ThumbEE Handler Base Register */
+#define JOSCR           p14,7,c1,c0,0   /* Jazelle OS Control Register */
+
+/* CP14 CR2: */
+#define JMCR            p14,7,c2,c0,0   /* Jazelle Main Configuration Register */
+
+
 /* Coprocessor 15 */
 
 /* CP15 CR0: CPUID and Cache Type Registers */
@@ -112,6 +125,8 @@
 
 /* CP15 CR1: System Control Registers */
 #define SCTLR           p15,0,c1,c0,0   /* System Control Register */
+#define ACTLR           p15,0,c1,c0,1   /* Auxiliary Control Register */
+#define CPACR           p15,0,c1,c0,2   /* Coprocessor Access Control Register */
 #define SCR             p15,0,c1,c1,0   /* Secure Configuration Register */
 #define NSACR           p15,0,c1,c1,2   /* Non-Secure Access Control Register */
 #define HSCTLR          p15,4,c1,c0,0   /* Hyp. System Control Register */
@@ -127,12 +142,15 @@
 #define VTTBR           p15,6,c2        /* Virtualization Translation Table Base Register */
 
 /* CP15 CR3: Domain Access Control Register */
+#define DACR            p15,0,c3,c0,0   /* Domain Access Control Register */
 
 /* CP15 CR4: */
 
 /* CP15 CR5: Fault Status Registers */
 #define DFSR            p15,0,c5,c0,0   /* Data Fault Status Register */
 #define IFSR            p15,0,c5,c0,1   /* Instruction Fault Status Register */
+#define ADFSR           p15,0,c5,c1,0   /* Auxiliary Data Fault Status Register */
+#define AIFSR           p15,0,c5,c1,1   /* Auxiliary Instruction Fault Status Register */
 #define HSR             p15,4,c5,c2,0   /* Hyp. Syndrome Register */
 
 /* CP15 CR6: Fault Address Registers */
@@ -144,6 +162,7 @@
 
 /* CP15 CR7: Cache and address translation operations */
 #define PAR             p15,0,c7        /* Physical Address Register */
+
 #define ICIALLUIS       p15,0,c7,c1,0   /* Invalidate all instruction caches to PoU inner shareable */
 #define BPIALLIS        p15,0,c7,c1,6   /* Invalidate entire branch predictor array inner shareable */
 #define ICIALLU         p15,0,c7,c5,0   /* Invalidate all instruction caches to PoU */
@@ -192,20 +211,24 @@
 /* CP15 CR9: */
 
 /* CP15 CR10: */
-#define MAIR0           p15,0,c10,c2,0  /* Memory Attribute Indirection Register 0 */
-#define MAIR1           p15,0,c10,c2,1  /* Memory Attribute Indirection Register 1 */
+#define MAIR0           p15,0,c10,c2,0  /* Memory Attribute Indirection Register 0 AKA PRRR */
+#define MAIR1           p15,0,c10,c2,1  /* Memory Attribute Indirection Register 1 AKA NMRR */
 #define HMAIR0          p15,4,c10,c2,0  /* Hyp. Memory Attribute Indirection Register 0 */
 #define HMAIR1          p15,4,c10,c2,1  /* Hyp. Memory Attribute Indirection Register 1 */
 
 /* CP15 CR11: DMA Operations for TCM Access */
 
 /* CP15 CR12:  */
+#define VBAR            p15,0,c12,c0,0  /* Vector Base Address Register */
 #define HVBAR           p15,4,c12,c0,0  /* Hyp. Vector Base Address Register */
 
 /* 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 */
+#define TPIDRURW        p15,0,c13,c0,2  /* Software Thread ID, User, R/W */
+#define TPIDRURO        p15,0,c13,c0,3  /* Software Thread ID, User, R/O */
+#define TPIDRPRW        p15,0,c13,c0,4  /* Software Thread ID, Priveleged */
+#define HTPIDR          p15,4,c13,c0,2  /* HYp Software Thread Id Register */
 
 /* CP15 CR14:  */
 #define CNTPCT          p15,0,c14       /* Time counter value */
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index f295a82..620b26e 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -81,8 +81,37 @@ struct arch_vcpu
      */
     struct cpu_info *cpu_info;
 
-    uint32_t sctlr;
-    uint32_t ttbr0, ttbr1, ttbcr;
+    /* Fault Status */
+    uint32_t dfar, ifar;
+    uint32_t dfsr, ifsr;
+    uint32_t adfsr, aifsr;
+
+    /* MMU */
+    uint32_t vbar;
+    uint32_t ttbcr;
+    uint32_t ttbr0, ttbr1;
+
+    uint32_t dacr;
+    uint64_t par;
+    uint32_t mair0, mair1;
+
+    /* Control Registers */
+    uint32_t actlr, sctlr;
+    uint32_t cpacr;
+
+    uint32_t contextidr;
+    uint32_t tpidrurw;
+    uint32_t tpidruro;
+    uint32_t tpidrprw;
+
+    uint32_t teecr, teehbr;
+    uint32_t joscr, jmcr;
+
+    /* CP 15 */
+    uint32_t csselr;
+
+    uint32_t gic_hcr, gic_vmcr, gic_apr;
+    uint32_t gic_lr[64];
 
     struct {
         struct vgic_irq_rank private_irqs;
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index e439727..e915cbf 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -124,6 +124,9 @@ typedef uint32_t xen_ulong_t;
 
 struct vcpu_guest_context {
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
+
+    uint32_t sctlr;
+    uint32_t ttbr0, ttbr1, ttbcr;
 };
 typedef struct vcpu_guest_context vcpu_guest_context_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 19/40] arm: dump a page table walk when va_to_par fails.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (16 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 18/40] arm: context switch a bunch of guest state Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 20/40] arm: dump guest s1 walk on data abort which is not a stage 2 issue Ian Campbell
                     ` (20 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/include/asm-arm/page.h |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index 2783c30..6efe23c 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -296,7 +296,11 @@ static inline uint64_t va_to_par(uint32_t va)
 {
     uint64_t par = __va_to_par(va);
     /* It is not OK to call this with an invalid VA */
-    if ( par & PAR_F ) panic_PAR(par, "Hypervisor");
+    if ( par & PAR_F )
+    {
+        dump_hyp_walk(va);
+        panic_PAR(par, "Hypervisor");
+    }
     return par;
 }
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 20/40] arm: dump guest s1 walk on data abort which is not a stage 2 issue.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (17 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 19/40] arm: dump a page table walk when va_to_par fails Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 21/40] arm: implement vcpu_show_execution_state Ian Campbell
                     ` (19 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/traps.c            |   75 +++++++++++++++++++++++++++++++++++---
 xen/include/asm-arm/processor.h |    1 +
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 40bb375..d8eb5a9 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -28,6 +28,7 @@
 #include <xen/errno.h>
 #include <xen/hypercall.h>
 #include <xen/softirq.h>
+#include <xen/domain_page.h>
 #include <public/xen.h>
 #include <asm/regs.h>
 #include <asm/cpregs.h>
@@ -528,6 +529,62 @@ static void do_cp15_64(struct cpu_user_regs *regs,
 
 }
 
+void dump_guest_s1_walk(struct domain *d, uint32_t addr)
+{
+    uint32_t ttbcr = READ_CP32(TTBCR);
+    uint32_t ttbr0 = READ_CP32(TTBR0);
+    paddr_t paddr;
+    uint32_t offset;
+    uint32_t *first = NULL, *second = NULL;
+
+    printk("dom%d VA 0x%08"PRIx32"\n", d->domain_id, addr);
+    printk("    TTBCR: 0x%08"PRIx32"\n", ttbcr);
+    printk("    TTBR0: 0x%08"PRIx32" = 0x%"PRIpaddr"\n",
+           ttbr0, p2m_lookup(d, ttbr0 & PAGE_MASK));
+
+    if ( ttbcr & TTBCR_EAE )
+    {
+        printk("Cannot handle LPAE guest PT walk\n");
+        return;
+    }
+    if ( (ttbcr & TTBCR_N_MASK) != 0 )
+    {
+        printk("Cannot handle TTBR1 guest walks\n");
+        return;
+    }
+
+    paddr = p2m_lookup(d, ttbr0 & PAGE_MASK);
+    if ( paddr == INVALID_PADDR )
+    {
+        printk("Failed TTBR0 maddr lookup\n");
+        goto done;
+    }
+    first = map_domain_page(paddr>>PAGE_SHIFT);
+
+    offset = addr >> (12+10);
+    printk("1ST[0x%"PRIx32"] (0x%"PRIpaddr") = 0x%08"PRIx32"\n",
+           offset, paddr, first[offset]);
+    if ( !(first[offset] & 0x1) ||
+         !(first[offset] & 0x2) )
+        goto done;
+
+    paddr = p2m_lookup(d, first[offset] & PAGE_MASK);
+
+    if ( paddr == INVALID_PADDR )
+    {
+        printk("Failed L1 entry maddr lookup\n");
+        goto done;
+    }
+    second = map_domain_page(paddr>>PAGE_SHIFT);
+    offset = (addr >> 12) & 0x3FF;
+    printk("2ND[0x%"PRIx32"] (0x%"PRIpaddr") = 0x%08"PRIx32"\n",
+           offset, paddr, second[offset]);
+
+done:
+    if (second) unmap_domain_page(second);
+    if (first) unmap_domain_page(first);
+}
+
 static void do_trap_data_abort_guest(struct cpu_user_regs *regs,
                                      struct hsr_dabt dabt)
 {
@@ -535,11 +592,12 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs,
     int level = -1;
     mmio_info_t info;
 
+    info.dabt = dabt;
+    info.gva = READ_CP32(HDFAR);
+
     if (dabt.s1ptw)
         goto bad_data_abort;
 
-    info.dabt = dabt;
-    info.gva = READ_CP32(HDFAR);
     info.gpa = gva_to_ipa(info.gva);
 
     if (handle_mmio(&info))
@@ -553,18 +611,23 @@ bad_data_abort:
     msg = decode_fsc( dabt.dfsc, &level);
 
     printk("Guest data abort: %s%s%s\n"
-           "    gva=%"PRIx32" gpa=%"PRIpaddr"\n",
+           "    gva=%"PRIx32"\n",
            msg, dabt.s1ptw ? " S2 during S1" : "",
            fsc_level_str(level),
-           info.gva, info.gpa);
-    if (dabt.valid)
+           info.gva);
+    if ( !dabt.s1ptw )
+        printk("    gpa=%"PRIpaddr"\n", info.gpa);
+    if ( dabt.valid )
         printk("    size=%d sign=%d write=%d reg=%d\n",
                dabt.size, dabt.sign, dabt.write, dabt.reg);
     else
         printk("    instruction syndrome invalid\n");
     printk("    eat=%d cm=%d s1ptw=%d dfsc=%d\n",
            dabt.eat, dabt.cache, dabt.s1ptw, dabt.dfsc);
-
+    if ( !dabt.s1ptw )
+        dump_p2m_lookup(current->domain, info.gpa);
+    else
+        dump_guest_s1_walk(current->domain, info.gva);
     show_execution_state(regs);
     panic("Unhandled guest data abort\n");
 }
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index ec6fb48..81924a4 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -25,6 +25,7 @@
 #define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
 
 /* TTBCR Translation Table Base Control Register */
+#define TTBCR_EAE    0x80000000
 #define TTBCR_N_MASK 0x07
 #define TTBCR_N_16KB 0x00
 #define TTBCR_N_8KB  0x01
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 21/40] arm: implement vcpu_show_execution_state
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (18 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 20/40] arm: dump guest s1 walk on data abort which is not a stage 2 issue Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 13:04     ` Stefano Stabellini
  2012-06-26 10:29   ` [PATCH V2 22/40] arm: use correct attributes for mappings in copy_from_paddr() Ian Campbell
                     ` (18 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/dummy.S |    1 -
 xen/arch/arm/traps.c |   56 +++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
index 03f7489..cab9522 100644
--- a/xen/arch/arm/dummy.S
+++ b/xen/arch/arm/dummy.S
@@ -21,7 +21,6 @@ DUMMY(pirq_set_affinity);
 DUMMY(arch_get_info_guest);
 DUMMY(arch_vcpu_reset);
 NOP(update_vcpu_system_time);
-DUMMY(vcpu_show_execution_state);
 
 /* Page Reference & Type Maintenance */
 DUMMY(get_page);
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index d8eb5a9..f5f43da 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -170,7 +170,13 @@ void panic_PAR(uint64_t par, const char *when)
     panic("Error during %s-to-physical address translation\n", when);
 }
 
-void show_registers(struct cpu_user_regs *regs)
+struct reg_ctxt {
+    uint32_t sctlr;
+    uint32_t ttbr0, ttbr1, ttbcr;
+};
+static void _show_registers(struct cpu_user_regs *regs,
+                            struct reg_ctxt *ctxt,
+                            int guest_mode)
 {
     static const char *mode_strings[] = {
        [PSR_MODE_USR] = "USR",
@@ -187,7 +193,7 @@ void show_registers(struct cpu_user_regs *regs)
     print_xen_info();
     printk("CPU:    %d\n", smp_processor_id());
     printk("PC:     %08"PRIx32, regs->pc);
-    if ( !guest_mode(regs) )
+    if ( !guest_mode )
             print_symbol(" %s", regs->pc);
     printk("\n");
     printk("CPSR:   %08"PRIx32" MODE:%s\n", regs->cpsr,
@@ -199,7 +205,7 @@ void show_registers(struct cpu_user_regs *regs)
     printk("     R8: %08"PRIx32" R9: %08"PRIx32" R10:%08"PRIx32" R11:%08"PRIx32" R12:%08"PRIx32"\n",
            regs->r8, regs->r9, regs->r10, regs->r11, regs->r12);
 
-    if ( guest_mode(regs) )
+    if ( guest_mode )
     {
         printk("USR: SP: %08"PRIx32" LR: %08"PRIx32" CPSR:%08"PRIx32"\n",
                regs->sp_usr, regs->lr_usr, regs->cpsr);
@@ -217,8 +223,8 @@ void show_registers(struct cpu_user_regs *regs)
                regs->r8_fiq, regs->r9_fiq, regs->r10_fiq, regs->r11_fiq, regs->r11_fiq);
         printk("\n");
         printk("TTBR0 %08"PRIx32" TTBR1 %08"PRIx32" TTBCR %08"PRIx32"\n",
-               READ_CP32(TTBR0), READ_CP32(TTBR1), READ_CP32(TTBCR));
-        printk("SCTLR %08"PRIx32"\n", READ_CP32(SCTLR));
+               ctxt->ttbr0, ctxt->ttbr1, ctxt->ttbcr);
+        printk("SCTLR %08"PRIx32"\n", ctxt->sctlr);
         printk("VTTBR %010"PRIx64"\n", READ_CP64(VTTBR));
         printk("\n");
     }
@@ -241,6 +247,26 @@ void show_registers(struct cpu_user_regs *regs)
     printk("\n");
 }
 
+void show_registers(struct cpu_user_regs *regs)
+{
+    struct reg_ctxt ctxt;
+    ctxt.sctlr = READ_CP32(SCTLR);
+    ctxt.ttbcr = READ_CP32(TTBCR);
+    ctxt.ttbr0 = READ_CP32(TTBR0);
+    ctxt.ttbr1 = READ_CP32(TTBR1);
+    _show_registers(regs, &ctxt, guest_mode(regs));
+}
+
+void vcpu_show_registers(const struct vcpu *v)
+{
+    struct reg_ctxt ctxt;
+    ctxt.sctlr = v->arch.sctlr;
+    ctxt.ttbcr = v->arch.ttbcr;
+    ctxt.ttbr0 = v->arch.ttbr0;
+    ctxt.ttbr1 = v->arch.ttbr1;
+    _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1);
+}
+
 static void show_guest_stack(struct cpu_user_regs *regs)
 {
     printk("GUEST STACK GOES HERE\n");
@@ -334,6 +360,26 @@ void show_execution_state(struct cpu_user_regs *regs)
     show_stack(regs);
 }
 
+void vcpu_show_execution_state(struct vcpu *v)
+{
+    printk("*** Dumping Dom%d vcpu#%d state: ***\n",
+           v->domain->domain_id, v->vcpu_id);
+
+    if ( v == current )
+    {
+        show_execution_state(guest_cpu_user_regs());
+        return;
+    }
+
+    vcpu_pause(v); /* acceptably dangerous */
+
+    vcpu_show_registers(v);
+    if ( !usr_mode(&v->arch.cpu_info->guest_cpu_user_regs) )
+        show_guest_stack(&v->arch.cpu_info->guest_cpu_user_regs);
+
+    vcpu_unpause(v);
+}
+
 static void do_unexpected_trap(const char *msg, struct cpu_user_regs *regs)
 {
     printk("Unexpected Trap: %s\n", msg);
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 22/40] arm: use correct attributes for mappings in copy_from_paddr()
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (19 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 21/40] arm: implement vcpu_show_execution_state Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 23/40] arm: map fixmaps non-executable Ian Campbell
                     ` (17 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

The DTB is in RAM (hence bufferable), kernel is in flash and therefor requires
a device type mapping (hence dev shared).

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: David Vrabel <david.vrabel@citrix.com>
---
 xen/arch/arm/kernel.c       |    8 ++++----
 xen/arch/arm/setup.c        |    2 +-
 xen/include/asm-arm/page.h  |   15 +++++++++++++++
 xen/include/asm-arm/setup.h |    2 +-
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index 130d488..2d56130 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -39,7 +39,7 @@ struct minimal_dtb_header {
  * @paddr: source physical address
  * @len: length to copy
  */
-void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
+void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len, int attrindx)
 {
     void *src = (void *)FIXMAP_ADDR(FIXMAP_MISC);
 
@@ -51,7 +51,7 @@ void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
         s = paddr & (PAGE_SIZE-1);
         l = min(PAGE_SIZE - s, len);
 
-        set_fixmap(FIXMAP_MISC, p, DEV_SHARED);
+        set_fixmap(FIXMAP_MISC, p, attrindx);
         memcpy(dst, src + s, l);
 
         paddr += l;
@@ -111,7 +111,7 @@ static int kernel_try_zimage_prepare(struct kernel_info *info)
     /*
      * Check for an appended DTB.
      */
-    copy_from_paddr(&dtb_hdr, KERNEL_FLASH_ADDRESS + end - start, sizeof(dtb_hdr));
+    copy_from_paddr(&dtb_hdr, KERNEL_FLASH_ADDRESS + end - start, sizeof(dtb_hdr), DEV_SHARED);
     if (be32_to_cpu(dtb_hdr.magic) == DTB_MAGIC) {
         end += be32_to_cpu(dtb_hdr.total_size);
     }
@@ -151,7 +151,7 @@ static int kernel_try_elf_prepare(struct kernel_info *info)
     if ( info->kernel_img == NULL )
         panic("Cannot allocate temporary buffer for kernel.\n");
 
-    copy_from_paddr(info->kernel_img, KERNEL_FLASH_ADDRESS, KERNEL_FLASH_SIZE);
+    copy_from_paddr(info->kernel_img, KERNEL_FLASH_ADDRESS, KERNEL_FLASH_SIZE, DEV_SHARED);
 
     if ( (rc = elf_init(&info->elf.elf, info->kernel_img, KERNEL_FLASH_SIZE )) != 0 )
         return rc;
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index d6c0178..fd70553 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -122,7 +122,7 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size)
      * TODO: handle other payloads too.
      */
     device_tree_flattened = mfn_to_virt(alloc_boot_pages(dtb_pages, 1));
-    copy_from_paddr(device_tree_flattened, dtb_paddr, dtb_size);
+    copy_from_paddr(device_tree_flattened, dtb_paddr, dtb_size, BUFFERABLE);
 
     /* Add non-xenheap memory */
     init_boot_pages(pfn_to_paddr(xenheap_mfn_start + xenheap_pages),
diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index 6efe23c..2b6c1780 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -36,6 +36,14 @@
 #define MAIR0VAL 0xeeaa4400
 #define MAIR1VAL 0xff000004
 
+/*
+ * Attribute Indexes.
+ *
+ * These are valid in the AttrIndx[2:0] field of an LPAE stage 1 page
+ * table entry. They are indexes into the bytes of the MAIR*
+ * registers, as defined above.
+ *
+ */
 #define UNCACHED      0x0
 #define BUFFERABLE    0x1
 #define WRITETHROUGH  0x2
@@ -46,6 +54,13 @@
 #define DEV_WC        BUFFERABLE
 #define DEV_CACHED    WRITEBACK
 
+/*
+ * Stage 2 Memory Type.
+ *
+ * These are valid in the MemAttr[3:0] field of an LPAE stage 2 page
+ * table entry.
+ *
+ */
 #define MATTR_DEV     0x1
 #define MATTR_MEM     0xf
 
diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
index 05ff89e..6433b4e 100644
--- a/xen/include/asm-arm/setup.h
+++ b/xen/include/asm-arm/setup.h
@@ -3,7 +3,7 @@
 
 #include <public/version.h>
 
-void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
+void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len, int attrindx);
 
 void arch_get_xen_caps(xen_capabilities_info_t *info);
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 23/40] arm: map fixmaps non-executable.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (20 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 22/40] arm: use correct attributes for mappings in copy_from_paddr() Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 24/40] arm: fix locking in create_p2m_entries Ian Campbell
                     ` (16 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/mm.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 715a98a..40ac176 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -106,6 +106,7 @@ void set_fixmap(unsigned map, unsigned long mfn, unsigned attributes)
     lpae_t pte = mfn_to_xen_entry(mfn);
     pte.pt.table = 1; /* 4k mappings always have this bit set */
     pte.pt.ai = attributes;
+    pte.pt.xn = 1;
     write_pte(xen_fixmap + third_table_offset(FIXMAP_ADDR(map)), pte);
     flush_xen_data_tlb_va(FIXMAP_ADDR(map));
 }
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 24/40] arm: fix locking in create_p2m_entries
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (21 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 23/40] arm: map fixmaps non-executable Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 25/40] arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU) Ian Campbell
                     ` (15 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

For some reason we were holding the lock over only the unmaps at the end of
the function, rather than for the whole walk.

We might want to be more clever in the future, but for now lets just lock for
the whole walk+create process.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/p2m.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 35bfa2f..5f20246 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -132,6 +132,8 @@ static int create_p2m_entries(struct domain *d,
     paddr_t addr;
     unsigned long cur_first_offset = ~0, cur_second_offset = ~0;
 
+    spin_lock(&p2m->lock);
+
     /* XXX Don't actually handle 40 bit guest physical addresses */
     BUG_ON(start_gpaddr & 0x8000000000ULL);
     BUG_ON(end_gpaddr   & 0x8000000000ULL);
@@ -213,8 +215,6 @@ static int create_p2m_entries(struct domain *d,
     rc = 0;
 
 out:
-    spin_lock(&p2m->lock);
-
     if (third) unmap_domain_page(third);
     if (second) unmap_domain_page(second);
     if (first) unmap_domain_page(first);
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 25/40] arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU)
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (22 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 24/40] arm: fix locking in create_p2m_entries Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 13:08     ` Stefano Stabellini
  2012-06-26 10:29   ` [PATCH V2 26/40] arm: use interrupt safe spin locks in vgic_vcpu_inject_irq Ian Campbell
                     ` (14 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This tracks SPIs in struct arch_domain and PPIs+SGIs in struct arch_vcpu which
seems more logical.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/vgic.c          |   12 +++++++-----
 xen/include/asm-arm/domain.h |   10 ++++++++++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 629a0da..af3523f 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -82,9 +82,8 @@ int domain_vgic_init(struct domain *d)
     d->arch.vgic.shared_irqs =
         xmalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
     d->arch.vgic.pending_irqs =
-        xmalloc_array(struct pending_irq,
-                d->arch.vgic.nr_lines + (32 * d->max_vcpus));
-    for (i=0; i<d->arch.vgic.nr_lines + (32 * d->max_vcpus); i++)
+        xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
+    for (i=0; i<d->arch.vgic.nr_lines; i++)
         INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
     for (i=0; i<DOMAIN_NR_RANKS(d); i++)
         spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
@@ -98,6 +97,10 @@ int vcpu_vgic_init(struct vcpu *v)
 
     spin_lock_init(&v->arch.vgic.private_irqs.lock);
 
+    memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
+    for (i = 0; i < 32; i++)
+        INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
+
     /* For SGI and PPI the target is always this CPU */
     for ( i = 0 ; i < 8 ; i++ )
         v->arch.vgic.private_irqs.itargets[i] =
@@ -535,8 +538,7 @@ struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
     /* Pending irqs allocation strategy: the first vgic.nr_lines irqs
      * are used for SPIs; the rests are used for per cpu irqs */
     if ( irq < 32 )
-        n = &v->domain->arch.vgic.pending_irqs[irq + (v->vcpu_id * 32)
-            + v->domain->arch.vgic.nr_lines];
+        n = &v->arch.vgic.pending_irqs[irq];
     else
         n = &v->domain->arch.vgic.pending_irqs[irq - 32];
     return n;
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 620b26e..32deb52 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -46,6 +46,10 @@ struct arch_domain
         int ctlr;
         int nr_lines;
         struct vgic_irq_rank *shared_irqs;
+        /*
+         * SPIs are domain global, SGIs and PPIs are per-VCPU and stored in
+         * struct arch_vcpu.
+         */
         struct pending_irq *pending_irqs;
     } vgic;
 
@@ -114,7 +118,13 @@ struct arch_vcpu
     uint32_t gic_lr[64];
 
     struct {
+        /*
+         * SGIs and PPIs are per-VCPU, SPIs are domain global and in
+         * struct arch_domain.
+         */
+        struct pending_irq pending_irqs[32];
         struct vgic_irq_rank private_irqs;
+
         /* This list is ordered by IRQ priority and it is used to keep
          * track of the IRQs that the VGIC injected into the guest.
          * Depending on the availability of LR registers, the IRQs might
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 26/40] arm: use interrupt safe spin locks in vgic_vcpu_inject_irq
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (23 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 25/40] arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU) Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 13:06     ` Stefano Stabellini
  2012-06-26 10:29   ` [PATCH V2 27/40] arm: map GICV in all domains, not just dom0 Ian Campbell
                     ` (13 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This function can be called in both interrupt and regular context.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/vgic.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index af3523f..91d6166 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -550,6 +550,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
     uint8_t priority;
     struct vgic_irq_rank *rank = vgic_irq_rank(v, 8, idx);
     struct pending_irq *iter, *n = irq_to_pending(v, irq);
+    unsigned long flags;
 
     /* irq still pending */
     if (!list_empty(&n->inflight))
@@ -566,7 +567,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
 
     gic_set_guest_irq(irq, GICH_LR_PENDING, priority);
 
-    spin_lock(&v->arch.vgic.lock);
+    spin_lock_irqsave(&v->arch.vgic.lock, flags);
     list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
     {
         if ( iter->priority > priority )
@@ -577,7 +578,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
         }
     }
     list_add_tail(&n->inflight, &v->arch.vgic.inflight_irqs);
-    spin_unlock(&v->arch.vgic.lock);
+    spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
     /* we have a new higher priority irq, inject it into the guest */
 }
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 27/40] arm: map GICV in all domains, not just dom0.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (24 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 26/40] arm: use interrupt safe spin locks in vgic_vcpu_inject_irq Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 28/40] arm: enable data-cache at the same time as enabling the MMU, not before Ian Campbell
                     ` (12 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This requires that we allocate all p2m pages from domheap without a particular
dom because max pages is not setup yet so there is no allocation available to
us.

At some point we should create a separate p2m allocation (similar to x86's shadow allocation) and use that.

Also we seem to have been calling p2m_alloc_table twice for dom0.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen/arch/arm/domain.c       |   10 +++++++---
 xen/arch/arm/domain_build.c |    5 -----
 xen/arch/arm/gic.c          |    7 ++-----
 xen/arch/arm/gic.h          |    2 +-
 xen/arch/arm/p2m.c          |    3 ++-
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index d11be78..a7b7d4a 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -323,10 +323,13 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
 
         if ( (rc = p2m_alloc_table(d)) != 0 )
             goto fail;
-    }
 
-    if ( (rc = domain_vgic_init(d)) != 0 )
-        goto fail;
+        if ( (rc = gicv_setup(d)) != 0 )
+            goto fail;
+
+        if ( (rc = domain_vgic_init(d)) != 0 )
+            goto fail;
+    }
 
     /* Domain 0 gets a real UART not an emulated one */
     if ( d->domain_id && (rc = domain_uart0_init(d)) != 0 )
@@ -334,6 +337,7 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
 
     rc = 0;
 fail:
+    /*XXX unwind allocations etc */
     return rc;
 }
 
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 72e775c..1b19e54 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -270,9 +270,6 @@ int construct_dom0(struct domain *d)
 
     d->max_pages = ~0U;
 
-    if ( (rc = p2m_alloc_table(d)) != 0 )
-        return rc;
-
     rc = prepare_dtb(d, &kinfo);
     if ( rc < 0 )
         return rc;
@@ -288,8 +285,6 @@ int construct_dom0(struct domain *d)
     printk("Map VGIC MMIO regions 1:1 in the P2M %#llx->%#llx\n", 0x2C008000ULL, 0x2DFFFFFFULL);
     map_mmio_regions(d, 0x2C008000, 0x2DFFFFFF, 0x2C008000);
 
-    gicv_setup(d);
-
     printk("Routing peripheral interrupts to guest\n");
     /* TODO Get from device tree */
     gic_route_irq_to_guest(d, 34, "timer0");
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 339c327..47995b4 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -541,14 +541,11 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
     do_IRQ(regs, irq, is_fiq);
 }
 
-void gicv_setup(struct domain *d)
+int gicv_setup(struct domain *d)
 {
     /* map the gic virtual cpu interface in the gic cpu interface region of
      * the guest */
-    printk("mapping GICC at %#"PRIx32" to %#"PRIx32"\n",
-           GIC_BASE_ADDRESS + GIC_CR_OFFSET,
-           GIC_BASE_ADDRESS + GIC_VR_OFFSET);
-    map_mmio_regions(d, GIC_BASE_ADDRESS + GIC_CR_OFFSET,
+    return map_mmio_regions(d, GIC_BASE_ADDRESS + GIC_CR_OFFSET,
                         GIC_BASE_ADDRESS + GIC_CR_OFFSET + (2 * PAGE_SIZE) - 1,
                         GIC_BASE_ADDRESS + GIC_VR_OFFSET);
 }
diff --git a/xen/arch/arm/gic.h b/xen/arch/arm/gic.h
index ac9cf3a..018d820 100644
--- a/xen/arch/arm/gic.h
+++ b/xen/arch/arm/gic.h
@@ -148,7 +148,7 @@ extern void gic_init_secondary_cpu(void);
 /* Take down a CPU's per-CPU GIC interface */
 extern void gic_disable_cpu(void);
 /* setup the gic virtual interface for a guest */
-extern void gicv_setup(struct domain *d);
+extern int gicv_setup(struct domain *d);
 
 /* Context switch */
 extern void gic_save_state(struct vcpu *v);
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 5f20246..67bfeba 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -4,6 +4,7 @@
 #include <xen/errno.h>
 #include <xen/domain_page.h>
 #include <asm/flushtlb.h>
+#include "gic.h"
 
 void dump_p2m_lookup(struct domain *d, paddr_t addr)
 {
@@ -102,7 +103,7 @@ static int p2m_create_table(struct domain *d,
 
     BUG_ON(entry->p2m.valid);
 
-    page = alloc_domheap_page(d, 0);
+    page = alloc_domheap_page(NULL, 0);
     if ( page == NULL )
         return -ENOMEM;
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 28/40] arm: enable data-cache at the same time as enabling the MMU, not before
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (25 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 27/40] arm: map GICV in all domains, not just dom0 Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 11:02     ` Tim Deegan
  2012-06-26 10:29   ` [PATCH V2 29/40] arm: Upgrade guest barriers to Outer-Shareable. Enable Protected Table Walk Ian Campbell
                     ` (11 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

With enough warnings enabled the model seemed to be complaining that pages
cached before paging was enabled had been mapped with to inconsistent sets of
attributes. I'm not convinced that isn't a model issue, nor am I convinced
this has really fixed anything, but it seems sensible enough.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/head.S |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/head.S b/xen/arch/arm/head.S
index 9a7714a..cdbe011 100644
--- a/xen/arch/arm/head.S
+++ b/xen/arch/arm/head.S
@@ -148,10 +148,11 @@ hyp:
 	 * Exceptions in LE ARM,
 	 * Low-latency IRQs disabled,
 	 * Write-implies-XN disabled (for now),
-	 * I-cache and d-cache enabled,
+	 * D-cache disabled (for now),
+	 * I-cache enabled,
 	 * Alignment checking enabled,
 	 * MMU translation disabled (for now). */
-	ldr   r0, =(HSCTLR_BASE|SCTLR_A|SCTLR_C)
+	ldr   r0, =(HSCTLR_BASE|SCTLR_A)
 	mcr   CP32(r0, HSCTLR)
 
 	/* Write Xen's PT's paddr into the HTTBR */
@@ -210,7 +211,7 @@ pt_ready:
 
 	ldr   r1, =paging            /* Explicit vaddr, not RIP-relative */
 	mrc   CP32(r0, HSCTLR)
-	orr   r0, r0, #0x1           /* Add in the MMU enable bit */
+	orr   r0, r0, #(SCTLR_M|SCTLR_C) /* Enable MMU and D-cache */
 	dsb                          /* Flush PTE writes and finish reads */
 	mcr   CP32(r0, HSCTLR)       /* now paging is enabled */
 	isb                          /* Now, flush the icache */
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 29/40] arm: Upgrade guest barriers to Outer-Shareable. Enable Protected Table Walk.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (26 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 28/40] arm: enable data-cache at the same time as enabling the MMU, not before Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 30/40] arm: gic.lock can be taken in interrupt context, so lock appropriately Ian Campbell
                     ` (10 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Upgrading barriers is conservative and may not be necessary.

Protected Table Walk traps stage 1 page tables which refer to device memory
(per stage 2) using a non-device mapping. This generally indicates a guest
error but trapping it as a fault for now helps us know if something odd is
going on.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/domain_build.c     |    2 +-
 xen/include/asm-arm/processor.h |    4 ++++
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 1b19e54..a9e7f43 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -333,7 +333,7 @@ int construct_dom0(struct domain *d)
 
     WRITE_CP32(SCTLR_BASE, SCTLR);
 
-    WRITE_CP32(HCR_AMO|HCR_IMO|HCR_VM, HCR);
+    WRITE_CP32(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM, HCR);
     isb();
 
     local_abort_enable();
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 81924a4..9b3c9dd 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -76,6 +76,10 @@
 #define HCR_TWI         (1<<13)
 #define HCR_DC          (1<<12)
 #define HCR_BSU_MASK    (3<<10)
+#define HCR_BSU_NONE     (0<<10)
+#define HCR_BSU_INNER    (1<<10)
+#define HCR_BSU_OUTER    (2<<10)
+#define HCR_BSU_FULL     (3<<10)
 #define HCR_FB          (1<<9)
 #define HCR_VA          (1<<8)
 #define HCR_VI          (1<<7)
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 30/40] arm: gic.lock can be taken in interrupt context, so lock appropriately.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (27 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 29/40] arm: Upgrade guest barriers to Outer-Shareable. Enable Protected Table Walk Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 31/40] arm: context switch virtual timer registers Ian Campbell
                     ` (9 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

In particular it is taken by gic_set_guest_irq which is called by
vgic_vcpu_inject_irq

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/gic.c |   20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 47995b4..1baccba 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -329,19 +329,19 @@ int __init gic_init(void)
 /* Set up the per-CPU parts of the GIC for a secondary CPU */
 void __cpuinit gic_init_secondary_cpu(void)
 {
-    spin_lock(&gic.lock);
+    spin_lock_irq(&gic.lock);
     gic_cpu_init();
     gic_hyp_init();
-    spin_unlock(&gic.lock);
+    spin_unlock_irq(&gic.lock);
 }
 
 /* Shut down the per-CPU GIC interface */
 void gic_disable_cpu(void)
 {
-    spin_lock(&gic.lock);
+    spin_lock_irq(&gic.lock);
     gic_cpu_disable();
     gic_hyp_disable();
-    spin_unlock(&gic.lock);
+    spin_unlock_irq(&gic.lock);
 }
 
 void gic_route_irqs(void)
@@ -439,7 +439,7 @@ void gic_set_guest_irq(unsigned int virtual_irq,
 
     events_maintenance(current);
 
-    spin_lock(&gic.lock);
+    spin_lock_irq(&gic.lock);
 
     if ( list_empty(&gic.lr_pending) )
     {
@@ -465,7 +465,7 @@ void gic_set_guest_irq(unsigned int virtual_irq,
     list_add_tail(&n->lr_queue, &gic.lr_pending);
 
 out:
-    spin_unlock(&gic.lock);
+    spin_unlock_irq(&gic.lock);
     return;
 }
 
@@ -557,7 +557,7 @@ static void events_maintenance(struct vcpu *v)
             (unsigned long *)&vcpu_info(v, evtchn_upcall_pending));
 
     if (!already_pending && gic.event_mask != 0) {
-        spin_lock(&gic.lock);
+        spin_lock_irq(&gic.lock);
         while ((i = find_next_bit((const long unsigned int *) &gic.event_mask,
                         sizeof(uint64_t), i)) < sizeof(uint64_t)) {
 
@@ -567,7 +567,7 @@ static void events_maintenance(struct vcpu *v)
 
             i++;
         }
-        spin_unlock(&gic.lock);
+        spin_unlock_irq(&gic.lock);
     }
 }
 
@@ -583,7 +583,7 @@ static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *r
                               sizeof(eisr), i)) < sizeof(eisr)) {
         struct pending_irq *p;
 
-        spin_lock(&gic.lock);
+        spin_lock_irq(&gic.lock);
         lr = GICH[GICH_LR + i];
         virq = lr & GICH_LR_VIRTUAL_MASK;
         GICH[GICH_LR + i] = 0;
@@ -599,7 +599,7 @@ static void maintenance_interrupt(int irq, void *dev_id, struct cpu_user_regs *r
         } else {
             gic_inject_irq_stop();
         }
-        spin_unlock(&gic.lock);
+        spin_unlock_irq(&gic.lock);
 
         spin_lock(&current->arch.vgic.lock);
         p = irq_to_pending(current, virq);
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 31/40] arm: context switch virtual timer registers
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (28 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 30/40] arm: gic.lock can be taken in interrupt context, so lock appropriately Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 32/40] arm: the hyp timer seems to work in newer model versions, default to using it Ian Campbell
                     ` (8 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/domain.c        |   10 ++++++++++
 xen/include/asm-arm/cpregs.h |    3 +++
 xen/include/asm-arm/domain.h |    5 +++++
 3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index a7b7d4a..2b5515d 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -49,6 +49,11 @@ static void ctxt_switch_from(struct vcpu *p)
     p->arch.tpidruro = READ_CP32(TPIDRURO);
     p->arch.tpidrprw = READ_CP32(TPIDRPRW);
 
+    /* Arch timer */
+    p->arch.cntvoff = READ_CP64(CNTVOFF);
+    p->arch.cntv_cval = READ_CP64(CNTV_CVAL);
+    p->arch.cntv_ctl = READ_CP32(CNTV_CTL);
+
     /* XXX only save these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
     p->arch.teecr = READ_CP32(TEECR);
     p->arch.teehbr = READ_CP32(TEEHBR);
@@ -128,6 +133,11 @@ static void ctxt_switch_to(struct vcpu *n)
     WRITE_CP32(n->arch.mair1, MAIR1);
     isb();
 
+    /* Arch timer */
+    WRITE_CP64(n->arch.cntvoff, CNTVOFF);
+    WRITE_CP64(n->arch.cntv_cval, CNTV_CVAL);
+    WRITE_CP32(n->arch.cntv_ctl, CNTV_CTL);
+
     /* Control Registers */
     WRITE_CP32(n->arch.actlr, ACTLR);
     WRITE_CP32(n->arch.sctlr, SCTLR);
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index bd46942..34a9e93 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -238,10 +238,13 @@
 #define CNTP_CTL        p15,0,c14,c2,1  /* Physical Timer control register */
 #define CNTVCT          p15,1,c14       /* Time counter value + offset */
 #define CNTP_CVAL       p15,2,c14       /* Physical Timer comparator */
+#define CNTV_CVAL       p15,3,c14       /* Virt. Timer comparator */
 #define CNTVOFF         p15,4,c14       /* Time counter offset */
 #define CNTHCTL         p15,4,c14,c1,0  /* Time counter hyp. control */
 #define CNTHP_TVAL      p15,4,c14,c2,0  /* Hyp. Timer value */
 #define CNTHP_CTL       p15,4,c14,c2,1  /* Hyp. Timer control register */
+#define CNTV_TVAL       p15,0,c14,c3,0  /* Virt. Timer value */
+#define CNTV_CTL        p15,0,c14,c3,1  /* Virt. TImer control register */
 #define CNTHP_CVAL      p15,6,c14       /* Hyp. Timer comparator */
 
 /* CP15 CR15: Implementation Defined Registers */
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 32deb52..230ea8c 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -111,6 +111,11 @@ struct arch_vcpu
     uint32_t teecr, teehbr;
     uint32_t joscr, jmcr;
 
+    /* Arch timers */
+    uint64_t cntvoff;
+    uint64_t cntv_cval;
+    uint32_t cntv_ctl;
+
     /* CP 15 */
     uint32_t csselr;
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 32/40] arm: the hyp timer seems to work in newer model versions, default to using it.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (29 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 31/40] arm: context switch virtual timer registers Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 33/40] arm: unwind allocations etc on arch_domain_create_failure Ian Campbell
                     ` (7 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/time.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index 437dc71..1587fa2 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -27,8 +27,12 @@
 #include <xen/time.h>
 #include <asm/system.h>
 
-/* Unfortunately the hypervisor timer interrupt appears to be buggy */
-#define USE_HYP_TIMER 0
+/*
+ * Unfortunately the hypervisor timer interrupt appears to be buggy in
+ * some versions of the model. Disable this to use the physical timer
+ * instead.
+ */
+#define USE_HYP_TIMER 1
 
 /* For fine-grained timekeeping, we use the ARM "Generic Timer", a
  * register-mapped time source in the SoC. */
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 33/40] arm: unwind allocations etc on arch_domain_create_failure
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (30 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 32/40] arm: the hyp timer seems to work in newer model versions, default to using it Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-28 11:05     ` Tim Deegan
  2012-06-26 10:29   ` [PATCH V2 34/40] HACK: arm: initial XENMAPSPACE_gmfn_foreign Ian Campbell
                     ` (6 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

This involves adding the necessary teardown/free functions for some modules.

Don't initialise full arch domain state for the idle domain, it's not needed.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/domain.c     |   42 +++++++++++++++++++++++++-----------------
 xen/arch/arm/gic.h        |    3 +++
 xen/arch/arm/p2m.c        |   15 +++++++++++++++
 xen/arch/arm/vgic.c       |    6 ++++++
 xen/arch/arm/vpl011.c     |    5 +++++
 xen/arch/arm/vpl011.h     |    1 +
 xen/include/asm-arm/p2m.h |    3 +++
 7 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 2b5515d..ac6a30d 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -317,37 +317,45 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
 {
     int rc;
 
+    /* Idle domains do not need this setup */
+    if ( is_idle_domain(d) )
+        return 0;
+
     rc = -ENOMEM;
     if ( (rc = p2m_init(d)) != 0 )
         goto fail;
 
-    if ( !is_idle_domain(d) )
-    {
-        rc = -ENOMEM;
-        if ( (d->shared_info = alloc_xenheap_pages(0, 0)) == NULL )
-            goto fail;
+    if ( (d->shared_info = alloc_xenheap_pages(0, 0)) == NULL )
+        goto fail;
 
-        clear_page(d->shared_info);
-        share_xen_page_with_guest(
-                virt_to_page(d->shared_info), d, XENSHARE_writable);
+    clear_page(d->shared_info);
+    share_xen_page_with_guest(
+        virt_to_page(d->shared_info), d, XENSHARE_writable);
 
-        if ( (rc = p2m_alloc_table(d)) != 0 )
-            goto fail;
+    if ( (rc = p2m_alloc_table(d)) != 0 )
+        goto fail;
 
-        if ( (rc = gicv_setup(d)) != 0 )
-            goto fail;
+    if ( (rc = gicv_setup(d)) != 0 )
+        goto fail;
 
-        if ( (rc = domain_vgic_init(d)) != 0 )
-            goto fail;
-    }
+    if ( (rc = domain_vgic_init(d)) != 0 )
+        goto fail;
 
     /* Domain 0 gets a real UART not an emulated one */
     if ( d->domain_id && (rc = domain_uart0_init(d)) != 0 )
         goto fail;
 
-    rc = 0;
+    return 0;
+
 fail:
-    /*XXX unwind allocations etc */
+    d->is_dying = DOMDYING_dead;
+    free_xenheap_page(d->shared_info);
+
+    p2m_teardown(d);
+
+    domain_vgic_free(d);
+    domain_uart0_free(d);
+
     return rc;
 }
 
diff --git a/xen/arch/arm/gic.h b/xen/arch/arm/gic.h
index 018d820..e36d6ad 100644
--- a/xen/arch/arm/gic.h
+++ b/xen/arch/arm/gic.h
@@ -125,7 +125,10 @@
 #define VGIC_IRQ_EVTCHN_CALLBACK 31
 
 extern int domain_vgic_init(struct domain *d);
+extern void domain_vgic_free(struct domain *d);
+
 extern int vcpu_vgic_init(struct vcpu *v);
+
 extern void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq,int virtual);
 extern struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq);
 
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 67bfeba..073216b 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -288,6 +288,21 @@ int p2m_alloc_table(struct domain *d)
     return 0;
 }
 
+void p2m_teardown(struct domain *d)
+{
+    struct p2m_domain *p2m = &d->arch.p2m;
+    struct page_info *pg;
+
+    spin_lock(&p2m->lock);
+
+    while ( (pg = page_list_remove_head(&p2m->pages)) )
+        free_domheap_page(pg);
+
+    p2m->first_level = NULL;
+
+    spin_unlock(&p2m->lock);
+}
+
 int p2m_init(struct domain *d)
 {
     struct p2m_domain *p2m = &d->arch.p2m;
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 91d6166..06bbd0c 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -90,6 +90,12 @@ int domain_vgic_init(struct domain *d)
     return 0;
 }
 
+void domain_vgic_free(struct domain *d)
+{
+    xfree(d->arch.vgic.shared_irqs);
+    xfree(d->arch.vgic.pending_irqs);
+}
+
 int vcpu_vgic_init(struct vcpu *v)
 {
     int i;
diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
index 5dc8b28..1522667 100644
--- a/xen/arch/arm/vpl011.c
+++ b/xen/arch/arm/vpl011.c
@@ -56,6 +56,11 @@ int domain_uart0_init(struct domain *d)
 
 }
 
+void domain_uart0_free(struct domain *d)
+{
+    xfree(d->arch.uart0.buf);
+}
+
 static void uart0_print_char(char c)
 {
     struct vpl011 *uart = &current->domain->arch.uart0;
diff --git a/xen/arch/arm/vpl011.h b/xen/arch/arm/vpl011.h
index 952d812..eabd99d 100644
--- a/xen/arch/arm/vpl011.h
+++ b/xen/arch/arm/vpl011.h
@@ -21,6 +21,7 @@
 #define __ARCH_ARM_VPL011_H__
 
 extern int domain_uart0_init(struct domain *d);
+extern void domain_uart0_free(struct domain *d);
 
 #endif
 
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 666bb88..14e71bf 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -23,6 +23,9 @@ struct p2m_domain {
 /* Init the datastructures for later use by the p2m code */
 int p2m_init(struct domain *d);
 
+/* Return all the p2m resources to Xen. */
+void p2m_teardown(struct domain *d);
+
 /* Allocate a new p2m table for a domain.
  *
  * Returns 0 for success or -errno.
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 34/40] HACK: arm: initial XENMAPSPACE_gmfn_foreign
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (31 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 33/40] arm: unwind allocations etc on arch_domain_create_failure Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:29   ` [PATCH V2 35/40] arm: move PSR flag definitions into interface, for tools use Ian Campbell
                     ` (5 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Should use same interface as hybrid x86.
---
 xen/arch/arm/mm.c             |   32 ++++++++++++++++++++++++++------
 xen/arch/x86/mm.c             |    2 ++
 xen/include/public/arch-arm.h |    1 +
 xen/include/public/memory.h   |   12 +++++++-----
 4 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 40ac176..d369ee3 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -470,12 +470,32 @@ static int xenmem_add_to_physmap_once(
 
     switch ( xatp->space )
     {
-        case XENMAPSPACE_shared_info:
-            if ( xatp->idx == 0 )
-                mfn = virt_to_mfn(d->shared_info);
-            break;
-        default:
-            return -ENOSYS;
+    case XENMAPSPACE_shared_info:
+        if ( xatp->idx == 0 )
+            mfn = virt_to_mfn(d->shared_info);
+        break;
+    case XENMAPSPACE_gmfn_foreign:
+    {
+        paddr_t maddr;
+        struct domain *od;
+
+        rc = rcu_lock_target_domain_by_id(xatp->foreign_domid, &od);
+        if ( rc < 0 )
+            return rc;
+        maddr = p2m_lookup(od, xatp->idx << PAGE_SHIFT);
+        if ( maddr == INVALID_PADDR )
+        {
+            printk("bad p2m lookup\n");
+            dump_p2m_lookup(od, xatp->idx << PAGE_SHIFT);
+            rcu_unlock_domain(od);
+            return -EINVAL;
+        }
+        mfn = maddr >> PAGE_SHIFT;
+        rcu_unlock_domain(od);
+        break;
+    }
+    default:
+        return -ENOSYS;
     }
 
     domain_lock(d);
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index c543f03..8190fa0 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4573,6 +4573,8 @@ static int xenmem_add_to_physmap_once(
             mfn = idx;
             page = mfn_to_page(mfn);
             break;
+        case XENMAPSPACE_gmfn_foreign:
+            return -ENOSYS;
         }
         default:
             break;
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index e915cbf..b52bfc7 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -121,6 +121,7 @@ typedef uint64_t xen_pfn_t;
 #define XEN_LEGACY_MAX_VCPUS 1
 
 typedef uint32_t xen_ulong_t;
+#define PRI_xen_ulong PRIx32
 
 struct vcpu_guest_context {
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 86d02c8..b2adfbe 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -212,11 +212,13 @@ struct xen_add_to_physmap {
     uint16_t    size;
 
     /* Source mapping space. */
-#define XENMAPSPACE_shared_info 0 /* shared info page */
-#define XENMAPSPACE_grant_table 1 /* grant table page */
-#define XENMAPSPACE_gmfn        2 /* GMFN */
-#define XENMAPSPACE_gmfn_range  3 /* GMFN range */
-    unsigned int space;
+#define XENMAPSPACE_shared_info  0 /* shared info page */
+#define XENMAPSPACE_grant_table  1 /* grant table page */
+#define XENMAPSPACE_gmfn         2 /* GMFN */
+#define XENMAPSPACE_gmfn_range   3 /* GMFN range */
+#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another guest */
+    uint16_t space;
+    domid_t foreign_domid; /* IFF gmfn_foreign */
 
 #define XENMAPIDX_grant_table_status 0x80000000
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 35/40] arm: move PSR flag definitions into interface, for tools use.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (32 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 34/40] HACK: arm: initial XENMAPSPACE_gmfn_foreign Ian Campbell
@ 2012-06-26 10:29   ` Ian Campbell
  2012-06-26 10:30   ` [PATCH V2 36/40] libxc: add ARM support to xc_dom (PV domain building) Ian Campbell
                     ` (4 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:29 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/arch/arm/entry.S            |    1 +
 xen/include/asm-arm/page.h      |    2 ++
 xen/include/asm-arm/processor.h |   21 ---------------------
 xen/include/asm-arm/system.h    |    2 +-
 xen/include/public/arch-arm.h   |   23 ++++++++++++++++++++++-
 5 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/xen/arch/arm/entry.S b/xen/arch/arm/entry.S
index 5bc3906..2ff32a1 100644
--- a/xen/arch/arm/entry.S
+++ b/xen/arch/arm/entry.S
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <asm/asm_defns.h>
+#include <public/xen.h>
 
 #define SAVE_ONE_BANKED(reg)	mrs r11, reg; str r11, [sp, #UREGS_##reg]
 #define RESTORE_ONE_BANKED(reg)	ldr r11, [sp, #UREGS_##reg]; msr reg, r11
diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index 2b6c1780..f3e4d1a 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -2,6 +2,8 @@
 #define __ARM_PAGE_H__
 
 #include <xen/config.h>
+#include <public/xen.h>
+#include <asm/processor.h>
 
 #define PADDR_BITS              40
 #define PADDR_MASK              ((1ULL << PADDR_BITS)-1)
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 9b3c9dd..3849b23 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -3,27 +3,6 @@
 
 #include <asm/cpregs.h>
 
-/* PSR bits (CPSR, SPSR)*/
-
-/* 0-4: Mode */
-#define PSR_MODE_MASK 0x1f
-#define PSR_MODE_USR 0x10
-#define PSR_MODE_FIQ 0x11
-#define PSR_MODE_IRQ 0x12
-#define PSR_MODE_SVC 0x13
-#define PSR_MODE_MON 0x16
-#define PSR_MODE_ABT 0x17
-#define PSR_MODE_HYP 0x1a
-#define PSR_MODE_UND 0x1b
-#define PSR_MODE_SYS 0x1f
-
-#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
-#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
-#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
-#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
-#define PSR_BIG_ENDIAN  (1<<9)        /* Big Endian Mode */
-#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
-
 /* TTBCR Translation Table Base Control Register */
 #define TTBCR_EAE    0x80000000
 #define TTBCR_N_MASK 0x07
diff --git a/xen/include/asm-arm/system.h b/xen/include/asm-arm/system.h
index 7963ea5..216ef1f 100644
--- a/xen/include/asm-arm/system.h
+++ b/xen/include/asm-arm/system.h
@@ -3,7 +3,7 @@
 #define __ASM_SYSTEM_H
 
 #include <xen/lib.h>
-#include <asm/processor.h>
+#include <public/arch-arm.h>
 
 #define nop() \
     asm volatile ( "nop" )
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index b52bfc7..7ebe966 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -139,7 +139,28 @@ struct arch_shared_info { };
 typedef struct arch_shared_info arch_shared_info_t;
 typedef uint64_t xen_callback_t;
 
-#endif
+#endif /* ifndef __ASSEMBLY __ */
+
+/* PSR bits (CPSR, SPSR)*/
+
+/* 0-4: Mode */
+#define PSR_MODE_MASK 0x1f
+#define PSR_MODE_USR 0x10
+#define PSR_MODE_FIQ 0x11
+#define PSR_MODE_IRQ 0x12
+#define PSR_MODE_SVC 0x13
+#define PSR_MODE_MON 0x16
+#define PSR_MODE_ABT 0x17
+#define PSR_MODE_HYP 0x1a
+#define PSR_MODE_UND 0x1b
+#define PSR_MODE_SYS 0x1f
+
+#define PSR_THUMB       (1<<5)        /* Thumb Mode enable */
+#define PSR_FIQ_MASK    (1<<6)        /* Fast Interrupt mask */
+#define PSR_IRQ_MASK    (1<<7)        /* Interrupt mask */
+#define PSR_ABT_MASK    (1<<8)        /* Asynchronous Abort mask */
+#define PSR_BIG_ENDIAN  (1<<9)        /* Big Endian Mode */
+#define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
 
 #endif /*  __XEN_PUBLIC_ARCH_ARM_H__ */
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 36/40] libxc: add ARM support to xc_dom (PV domain building)
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (33 preceding siblings ...)
  2012-06-26 10:29   ` [PATCH V2 35/40] arm: move PSR flag definitions into interface, for tools use Ian Campbell
@ 2012-06-26 10:30   ` Ian Campbell
  2012-06-26 10:30   ` [PATCH V2 37/40] arm: implement VGCF_online Ian Campbell
                     ` (3 subsequent siblings)
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:30 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Includes ARM zImage support.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxc/Makefile                 |    1 +
 tools/libxc/xc_dom.h                 |    5 +-
 tools/libxc/xc_dom_arm.c             |  135 +++++++++++++++++++++++++++-
 tools/libxc/xc_dom_armzimageloader.c |  167 ++++++++++++++++++++++++++++++++++
 tools/libxc/xc_dom_core.c            |   12 ++-
 tools/libxc/xg_private.h             |    4 +
 6 files changed, 315 insertions(+), 9 deletions(-)
 create mode 100644 tools/libxc/xc_dom_armzimageloader.c

diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index ca38cbd..a01d457 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -59,6 +59,7 @@ GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
 GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
 GUEST_SRCS-y                 += xc_dom_elfloader.c
 GUEST_SRCS-$(CONFIG_X86)     += xc_dom_bzimageloader.c
+GUEST_SRCS-$(CONFIG_ARM)     += xc_dom_armzimageloader.c
 GUEST_SRCS-y                 += xc_dom_binloader.c
 GUEST_SRCS-y                 += xc_dom_compat_linux.c
 
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
index 2aef64a..4db8fad 100644
--- a/tools/libxc/xc_dom.h
+++ b/tools/libxc/xc_dom.h
@@ -93,6 +93,7 @@ struct xc_dom_image {
     void *p2m_guest;
 
     /* physical memory */
+    xen_pfn_t rambase_pfn;
     xen_pfn_t total_pages;
     struct xc_dom_phys *phys_pages;
     int realmodearea_log;
@@ -286,7 +287,7 @@ static inline xen_pfn_t xc_dom_p2m_host(struct xc_dom_image *dom, xen_pfn_t pfn)
 {
     if (dom->shadow_enabled)
         return pfn;
-    return dom->p2m_host[pfn];
+    return dom->p2m_host[pfn - dom->rambase_pfn];
 }
 
 static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom,
@@ -294,7 +295,7 @@ static inline xen_pfn_t xc_dom_p2m_guest(struct xc_dom_image *dom,
 {
     if (xc_dom_feature_translated(dom))
         return pfn;
-    return dom->p2m_host[pfn];
+    return dom->p2m_host[pfn - dom->rambase_pfn];
 }
 
 /* --- arch bits --------------------------------------------------- */
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index 122d0e8..9099cad 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -18,14 +18,138 @@
  * Copyright (c) 2011, Citrix Systems
  */
 #include <inttypes.h>
+
 #include <xen/xen.h>
+#include <xen/io/protocols.h>
+
 #include "xg_private.h"
 #include "xc_dom.h"
 
+/* ------------------------------------------------------------------------ */
+/*
+ * arm guests are hybrid and start off with paging disabled, therefore no
+ * pagetables and nothing to do here.
+ */
+static int count_pgtables_arm(struct xc_dom_image *dom)
+{
+    DOMPRINTF_CALLED(dom->xch);
+    return 0;
+}
+
+static int setup_pgtables_arm(struct xc_dom_image *dom)
+{
+    DOMPRINTF_CALLED(dom->xch);
+    return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int alloc_magic_pages(struct xc_dom_image *dom)
+{
+    DOMPRINTF_CALLED(dom->xch);
+    /* XXX
+     *   dom->p2m_guest
+     *   dom->start_info_pfn
+     *   dom->xenstore_pfn
+     *   dom->console_pfn
+     */
+    return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int start_info_arm(struct xc_dom_image *dom)
+{
+    DOMPRINTF_CALLED(dom->xch);
+    /* XXX */
+    return 0;
+}
+
+static int shared_info_arm(struct xc_dom_image *dom, void *ptr)
+{
+    DOMPRINTF_CALLED(dom->xch);
+    /* XXX */
+    return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int vcpu_arm(struct xc_dom_image *dom, void *ptr)
+{
+    vcpu_guest_context_t *ctxt = ptr;
+
+    DOMPRINTF_CALLED(dom->xch);
+
+    /* clear everything */
+    memset(ctxt, 0, sizeof(*ctxt));
+
+    ctxt->user_regs.pc = dom->parms.virt_entry;
+    ctxt->user_regs.r0 = 0; /* SBZ */
+    ctxt->user_regs.r1 = 2272; /* Machine NR: Versatile Express */
+
+    ctxt->user_regs.r2 = 0xffffffff; //devicetree_seg //dtb_paddr; //atags or dtb /* XXX using APPEND right now */
+    ctxt->user_regs.r3 = 0xdeadbeef;
+    ctxt->sctlr = /* #define SCTLR_BASE */0x00c50078;
+    ctxt->ttbr0 = 0;
+    ctxt->ttbr1 = 0;
+    ctxt->ttbcr = 0; /* Defined Reset Value */
+
+    ctxt->user_regs.cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
+
+    DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
+           ctxt->user_regs.cpsr, ctxt->user_regs.pc);
+
+    return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static struct xc_dom_arch xc_dom_32 = {
+    .guest_type = "xen-3.0-armv7l",
+    .native_protocol = XEN_IO_PROTO_ABI_ARM,
+    .page_shift = PAGE_SHIFT_ARM,
+    .sizeof_pfn = 8,
+    .alloc_magic_pages = alloc_magic_pages,
+    .count_pgtables = count_pgtables_arm,
+    .setup_pgtables = setup_pgtables_arm,
+    .start_info = start_info_arm,
+    .shared_info = shared_info_arm,
+    .vcpu = vcpu_arm,
+};
+
+static void __init register_arch_hooks(void)
+{
+    xc_dom_register_arch_hooks(&xc_dom_32);
+}
+
 int arch_setup_meminit(struct xc_dom_image *dom)
 {
-    errno = ENOSYS;
-    return -1;
+    int rc;
+    xen_pfn_t pfn, allocsz, i;
+
+    dom->shadow_enabled = 1;
+
+    dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
+
+    /* setup initial p2m */
+    for ( pfn = 0; pfn < dom->total_pages; pfn++ )
+        dom->p2m_host[pfn] = pfn + dom->rambase_pfn;
+
+    /* allocate guest memory */
+    for ( i = rc = allocsz = 0;
+          (i < dom->total_pages) && !rc;
+          i += allocsz )
+    {
+        allocsz = dom->total_pages - i;
+        if ( allocsz > 1024*1024 )
+            allocsz = 1024*1024;
+
+        rc = xc_domain_populate_physmap_exact(
+            dom->xch, dom->guest_domid, allocsz,
+            0, 0, &dom->p2m_host[i]);
+    }
+
+    return 0;
 }
 
 int arch_setup_bootearly(struct xc_dom_image *dom)
@@ -36,9 +160,14 @@ int arch_setup_bootearly(struct xc_dom_image *dom)
 
 int arch_setup_bootlate(struct xc_dom_image *dom)
 {
-    DOMPRINTF("%s: doing nothing", __FUNCTION__);
+    /* XXX
+     *   map shared info
+     *   map grant tables
+     *   setup shared info
+     */
     return 0;
 }
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_dom_armzimageloader.c b/tools/libxc/xc_dom_armzimageloader.c
new file mode 100644
index 0000000..220176d
--- /dev/null
+++ b/tools/libxc/xc_dom_armzimageloader.c
@@ -0,0 +1,167 @@
+/*
+ * Xen domain builder -- ARM zImage bits
+ *
+ * Parse and load ARM zImage kernel images.
+ *
+ * Copyright (C) 2012, Citrix Systems.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "xg_private.h"
+#include "xc_dom.h"
+
+#include <arpa/inet.h> /* XXX ntohl is not the right function... */
+
+#define ZIMAGE_MAGIC_OFFSET 0x24
+#define ZIMAGE_START_OFFSET 0x28
+#define ZIMAGE_END_OFFSET   0x2c
+
+#define ZIMAGE_MAGIC 0x016f2818
+
+struct minimal_dtb_header {
+    uint32_t magic;
+    uint32_t total_size;
+    /* There are other fields but we don't use them yet. */
+};
+
+#define DTB_MAGIC 0xd00dfeed
+
+static int xc_dom_probe_zimage_kernel(struct xc_dom_image *dom)
+{
+    uint32_t *zimage;
+    uint32_t end;
+
+    if ( dom->kernel_blob == NULL )
+    {
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: no kernel image loaded", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    if ( dom->kernel_size < 0x30 /*sizeof(struct setup_header)*/ )
+    {
+        xc_dom_printf(dom->xch, "%s: kernel image too small", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    zimage = (uint32_t *)dom->kernel_blob;
+    if ( zimage[ZIMAGE_MAGIC_OFFSET/4] != ZIMAGE_MAGIC )
+    {
+        xc_dom_printf(dom->xch, "%s: kernel is not a bzImage", __FUNCTION__);
+        return -EINVAL;
+    }
+
+    end = zimage[ZIMAGE_END_OFFSET/4];
+
+    /*
+     * Check for an appended DTB.
+     */
+    if ( end + sizeof(struct minimal_dtb_header) < dom->kernel_size ) {
+        struct minimal_dtb_header *dtb_hdr;
+        dtb_hdr = (struct minimal_dtb_header *)(dom->kernel_blob + end);
+        if (ntohl/*be32_to_cpu*/(dtb_hdr->magic) == DTB_MAGIC) {
+            xc_dom_printf(dom->xch, "%s: found an appended DTB", __FUNCTION__);
+            end += ntohl/*be32_to_cpu*/(dtb_hdr->total_size);
+        }
+    }
+
+    dom->kernel_size = end;
+
+    return 0;
+}
+
+static int xc_dom_parse_zimage_kernel(struct xc_dom_image *dom)
+{
+    uint32_t *zimage;
+    uint32_t start, entry_addr;
+    uint64_t v_start, v_end;
+    uint64_t rambase = 0x80000000; /* XXX */
+
+    DOMPRINTF_CALLED(dom->xch);
+
+    zimage = (uint32_t *)dom->kernel_blob;
+
+    dom->rambase_pfn = rambase >> XC_PAGE_SHIFT;
+
+    v_start = rambase + 0x8000; /* XXX */
+    v_end = v_start + dom->kernel_size;
+
+    start = zimage[ZIMAGE_START_OFFSET/4];
+
+    if (start == 0)
+        entry_addr = v_start;
+    else
+        entry_addr = start;
+
+    /* find kernel segment */
+    dom->kernel_seg.vstart = v_start;
+    dom->kernel_seg.vend   = v_end;
+
+    dom->parms.virt_entry = entry_addr;
+
+    dom->guest_type = "xen-3.0-armv7l";
+    DOMPRINTF("%s: %s: RAM starts at %"PRI_xen_pfn,
+              __FUNCTION__, dom->guest_type, dom->rambase_pfn);
+    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
+              __FUNCTION__, dom->guest_type,
+              dom->kernel_seg.vstart, dom->kernel_seg.vend);
+    return 0;
+}
+
+static int xc_dom_load_zimage_kernel(struct xc_dom_image *dom)
+{
+    void *dst;
+
+    DOMPRINTF_CALLED(dom->xch);
+
+    dst = xc_dom_seg_to_ptr(dom, &dom->kernel_seg);
+
+    DOMPRINTF("%s: kernel sed %#"PRIx64"-%#"PRIx64,
+              __func__, dom->kernel_seg.vstart, dom->kernel_seg.vend);
+    DOMPRINTF("%s: copy %zd bytes from blob %p to dst %p",
+              __func__, dom->kernel_size, dom->kernel_blob, dst);
+
+    memcpy(dst, dom->kernel_blob, dom->kernel_size);
+
+    return 0;
+}
+
+static struct xc_dom_loader zimage_loader = {
+    .name = "Linux zImage (ARM)",
+    .probe = xc_dom_probe_zimage_kernel,
+    .parser = xc_dom_parse_zimage_kernel,
+    .loader = xc_dom_load_zimage_kernel,
+};
+
+static void __init register_loader(void)
+{
+    xc_dom_register_loader(&zimage_loader);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index fea9de5..b0d48d5 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -307,15 +307,17 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t pfn,
                         xen_pfn_t count)
 {
     struct xc_dom_phys *phys;
+    xen_pfn_t offset;
     unsigned int page_shift = XC_DOM_PAGE_SHIFT(dom);
     char *mode = "unset";
 
-    if ( pfn > dom->total_pages ||    /* multiple checks to avoid overflows */
+    offset = pfn-dom->rambase_pfn;
+    if ( offset > dom->total_pages ||    /* multiple checks to avoid overflows */
          count > dom->total_pages ||
-         pfn > dom->total_pages - count )
+         offset > dom->total_pages - count )
     {
-        DOMPRINTF("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")",
-                  __FUNCTION__, pfn, dom->total_pages);
+        DOMPRINTF("%s: pfn %"PRI_xen_pfn" out of range (0x%" PRIpfn " > 0x%" PRIpfn ")",
+                  __FUNCTION__, pfn, offset, dom->total_pages);
         return NULL;
     }
 
@@ -599,6 +601,8 @@ struct xc_dom_image *xc_dom_allocate(xc_interface *xch,
     dom->parms.virt_hv_start_low = UNSET_ADDR;
     dom->parms.elf_paddr_offset = UNSET_ADDR;
 
+    dom->rambase_pfn = 0;
+
     dom->alloc_malloc += sizeof(*dom);
     return dom;
 
diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h
index a29fa26..a271942 100644
--- a/tools/libxc/xg_private.h
+++ b/tools/libxc/xg_private.h
@@ -148,6 +148,10 @@ typedef l4_pgentry_64_t l4_pgentry_t;
 #define l4_table_offset(_a) l4_table_offset_x86_64(_a)
 #endif
 
+#define PAGE_SHIFT_ARM          12
+#define PAGE_SIZE_ARM           (1UL << PAGE_SHIFT_ARM)
+#define PAGE_MASK_ARM           (~(PAGE_SIZE_ARM-1))
+
 #define PAGE_SHIFT_X86          12
 #define PAGE_SIZE_X86           (1UL << PAGE_SHIFT_X86)
 #define PAGE_MASK_X86           (~(PAGE_SIZE_X86-1))
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 37/40] arm: implement VGCF_online
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (34 preceding siblings ...)
  2012-06-26 10:30   ` [PATCH V2 36/40] libxc: add ARM support to xc_dom (PV domain building) Ian Campbell
@ 2012-06-26 10:30   ` Ian Campbell
  2012-06-28 11:06     ` Tim Deegan
  2012-06-26 10:30   ` [PATCH V2 38/40] arm: fix typo s/approprately/appropriately/g Ian Campbell
                     ` (2 subsequent siblings)
  38 siblings, 1 reply; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:30 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxc/xc_dom_arm.c      |    2 ++
 xen/arch/arm/domain.c         |    5 ++++-
 xen/include/public/arch-arm.h |    4 ++++
 3 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index 9099cad..bea409b 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -96,6 +96,8 @@ static int vcpu_arm(struct xc_dom_image *dom, void *ptr)
 
     ctxt->user_regs.cpsr = PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
 
+    ctxt->flags = VGCF_online;
+
     DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
            ctxt->user_regs.cpsr, ctxt->user_regs.pc);
 
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index ac6a30d..f61568b 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -416,7 +416,10 @@ int arch_set_info_guest(
     v->arch.ttbr1 = ctxt->ttbr1;
     v->arch.ttbcr = ctxt->ttbcr;
 
-    clear_bit(_VPF_down, &v->pause_flags);
+    if ( ctxt->flags & VGCF_online )
+        clear_bit(_VPF_down, &v->pause_flags);
+    else
+        set_bit(_VPF_down, &v->pause_flags);
 
     return 0;
 }
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index 7ebe966..6e0fe47 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -124,6 +124,10 @@ typedef uint32_t xen_ulong_t;
 #define PRI_xen_ulong PRIx32
 
 struct vcpu_guest_context {
+#define _VGCF_online                   0
+#define VGCF_online                    (1<<_VGCF_online)
+    uint32_t flags;                         /* VGCF_* */
+
     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
 
     uint32_t sctlr;
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 38/40] arm: fix typo s/approprately/appropriately/g
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (35 preceding siblings ...)
  2012-06-26 10:30   ` [PATCH V2 37/40] arm: implement VGCF_online Ian Campbell
@ 2012-06-26 10:30   ` Ian Campbell
  2012-06-26 10:30   ` [PATCH V2 39/40] HACK: add simple xcbuild Ian Campbell
  2012-06-26 10:30   ` [PATCH V2 40/40] HACK: arm: disable hypercall continuations Ian Campbell
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:30 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Tim Deegan <tim@xen.org>
---
 xen/include/asm-arm/page.h |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index f3e4d1a..9511c45 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -102,7 +102,7 @@ typedef struct {
     unsigned long af:1;         /* Access Flag */
     unsigned long ng:1;         /* Not-Global */
 
-    /* The base address must be approprately aligned for Block entries */
+    /* The base address must be appropriately aligned for Block entries */
     unsigned long base:28;      /* Base address of block or next table */
     unsigned long sbz:12;       /* Must be zero */
 
@@ -137,7 +137,7 @@ typedef struct {
     unsigned long af:1;         /* Access Flag */
     unsigned long sbz4:1;
 
-    /* The base address must be approprately aligned for Block entries */
+    /* The base address must be appropriately aligned for Block entries */
     unsigned long base:28;      /* Base address of block or next table */
     unsigned long sbz3:12;
 
@@ -162,7 +162,7 @@ typedef struct {
 
     unsigned long pad2:10;
 
-    /* The base address must be approprately aligned for Block entries */
+    /* The base address must be appropriately aligned for Block entries */
     unsigned long base:28;      /* Base address of block or next table */
 
     unsigned long pad1:24;
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 39/40] HACK: add simple xcbuild
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (36 preceding siblings ...)
  2012-06-26 10:30   ` [PATCH V2 38/40] arm: fix typo s/approprately/appropriately/g Ian Campbell
@ 2012-06-26 10:30   ` Ian Campbell
  2012-06-26 10:30   ` [PATCH V2 40/40] HACK: arm: disable hypercall continuations Ian Campbell
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:30 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Based on init-xenstore-domain.c.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/xcutils/Makefile  |    6 ++-
 tools/xcutils/xcbuild.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+), 1 deletions(-)
 create mode 100644 tools/xcutils/xcbuild.c

diff --git a/tools/xcutils/Makefile b/tools/xcutils/Makefile
index 6c502f1..dcd2c84 100644
--- a/tools/xcutils/Makefile
+++ b/tools/xcutils/Makefile
@@ -11,7 +11,7 @@
 XEN_ROOT	= $(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-PROGRAMS = xc_restore xc_save readnotes lsevtchn
+PROGRAMS = xc_restore xc_save readnotes lsevtchn xcbuild
 
 CFLAGS += -Werror
 
@@ -19,6 +19,7 @@ CFLAGS_xc_restore.o := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest)
 CFLAGS_xc_save.o    := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore)
 CFLAGS_readnotes.o  := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest)
 CFLAGS_lsevtchn.o   := $(CFLAGS_libxenctrl)
+CFLAGS_xcbuild.o    := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest)
 
 .PHONY: all
 all: build
@@ -32,6 +33,9 @@ xc_restore: xc_restore.o
 xc_save: xc_save.o
 	$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
 
+xcbuild: xcbuild.o
+	$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
+
 readnotes: readnotes.o
 	$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
 
diff --git a/tools/xcutils/xcbuild.c b/tools/xcutils/xcbuild.c
new file mode 100644
index 0000000..54f5c38
--- /dev/null
+++ b/tools/xcutils/xcbuild.c
@@ -0,0 +1,100 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <errno.h>
+
+#include <xenctrl.h>
+#include <xentoollog.h>
+#include <xc_dom.h>
+
+int main(int argc, char **argv)
+{
+	xentoollog_logger *logger;
+	xc_interface *xch;
+	int rv;
+	const char *image;
+	uint32_t domid;
+	xen_domain_handle_t handle;
+	int maxmem = 128; /* MB */
+	int memory_kb = 2*(maxmem + 1)*1024; /* bit of slack... */
+	struct xc_dom_image *dom;
+
+	image = (argc < 2) ? "guest.img" : argv[1];
+	printf("Image: %s\n", image);
+	printf("Memory: %dKB\n", memory_kb);
+
+	logger = (xentoollog_logger*)
+		xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0);
+	if ( logger == NULL )
+	{
+		perror("xtl_createlogger_stdiostream");
+		exit(1);
+	}
+
+	xch = xc_interface_open(logger, logger, 0);
+	if ( xch == NULL )
+	{
+		perror("xc_interface_open");
+		exit(1);
+	}
+
+	rv = xc_dom_loginit(xch);
+	if (rv) return rv;
+
+	//rv = xc_flask_context_to_sid(xch, argv[3], strlen(argv[3]), &ssid);
+	//if (rv) return rv;
+
+	rv = xc_domain_create(xch, 0 /* ssid */, handle, 0 /* flags */, &domid);
+	printf("xc_domain_create: %d (%d)\n", rv, errno);
+	if ( rv < 0 )
+	{
+		perror("xc_domain_create");
+		exit(1);
+	}
+
+	printf("building dom%d\n", domid);
+
+	rv = xc_domain_max_vcpus(xch, domid, 1);
+	if ( rv < 0)
+	{
+		perror("xc_domain_max_vcpus");
+		exit(1);
+	}
+
+	rv = xc_domain_setmaxmem(xch, domid, memory_kb);
+	if ( rv < 0)
+	{
+		perror("xc_domain_setmaxmem");
+		exit(1);
+	}
+
+	dom = xc_dom_allocate(xch, "", NULL);
+	rv = xc_dom_kernel_file(dom, image);
+	if (rv) return rv;
+	rv = xc_dom_boot_xen_init(dom, xch, domid);
+	if (rv) return rv;
+	rv = xc_dom_parse_image(dom);
+	if (rv) return rv;
+	rv = xc_dom_mem_init(dom, 2*maxmem);/* XXX */
+	if (rv) return rv;
+	rv = xc_dom_boot_mem_init(dom);
+	if (rv) return rv;
+	rv = xc_dom_build_image(dom);
+	if (rv) return rv;
+	rv = xc_dom_boot_image(dom);
+	if (rv) return rv;
+
+	xc_dom_release(dom);
+
+	rv = xc_domain_unpause(xch, domid);
+	if ( rv )
+	{
+		perror("xc_domain_unpause");
+		exit(1);
+	}
+
+	xc_interface_close(xch);
+
+	return 0;
+}
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH V2 40/40] HACK: arm: disable hypercall continuations.
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
                     ` (37 preceding siblings ...)
  2012-06-26 10:30   ` [PATCH V2 39/40] HACK: add simple xcbuild Ian Campbell
@ 2012-06-26 10:30   ` Ian Campbell
  38 siblings, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 10:30 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Campbell

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/include/xen/sched.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 53804c8..15fa6b4 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -577,10 +577,14 @@ unsigned long hypercall_create_continuation(
     unsigned int op, const char *format, ...);
 void hypercall_cancel_continuation(void);
 
+#ifdef CONFIG_ARM
+#define hypercall_preempt_check() (0)
+#else
 #define hypercall_preempt_check() (unlikely(    \
         softirq_pending(smp_processor_id()) |   \
         local_events_need_delivery()            \
     ))
+#endif
 
 extern struct domain *domain_list;
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang
  2012-06-26 10:29 [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang Ian Campbell
  2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
@ 2012-06-26 15:26 ` Ian Campbell
  1 sibling, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-26 15:26 UTC (permalink / raw)
  To: xen-devel

On Tue, 2012-06-26 at 11:29 +0100, Ian Campbell wrote:
> I intend to commit those patches which are acked and which do not depend
> on non-acked patches shortly.
> 
> A     01 arm: allocate top level p2m page for all non-idle domains
> A     02 arm: handy function to print a walk of a page table
> A     03 arm: correct and expand TLB flush CP15 registers
> A     04 arm: restore stack on return from trap.
> A     05 arm: enable interrupts while handling traps
> A     06 arm: hook up domctl and memory_op
> A     07 arm: allocate and setup a guest vcpu.
> A     08 arm: print domid as part of debug trap
> A     09 arm: remove unnecessarily verbose print from p2m_load_VTTBR
> A     10 arm: implement p2m lookup
> A     11 arm: remove hard tabs from init_idle_domain
> A     12 arm: stub out sync_vcpu_execstate
> A     13 arm: implement stub version of flush_tlb_mask.
> A     14 arm: do not set max_vcpus = 8 in arch_domain_create.
> A     15 arm: Add simple cpu_{sibling,core}_mask

I have applied these.

[...]
> A     18 arm: context switch a bunch of guest state.
> A     19 arm: dump a page table walk when va_to_par fails.
> A     20 arm: dump guest s1 walk on data abort which is not a stage 2 issue.

And these.

[...]
> A     22 arm: use correct attributes for mappings in copy_from_paddr()

This didn't apply without "16 arm: allow p2m to be created with specific
MATTR.", skipped.

> A     23 arm: map fixmaps non-executable.
> A     24 arm: fix locking in create_p2m_entries

Applied these too.

After this point there were increasingly more rejects due to missing
patches, so I stopped.

Ian.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 17/40] arm: implement vpl011 (UART) emulator.
  2012-06-26 10:29   ` [PATCH V2 17/40] arm: implement vpl011 (UART) emulator Ian Campbell
@ 2012-06-28 11:00     ` Tim Deegan
  0 siblings, 0 replies; 51+ messages in thread
From: Tim Deegan @ 2012-06-28 11:00 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

At 10:29 +0000 on 26 Jun (1340706581), Ian Campbell wrote:
> This is not interended to provide a full emulation, but rather just enough to
> satisfy the use made by Linux' boot time decompressor code (which is too early
> for DT etc)
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Tim Deegan <tim@xen.org>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 28/40] arm: enable data-cache at the same time as enabling the MMU, not before
  2012-06-26 10:29   ` [PATCH V2 28/40] arm: enable data-cache at the same time as enabling the MMU, not before Ian Campbell
@ 2012-06-28 11:02     ` Tim Deegan
  0 siblings, 0 replies; 51+ messages in thread
From: Tim Deegan @ 2012-06-28 11:02 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

At 10:29 +0000 on 26 Jun (1340706592), Ian Campbell wrote:
> With enough warnings enabled the model seemed to be complaining that pages
> cached before paging was enabled had been mapped with to inconsistent sets of
> attributes. I'm not convinced that isn't a model issue, nor am I convinced
> this has really fixed anything, but it seems sensible enough.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Tim Deegan <tim@xen.org>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 33/40] arm: unwind allocations etc on arch_domain_create_failure
  2012-06-26 10:29   ` [PATCH V2 33/40] arm: unwind allocations etc on arch_domain_create_failure Ian Campbell
@ 2012-06-28 11:05     ` Tim Deegan
  0 siblings, 0 replies; 51+ messages in thread
From: Tim Deegan @ 2012-06-28 11:05 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

At 10:29 +0000 on 26 Jun (1340706597), Ian Campbell wrote:
> This involves adding the necessary teardown/free functions for some modules.
> 
> Don't initialise full arch domain state for the idle domain, it's not needed.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Tim Deegan <tim@xen.org>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 37/40] arm: implement VGCF_online
  2012-06-26 10:30   ` [PATCH V2 37/40] arm: implement VGCF_online Ian Campbell
@ 2012-06-28 11:06     ` Tim Deegan
  0 siblings, 0 replies; 51+ messages in thread
From: Tim Deegan @ 2012-06-28 11:06 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

At 10:30 +0000 on 26 Jun (1340706601), Ian Campbell wrote:
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Tim Deegan <tim@xen.org>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR.
  2012-06-26 10:29   ` [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR Ian Campbell
@ 2012-06-28 12:46     ` Ian Campbell
  2012-06-28 13:00     ` Stefano Stabellini
  1 sibling, 0 replies; 51+ messages in thread
From: Ian Campbell @ 2012-06-28 12:46 UTC (permalink / raw)
  To: xen-devel

On Tue, 2012-06-26 at 11:29 +0100, Ian Campbell wrote:
> Rename p2m_create_entry to p2m_create_table since it can now only be used to
> insert non-leaf entries into the page table.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

This change should also have incorporated the following which somehow
ended up in
         [PATCH V2 22/40] arm: use correct attributes for mappings in copy_from_paddr()
I'll move them over...

diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index 6efe23c..2b6c1780 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -36,6 +36,14 @@
 #define MAIR0VAL 0xeeaa4400
 #define MAIR1VAL 0xff000004
 
+/*
+ * Attribute Indexes.
+ *
+ * These are valid in the AttrIndx[2:0] field of an LPAE stage 1 page
+ * table entry. They are indexes into the bytes of the MAIR*
+ * registers, as defined above.
+ *
+ */
 #define UNCACHED      0x0
 #define BUFFERABLE    0x1
 #define WRITETHROUGH  0x2
@@ -46,6 +54,13 @@
 #define DEV_WC        BUFFERABLE
 #define DEV_CACHED    WRITEBACK
 
+/*
+ * Stage 2 Memory Type.
+ *
+ * These are valid in the MemAttr[3:0] field of an LPAE stage 2 page
+ * table entry.
+ *
+ */
 #define MATTR_DEV     0x1
 #define MATTR_MEM     0xf

^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR.
  2012-06-26 10:29   ` [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR Ian Campbell
  2012-06-28 12:46     ` Ian Campbell
@ 2012-06-28 13:00     ` Stefano Stabellini
  1 sibling, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2012-06-28 13:00 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, 26 Jun 2012, Ian Campbell wrote:
> Rename p2m_create_entry to p2m_create_table since it can now only be used to
> insert non-leaf entries into the page table.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>


Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

>  xen/arch/arm/p2m.c         |   22 ++++++++++++----------
>  xen/include/asm-arm/page.h |    6 ++++--
>  2 files changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index ec41d38..35bfa2f 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -91,7 +91,8 @@ int p2m_pod_decrease_reservation(struct domain *d,
>      return -ENOSYS;
>  }
>  
> -static int p2m_create_entry(struct domain *d,
> +/* Allocate a new page table page and hook it in via the given entry */
> +static int p2m_create_table(struct domain *d,
>                              lpae_t *entry)
>  {
>      struct p2m_domain *p2m = &d->arch.p2m;
> @@ -111,7 +112,7 @@ static int p2m_create_entry(struct domain *d,
>      clear_page(p);
>      unmap_domain_page(p);
>  
> -    pte = mfn_to_p2m_entry(page_to_mfn(page));
> +    pte = mfn_to_p2m_entry(page_to_mfn(page), MATTR_MEM);
>  
>      write_pte(entry, pte);
>  
> @@ -122,7 +123,8 @@ static int create_p2m_entries(struct domain *d,
>                       int alloc,
>                       paddr_t start_gpaddr,
>                       paddr_t end_gpaddr,
> -                     paddr_t maddr)
> +                     paddr_t maddr,
> +                     int mattr)
>  {
>      int rc;
>      struct p2m_domain *p2m = &d->arch.p2m;
> @@ -140,7 +142,7 @@ static int create_p2m_entries(struct domain *d,
>      {
>          if ( !first[first_table_offset(addr)].p2m.valid )
>          {
> -            rc = p2m_create_entry(d, &first[first_table_offset(addr)]);
> +            rc = p2m_create_table(d, &first[first_table_offset(addr)]);
>              if ( rc < 0 ) {
>                  printk("p2m_populate_ram: L1 failed\n");
>                  goto out;
> @@ -159,7 +161,7 @@ static int create_p2m_entries(struct domain *d,
>  
>          if ( !second[second_table_offset(addr)].p2m.valid )
>          {
> -            rc = p2m_create_entry(d, &second[second_table_offset(addr)]);
> +            rc = p2m_create_table(d, &second[second_table_offset(addr)]);
>              if ( rc < 0 ) {
>                  printk("p2m_populate_ram: L2 failed\n");
>                  goto out;
> @@ -198,11 +200,11 @@ static int create_p2m_entries(struct domain *d,
>                  goto out;
>              }
>  
> -            pte = mfn_to_p2m_entry(page_to_mfn(page));
> +            pte = mfn_to_p2m_entry(page_to_mfn(page), mattr);
>  
>              write_pte(&third[third_table_offset(addr)], pte);
>          } else {
> -            lpae_t pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT);
> +            lpae_t pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr);
>              write_pte(&third[third_table_offset(addr)], pte);
>              maddr += PAGE_SIZE;
>          }
> @@ -226,7 +228,7 @@ int p2m_populate_ram(struct domain *d,
>                       paddr_t start,
>                       paddr_t end)
>  {
> -    return create_p2m_entries(d, 1, start, end, 0);
> +    return create_p2m_entries(d, 1, start, end, 0, MATTR_MEM);
>  }
>  
>  int map_mmio_regions(struct domain *d,
> @@ -234,7 +236,7 @@ int map_mmio_regions(struct domain *d,
>                       paddr_t end_gaddr,
>                       paddr_t maddr)
>  {
> -    return create_p2m_entries(d, 0, start_gaddr, end_gaddr, maddr);
> +    return create_p2m_entries(d, 0, start_gaddr, end_gaddr, maddr, MATTR_DEV);
>  }
>  
>  int guest_physmap_add_page(struct domain *d,
> @@ -244,7 +246,7 @@ int guest_physmap_add_page(struct domain *d,
>  {
>      return create_p2m_entries(d, 0, gpfn << PAGE_SHIFT,
>                                (gpfn + (1<<page_order)) << PAGE_SHIFT,
> -                              mfn << PAGE_SHIFT);
> +                              mfn << PAGE_SHIFT, MATTR_MEM);
>  }
>  
>  void guest_physmap_remove_page(struct domain *d,
> diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
> index 183ba5f..2783c30 100644
> --- a/xen/include/asm-arm/page.h
> +++ b/xen/include/asm-arm/page.h
> @@ -46,6 +46,8 @@
>  #define DEV_WC        BUFFERABLE
>  #define DEV_CACHED    WRITEBACK
>  
> +#define MATTR_DEV     0x1
> +#define MATTR_MEM     0xf
>  
>  #ifndef __ASSEMBLY__
>  
> @@ -187,7 +189,7 @@ static inline lpae_t mfn_to_xen_entry(unsigned long mfn)
>      return e;
>  }
>  
> -static inline lpae_t mfn_to_p2m_entry(unsigned long mfn)
> +static inline lpae_t mfn_to_p2m_entry(unsigned long mfn, unsigned int mattr)
>  {
>      paddr_t pa = ((paddr_t) mfn) << PAGE_SHIFT;
>      lpae_t e = (lpae_t) {
> @@ -196,7 +198,7 @@ static inline lpae_t mfn_to_p2m_entry(unsigned long mfn)
>          .p2m.sh = LPAE_SH_OUTER,
>          .p2m.write = 1,
>          .p2m.read = 1,
> -        .p2m.mattr = 0xf,
> +        .p2m.mattr = mattr,
>          .p2m.table = 1,
>          .p2m.valid = 1,
>      };
> -- 
> 1.7.9.1
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 21/40] arm: implement vcpu_show_execution_state
  2012-06-26 10:29   ` [PATCH V2 21/40] arm: implement vcpu_show_execution_state Ian Campbell
@ 2012-06-28 13:04     ` Stefano Stabellini
  0 siblings, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2012-06-28 13:04 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, 26 Jun 2012, Ian Campbell wrote:
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

>  xen/arch/arm/dummy.S |    1 -
>  xen/arch/arm/traps.c |   56 +++++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 51 insertions(+), 6 deletions(-)
> 
> diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
> index 03f7489..cab9522 100644
> --- a/xen/arch/arm/dummy.S
> +++ b/xen/arch/arm/dummy.S
> @@ -21,7 +21,6 @@ DUMMY(pirq_set_affinity);
>  DUMMY(arch_get_info_guest);
>  DUMMY(arch_vcpu_reset);
>  NOP(update_vcpu_system_time);
> -DUMMY(vcpu_show_execution_state);
>  
>  /* Page Reference & Type Maintenance */
>  DUMMY(get_page);
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index d8eb5a9..f5f43da 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -170,7 +170,13 @@ void panic_PAR(uint64_t par, const char *when)
>      panic("Error during %s-to-physical address translation\n", when);
>  }
>  
> -void show_registers(struct cpu_user_regs *regs)
> +struct reg_ctxt {
> +    uint32_t sctlr;
> +    uint32_t ttbr0, ttbr1, ttbcr;
> +};
> +static void _show_registers(struct cpu_user_regs *regs,
> +                            struct reg_ctxt *ctxt,
> +                            int guest_mode)
>  {
>      static const char *mode_strings[] = {
>         [PSR_MODE_USR] = "USR",
> @@ -187,7 +193,7 @@ void show_registers(struct cpu_user_regs *regs)
>      print_xen_info();
>      printk("CPU:    %d\n", smp_processor_id());
>      printk("PC:     %08"PRIx32, regs->pc);
> -    if ( !guest_mode(regs) )
> +    if ( !guest_mode )
>              print_symbol(" %s", regs->pc);
>      printk("\n");
>      printk("CPSR:   %08"PRIx32" MODE:%s\n", regs->cpsr,
> @@ -199,7 +205,7 @@ void show_registers(struct cpu_user_regs *regs)
>      printk("     R8: %08"PRIx32" R9: %08"PRIx32" R10:%08"PRIx32" R11:%08"PRIx32" R12:%08"PRIx32"\n",
>             regs->r8, regs->r9, regs->r10, regs->r11, regs->r12);
>  
> -    if ( guest_mode(regs) )
> +    if ( guest_mode )
>      {
>          printk("USR: SP: %08"PRIx32" LR: %08"PRIx32" CPSR:%08"PRIx32"\n",
>                 regs->sp_usr, regs->lr_usr, regs->cpsr);
> @@ -217,8 +223,8 @@ void show_registers(struct cpu_user_regs *regs)
>                 regs->r8_fiq, regs->r9_fiq, regs->r10_fiq, regs->r11_fiq, regs->r11_fiq);
>          printk("\n");
>          printk("TTBR0 %08"PRIx32" TTBR1 %08"PRIx32" TTBCR %08"PRIx32"\n",
> -               READ_CP32(TTBR0), READ_CP32(TTBR1), READ_CP32(TTBCR));
> -        printk("SCTLR %08"PRIx32"\n", READ_CP32(SCTLR));
> +               ctxt->ttbr0, ctxt->ttbr1, ctxt->ttbcr);
> +        printk("SCTLR %08"PRIx32"\n", ctxt->sctlr);
>          printk("VTTBR %010"PRIx64"\n", READ_CP64(VTTBR));
>          printk("\n");
>      }
> @@ -241,6 +247,26 @@ void show_registers(struct cpu_user_regs *regs)
>      printk("\n");
>  }
>  
> +void show_registers(struct cpu_user_regs *regs)
> +{
> +    struct reg_ctxt ctxt;
> +    ctxt.sctlr = READ_CP32(SCTLR);
> +    ctxt.ttbcr = READ_CP32(TTBCR);
> +    ctxt.ttbr0 = READ_CP32(TTBR0);
> +    ctxt.ttbr1 = READ_CP32(TTBR1);
> +    _show_registers(regs, &ctxt, guest_mode(regs));
> +}
> +
> +void vcpu_show_registers(const struct vcpu *v)
> +{
> +    struct reg_ctxt ctxt;
> +    ctxt.sctlr = v->arch.sctlr;
> +    ctxt.ttbcr = v->arch.ttbcr;
> +    ctxt.ttbr0 = v->arch.ttbr0;
> +    ctxt.ttbr1 = v->arch.ttbr1;
> +    _show_registers(&v->arch.cpu_info->guest_cpu_user_regs, &ctxt, 1);
> +}
> +
>  static void show_guest_stack(struct cpu_user_regs *regs)
>  {
>      printk("GUEST STACK GOES HERE\n");
> @@ -334,6 +360,26 @@ void show_execution_state(struct cpu_user_regs *regs)
>      show_stack(regs);
>  }
>  
> +void vcpu_show_execution_state(struct vcpu *v)
> +{
> +    printk("*** Dumping Dom%d vcpu#%d state: ***\n",
> +           v->domain->domain_id, v->vcpu_id);
> +
> +    if ( v == current )
> +    {
> +        show_execution_state(guest_cpu_user_regs());
> +        return;
> +    }
> +
> +    vcpu_pause(v); /* acceptably dangerous */
> +
> +    vcpu_show_registers(v);
> +    if ( !usr_mode(&v->arch.cpu_info->guest_cpu_user_regs) )
> +        show_guest_stack(&v->arch.cpu_info->guest_cpu_user_regs);
> +
> +    vcpu_unpause(v);
> +}
> +
>  static void do_unexpected_trap(const char *msg, struct cpu_user_regs *regs)
>  {
>      printk("Unexpected Trap: %s\n", msg);
> -- 
> 1.7.9.1
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 26/40] arm: use interrupt safe spin locks in vgic_vcpu_inject_irq
  2012-06-26 10:29   ` [PATCH V2 26/40] arm: use interrupt safe spin locks in vgic_vcpu_inject_irq Ian Campbell
@ 2012-06-28 13:06     ` Stefano Stabellini
  0 siblings, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2012-06-28 13:06 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, 26 Jun 2012, Ian Campbell wrote:
> This function can be called in both interrupt and regular context.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>


Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

>  xen/arch/arm/vgic.c |    5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index af3523f..91d6166 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -550,6 +550,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
>      uint8_t priority;
>      struct vgic_irq_rank *rank = vgic_irq_rank(v, 8, idx);
>      struct pending_irq *iter, *n = irq_to_pending(v, irq);
> +    unsigned long flags;
>  
>      /* irq still pending */
>      if (!list_empty(&n->inflight))
> @@ -566,7 +567,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
>  
>      gic_set_guest_irq(irq, GICH_LR_PENDING, priority);
>  
> -    spin_lock(&v->arch.vgic.lock);
> +    spin_lock_irqsave(&v->arch.vgic.lock, flags);
>      list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
>      {
>          if ( iter->priority > priority )
> @@ -577,7 +578,7 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
>          }
>      }
>      list_add_tail(&n->inflight, &v->arch.vgic.inflight_irqs);
> -    spin_unlock(&v->arch.vgic.lock);
> +    spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
>      /* we have a new higher priority irq, inject it into the guest */
>  }
>  
> -- 
> 1.7.9.1
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH V2 25/40] arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU)
  2012-06-26 10:29   ` [PATCH V2 25/40] arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU) Ian Campbell
@ 2012-06-28 13:08     ` Stefano Stabellini
  0 siblings, 0 replies; 51+ messages in thread
From: Stefano Stabellini @ 2012-06-28 13:08 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, 26 Jun 2012, Ian Campbell wrote:
> This tracks SPIs in struct arch_domain and PPIs+SGIs in struct arch_vcpu which
> seems more logical.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>


Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

>  xen/arch/arm/vgic.c          |   12 +++++++-----
>  xen/include/asm-arm/domain.h |   10 ++++++++++
>  2 files changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 629a0da..af3523f 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -82,9 +82,8 @@ int domain_vgic_init(struct domain *d)
>      d->arch.vgic.shared_irqs =
>          xmalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
>      d->arch.vgic.pending_irqs =
> -        xmalloc_array(struct pending_irq,
> -                d->arch.vgic.nr_lines + (32 * d->max_vcpus));
> -    for (i=0; i<d->arch.vgic.nr_lines + (32 * d->max_vcpus); i++)
> +        xzalloc_array(struct pending_irq, d->arch.vgic.nr_lines);
> +    for (i=0; i<d->arch.vgic.nr_lines; i++)
>          INIT_LIST_HEAD(&d->arch.vgic.pending_irqs[i].inflight);
>      for (i=0; i<DOMAIN_NR_RANKS(d); i++)
>          spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
> @@ -98,6 +97,10 @@ int vcpu_vgic_init(struct vcpu *v)
>  
>      spin_lock_init(&v->arch.vgic.private_irqs.lock);
>  
> +    memset(&v->arch.vgic.pending_irqs, 0, sizeof(v->arch.vgic.pending_irqs));
> +    for (i = 0; i < 32; i++)
> +        INIT_LIST_HEAD(&v->arch.vgic.pending_irqs[i].inflight);
> +
>      /* For SGI and PPI the target is always this CPU */
>      for ( i = 0 ; i < 8 ; i++ )
>          v->arch.vgic.private_irqs.itargets[i] =
> @@ -535,8 +538,7 @@ struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
>      /* Pending irqs allocation strategy: the first vgic.nr_lines irqs
>       * are used for SPIs; the rests are used for per cpu irqs */
>      if ( irq < 32 )
> -        n = &v->domain->arch.vgic.pending_irqs[irq + (v->vcpu_id * 32)
> -            + v->domain->arch.vgic.nr_lines];
> +        n = &v->arch.vgic.pending_irqs[irq];
>      else
>          n = &v->domain->arch.vgic.pending_irqs[irq - 32];
>      return n;
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 620b26e..32deb52 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -46,6 +46,10 @@ struct arch_domain
>          int ctlr;
>          int nr_lines;
>          struct vgic_irq_rank *shared_irqs;
> +        /*
> +         * SPIs are domain global, SGIs and PPIs are per-VCPU and stored in
> +         * struct arch_vcpu.
> +         */
>          struct pending_irq *pending_irqs;
>      } vgic;
>  
> @@ -114,7 +118,13 @@ struct arch_vcpu
>      uint32_t gic_lr[64];
>  
>      struct {
> +        /*
> +         * SGIs and PPIs are per-VCPU, SPIs are domain global and in
> +         * struct arch_domain.
> +         */
> +        struct pending_irq pending_irqs[32];
>          struct vgic_irq_rank private_irqs;
> +
>          /* This list is ordered by IRQ priority and it is used to keep
>           * track of the IRQs that the VGIC injected into the guest.
>           * Depending on the availability of LR registers, the IRQs might
> -- 
> 1.7.9.1
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2012-06-28 13:08 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-26 10:29 [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang Ian Campbell
2012-06-26 10:29 ` [PATCH V2 01/40] arm: allocate top level p2m page for all non-idle domains Ian Campbell
2012-06-26 10:29   ` [PATCH V2 02/40] arm: handy function to print a walk of a page table Ian Campbell
2012-06-26 10:29   ` [PATCH V2 03/40] arm: correct and expand TLB flush CP15 registers Ian Campbell
2012-06-26 10:29   ` [PATCH V2 04/40] arm: restore stack on return from trap Ian Campbell
2012-06-26 10:29   ` [PATCH V2 05/40] arm: enable interrupts while handling traps Ian Campbell
2012-06-26 10:29   ` [PATCH V2 06/40] arm: hook up domctl and memory_op Ian Campbell
2012-06-26 10:29   ` [PATCH V2 07/40] arm: allocate and setup a guest vcpu Ian Campbell
2012-06-26 10:29   ` [PATCH V2 08/40] arm: print domid as part of debug trap Ian Campbell
2012-06-26 10:29   ` [PATCH V2 09/40] arm: remove unnecessarily verbose print from p2m_load_VTTBR Ian Campbell
2012-06-26 10:29   ` [PATCH V2 10/40] arm: implement p2m lookup Ian Campbell
2012-06-26 10:29   ` [PATCH V2 11/40] arm: remove hard tabs from init_idle_domain Ian Campbell
2012-06-26 10:29   ` [PATCH V2 12/40] arm: stub out sync_vcpu_execstate Ian Campbell
2012-06-26 10:29   ` [PATCH V2 13/40] arm: implement stub version of flush_tlb_mask Ian Campbell
2012-06-26 10:29   ` [PATCH V2 14/40] arm: do not set max_vcpus = 8 in arch_domain_create Ian Campbell
2012-06-26 10:29   ` [PATCH V2 15/40] arm: Add simple cpu_{sibling, core}_mask Ian Campbell
2012-06-26 10:29   ` [PATCH V2 16/40] arm: allow p2m to be created with specific MATTR Ian Campbell
2012-06-28 12:46     ` Ian Campbell
2012-06-28 13:00     ` Stefano Stabellini
2012-06-26 10:29   ` [PATCH V2 17/40] arm: implement vpl011 (UART) emulator Ian Campbell
2012-06-28 11:00     ` Tim Deegan
2012-06-26 10:29   ` [PATCH V2 18/40] arm: context switch a bunch of guest state Ian Campbell
2012-06-26 10:29   ` [PATCH V2 19/40] arm: dump a page table walk when va_to_par fails Ian Campbell
2012-06-26 10:29   ` [PATCH V2 20/40] arm: dump guest s1 walk on data abort which is not a stage 2 issue Ian Campbell
2012-06-26 10:29   ` [PATCH V2 21/40] arm: implement vcpu_show_execution_state Ian Campbell
2012-06-28 13:04     ` Stefano Stabellini
2012-06-26 10:29   ` [PATCH V2 22/40] arm: use correct attributes for mappings in copy_from_paddr() Ian Campbell
2012-06-26 10:29   ` [PATCH V2 23/40] arm: map fixmaps non-executable Ian Campbell
2012-06-26 10:29   ` [PATCH V2 24/40] arm: fix locking in create_p2m_entries Ian Campbell
2012-06-26 10:29   ` [PATCH V2 25/40] arm: split pending SPIs (global) out from pending PPIs and SGIs (per CPU) Ian Campbell
2012-06-28 13:08     ` Stefano Stabellini
2012-06-26 10:29   ` [PATCH V2 26/40] arm: use interrupt safe spin locks in vgic_vcpu_inject_irq Ian Campbell
2012-06-28 13:06     ` Stefano Stabellini
2012-06-26 10:29   ` [PATCH V2 27/40] arm: map GICV in all domains, not just dom0 Ian Campbell
2012-06-26 10:29   ` [PATCH V2 28/40] arm: enable data-cache at the same time as enabling the MMU, not before Ian Campbell
2012-06-28 11:02     ` Tim Deegan
2012-06-26 10:29   ` [PATCH V2 29/40] arm: Upgrade guest barriers to Outer-Shareable. Enable Protected Table Walk Ian Campbell
2012-06-26 10:29   ` [PATCH V2 30/40] arm: gic.lock can be taken in interrupt context, so lock appropriately Ian Campbell
2012-06-26 10:29   ` [PATCH V2 31/40] arm: context switch virtual timer registers Ian Campbell
2012-06-26 10:29   ` [PATCH V2 32/40] arm: the hyp timer seems to work in newer model versions, default to using it Ian Campbell
2012-06-26 10:29   ` [PATCH V2 33/40] arm: unwind allocations etc on arch_domain_create_failure Ian Campbell
2012-06-28 11:05     ` Tim Deegan
2012-06-26 10:29   ` [PATCH V2 34/40] HACK: arm: initial XENMAPSPACE_gmfn_foreign Ian Campbell
2012-06-26 10:29   ` [PATCH V2 35/40] arm: move PSR flag definitions into interface, for tools use Ian Campbell
2012-06-26 10:30   ` [PATCH V2 36/40] libxc: add ARM support to xc_dom (PV domain building) Ian Campbell
2012-06-26 10:30   ` [PATCH V2 37/40] arm: implement VGCF_online Ian Campbell
2012-06-28 11:06     ` Tim Deegan
2012-06-26 10:30   ` [PATCH V2 38/40] arm: fix typo s/approprately/appropriately/g Ian Campbell
2012-06-26 10:30   ` [PATCH V2 39/40] HACK: add simple xcbuild Ian Campbell
2012-06-26 10:30   ` [PATCH V2 40/40] HACK: arm: disable hypercall continuations Ian Campbell
2012-06-26 15:26 ` [PATCH 00/40 V2] arm: boot a dom1 to "Calibrating delay loop" then hang Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.