From patchwork Tue Jul 25 16:20:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helge Deller X-Patchwork-Id: 9862495 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8079F600F5 for ; Tue, 25 Jul 2017 16:21:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 816EE2022C for ; Tue, 25 Jul 2017 16:21:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 762222858B; Tue, 25 Jul 2017 16:21:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA0F82022C for ; Tue, 25 Jul 2017 16:21:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752381AbdGYQVK (ORCPT ); Tue, 25 Jul 2017 12:21:10 -0400 Received: from mout.gmx.net ([212.227.17.22]:50358 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752300AbdGYQVJ (ORCPT ); Tue, 25 Jul 2017 12:21:09 -0400 Received: from p100.box ([193.159.17.88]) by mail.gmx.com (mrgmx102 [212.227.17.168]) with ESMTPSA (Nemesis) id 0Lj4xG-1e9uUg2Wo2-00dHN7; Tue, 25 Jul 2017 18:20:56 +0200 Date: Tue, 25 Jul 2017 18:20:54 +0200 From: Helge Deller To: linux-parisc@vger.kernel.org, James Bottomley , John David Anglin Subject: [PATCH] parisc: Fix crash when calling PDC_PAT_MEM PDT firmware function Message-ID: <20170725162054.GA12452@p100.box> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Provags-ID: V03:K0:HYXIb8eaq2P30u4Ly3g+b84Mjvm1snLQTe/5byKoXaqGZP6inly PM52aVYInIDXx7EYB5JiZ3VwjnV94thkjV6NmMdf2C/qrF7shUxO/z5HmwpxzXD+5e1JbDz H6DpeS39jtzulKzYDf27/vXdH7hhu7WzRHzB03JlWKFcfZxxTCG0wmp5qZPrWG5SSTCYJcZ NtWDfso6xNzrcx4nzZzrg== X-UI-Out-Filterresults: notjunk:1; V01:K0:mZScjLwcNE0=:K5l+RA86uhUzsmjKA4Sf2l A7FCDMa7SHdbSeFhLWLeCJafQobpQjgULe+m0p69FiRzHDpekYtzcYGHUI7Qvcfapl5D9aTXp EygTAtooXWUkBJu9Vrhe/ORXpUH9ZG4y6OLnMebbjHDf9t82hLc6sfnX8/fUJZcFXPQ7p74Jh mtpZtyLd1+a/bnRhKTnU0gHGnW4sdZio6ei1gmcHFZsTMefiHWinLPqri+C1Us4Wlmy4iIdiv Ityv/Rmz+E4QUbqKbMvuJ9ayclcacne3kUInf9aghtLT+zOPs21t08vIqKOCwlqZn+eide3hk tbmlt/Aqesn6vftdb1S59XHFzyXpk1+qf9CkwRnydxjjeZEIdnzUoLyJ901o+hQ/yLqjxA6Uw P/Kuqzzk8m5u11DjfwvK2s2Qn0/LWRm0wzkr0HeGWqhKfDun/azUrS/HQxxyDgeZWW/a5GQBR 3qxLXwNlgPfn7Gfce62fvnQKI0rKB8qus+ETWrRrfPlpb87rvIYlnbXbdqLKHARnes7d8FMfO Z9lFW61GDplz7Vrh3RH2RFN8jPW4q0HtRw9HOIT0OrpDl3rlWScVwrkZIDnJ2IiAg5RRAQo+Y qaot+CEoJmynInWIPK1cU0XEJP4Om+f59my1b6UZ4hVZ9+xHNCXdHfhgO30tLY/ZqmZlMEvHD +cX8tRe1Pl6XLl8tiBzk5P9KgRewzD0kmWnMFMoZnczluWnVbgOtAfPB/1al2lNhStqlXOh+0 qvOXvrH5l7FsP6/NqNnp63CXs5RlLN/8CgwZ6DMuloieerj5cb6PyL/62YRzRXmzE9YzM2Nz4 8utfPPqciOO5D8JugHZa1lWy0Do4w== Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Commit c9c2877d08d9 ("parisc: Add Page Deallocation Table (PDT) support") introduced the pdc_pat_mem_read_pd_pdt() firmware helper function, which crashed the system because it trashed the stack if the pdc_pat_mem_read_pd_retinfo struct was located on the stack (and which is in size less than the required 32 64-bit values). Fix it by using the pdc_result struct instead when calling firmware and copy the return values back into the result struct when finished sucessfully. While debugging this code I noticed that the pdc_type wasn't set correctly either, so let's fix that too. Fixes: c9c2877d08d9 ("parisc: Add Page Deallocation Table (PDT) support") Signed-off-by: Helge Deller --- To unsubscribe from this list: send the line "unsubscribe linux-parisc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 9819025..526ed90 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -1481,12 +1481,19 @@ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, unsigned long offset) { int retval; - unsigned long flags; + unsigned long flags, entries; spin_lock_irqsave(&pdc_lock, flags); retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_PD_READ, - __pa(&pret), __pa(pdt_entries_ptr), + __pa(&pdc_result), __pa(pdt_entries_ptr), count, offset); + + if (retval == PDC_OK) { + entries = min(pdc_result[0], count); + pret->actual_count_bytes = entries; + pret->pdt_entries = entries / sizeof(unsigned long); + } + spin_unlock_irqrestore(&pdc_lock, flags); return retval; diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c index f3a797e..be8bed60 100644 --- a/arch/parisc/kernel/pdt.c +++ b/arch/parisc/kernel/pdt.c @@ -112,10 +112,12 @@ void __init pdc_pdt_init(void) #ifdef CONFIG_64BIT struct pdc_pat_mem_read_pd_retinfo pat_pret; + /* try old obsolete PAT firmware function first */ + pdt_type = PDT_PAT_OLD; ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, MAX_PDT_ENTRIES); if (ret != PDC_OK) { - pdt_type = PDT_PAT_OLD; + pdt_type = PDT_PAT_NEW; ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry, MAX_PDT_TABLE_SIZE, 0); }