From patchwork Thu May 28 13:54:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael van der Westhuizen X-Patchwork-Id: 6498951 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id A217F9F40A for ; Thu, 28 May 2015 13:57:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ADD482045B for ; Thu, 28 May 2015 13:57:50 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7CE64205E7 for ; Thu, 28 May 2015 13:57:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YxyHS-0000Y9-6S; Thu, 28 May 2015 13:55:30 +0000 Received: from mail-wg0-f48.google.com ([74.125.82.48]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YxyHN-0007qp-8V for linux-arm-kernel@lists.infradead.org; Thu, 28 May 2015 13:55:26 +0000 Received: by wgv5 with SMTP id 5so37193347wgv.1 for ; Thu, 28 May 2015 06:55:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=f1kL/ti6r64VCBjuMdng3f3Sa3v8ZLxPJ7wlqXy0XlE=; b=ApS2qcfRhIJXBcd4dBluCHXAgh+00LroCpDQagLsmGb2aN55sSeYh90BzJqk12s9// N5GaDZ+yyv0s1JnhBXCyF+KEnEIm+I1vRRwItTBkywmy7rnO3W8eG4vKXMhoxLq8y989 D38VEqC62/wNQLHnNcgmi0ybCiJBd5qDW20P6vR54HE42YtHOEo1bfdF4osbE4KNuSwz J8IyBI9TeL8EC/0IHylD7jOvpJuh9zehDOp0t1aEi3Kqqurz6xjZ0XvuY0bDyboXLoXv hYF+a4kWymC2V14dOYUdpYoUR1yw2qa7V5yIa5tki5+HoX+d33psRzWttreCZn5bx24C usNA== X-Gm-Message-State: ALoCoQnIXyMGdfjb+ojivVRytmxQl17w/9UVomfNplLW/jn0HeHsYWJ+jMTWgkI/F4OEUlRtQfum X-Received: by 10.180.105.74 with SMTP id gk10mr61659077wib.29.1432821302134; Thu, 28 May 2015 06:55:02 -0700 (PDT) Received: from localhost.localdomain (105-237-239-188.access.mtnbusiness.co.za. [105.237.239.188]) by mx.google.com with ESMTPSA id bm9sm3480547wjc.21.2015.05.28.06.54.59 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 May 2015 06:55:01 -0700 (PDT) From: Michael van der Westhuizen To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2] arm: tcm: Don't crash when TCM banks are protected by TrustZone Date: Thu, 28 May 2015 15:54:47 +0200 Message-Id: <1432821287-31436-1-git-send-email-michael@smart-africa.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1432805760-4590-1-git-send-email-michael@smart-africa.com> References: <1432805760-4590-1-git-send-email-michael@smart-africa.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150528_065525_476914_901E0978 X-CRM114-Status: GOOD ( 18.85 ) X-Spam-Score: -0.7 (/) Cc: Russell King , Michael van der Westhuizen , Linus Walleij , Dave Martin X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Fixes the TCM initialisation code to handle TCM banks that are present but inaccessible due to TrustZone configuration. This is the default case when enabling the non-secure world. It may also be the case that that the user decided to use TCM for TrustZone. This change has exposed a bug in handling of TCM where no TCM bank was usable (the 0 size TCM case). This change addresses the resulting hang. This code only handles the ARMv6 TCMTR register format, and will not work correctly on boards that use the ARMv7 (or any other) format. This is handled by performing an early exit from the initialisation function when the TCMTR reports any format other than v6. Signed-off-by: Michael van der Westhuizen Cc: Linus Walleij Cc: Russell King Cc: Dave Martin --- Changes in v2: - Mark the TCM undefined hook data structure as __initdata, since that's what it is. - Ensure that we're dealing with an ARMv6 TCMTR format. arch/arm/kernel/tcm.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index 7a3be1d..d1905d9 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -17,6 +17,9 @@ #include #include #include +#include + +#define TCMTR_FORMAT_MASK 0xe0000000U static struct gen_pool *tcm_pool; static bool dtcm_present; @@ -175,6 +178,21 @@ static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, return 0; } +static int __init tcm_handler(struct pt_regs *regs, unsigned int instr) +{ + regs->uregs[(instr >> 12) & 0xf] = 0; + regs->ARM_pc += 4; + return 0; +} + +static struct undef_hook tcm_hook __initdata = { + .instr_mask = 0xffff0fdf, + .instr_val = 0xee190f11, + .cpsr_mask = MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = tcm_handler +}; + /* * This initializes the TCM memory */ @@ -204,9 +222,18 @@ void __init tcm_init(void) } tcm_status = read_cpuid_tcmstatus(); + + /* + * This code only supports v6-compatible TCMTR implementations. + */ + if (tcm_status & TCMTR_FORMAT_MASK) + return; + dtcm_banks = (tcm_status >> 16) & 0x03; itcm_banks = (tcm_status & 0x03); + register_undef_hook(&tcm_hook); + /* Values greater than 2 for D/ITCM banks are "reserved" */ if (dtcm_banks > 2) dtcm_banks = 0; @@ -218,7 +245,7 @@ void __init tcm_init(void) for (i = 0; i < dtcm_banks; i++) { ret = setup_tcm_bank(0, i, dtcm_banks, &dtcm_end); if (ret) - return; + goto unregister; } /* This means you compiled more code than fits into DTCM */ if (dtcm_code_sz > (dtcm_end - DTCM_OFFSET)) { @@ -227,6 +254,10 @@ void __init tcm_init(void) dtcm_code_sz, (dtcm_end - DTCM_OFFSET)); goto no_dtcm; } + /* This means that the DTCM sizes were 0 or the DTCM banks + * were inaccessible due to TrustZone configuration */ + if (!(dtcm_end - DTCM_OFFSET)) + goto no_dtcm; dtcm_res.end = dtcm_end - 1; request_resource(&iomem_resource, &dtcm_res); dtcm_iomap[0].length = dtcm_end - DTCM_OFFSET; @@ -250,15 +281,19 @@ no_dtcm: for (i = 0; i < itcm_banks; i++) { ret = setup_tcm_bank(1, i, itcm_banks, &itcm_end); if (ret) - return; + goto unregister; } /* This means you compiled more code than fits into ITCM */ if (itcm_code_sz > (itcm_end - ITCM_OFFSET)) { pr_info("CPU ITCM: %u bytes of code compiled to " "ITCM but only %lu bytes of ITCM present\n", itcm_code_sz, (itcm_end - ITCM_OFFSET)); - return; + goto unregister; } + /* This means that the ITCM sizes were 0 or the ITCM banks + * were inaccessible due to TrustZone configuration */ + if (!(itcm_end - ITCM_OFFSET)) + goto unregister; itcm_res.end = itcm_end - 1; request_resource(&iomem_resource, &itcm_res); itcm_iomap[0].length = itcm_end - ITCM_OFFSET; @@ -275,6 +310,9 @@ no_dtcm: pr_info("CPU ITCM: %u bytes of code compiled to ITCM but no " "ITCM banks present in CPU\n", itcm_code_sz); } + +unregister: + unregister_undef_hook(&tcm_hook); } /*