Skip to content

Commit 8294fec

Browse files
nhawkins48Russell King (Oracle)
authored andcommitted
ARM: 9206/1: A9: Add ARM ERRATA 764319 workaround (Updated)
Enable the workaround for the 764319 Cortex A-9 erratum. CP14 read accesses to the DBGPRSR and DBGOSLSR registers generate an unexpected Undefined Instruction exception when the DBGSWENABLE external pin is set to 0, even when the CP14 accesses are performed from a privileged mode. The work around catches the exception in a way the kernel does not stop execution with the use of undef_hook. This has been found to effect the HPE GXP SoC. Signed-off-by: Nick Hawkins <nick.hawkins@hpe.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
1 parent ad12c2f commit 8294fec

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

arch/arm/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,17 @@ config ARM_ERRATA_764369
972972
relevant cache maintenance functions and sets a specific bit
973973
in the diagnostic control register of the SCU.
974974

975+
config ARM_ERRATA_764319
976+
bool "ARM errata: Read to DBGPRSR and DBGOSLSR may generate Undefined instruction"
977+
depends on CPU_V7
978+
help
979+
This option enables the workaround for the 764319 Cortex A-9 erratum.
980+
CP14 read accesses to the DBGPRSR and DBGOSLSR registers generate an
981+
unexpected Undefined Instruction exception when the DBGSWENABLE
982+
external pin is set to 0, even when the CP14 accesses are performed
983+
from a privileged mode. This work around catches the exception in a
984+
way the kernel does not stop execution.
985+
975986
config ARM_ERRATA_775420
976987
bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
977988
depends on CPU_V7

arch/arm/kernel/hw_breakpoint.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,23 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
941941
return ret;
942942
}
943943

944+
#ifdef CONFIG_ARM_ERRATA_764319
945+
static int oslsr_fault;
946+
947+
static int debug_oslsr_trap(struct pt_regs *regs, unsigned int instr)
948+
{
949+
oslsr_fault = 1;
950+
instruction_pointer(regs) += 4;
951+
return 0;
952+
}
953+
954+
static struct undef_hook debug_oslsr_hook = {
955+
.instr_mask = 0xffffffff,
956+
.instr_val = 0xee115e91,
957+
.fn = debug_oslsr_trap,
958+
};
959+
#endif
960+
944961
/*
945962
* One-time initialisation.
946963
*/
@@ -974,7 +991,16 @@ static bool core_has_os_save_restore(void)
974991
case ARM_DEBUG_ARCH_V7_1:
975992
return true;
976993
case ARM_DEBUG_ARCH_V7_ECP14:
994+
#ifdef CONFIG_ARM_ERRATA_764319
995+
oslsr_fault = 0;
996+
register_undef_hook(&debug_oslsr_hook);
977997
ARM_DBG_READ(c1, c1, 4, oslsr);
998+
unregister_undef_hook(&debug_oslsr_hook);
999+
if (oslsr_fault)
1000+
return false;
1001+
#else
1002+
ARM_DBG_READ(c1, c1, 4, oslsr);
1003+
#endif
9781004
if (oslsr & ARM_OSLSR_OSLM0)
9791005
return true;
9801006
fallthrough;

0 commit comments

Comments
 (0)