Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965865Ab3GSFbH (ORCPT ); Fri, 19 Jul 2013 01:31:07 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:40030 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965510Ab3GSF1P (ORCPT ); Fri, 19 Jul 2013 01:27:15 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Will Deacon , Catalin Carinas , Marc Zyngier , Russell King Subject: [ 60/72] ARM: 7767/1: let the ASID allocator handle suspended animation Date: Thu, 18 Jul 2013 22:26:17 -0700 Message-Id: <20130719052603.973434963@linuxfoundation.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <20130719052559.852627424@linuxfoundation.org> References: <20130719052559.852627424@linuxfoundation.org> User-Agent: quilt/0.60-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2658 Lines: 89 3.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Marc Zyngier commit ae120d9edfe96628f03d87634acda0bfa7110632 upstream. When a CPU is running a process, the ASID for that process is held in a per-CPU variable (the "active ASIDs" array). When the ASID allocator handles a rollover, it copies the active ASIDs into a "reserved ASIDs" array to ensure that a process currently running on another CPU will continue to run unaffected. The active array is zero-ed to indicate that a rollover occurred. Because of this mechanism, a reserved ASID is only remembered for a single rollover. A subsequent rollover will completely refill the reserved ASIDs array. In a severely oversubscribed environment where a CPU can be prevented from running for extended periods of time (think virtual machines), the above has a horrible side effect: [P{a} denotes process P running with ASID a] CPU-0 CPU-1 A{x} [active = ] [suspended] runs B{y} [active = ] [rollover: active = <0 0> reserved = ] runs B{y} [active = <0 y> reserved = ] [rollover: active = <0 0> reserved = <0 y>] runs C{x} [active = <0 x>] [resumes] runs A{x} At that stage, both A and C have the same ASID, with deadly consequences. The fix is to preserve reserved ASIDs across rollovers if the CPU doesn't have an active ASID when the rollover occurs. Acked-by: Will Deacon Acked-by: Catalin Carinas Signed-off-by: Marc Zyngier Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- arch/arm/mm/context.c | 9 +++++++++ 1 file changed, 9 insertions(+) --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -128,6 +128,15 @@ static void flush_context(unsigned int c asid = 0; } else { asid = atomic64_xchg(&per_cpu(active_asids, i), 0); + /* + * If this CPU has already been through a + * rollover, but hasn't run another task in + * the meantime, we must preserve its reserved + * ASID, as this is the only trace we have of + * the process it is still running. + */ + if (asid == 0) + asid = per_cpu(reserved_asids, i); __set_bit(ASID_TO_IDX(asid), asid_map); } per_cpu(reserved_asids, i) = asid; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/