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

Commit 80eb3491 authored by shaohanlin's avatar shaohanlin
Browse files

Merge SPL 2021-01-05 into mp

* origin/8901-fp3-q-mp-release-spl-202101:
  msm: camera: cci: Fix incorrect use of cci config ioctl
  msm: kgsl: Fix possible use-after-free while adding context to active list
  msm: kgsl: Correctly clean up dma buffer attachment in case of error
  msm: kgsl: skip if requested address doesn't fall in the svm range
  fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info()
  x86/speculation: Prevent rogue cross-process SSBD shutdown
  x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS.
Change-Id: I79012175ad8d7b2dacd8b61f87b65026bd05ca1d
parents f7d8bee2 f9b5d969
Loading
Loading
Loading
Loading
+50 −25
Original line number Diff line number Diff line
@@ -487,7 +487,9 @@ early_param("nospectre_v1", nospectre_v1_cmdline);
static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init =
	SPECTRE_V2_NONE;

static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init =
static enum spectre_v2_user_mitigation spectre_v2_user_stibp __ro_after_init =
	SPECTRE_V2_USER_NONE;
static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init =
	SPECTRE_V2_USER_NONE;

#ifdef RETPOLINE
@@ -654,22 +656,35 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
		pr_info("mitigation: Enabling %s Indirect Branch Prediction Barrier\n",
			static_key_enabled(&switch_mm_always_ibpb) ?
			"always-on" : "conditional");

		spectre_v2_user_ibpb = mode;
	}

	/* If enhanced IBRS is enabled no STIPB required */
	if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
	/*
	 * If enhanced IBRS is enabled or SMT impossible, STIBP is not
	 * required.
	 */
	if (!smt_possible || spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
		return;

	/*
	 * If SMT is not possible or STIBP is not available clear the STIPB
	 * mode.
	 * At this point, an STIBP mode other than "off" has been set.
	 * If STIBP support is not being forced, check if STIBP always-on
	 * is preferred.
	 */
	if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP))
	if (mode != SPECTRE_V2_USER_STRICT &&
	    boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
		mode = SPECTRE_V2_USER_STRICT_PREFERRED;

	/*
	 * If STIBP is not available, clear the STIBP mode.
	 */
	if (!boot_cpu_has(X86_FEATURE_STIBP))
		mode = SPECTRE_V2_USER_NONE;

	spectre_v2_user_stibp = mode;

set_mode:
	spectre_v2_user = mode;
	/* Only print the STIBP mode when SMT possible */
	if (smt_possible)
	pr_info("%s\n", spectre_v2_user_strings[mode]);
}

@@ -910,7 +925,7 @@ void arch_smt_update(void)
{
	mutex_lock(&spec_ctrl_mutex);

	switch (spectre_v2_user) {
	switch (spectre_v2_user_stibp) {
	case SPECTRE_V2_USER_NONE:
		break;
	case SPECTRE_V2_USER_STRICT:
@@ -1142,13 +1157,16 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
{
	switch (ctrl) {
	case PR_SPEC_ENABLE:
		if (spectre_v2_user == SPECTRE_V2_USER_NONE)
		if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
		    spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
			return 0;
		/*
		 * Indirect branch speculation is always disabled in strict
		 * mode.
		 */
		if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
		if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
		    spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
		    spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
			return -EPERM;
		task_clear_spec_ib_disable(task);
		task_update_spec_tif(task);
@@ -1159,9 +1177,12 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
		 * Indirect branch speculation is always allowed when
		 * mitigation is force disabled.
		 */
		if (spectre_v2_user == SPECTRE_V2_USER_NONE)
		if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
		    spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
			return -EPERM;
		if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
		if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
		    spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
		    spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
			return 0;
		task_set_spec_ib_disable(task);
		if (ctrl == PR_SPEC_FORCE_DISABLE)
@@ -1192,7 +1213,8 @@ void arch_seccomp_spec_mitigate(struct task_struct *task)
{
	if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP)
		ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE);
	if (spectre_v2_user == SPECTRE_V2_USER_SECCOMP)
	if (spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
	    spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP)
		ib_prctl_set(task, PR_SPEC_FORCE_DISABLE);
}
#endif
@@ -1221,22 +1243,25 @@ static int ib_prctl_get(struct task_struct *task)
	if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
		return PR_SPEC_NOT_AFFECTED;

	switch (spectre_v2_user) {
	case SPECTRE_V2_USER_NONE:
	if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
	    spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
		return PR_SPEC_ENABLE;
	case SPECTRE_V2_USER_PRCTL:
	case SPECTRE_V2_USER_SECCOMP:
	else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
	    spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
	    spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
		return PR_SPEC_DISABLE;
	else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL ||
	    spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
	    spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL ||
	    spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) {
		if (task_spec_ib_force_disable(task))
			return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
		if (task_spec_ib_disable(task))
			return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
		return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
	case SPECTRE_V2_USER_STRICT:
		return PR_SPEC_DISABLE;
	default:
	} else
		return PR_SPEC_NOT_AFFECTED;
}
}

int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
{
@@ -1476,7 +1501,7 @@ static char *stibp_state(void)
	if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
		return "";

	switch (spectre_v2_user) {
	switch (spectre_v2_user_stibp) {
	case SPECTRE_V2_USER_NONE:
		return ", STIBP: disabled";
	case SPECTRE_V2_USER_STRICT:
+10 −18
Original line number Diff line number Diff line
@@ -324,28 +324,20 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp,
	u64 msr = x86_spec_ctrl_base;
	bool updmsr = false;

	/*
	 * If TIF_SSBD is different, select the proper mitigation
	 * method. Note that if SSBD mitigation is disabled or permanentely
	 * enabled this branch can't be taken because nothing can set
	 * TIF_SSBD.
	 */
	if (tif_diff & _TIF_SSBD) {
	/* Handle change of TIF_SSBD depending on the mitigation method. */
	if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) {
		if (tif_diff & _TIF_SSBD)
			amd_set_ssb_virt_state(tifn);
	} else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) {
		if (tif_diff & _TIF_SSBD)
			amd_set_core_ssb_state(tifn);
	} else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) ||
		   static_cpu_has(X86_FEATURE_AMD_SSBD)) {
		updmsr |= !!(tif_diff & _TIF_SSBD);
		msr |= ssbd_tif_to_spec_ctrl(tifn);
			updmsr  = true;
		}
	}

	/*
	 * Only evaluate TIF_SPEC_IB if conditional STIBP is enabled,
	 * otherwise avoid the MSR write.
	 */
	/* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled. */
	if (IS_ENABLED(CONFIG_SMP) &&
	    static_branch_unlikely(&switch_to_cond_stibp)) {
		updmsr |= !!(tif_diff & _TIF_SPEC_IB);
+3 −2
Original line number Diff line number Diff line
/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -487,11 +487,12 @@ void adreno_drawctxt_detach(struct kgsl_context *context)
	drawctxt = ADRENO_CONTEXT(context);
	rb = drawctxt->rb;

	spin_lock(&drawctxt->lock);

	spin_lock(&adreno_dev->active_list_lock);
	list_del_init(&drawctxt->active_node);
	spin_unlock(&adreno_dev->active_list_lock);

	spin_lock(&drawctxt->lock);
	count = drawctxt_detach_drawobjs(drawctxt, list);
	spin_unlock(&drawctxt->lock);

+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -2487,7 +2487,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,
	return 0;

unmap:
	if (param->type == KGSL_USER_MEM_TYPE_DMABUF) {
	if (kgsl_memdesc_usermem_type(&entry->memdesc) == KGSL_MEM_ENTRY_ION) {
		kgsl_destroy_ion(entry->priv_data);
		entry->memdesc.sgt = NULL;
	}
@@ -2793,7 +2793,7 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv,
	return result;

error_attach:
	switch (memtype) {
	switch (kgsl_memdesc_usermem_type(&entry->memdesc)) {
	case KGSL_MEM_ENTRY_ION:
		kgsl_destroy_ion(entry->priv_data);
		entry->memdesc.sgt = NULL;
+18 −3
Original line number Diff line number Diff line
@@ -2427,6 +2427,22 @@ static uint64_t kgsl_iommu_find_svm_region(struct kgsl_pagetable *pagetable,
	return addr;
}

static bool iommu_addr_in_svm_ranges(struct kgsl_iommu_pt *pt,
	u64 gpuaddr, u64 size)
{
	if ((gpuaddr >= pt->compat_va_start && gpuaddr < pt->compat_va_end) &&
		((gpuaddr + size) > pt->compat_va_start &&
			(gpuaddr + size) <= pt->compat_va_end))
		return true;

	if ((gpuaddr >= pt->svm_start && gpuaddr < pt->svm_end) &&
		((gpuaddr + size) > pt->svm_start &&
			(gpuaddr + size) <= pt->svm_end))
		return true;

	return false;
}

static int kgsl_iommu_set_svm_region(struct kgsl_pagetable *pagetable,
		uint64_t gpuaddr, uint64_t size)
{
@@ -2434,9 +2450,8 @@ static int kgsl_iommu_set_svm_region(struct kgsl_pagetable *pagetable,
	struct kgsl_iommu_pt *pt = pagetable->priv;
	struct rb_node *node;

	/* Make sure the requested address doesn't fall in the global range */
	if (ADDR_IN_GLOBAL(pagetable->mmu, gpuaddr) ||
			ADDR_IN_GLOBAL(pagetable->mmu, gpuaddr + size))
	/* Make sure the requested address doesn't fall out of SVM range */
	if (!iommu_addr_in_svm_ranges(pt, gpuaddr, size))
		return -ENOMEM;

	spin_lock(&pagetable->lock);
Loading