Hi, Will,

On 2015/6/1 18:16, Will Deacon wrote:
> On Sun, May 31, 2015 at 05:27:10AM +0100, Zhichao Huang wrote:
>> Until now we enable debug mode all the time even if we don't
>> actually need it.
>>
>> Inspired by the implementation in arm64, disable debug mode if
>> we don't need it. And then we are able to reduce unnecessary
>> registers saving/restoring when the debug mode is disabled.
> 
> I'm terrified about this patch. Enabling monitor mode has proven to be
> *extremely* fragile in practice on 32-bit ARM SoCs, so trying to do this
> morei often makes me very nervous.
> 
>> Signed-off-by: Zhichao Huang <zhichao.hu...@linaro.org>
>> ---
>>  arch/arm/kernel/hw_breakpoint.c | 55 
>> ++++++++++++++++++++++++++++++++++-------
>>  1 file changed, 46 insertions(+), 9 deletions(-)
>>
>> diff --git a/arch/arm/kernel/hw_breakpoint.c 
>> b/arch/arm/kernel/hw_breakpoint.c
>> index dc7d0a9..1d27563 100644
>> --- a/arch/arm/kernel/hw_breakpoint.c
>> +++ b/arch/arm/kernel/hw_breakpoint.c
>> @@ -266,8 +266,7 @@ static int enable_monitor_mode(void)
>>      }
>>  
>>      /* Check that the write made it through. */
>> -    ARM_DBG_READ(c0, c1, 0, dscr);
>> -    if (!(dscr & ARM_DSCR_MDBGEN)) {
>> +    if (!monitor_mode_enabled()) {
>>              pr_warn_once("Failed to enable monitor mode on CPU %d.\n",
>>                              smp_processor_id());
>>              return -EPERM;
> 
> Ok, this hunk is harmless :)
> 
>> @@ -277,6 +276,43 @@ out:
>>      return 0;
>>  }
>>  
>> +static int disable_monitor_mode(void)
>> +{
>> +    u32 dscr;
>> +
>> +    ARM_DBG_READ(c0, c1, 0, dscr);
>> +
>> +    /* If monitor mode is already disabled, just return. */
>> +    if (!(dscr & ARM_DSCR_MDBGEN))
>> +            goto out;
>> +
>> +    /* Write to the corresponding DSCR. */
>> +    switch (get_debug_arch()) {
>> +    case ARM_DEBUG_ARCH_V6:
>> +    case ARM_DEBUG_ARCH_V6_1:
>> +            ARM_DBG_WRITE(c0, c1, 0, (dscr & ~ARM_DSCR_MDBGEN));
>> +            break;
>> +    case ARM_DEBUG_ARCH_V7_ECP14:
>> +    case ARM_DEBUG_ARCH_V7_1:
>> +    case ARM_DEBUG_ARCH_V8:
>> +            ARM_DBG_WRITE(c0, c2, 2, (dscr & ~ARM_DSCR_MDBGEN));
>> +            isb();
>> +            break;
>> +    default:
>> +            return -ENODEV;
>> +    }
>> +
>> +    /* Check that the write made it through. */
>> +    if (monitor_mode_enabled()) {
>> +            pr_warn_once("Failed to disable monitor mode on CPU %d.\n",
>> +                            smp_processor_id());
>> +            return -EPERM;
>> +    }
>> +
>> +out:
>> +    return 0;
>> +}
> 
> I'm not comfortable with this. enable_monitor_mode has precisly one caller
> [reset_ctrl_regs] which goes to some lengths to get the system into a
> well-defined state. On top of that, the whole thing is run with an undef
> hook registered because there isn't an architected way to discover whether
> or not DBGSWENABLE is driven low.
> 
> Why exactly do you need this? Can you not trap guest debug accesses some
> other way?

OK, I shall look for some other ways to reduce the overhead of world switch.

And another problem might be that, when we start an ARMv7 vm (specify CPU to
be Cortex-A57) on the ARMv8 platform, debug registers will always be 
saving/loading
because it is always detected that the debug mode is enabled even though we
didn't acutally use it.

> 
>>  int hw_breakpoint_slots(int type)
>>  {
>>      if (!debug_arch_supported())
>> @@ -338,6 +374,8 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
>>      int i, max_slots, ctrl_base, val_base;
>>      u32 addr, ctrl;
>>  
>> +    enable_monitor_mode();
>> +
>>      addr = info->address;
>>      ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
>>  
>> @@ -430,6 +468,8 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
>>  
>>      /* Reset the control register. */
>>      write_wb_reg(base + i, 0);
>> +
>> +    disable_monitor_mode();
> 
> My previous concerns notwithstanding, shouldn't this be refcounted?

Maybe shouldn't in my opinion, because we install/uninstall breakpoints only 
when
we does context switch, and then we always install/uninstall all the 
breakpoints.

> 
> Will
> 
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to