mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 04:42:04 -04:00
Merge "arm64: Add TLB conflict fault handler"
This commit is contained in:
commit
45e5597f7b
6 changed files with 63 additions and 0 deletions
|
|
@ -1793,6 +1793,14 @@ config BUILD_ARM64_DT_OVERLAY
|
|||
required flags to add DT overlay in the
|
||||
compilation.
|
||||
|
||||
config TLB_CONF_HANDLER
|
||||
bool "enable handler for TLB conflict"
|
||||
help
|
||||
This option enables graceful handling of TLB
|
||||
conflict in EL2. Say yes here to enable TLB
|
||||
conflict handler.
|
||||
If unsure, Say n.
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
depends on COMPAT && SYSVIPC
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@
|
|||
#include <linux/preempt.h>
|
||||
#include <linux/hugetlb.h>
|
||||
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
#include <linux/qcom_scm.h>
|
||||
#endif
|
||||
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/bug.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
|
|
@ -691,6 +695,15 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
static int do_tlb_conf_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs)
|
||||
{
|
||||
if (qcom_scm_tlb_conf_handler(addr))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct fault_info fault_info[] = {
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "ttbr address size fault" },
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "level 1 address size fault" },
|
||||
|
|
@ -740,7 +753,11 @@ static const struct fault_info fault_info[] = {
|
|||
{ do_bad, SIGKILL, SI_KERNEL, "unknown 45" },
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "unknown 46" },
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "unknown 47" },
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
{ do_tlb_conf_fault, SIGKILL, SI_KERNEL, "TLB conflict abort" },
|
||||
#else
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "TLB conflict abort" },
|
||||
#endif
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "Unsupported atomic hardware update fault" },
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "unknown 50" },
|
||||
{ do_bad, SIGKILL, SI_KERNEL, "unknown 51" },
|
||||
|
|
|
|||
|
|
@ -1020,6 +1020,27 @@ int __qcom_scm_sec_wdog_trigger(struct device *dev)
|
|||
return ret ? : desc.res[0];
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
int __qcom_scm_tlb_conf_handler(struct device *dev, unsigned long addr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#define SCM_TLB_CONFLICT_CMD 0x1F
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_MP,
|
||||
.cmd = SCM_TLB_CONFLICT_CMD,
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
desc.args[0] = addr;
|
||||
desc.arginfo = QCOM_SCM_ARGS(1);
|
||||
|
||||
ret = qcom_scm_call_atomic(dev, &desc);
|
||||
|
||||
return ret ? : desc.res[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
void __qcom_scm_disable_sdi(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -160,6 +160,14 @@ int qcom_scm_sec_wdog_trigger(void)
|
|||
}
|
||||
EXPORT_SYMBOL(qcom_scm_sec_wdog_trigger);
|
||||
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
int qcom_scm_tlb_conf_handler(unsigned long addr)
|
||||
{
|
||||
return __qcom_scm_tlb_conf_handler(__scm->dev, addr);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_tlb_conf_handler);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* qcom_scm_disable_sdi() - Disable SDI
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags);
|
|||
extern void __qcom_scm_cpu_hp(struct device *dev, u32 flags);
|
||||
extern int __qcom_scm_sec_wdog_deactivate(struct device *dev);
|
||||
extern int __qcom_scm_sec_wdog_trigger(struct device *dev);
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
extern int __qcom_scm_tlb_conf_handler(struct device *dev, unsigned long addr);
|
||||
#endif
|
||||
extern void __qcom_scm_disable_sdi(struct device *dev);
|
||||
extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id);
|
||||
extern int __qcom_scm_spin_cpu(struct device *dev);
|
||||
|
|
|
|||
|
|
@ -86,6 +86,9 @@ extern void qcom_scm_cpu_power_down(u32 flags);
|
|||
extern void qcom_scm_cpu_hp(u32 flags);
|
||||
extern int qcom_scm_sec_wdog_deactivate(void);
|
||||
extern int qcom_scm_sec_wdog_trigger(void);
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
extern int qcom_scm_tlb_conf_handler(unsigned long addr);
|
||||
#endif
|
||||
extern void qcom_scm_disable_sdi(void);
|
||||
extern int qcom_scm_set_remote_state(u32 state, u32 id);
|
||||
extern int qcom_scm_spin_cpu(void);
|
||||
|
|
@ -231,6 +234,9 @@ static inline void qcom_scm_cpu_power_down(u32 flags) {}
|
|||
static inline void qcom_scm_cpu_hp(u32 flags) {}
|
||||
static inline int qcom_scm_sec_wdog_deactivate(void) { return -ENODEV; }
|
||||
static inline int qcom_scm_sec_wdog_trigger(void) { return -ENODEV; }
|
||||
#ifdef CONFIG_TLB_CONF_HANDLER
|
||||
static inline int qcom_scm_tlb_conf_handler(unsigned long addr) { return -ENODEV; }
|
||||
#endif
|
||||
static inline void qcom_scm_disable_sdi(void) {}
|
||||
static inline u32 qcom_scm_set_remote_state(u32 state, u32 id)
|
||||
{ return -ENODEV; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue