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

Commit b9018240 authored by bait_dispatcher_monitor_system's avatar bait_dispatcher_monitor_system Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: rtb: Fix buffer corruption issue"

parents e94268f1 a5ad036f
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2015, 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
@@ -160,10 +160,20 @@ static void uncached_logk_timestamp(int idx)
}

#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
/*
 * Since it is not necessarily true that nentries % step_size == 0,
 * must make appropriate adjustments to the index when a "wraparound"
 * occurs to ensure that msm_rtb.rtb[x] always belongs to the same cpu.
 * It is desired to give all cpus the same number of entries; this leaves
 * (nentries % step_size) dead space at the end of the buffer.
 */
static int msm_rtb_get_idx(void)
{
	int cpu, i, offset;
	atomic_t *index;
	unsigned long flags;
	u32 unused_buffer_size = msm_rtb.nentries % msm_rtb.step_size;
	int adjusted_size;

	/*
	 * ideally we would use get_cpu but this is a close enough
@@ -173,17 +183,24 @@ static int msm_rtb_get_idx(void)

	index = &per_cpu(msm_rtb_idx_cpu, cpu);

	local_irq_save(flags);
	i = atomic_add_return(msm_rtb.step_size, index);
	i -= msm_rtb.step_size;

	/* Check if index has wrapped around */
	offset = (i & (msm_rtb.nentries - 1)) -
		 ((i - msm_rtb.step_size) & (msm_rtb.nentries - 1));
	/*
	 * Check if index has wrapped around or is in the unused region at the
	 * end of the buffer
	 */
	adjusted_size = atomic_read(index) + unused_buffer_size;
	offset = (adjusted_size & (msm_rtb.nentries - 1)) -
		 ((adjusted_size - msm_rtb.step_size) & (msm_rtb.nentries - 1));
	if (offset < 0) {
		uncached_logk_timestamp(i);
		i = atomic_add_return(msm_rtb.step_size, index);
		i = atomic_add_return(msm_rtb.step_size + unused_buffer_size,
									index);
		i -= msm_rtb.step_size;
	}
	local_irq_restore(flags);

	return i;
}