|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 12/14] xen: arm: handle hypercalls from 64-bit guests
On Tue, 12 Mar 2013, Ian Campbell wrote:
> From: Ian Campbell <ian.campbell@xxxxxxxxxx>
>
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> xen/arch/arm/traps.c | 67
> ++++++++++++++++++++++++++++-----------
> xen/include/asm-arm/processor.h | 7 ++--
> 2 files changed, 54 insertions(+), 20 deletions(-)
>
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index f1dd557..190d1e8 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -726,8 +726,8 @@ unsigned long do_arch_0(unsigned int cmd, unsigned long
> long value)
> return 0;
> }
>
> -typedef unsigned long (*arm_hypercall_fn_t)(
> - unsigned int, unsigned int, unsigned int, unsigned int, unsigned int);
> +typedef register_t (*arm_hypercall_fn_t)(
> + register_t, register_t, register_t, register_t, register_t);
>
> typedef struct {
> arm_hypercall_fn_t fn;
> @@ -783,30 +783,49 @@ 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)
> +#ifdef CONFIG_ARM_64
> +#define HYPERCALL_RESULT_REG(r) (r)->x0
> +#define HYPERCALL_ARG1(r) (r)->x0
> +#define HYPERCALL_ARG2(r) (r)->x1
> +#define HYPERCALL_ARG3(r) (r)->x2
> +#define HYPERCALL_ARG4(r) (r)->x3
> +#define HYPERCALL_ARG5(r) (r)->x4
> +#define HYPERCALL_ARGS(r) (r)->x0, (r)->x1, (r)->x2, (r)->x3, (r)->x4
> +#else
> +#define HYPERCALL_RESULT_REG(r) (r)->r0
> +#define HYPERCALL_ARG1(r) (r)->r0
> +#define HYPERCALL_ARG2(r) (r)->r1
> +#define HYPERCALL_ARG3(r) (r)->r2
> +#define HYPERCALL_ARG4(r) (r)->r3
> +#define HYPERCALL_ARG5(r) (r)->r4
> +#define HYPERCALL_ARGS(r) (r)->r0, (r)->r1, (r)->r2, (r)->r3, (r)->r4
> +#endif
> +
> +static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
> + unsigned long iss)
> {
> arm_hypercall_fn_t call = NULL;
> #ifndef NDEBUG
> - uint32_t orig_pc = regs->pc;
> + register_t orig_pc = regs->pc;
> #endif
>
> if ( iss != XEN_HYPERCALL_TAG )
> domain_crash_synchronous();
>
> - if ( regs->r12 >= ARRAY_SIZE(arm_hypercall_table) )
> + if ( *nr >= ARRAY_SIZE(arm_hypercall_table) )
> {
> - regs->r0 = -ENOSYS;
> + HYPERCALL_RESULT_REG(regs) = -ENOSYS;
> return;
> }
>
> - call = arm_hypercall_table[regs->r12].fn;
> + call = arm_hypercall_table[*nr].fn;
> if ( call == NULL )
> {
> - regs->r0 = -ENOSYS;
> + HYPERCALL_RESULT_REG(regs) = -ENOSYS;
> return;
> }
>
> - regs->r0 = call(regs->r0, regs->r1, regs->r2, regs->r3, regs->r4);
> + HYPERCALL_RESULT_REG(regs) = call(HYPERCALL_ARGS(regs));
>
> #ifndef NDEBUG
> /*
> @@ -815,16 +834,16 @@ static void do_trap_hypercall(struct cpu_user_regs
> *regs, unsigned long iss)
> */
> if ( orig_pc == regs->pc )
> {
> - switch ( arm_hypercall_table[regs->r12].nr_args ) {
> - case 5: regs->r4 = 0xDEADBEEF;
> - case 4: regs->r3 = 0xDEADBEEF;
> - case 3: regs->r2 = 0xDEADBEEF;
> - case 2: regs->r1 = 0xDEADBEEF;
> - case 1: /* Don't clobber r0 -- it's the return value */
> + switch ( arm_hypercall_table[*nr].nr_args ) {
> + case 5: HYPERCALL_ARG5(regs) = 0xDEADBEEF;
> + case 4: HYPERCALL_ARG4(regs) = 0xDEADBEEF;
> + case 3: HYPERCALL_ARG3(regs) = 0xDEADBEEF;
> + case 2: HYPERCALL_ARG2(regs) = 0xDEADBEEF;
> + case 1: /* Don't clobber x0/r0 -- it's the return value */
> break;
> default: BUG();
> }
> - regs->r12 = 0xDEADBEEF;
> + *nr = 0xDEADBEEF;
> }
> #endif
> }
> @@ -1079,11 +1098,23 @@ asmlinkage void do_trap_hypervisor(struct
> cpu_user_regs *regs)
> goto bad_trap;
> do_cp15_64(regs, hsr);
> break;
> - case HSR_EC_HVC:
> + case HSR_EC_HVC32:
> +#ifndef NDEBUG
> + if ( (hsr.iss & 0xff00) == 0xff00 )
> + return do_debug_trap(regs, hsr.iss & 0x00ff);
> +#endif
> + do_trap_hypercall(regs, (register_t *)®s->r12, hsr.iss);
> + break;
> +
> +#ifdef CONFIG_ARM_64
> + case HSR_EC_HVC64:
> +#ifndef NDEBUG
> if ( (hsr.iss & 0xff00) == 0xff00 )
> return do_debug_trap(regs, hsr.iss & 0x00ff);
> - do_trap_hypercall(regs, hsr.iss);
> +#endif
> + do_trap_hypercall(regs, ®s->x16, hsr.iss);
> break;
> +#endif
> case HSR_EC_DATA_ABORT_GUEST:
> do_trap_data_abort_guest(regs, hsr.dabt);
> break;
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 32c441b..17f5465 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -86,8 +86,11 @@
> #define HSR_EC_JAZELLE 0x09
> #define HSR_EC_BXJ 0x0a
> #define HSR_EC_CP14_64 0x0c
> -#define HSR_EC_SVC 0x11
> -#define HSR_EC_HVC 0x12
> +#define HSR_EC_SVC32 0x11
> +#define HSR_EC_HVC32 0x12
> +#ifdef CONFIG_ARM_64
> +#define HSR_EC_HVC64 0x16
> +#endif
> #define HSR_EC_INSTR_ABORT_GUEST 0x20
> #define HSR_EC_INSTR_ABORT_HYP 0x21
> #define HSR_EC_DATA_ABORT_GUEST 0x24
> --
> 1.7.10.4
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |