Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-09 Thread Christoffer Dall
On Tue, Jul 07, 2015 at 11:24:06AM +0100, Will Deacon wrote:
 On Tue, Jul 07, 2015 at 11:06:57AM +0100, Zhichao Huang wrote:
  Chazy and me are talking about how to reduce the saving/restoring
  overhead for debug registers.
  We want to add a state in hw_breakpoint.c to indicate whether the host
  enable any hwbrpts or not (might export a fuction that kvm can call),
  then we can read this state from memory instead of reading from real
  hardware registers, and to decide whether we need a world switch or
  not.
  Does it acceptable?
 
 Maybe, hard to tell without the code. There are obvious races to deal with
 if you use variables to indicate whether resources are in use -- why not
 just trap debug access from the host as well? Then you could keep track of
 the owner in kvm and trap accesses from everybody else.
 
The only information we're looking for here is whether the host has
enabled some break/watch point so that we need to disable them before
running the guest.

Just to re-iterate, when we are about to run a guest, we have the
following cases:

1) Neither the host nor the guest has configured any [WB]points
2) Only the host has configured any [WB]points
3) Only the guest has configured any [WB]points
4) Both the host and the guest have configured any [WB]points

In case (1), KVM should enable trapping and swtich the register state on
guest accesses.

In cases (2), (3), and (4) we must switch the register state on each
entry/exit.

If we are to trap debug register accesses in KVM to set a flag to keep
track of the owner (iow. has the host touched the registers) then don't
we impose an ordering requirement of whether KVM or the breakpoint
functionality gets initialized first, and we need to take special care
when tearing down KVM to disable the traps?  It sounds a little complex.

I've previously suggested to simply look at the B/W control registers to
figure out what to do.  Caching the state in memory is an optimization,
do we even have any idea how important such an optimization is?

Thanks,
-Christoffer
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-08 Thread Zhichao Huang
Hi, Will,

Are you happy with this?:

diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c

+bool hw_breakpoint_enabled(void)
+{
+struct perf_event **slots;
+int i;
+
+slots = this_cpu_ptr(bp_on_reg);
+for (i = 0; i  core_num_brps; i++) {
+if (slots[i])
+return true;
+}
+
+slots = this_cpu_ptr(wp_on_reg);
+for (i = 0; i  core_num_wrps; i++) {
+if (slots[i])
+return true;
+}
+
+return false;
+}

It doesn't change any existing functions, and even doesn't add a new
variables, it just provide an indication for KVM, and it's low-overhead.

We will only call it upon guest entry, so there is also no race for it.


On July 7, 2015 6:24:06 PM GMT+08:00, Will Deacon will.dea...@arm.com wrote:
On Tue, Jul 07, 2015 at 11:06:57AM +0100, Zhichao Huang wrote:
 Chazy and me are talking about how to reduce the saving/restoring
 overhead for debug registers.
 We want to add a state in hw_breakpoint.c to indicate whether the
host
 enable any hwbrpts or not (might export a fuction that kvm can call),
 then we can read this state from memory instead of reading from real
 hardware registers, and to decide whether we need a world switch or
 not.
 Does it acceptable?

Maybe, hard to tell without the code. There are obvious races to deal
with
if you use variables to indicate whether resources are in use -- why
not
just trap debug access from the host as well? Then you could keep track
of
the owner in kvm and trap accesses from everybody else.

Will

-- 
Zhichao Huang
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-08 Thread Will Deacon
On Wed, Jul 08, 2015 at 11:50:22AM +0100, Zhichao Huang wrote:
 Are you happy with this?:

You miss the reserved breakpoint, I think.
I also still don't understand why this is preferable to trapping.

Will
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-07 Thread Zhichao Huang
Hi, Will,

Chazy and me are talking about how to reduce the saving/restoring
overhead for debug registers.
We want to add a state in hw_breakpoint.c to indicate whether the host
enable any hwbrpts or not (might export a fuction that kvm can call),
then we can read this state from memory instead of reading from real
hardware registers, and to decide whether we need a world switch or
not.
Does it acceptable?


On July 3, 2015 7:56:11 PM GMT+08:00, Christoffer Dall 
christoffer.d...@linaro.org wrote:
On Fri, Jul 03, 2015 at 05:54:47PM +0800, Zhichao Huang wrote:
 
 
 On June 30, 2015 5:20:20 PM GMT+08:00, Christoffer Dall 
 christoffer.d...@linaro.org wrote:
 On Mon, Jun 22, 2015 at 06:41:31PM +0800, Zhichao Huang wrote:
  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: Zhichao Huang zhichao.hu...@linaro.org
  ---
   arch/arm/include/asm/kvm_asm.h  |  3 +++
   arch/arm/include/asm/kvm_host.h |  3 +++
   arch/arm/kernel/asm-offsets.c   |  1 +
   arch/arm/kvm/coproc.c   | 39 
  --
   arch/arm/kvm/interrupts_head.S  | 42 
  +
   5 files changed, 86 insertions(+), 2 deletions(-)
  
  diff --git a/arch/arm/include/asm/kvm_asm.h 
  b/arch/arm/include/asm/kvm_asm.h
  index ba65e05..4fb64cf 100644
  --- a/arch/arm/include/asm/kvm_asm.h
  +++ b/arch/arm/include/asm/kvm_asm.h
  @@ -64,6 +64,9 @@
   #define cp14_DBGDSCRext  65  /* Debug Status and Control external */
   #define NR_CP14_REGS 66  /* Number of regs (incl. invalid) */
   
  +#define KVM_ARM_DEBUG_DIRTY_SHIFT0
  +#define KVM_ARM_DEBUG_DIRTY  (1  KVM_ARM_DEBUG_DIRTY_SHIFT)
  +
   #define ARM_EXCEPTION_RESET0
   #define ARM_EXCEPTION_UNDEFINED   1
   #define ARM_EXCEPTION_SOFTWARE2
  diff --git a/arch/arm/include/asm/kvm_host.h 
  b/arch/arm/include/asm/kvm_host.h
  index 3d16820..09b54bf 100644
  --- a/arch/arm/include/asm/kvm_host.h
  +++ b/arch/arm/include/asm/kvm_host.h
  @@ -127,6 +127,9 @@ struct kvm_vcpu_arch {
/* System control coprocessor (cp14) */
u32 cp14[NR_CP14_REGS];
   
  + /* Debug state */
  + u32 debug_flags;
  +
/*
 * Anything that is not used directly from assembly code goes
 * here.
  diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
  index 9158de0..e876109 100644
  --- a/arch/arm/kernel/asm-offsets.c
  +++ b/arch/arm/kernel/asm-offsets.c
  @@ -185,6 +185,7 @@ int main(void)
 DEFINE(VCPU_FIQ_REGS,  offsetof(struct kvm_vcpu,
 arch.regs.fiq_regs));
 DEFINE(VCPU_PC,offsetof(struct kvm_vcpu,
 arch.regs.usr_regs.ARM_pc));
 DEFINE(VCPU_CPSR,  offsetof(struct kvm_vcpu,
 arch.regs.usr_regs.ARM_cpsr));
  +  DEFINE(VCPU_DEBUG_FLAGS,   offsetof(struct kvm_vcpu,
 arch.debug_flags));
 DEFINE(VCPU_HCR,   offsetof(struct kvm_vcpu, arch.hcr));
 DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines));
 DEFINE(VCPU_HSR,   offsetof(struct kvm_vcpu, 
  arch.fault.hsr));
  diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
  index 648..fc0c2ef 100644
  --- a/arch/arm/kvm/coproc.c
  +++ b/arch/arm/kvm/coproc.c
  @@ -220,14 +220,49 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
return true;
   }
   
  +/*
  + * We want to avoid world-switching all the DBG registers all the
  + * time:
  + *
  + * - If we've touched any debug register, it is likely that we're
  + *   going to touch more of them. It then makes sense to disable the
  + *   traps and start doing the save/restore dance
  + * - If debug is active (ARM_DSCR_MDBGEN set), it is then mandatory
  + *   to save/restore the registers, as the guest depends on them.
  + *
  + * For this, we use a DIRTY bit, indicating the guest has modified the
  + * debug registers, used as follow:
  + *
  + * On guest entry:
  + * - If the dirty bit is set (because we're coming back from trapping),
  + *   disable the traps, save host registers, restore guest registers.
  + * - If debug is actively in use (ARM_DSCR_MDBGEN set),
  + *   set the dirty bit, disable the traps, save host registers,
  + *   restore guest registers.
  + * - Otherwise, enable the traps
  + *
  + * On guest exit:
  + * - If the dirty bit is set, save guest registers, restore host
  + *   registers and clear the dirty bit. This ensure that the host can
  + *   now use the debug registers.
  + *
  + * Notice:
  + * - For ARMv7, if the CONFIG_HAVE_HW_BREAKPOINT is set in the guest,
  + *   debug is always actively in use (ARM_DSCR_MDBGEN set).
  + *   We have to do the save/restore dance in this case, because the
  + *   host and the guest might use their respective debug registers
  + *   at any moment.
 
 so doesn't this pretty much invalidate the whole saving/dirty effort?
 
 Guests configured from for example multi_v7_defconfig will then act
 like
 this and 

Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-07 Thread Will Deacon
On Tue, Jul 07, 2015 at 11:06:57AM +0100, Zhichao Huang wrote:
 Chazy and me are talking about how to reduce the saving/restoring
 overhead for debug registers.
 We want to add a state in hw_breakpoint.c to indicate whether the host
 enable any hwbrpts or not (might export a fuction that kvm can call),
 then we can read this state from memory instead of reading from real
 hardware registers, and to decide whether we need a world switch or
 not.
 Does it acceptable?

Maybe, hard to tell without the code. There are obvious races to deal with
if you use variables to indicate whether resources are in use -- why not
just trap debug access from the host as well? Then you could keep track of
the owner in kvm and trap accesses from everybody else.

Will
___
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-03 Thread Zhichao Huang


On June 30, 2015 5:20:20 PM GMT+08:00, Christoffer Dall 
christoffer.d...@linaro.org wrote:
On Mon, Jun 22, 2015 at 06:41:31PM +0800, Zhichao Huang wrote:
 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: Zhichao Huang zhichao.hu...@linaro.org
 ---
  arch/arm/include/asm/kvm_asm.h  |  3 +++
  arch/arm/include/asm/kvm_host.h |  3 +++
  arch/arm/kernel/asm-offsets.c   |  1 +
  arch/arm/kvm/coproc.c   | 39 --
  arch/arm/kvm/interrupts_head.S  | 42
+
  5 files changed, 86 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
 index ba65e05..4fb64cf 100644
 --- a/arch/arm/include/asm/kvm_asm.h
 +++ b/arch/arm/include/asm/kvm_asm.h
 @@ -64,6 +64,9 @@
  #define cp14_DBGDSCRext 65  /* Debug Status and Control external */
  #define NR_CP14_REGS66  /* Number of regs (incl. invalid) */
  
 +#define KVM_ARM_DEBUG_DIRTY_SHIFT   0
 +#define KVM_ARM_DEBUG_DIRTY (1  KVM_ARM_DEBUG_DIRTY_SHIFT)
 +
  #define ARM_EXCEPTION_RESET   0
  #define ARM_EXCEPTION_UNDEFINED   1
  #define ARM_EXCEPTION_SOFTWARE2
 diff --git a/arch/arm/include/asm/kvm_host.h 
 b/arch/arm/include/asm/kvm_host.h
 index 3d16820..09b54bf 100644
 --- a/arch/arm/include/asm/kvm_host.h
 +++ b/arch/arm/include/asm/kvm_host.h
 @@ -127,6 +127,9 @@ struct kvm_vcpu_arch {
  /* System control coprocessor (cp14) */
  u32 cp14[NR_CP14_REGS];
  
 +/* Debug state */
 +u32 debug_flags;
 +
  /*
   * Anything that is not used directly from assembly code goes
   * here.
 diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
 index 9158de0..e876109 100644
 --- a/arch/arm/kernel/asm-offsets.c
 +++ b/arch/arm/kernel/asm-offsets.c
 @@ -185,6 +185,7 @@ int main(void)
DEFINE(VCPU_FIQ_REGS, offsetof(struct kvm_vcpu,
arch.regs.fiq_regs));
DEFINE(VCPU_PC,   offsetof(struct kvm_vcpu,
arch.regs.usr_regs.ARM_pc));
DEFINE(VCPU_CPSR, offsetof(struct kvm_vcpu,
arch.regs.usr_regs.ARM_cpsr));
 +  DEFINE(VCPU_DEBUG_FLAGS,  offsetof(struct kvm_vcpu,
arch.debug_flags));
DEFINE(VCPU_HCR,  offsetof(struct kvm_vcpu, arch.hcr));
DEFINE(VCPU_IRQ_LINES,offsetof(struct kvm_vcpu, arch.irq_lines));
DEFINE(VCPU_HSR,  offsetof(struct kvm_vcpu, arch.fault.hsr));
 diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
 index 648..fc0c2ef 100644
 --- a/arch/arm/kvm/coproc.c
 +++ b/arch/arm/kvm/coproc.c
 @@ -220,14 +220,49 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
  return true;
  }
  
 +/*
 + * We want to avoid world-switching all the DBG registers all the
 + * time:
 + *
 + * - If we've touched any debug register, it is likely that we're
 + *   going to touch more of them. It then makes sense to disable the
 + *   traps and start doing the save/restore dance
 + * - If debug is active (ARM_DSCR_MDBGEN set), it is then mandatory
 + *   to save/restore the registers, as the guest depends on them.
 + *
 + * For this, we use a DIRTY bit, indicating the guest has modified
the
 + * debug registers, used as follow:
 + *
 + * On guest entry:
 + * - If the dirty bit is set (because we're coming back from
trapping),
 + *   disable the traps, save host registers, restore guest
registers.
 + * - If debug is actively in use (ARM_DSCR_MDBGEN set),
 + *   set the dirty bit, disable the traps, save host registers,
 + *   restore guest registers.
 + * - Otherwise, enable the traps
 + *
 + * On guest exit:
 + * - If the dirty bit is set, save guest registers, restore host
 + *   registers and clear the dirty bit. This ensure that the host can
 + *   now use the debug registers.
 + *
 + * Notice:
 + * - For ARMv7, if the CONFIG_HAVE_HW_BREAKPOINT is set in the guest,
 + *   debug is always actively in use (ARM_DSCR_MDBGEN set).
 + *   We have to do the save/restore dance in this case, because the
 + *   host and the guest might use their respective debug registers
 + *   at any moment.

so doesn't this pretty much invalidate the whole saving/dirty effort?

Guests configured from for example multi_v7_defconfig will then act
like
this and you will save/restore all these registers always.

Wouldn't a better approach be to enable trapping to hyp mode most of
the
time, and simply clear the enabled bit of any host-used break- or
wathcpoints upon guest entry, perhaps maintaining a bitmap of which
ones
must be re-set when exiting the guest, and thereby drastically reducing
the amount of save/restore code you'd have to perform.

Of course, you'd also have to keep track of whether the guest has any
breakpoints or watchpoints enabled for when you do the full
save/restore
dance.

That would also avoid all issues surrounding accesses to DBGDSCRext
register I think.

I have thought about it, which means to say, Since we can't 

Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-07-03 Thread Christoffer Dall
On Fri, Jul 03, 2015 at 05:54:47PM +0800, Zhichao Huang wrote:
 
 
 On June 30, 2015 5:20:20 PM GMT+08:00, Christoffer Dall 
 christoffer.d...@linaro.org wrote:
 On Mon, Jun 22, 2015 at 06:41:31PM +0800, Zhichao Huang wrote:
  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: Zhichao Huang zhichao.hu...@linaro.org
  ---
   arch/arm/include/asm/kvm_asm.h  |  3 +++
   arch/arm/include/asm/kvm_host.h |  3 +++
   arch/arm/kernel/asm-offsets.c   |  1 +
   arch/arm/kvm/coproc.c   | 39 
  --
   arch/arm/kvm/interrupts_head.S  | 42
 +
   5 files changed, 86 insertions(+), 2 deletions(-)
  
  diff --git a/arch/arm/include/asm/kvm_asm.h 
  b/arch/arm/include/asm/kvm_asm.h
  index ba65e05..4fb64cf 100644
  --- a/arch/arm/include/asm/kvm_asm.h
  +++ b/arch/arm/include/asm/kvm_asm.h
  @@ -64,6 +64,9 @@
   #define cp14_DBGDSCRext   65  /* Debug Status and Control external */
   #define NR_CP14_REGS  66  /* Number of regs (incl. invalid) */
   
  +#define KVM_ARM_DEBUG_DIRTY_SHIFT 0
  +#define KVM_ARM_DEBUG_DIRTY   (1  KVM_ARM_DEBUG_DIRTY_SHIFT)
  +
   #define ARM_EXCEPTION_RESET 0
   #define ARM_EXCEPTION_UNDEFINED   1
   #define ARM_EXCEPTION_SOFTWARE2
  diff --git a/arch/arm/include/asm/kvm_host.h 
  b/arch/arm/include/asm/kvm_host.h
  index 3d16820..09b54bf 100644
  --- a/arch/arm/include/asm/kvm_host.h
  +++ b/arch/arm/include/asm/kvm_host.h
  @@ -127,6 +127,9 @@ struct kvm_vcpu_arch {
 /* System control coprocessor (cp14) */
 u32 cp14[NR_CP14_REGS];
   
  +  /* Debug state */
  +  u32 debug_flags;
  +
 /*
  * Anything that is not used directly from assembly code goes
  * here.
  diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
  index 9158de0..e876109 100644
  --- a/arch/arm/kernel/asm-offsets.c
  +++ b/arch/arm/kernel/asm-offsets.c
  @@ -185,6 +185,7 @@ int main(void)
 DEFINE(VCPU_FIQ_REGS,   offsetof(struct kvm_vcpu,
 arch.regs.fiq_regs));
 DEFINE(VCPU_PC, offsetof(struct kvm_vcpu,
 arch.regs.usr_regs.ARM_pc));
 DEFINE(VCPU_CPSR,   offsetof(struct kvm_vcpu,
 arch.regs.usr_regs.ARM_cpsr));
  +  DEFINE(VCPU_DEBUG_FLAGS,offsetof(struct kvm_vcpu,
 arch.debug_flags));
 DEFINE(VCPU_HCR,offsetof(struct kvm_vcpu, arch.hcr));
 DEFINE(VCPU_IRQ_LINES,  offsetof(struct kvm_vcpu, arch.irq_lines));
 DEFINE(VCPU_HSR,offsetof(struct kvm_vcpu, 
  arch.fault.hsr));
  diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
  index 648..fc0c2ef 100644
  --- a/arch/arm/kvm/coproc.c
  +++ b/arch/arm/kvm/coproc.c
  @@ -220,14 +220,49 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
 return true;
   }
   
  +/*
  + * We want to avoid world-switching all the DBG registers all the
  + * time:
  + *
  + * - If we've touched any debug register, it is likely that we're
  + *   going to touch more of them. It then makes sense to disable the
  + *   traps and start doing the save/restore dance
  + * - If debug is active (ARM_DSCR_MDBGEN set), it is then mandatory
  + *   to save/restore the registers, as the guest depends on them.
  + *
  + * For this, we use a DIRTY bit, indicating the guest has modified
 the
  + * debug registers, used as follow:
  + *
  + * On guest entry:
  + * - If the dirty bit is set (because we're coming back from
 trapping),
  + *   disable the traps, save host registers, restore guest
 registers.
  + * - If debug is actively in use (ARM_DSCR_MDBGEN set),
  + *   set the dirty bit, disable the traps, save host registers,
  + *   restore guest registers.
  + * - Otherwise, enable the traps
  + *
  + * On guest exit:
  + * - If the dirty bit is set, save guest registers, restore host
  + *   registers and clear the dirty bit. This ensure that the host can
  + *   now use the debug registers.
  + *
  + * Notice:
  + * - For ARMv7, if the CONFIG_HAVE_HW_BREAKPOINT is set in the guest,
  + *   debug is always actively in use (ARM_DSCR_MDBGEN set).
  + *   We have to do the save/restore dance in this case, because the
  + *   host and the guest might use their respective debug registers
  + *   at any moment.
 
 so doesn't this pretty much invalidate the whole saving/dirty effort?
 
 Guests configured from for example multi_v7_defconfig will then act
 like
 this and you will save/restore all these registers always.
 
 Wouldn't a better approach be to enable trapping to hyp mode most of
 the
 time, and simply clear the enabled bit of any host-used break- or
 wathcpoints upon guest entry, perhaps maintaining a bitmap of which
 ones
 must be re-set when exiting the guest, and thereby drastically reducing
 the amount of save/restore code you'd have to perform.
 
 Of course, you'd also have to keep track of whether the guest has any
 breakpoints or watchpoints 

Re: [PATCH v3 08/11] KVM: arm: implement dirty bit mechanism for debug registers

2015-06-30 Thread Christoffer Dall
On Mon, Jun 22, 2015 at 06:41:31PM +0800, Zhichao Huang wrote:
 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: Zhichao Huang zhichao.hu...@linaro.org
 ---
  arch/arm/include/asm/kvm_asm.h  |  3 +++
  arch/arm/include/asm/kvm_host.h |  3 +++
  arch/arm/kernel/asm-offsets.c   |  1 +
  arch/arm/kvm/coproc.c   | 39 --
  arch/arm/kvm/interrupts_head.S  | 42 
 +
  5 files changed, 86 insertions(+), 2 deletions(-)
 
 diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
 index ba65e05..4fb64cf 100644
 --- a/arch/arm/include/asm/kvm_asm.h
 +++ b/arch/arm/include/asm/kvm_asm.h
 @@ -64,6 +64,9 @@
  #define cp14_DBGDSCRext  65  /* Debug Status and Control external */
  #define NR_CP14_REGS 66  /* Number of regs (incl. invalid) */
  
 +#define KVM_ARM_DEBUG_DIRTY_SHIFT0
 +#define KVM_ARM_DEBUG_DIRTY  (1  KVM_ARM_DEBUG_DIRTY_SHIFT)
 +
  #define ARM_EXCEPTION_RESET0
  #define ARM_EXCEPTION_UNDEFINED   1
  #define ARM_EXCEPTION_SOFTWARE2
 diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
 index 3d16820..09b54bf 100644
 --- a/arch/arm/include/asm/kvm_host.h
 +++ b/arch/arm/include/asm/kvm_host.h
 @@ -127,6 +127,9 @@ struct kvm_vcpu_arch {
   /* System control coprocessor (cp14) */
   u32 cp14[NR_CP14_REGS];
  
 + /* Debug state */
 + u32 debug_flags;
 +
   /*
* Anything that is not used directly from assembly code goes
* here.
 diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
 index 9158de0..e876109 100644
 --- a/arch/arm/kernel/asm-offsets.c
 +++ b/arch/arm/kernel/asm-offsets.c
 @@ -185,6 +185,7 @@ int main(void)
DEFINE(VCPU_FIQ_REGS,  offsetof(struct kvm_vcpu, 
 arch.regs.fiq_regs));
DEFINE(VCPU_PC,offsetof(struct kvm_vcpu, 
 arch.regs.usr_regs.ARM_pc));
DEFINE(VCPU_CPSR,  offsetof(struct kvm_vcpu, 
 arch.regs.usr_regs.ARM_cpsr));
 +  DEFINE(VCPU_DEBUG_FLAGS,   offsetof(struct kvm_vcpu, arch.debug_flags));
DEFINE(VCPU_HCR,   offsetof(struct kvm_vcpu, arch.hcr));
DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines));
DEFINE(VCPU_HSR,   offsetof(struct kvm_vcpu, arch.fault.hsr));
 diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
 index 648..fc0c2ef 100644
 --- a/arch/arm/kvm/coproc.c
 +++ b/arch/arm/kvm/coproc.c
 @@ -220,14 +220,49 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
   return true;
  }
  
 +/*
 + * We want to avoid world-switching all the DBG registers all the
 + * time:
 + *
 + * - If we've touched any debug register, it is likely that we're
 + *   going to touch more of them. It then makes sense to disable the
 + *   traps and start doing the save/restore dance
 + * - If debug is active (ARM_DSCR_MDBGEN set), it is then mandatory
 + *   to save/restore the registers, as the guest depends on them.
 + *
 + * For this, we use a DIRTY bit, indicating the guest has modified the
 + * debug registers, used as follow:
 + *
 + * On guest entry:
 + * - If the dirty bit is set (because we're coming back from trapping),
 + *   disable the traps, save host registers, restore guest registers.
 + * - If debug is actively in use (ARM_DSCR_MDBGEN set),
 + *   set the dirty bit, disable the traps, save host registers,
 + *   restore guest registers.
 + * - Otherwise, enable the traps
 + *
 + * On guest exit:
 + * - If the dirty bit is set, save guest registers, restore host
 + *   registers and clear the dirty bit. This ensure that the host can
 + *   now use the debug registers.
 + *
 + * Notice:
 + * - For ARMv7, if the CONFIG_HAVE_HW_BREAKPOINT is set in the guest,
 + *   debug is always actively in use (ARM_DSCR_MDBGEN set).
 + *   We have to do the save/restore dance in this case, because the
 + *   host and the guest might use their respective debug registers
 + *   at any moment.

so doesn't this pretty much invalidate the whole saving/dirty effort?

Guests configured from for example multi_v7_defconfig will then act like
this and you will save/restore all these registers always.

Wouldn't a better approach be to enable trapping to hyp mode most of the
time, and simply clear the enabled bit of any host-used break- or
wathcpoints upon guest entry, perhaps maintaining a bitmap of which ones
must be re-set when exiting the guest, and thereby drastically reducing
the amount of save/restore code you'd have to perform.

Of course, you'd also have to keep track of whether the guest has any
breakpoints or watchpoints enabled for when you do the full save/restore
dance.

That would also avoid all issues surrounding accesses to DBGDSCRext
register I think.

 + */
  static bool trap_debug32(struct kvm_vcpu *vcpu,
   const struct coproc_params *p,
   const