arm: allocate and setup a guest vcpu.
authorIan Campbell <ian.campbell@citrix.com>
Tue, 26 Jun 2012 15:23:48 +0000 (16:23 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Tue, 26 Jun 2012 15:23:48 +0000 (16:23 +0100)
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/domain.c
xen/arch/arm/dummy.S
xen/include/public/arch-arm.h

index 9339a11e763448e2a119ad155515be09cfd05d0c..b099d91e3b0ac68971f8ce5e73dacac7920d877d 100644 (file)
@@ -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)
 {
 }
index 016340c000b24bc9a5449e555f15b5a6ffc7d743..3b489178e23040112bb2d5d294dfc8136f20e340 100644 (file)
@@ -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);
index 1b1bcf3235d8fce7f08b26563d1d4f74f323f50f..e4397270e5838d91e16ccd44631bd5cb55ba5bad 100644 (file)
@@ -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);