Re: [PATCH 3/9] arm64: KVM: add trap handlers for AArch64 debug registers

2014-05-19 Thread Anup Patel
On 7 May 2014 20:50, Marc Zyngier  wrote:
> Add handlers for all the AArch64 debug registers that are accessible
> from EL0 or EL1. The trapping code keeps track of the state of the
> debug registers, allowing for the switch code to implement a lazy
> switching strategy.
>
> Signed-off-by: Marc Zyngier 
> ---
>  arch/arm64/include/asm/kvm_asm.h  |  28 ++--
>  arch/arm64/include/asm/kvm_host.h |   3 +
>  arch/arm64/kvm/sys_regs.c | 130 
> +-
>  3 files changed, 151 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h 
> b/arch/arm64/include/asm/kvm_asm.h
> index 9fcd54b..e6b159a 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -43,14 +43,25 @@
>  #defineAMAIR_EL1   19  /* Aux Memory Attribute Indirection 
> Register */
>  #defineCNTKCTL_EL1 20  /* Timer Control Register (EL1) */
>  #definePAR_EL1 21  /* Physical Address Register */
> +#define MDSCR_EL1  22  /* Monitor Debug System Control Register */
> +#define DBGBCR0_EL123  /* Debug Breakpoint Control Registers (0-15) 
> */
> +#define DBGBCR15_EL1   38
> +#define DBGBVR0_EL139  /* Debug Breakpoint Value Registers (0-15) */
> +#define DBGBVR15_EL1   54
> +#define DBGWCR0_EL155  /* Debug Watchpoint Control Registers (0-15) 
> */
> +#define DBGWCR15_EL1   70
> +#define DBGWVR0_EL171  /* Debug Watchpoint Value Registers (0-15) */
> +#define DBGWVR15_EL1   86
> +#define MDCCINT_EL187  /* Monitor Debug Comms Channel Interrupt 
> Enable Reg */
> +
>  /* 32bit specific registers. Keep them at the end of the range */
> -#defineDACR32_EL2  22  /* Domain Access Control Register */
> -#defineIFSR32_EL2  23  /* Instruction Fault Status Register 
> */
> -#defineFPEXC32_EL2 24  /* Floating-Point Exception Control 
> Register */
> -#defineDBGVCR32_EL225  /* Debug Vector Catch Register */
> -#defineTEECR32_EL1 26  /* ThumbEE Configuration Register */
> -#defineTEEHBR32_EL127  /* ThumbEE Handler Base Register */
> -#defineNR_SYS_REGS 28
> +#defineDACR32_EL2  88  /* Domain Access Control Register */
> +#defineIFSR32_EL2  89  /* Instruction Fault Status Register 
> */
> +#defineFPEXC32_EL2 90  /* Floating-Point Exception Control 
> Register */
> +#defineDBGVCR32_EL291  /* Debug Vector Catch Register */
> +#defineTEECR32_EL1 92  /* ThumbEE Configuration Register */
> +#defineTEEHBR32_EL193  /* ThumbEE Handler Base Register */
> +#defineNR_SYS_REGS 94
>
>  /* 32bit mapping */
>  #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
> @@ -87,6 +98,9 @@
>  #define ARM_EXCEPTION_IRQ0
>  #define ARM_EXCEPTION_TRAP   1
>
> +#define KVM_ARM64_DEBUG_DIRTY_SHIFT0
> +#define KVM_ARM64_DEBUG_DIRTY  (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
> +
>  #ifndef __ASSEMBLY__
>  struct kvm;
>  struct kvm_vcpu;
> diff --git a/arch/arm64/include/asm/kvm_host.h 
> b/arch/arm64/include/asm/kvm_host.h
> index 0a1d697..4737961 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -101,6 +101,9 @@ struct kvm_vcpu_arch {
> /* Exception Information */
> struct kvm_vcpu_fault_info fault;
>
> +   /* Debug state */
> +   u64 debug_flags;
> +
> /* Pointer to host CPU context */
> kvm_cpu_context_t *host_cpu_context;
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index fc8d4e3..618d4fb 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>
>  #include "sys_regs.h"
> @@ -173,6 +174,58 @@ static bool trap_wi_raz(struct kvm_vcpu *vcpu,
> return read_zero(vcpu, p);
>  }
>
> +static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
> +  const struct sys_reg_params *p,
> +  const struct sys_reg_desc *r)
> +{
> +   if (p->is_write) {
> +   return ignore_write(vcpu, p);
> +   } else {
> +   *vcpu_reg(vcpu, p->Rt) = (1 << 3);
> +   return true;
> +   }
> +}
> +
> +static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
> +  const struct sys_reg_params *p,
> +  const struct sys_reg_desc *r)
> +{
> +   if (p->is_write) {
> +   return ignore_write(vcpu, p);
> +   } else {
> +   *vcpu_reg(vcpu, p->Rt) = 0x; /* Implemented and disabled 
> */
> +   return true;
> +   }
> +}
> +
> +/*
> + * Trap handler for DBG[BW][CV]Rn_EL1 and MDSCR_EL1. We track the
> + * "dirtiness" of the registers.
> + */
> +static bool trap_debug_regs(struct 

[PATCH 3/9] arm64: KVM: add trap handlers for AArch64 debug registers

2014-05-07 Thread Marc Zyngier
Add handlers for all the AArch64 debug registers that are accessible
from EL0 or EL1. The trapping code keeps track of the state of the
debug registers, allowing for the switch code to implement a lazy
switching strategy.

Signed-off-by: Marc Zyngier 
---
 arch/arm64/include/asm/kvm_asm.h  |  28 ++--
 arch/arm64/include/asm/kvm_host.h |   3 +
 arch/arm64/kvm/sys_regs.c | 130 +-
 3 files changed, 151 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 9fcd54b..e6b159a 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -43,14 +43,25 @@
 #defineAMAIR_EL1   19  /* Aux Memory Attribute Indirection 
Register */
 #defineCNTKCTL_EL1 20  /* Timer Control Register (EL1) */
 #definePAR_EL1 21  /* Physical Address Register */
+#define MDSCR_EL1  22  /* Monitor Debug System Control Register */
+#define DBGBCR0_EL123  /* Debug Breakpoint Control Registers (0-15) */
+#define DBGBCR15_EL1   38
+#define DBGBVR0_EL139  /* Debug Breakpoint Value Registers (0-15) */
+#define DBGBVR15_EL1   54
+#define DBGWCR0_EL155  /* Debug Watchpoint Control Registers (0-15) */
+#define DBGWCR15_EL1   70
+#define DBGWVR0_EL171  /* Debug Watchpoint Value Registers (0-15) */
+#define DBGWVR15_EL1   86
+#define MDCCINT_EL187  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
+
 /* 32bit specific registers. Keep them at the end of the range */
-#defineDACR32_EL2  22  /* Domain Access Control Register */
-#defineIFSR32_EL2  23  /* Instruction Fault Status Register */
-#defineFPEXC32_EL2 24  /* Floating-Point Exception Control 
Register */
-#defineDBGVCR32_EL225  /* Debug Vector Catch Register */
-#defineTEECR32_EL1 26  /* ThumbEE Configuration Register */
-#defineTEEHBR32_EL127  /* ThumbEE Handler Base Register */
-#defineNR_SYS_REGS 28
+#defineDACR32_EL2  88  /* Domain Access Control Register */
+#defineIFSR32_EL2  89  /* Instruction Fault Status Register */
+#defineFPEXC32_EL2 90  /* Floating-Point Exception Control 
Register */
+#defineDBGVCR32_EL291  /* Debug Vector Catch Register */
+#defineTEECR32_EL1 92  /* ThumbEE Configuration Register */
+#defineTEEHBR32_EL193  /* ThumbEE Handler Base Register */
+#defineNR_SYS_REGS 94
 
 /* 32bit mapping */
 #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
@@ -87,6 +98,9 @@
 #define ARM_EXCEPTION_IRQ0
 #define ARM_EXCEPTION_TRAP   1
 
+#define KVM_ARM64_DEBUG_DIRTY_SHIFT0
+#define KVM_ARM64_DEBUG_DIRTY  (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
+
 #ifndef __ASSEMBLY__
 struct kvm;
 struct kvm_vcpu;
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 0a1d697..4737961 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -101,6 +101,9 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
 
+   /* Debug state */
+   u64 debug_flags;
+
/* Pointer to host CPU context */
kvm_cpu_context_t *host_cpu_context;
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index fc8d4e3..618d4fb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "sys_regs.h"
@@ -173,6 +174,58 @@ static bool trap_wi_raz(struct kvm_vcpu *vcpu,
return read_zero(vcpu, p);
 }
 
+static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
+  const struct sys_reg_params *p,
+  const struct sys_reg_desc *r)
+{
+   if (p->is_write) {
+   return ignore_write(vcpu, p);
+   } else {
+   *vcpu_reg(vcpu, p->Rt) = (1 << 3);
+   return true;
+   }
+}
+
+static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
+  const struct sys_reg_params *p,
+  const struct sys_reg_desc *r)
+{
+   if (p->is_write) {
+   return ignore_write(vcpu, p);
+   } else {
+   *vcpu_reg(vcpu, p->Rt) = 0x; /* Implemented and disabled */
+   return true;
+   }
+}
+
+/*
+ * Trap handler for DBG[BW][CV]Rn_EL1 and MDSCR_EL1. We track the
+ * "dirtiness" of the registers.
+ */
+static bool trap_debug_regs(struct kvm_vcpu *vcpu,
+   const struct sys_reg_params *p,
+   const struct sys_reg_desc *r)
+{
+   /*
+* The best thing to do would be to trap MDSCR_EL1
+* independently, test if DBG_MDSCR_KDE or DBG_MDSCR_MDE is
+* getting s