[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] xen/arm: trap SMC instructions and inject an UND exception



On Thu, 2 May 2013, Ian Campbell wrote:
> Currently only handles 32 bit guests. The 64-bit exception model is
> considerably different.
> 
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
>
> There are probably other places where injecting UND would be more appropriate
> than killing the guest. It should also be reasonably easy to extend this logic
> to inject DABT and PABT.
> ---
>  xen/arch/arm/traps.c                  |   56 
> ++++++++++++++++++++++++++++++++-
>  xen/include/asm-arm/arm32/processor.h |    4 ++-
>  xen/include/asm-arm/processor.h       |    8 +++++
>  xen/include/public/arch-arm.h         |    1 +
>  4 files changed, 67 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index b7487b7..72dddb2 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -59,7 +59,7 @@ void __cpuinit init_traps(void)
>      WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
>  
>      /* Setup hypervisor traps */
> -    WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM, HCR_EL2);
> +    WRITE_SYSREG(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_TSC|HCR_VM, 
> HCR_EL2);
>      isb();
>  }

My recent patch http://marc.info/?l=xen-devel&m=136734156810415 does
this


> @@ -239,6 +239,54 @@ void panic_PAR(uint64_t par)
>      panic("Error during Hypervisor-to-physical address translation\n");
>  }
>  
> +static void cpsr_switch_mode(struct cpu_user_regs *regs, int mode)
> +{
> +    uint32_t sctlr = READ_SYSREG32(SCTLR_EL1);
> +
> +    regs->cpsr &= 
> ~(PSR_MODE_MASK|PSR_IT_MASK|PSR_JAZELLE|PSR_BIG_ENDIAN|PSR_THUMB);
> +
> +    regs->cpsr |= mode;
> +    regs->cpsr |= PSR_IRQ_MASK;
> +    if (sctlr & SCTLR_TE)
> +        regs->cpsr |= PSR_THUMB;
> +    if (sctlr & SCTLR_EE)
> +        regs->cpsr |= PSR_BIG_ENDIAN;
> +}
> +
> +static vaddr_t exception_handler(vaddr_t offset)
> +{
> +    uint32_t sctlr = READ_SYSREG32(SCTLR_EL1);
> +
> +    if (sctlr & SCTLR_V)
> +        return 0xffff0000 + offset;
> +    else /* always have security exceptions */
> +        return READ_SYSREG(VBAR_EL1) + offset;
> +}
> +
> +/* Injects an Undefined Instruction exception into the current vcpu,
> + * PC is the exact address of the faulting instruction (without
> + * pipeline adjustments). See TakeUndefInstrException pseudocode in
> + * ARM.
> + */
> +static void inject_undef_exception(struct cpu_user_regs *regs,
> +                                   register_t preferred_return)
> +{
> +    uint32_t spsr = regs->cpsr;
> +    int is_thumb = (regs->cpsr & PSR_THUMB);
> +    /* Saved PC points to the instruction past the faulting instruction. */
> +    uint32_t return_offset = is_thumb ? 2 : 4;
> +
> +    /* Update processor mode */
> +    cpsr_switch_mode(regs, PSR_MODE_UND);
> +
> +    /* Update banked registers */
> +    regs->spsr_und = spsr;
> +    regs->lr_und = preferred_return + return_offset;
> +
> +    /* Branch to exception vector */
> +    regs->pc32 = exception_handler(VECTOR32_UND);
> +}
> +
>  struct reg_ctxt {
>      uint32_t sctlr, tcr;
>      uint64_t ttbr0, ttbr1;
> @@ -941,6 +989,12 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs 
> *regs)
>              goto bad_trap;
>          do_cp15_64(regs, hsr);
>          break;
> +    case HSR_EC_SMC:
> +        /* PC32 already contains the preferred exception return
> +         * address, so no need to adjust here.
> +         */
> +        inject_undef_exception(regs, regs->pc32);
> +        break;
>      case HSR_EC_HVC:
>          if ( (hsr.iss & 0xff00) == 0xff00 )
>              return do_debug_trap(regs, hsr.iss & 0x00ff);
> diff --git a/xen/include/asm-arm/arm32/processor.h 
> b/xen/include/asm-arm/arm32/processor.h
> index cd79170..d26fc85 100644
> --- a/xen/include/asm-arm/arm32/processor.h
> +++ b/xen/include/asm-arm/arm32/processor.h
> @@ -31,7 +31,9 @@ struct cpu_user_regs
>          uint32_t lr_usr;
>      };
>  
> -    uint32_t pc; /* Return IP */
> +    union {  /* Return IP, pc32 is used to allow code to be common with 
> 64-bit */
> +        uint32_t pc, pc32;
> +    };
>      uint32_t cpsr; /* Return mode */
>      uint32_t pad0; /* Doubleword-align the kernel half of the frame */
>  
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 1681ebf..1c9d793 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -85,6 +85,7 @@
>  #define HSR_EC_CP14_64              0x0c
>  #define HSR_EC_SVC                  0x11
>  #define HSR_EC_HVC                  0x12
> +#define HSR_EC_SMC                  0x13
>  #define HSR_EC_INSTR_ABORT_GUEST    0x20
>  #define HSR_EC_INSTR_ABORT_HYP      0x21
>  #define HSR_EC_DATA_ABORT_GUEST     0x24
> @@ -342,6 +343,13 @@ union hsr {
>  #define CNTx_CTL_MASK     (1u<<1)  /* Mask IRQ */
>  #define CNTx_CTL_PENDING  (1u<<2)  /* IRQ pending */
>  
> +/* Exception Vector offsets */
> +#define VECTOR32_RST  0
> +#define VECTOR32_UND  4
> +#define VECTOR32_SVC  8
> +#define VECTOR32_PABT 12
> +#define VECTOR32_DABT 16
> +
>  #if defined(CONFIG_ARM_32)
>  # include <asm/arm32/processor.h>
>  #elif defined(CONFIG_ARM_64)
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 2f5ce18..cea12b2 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -234,6 +234,7 @@ typedef uint64_t xen_callback_t;
>  #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_IT_MASK     (0x0600fc00)  /* Thumb If-Then Mask */
>  #define PSR_JAZELLE     (1<<24)       /* Jazelle Mode */
>  
>  #endif /*  __XEN_PUBLIC_ARCH_ARM_H__ */
> -- 
> 1.7.2.5
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.