Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45e5597f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: Add TLB conflict fault handler"

parents fa867b3c f056b8a3
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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"			},
+21 −0
Original line number Diff line number Diff line
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -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
 */
+3 −0
Original line number Diff line number Diff line
@@ -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);
Loading