aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2012-06-26 16:23:48 +0100
committerIan Campbell <ian.campbell@citrix.com>2012-06-26 16:23:48 +0100
commitbe7d2d56d45d20e3780b3df407826142c24bf703 (patch)
tree6d1e3a2cf8f89df7b014e7c03dff49a32d46264f
parent946446dda8ec5583376666a5517817d03a64cf73 (diff)
downloadxen-be7d2d56d45d20e3780b3df407826142c24bf703.tar.gz
xen-be7d2d56d45d20e3780b3df407826142c24bf703.tar.bz2
xen-be7d2d56d45d20e3780b3df407826142c24bf703.zip
arm: allocate and setup a guest vcpu.
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>
-rw-r--r--xen/arch/arm/domain.c67
-rw-r--r--xen/arch/arm/dummy.S3
-rw-r--r--xen/include/public/arch-arm.h9
3 files changed, 67 insertions, 12 deletions
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 9339a11e76..b099d91e3b 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 016340c000..3b489178e2 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 1b1bcf3235..e4397270e5 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);