From patchwork Wed Aug 30 19:13:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 111343 Delivered-To: patch@linaro.org Received: by 10.140.95.112 with SMTP id h103csp1410633qge; Wed, 30 Aug 2017 12:14:46 -0700 (PDT) X-Received: by 10.98.33.24 with SMTP id h24mr2608007pfh.213.1504120486057; Wed, 30 Aug 2017 12:14:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504120486; cv=none; d=google.com; s=arc-20160816; b=wL8nLtKPX0qMopI2dmGG+l1QkZ83cGRX6ixVNaeMsp+5BKJF2K0HKRLxJoz6/fWKnh qyqwLWhk4yzSi81lgoW/qQYUDvB92Z6quWBlBYjwpfIjALG820H36eMGqZGa5X5fXbD5 WKGnCI+42XOwjGXmO951HGg0CvbQgETMSx2ojaycw748qLbeQF4fKS7Rc3DbqAGgq74t RacGBnb5eKZeRiFl47h3T2tibTdAdzgZcMrI/mq5GUeLUaslNpPIT+C9+JYCDlSlHfPn pRDV862KJ2jdSze9ZrLCsU6QPmIuU8Ner7pJ73nRlHorrgHvAQCFoU/LmGzGcV5y6R5q ONqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=/vkx5dyXkOC49xCFjOBelqmaFHlZKq/UzKwfA3QgCyY=; b=nF8IbW8PkFFAC6Ge9/Ui8MEH++e5E3OVQQ1b1zPpqiYkXV1uoM8PC3fLeHpRTPPBOz tC7rvD6lSeLkTTxtASPxkZYnODcZcEN2SLPO740CEaooAWbFkUh1eTvXe74e9H+MwZzr nFglR4vj6nba2cwefWy7QiDjvt7aAu85iO+nQcWX9Hf1N5WoTF5+EBRT/38mSujvN/sS UTOsDP6x7Ihy6IKxCPIMKR1RROlHV3mXb3mnjlNrm15MrNzUbd3/qF3nwXXjotQKnZC9 NitkffZ43Hb4ewKSUzQmwAemBwjJKD6VrHkU4VQeOxcC/WXuOY69vGT8A0W90WwUBZpW 4RmA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i188si2899624pgc.79.2017.08.30.12.14.45; Wed, 30 Aug 2017 12:14:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750885AbdH3TOp (ORCPT + 2 others); Wed, 30 Aug 2017 15:14:45 -0400 Received: from goliath.siemens.de ([192.35.17.28]:55350 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750860AbdH3TOp (ORCPT ); Wed, 30 Aug 2017 15:14:45 -0400 Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id v7UJDwGb006371 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 30 Aug 2017 21:13:58 +0200 Received: from md1f2u6c.ww002.siemens.net.net ([139.25.68.37]) by mail1.siemens.de (8.15.2/8.15.2) with ESMTP id v7UJDvsA004213; Wed, 30 Aug 2017 21:13:58 +0200 From: Jan Kiszka To: Ben Hutchings Cc: cip-dev@lists.cip-project.org, Linus Torvalds , Peter Zijlstra , Thomas Gleixner , linux-efi@vger.kernel.org Subject: [PATCH 11/14] efi/capsule-loader: Use a cached copy of the capsule header Date: Wed, 30 Aug 2017 21:13:53 +0200 Message-Id: <77c3d7dfbafc5d23298ef751b68e3484d6939dae.1504120436.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 2.12.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Ard Biesheuvel commit 82c3768b8d68c40ecde92338899c838b7c674ffb upstream. Instead of kmapping the capsule data twice, copy the capsule header into the capsule info struct we keep locally. This is an improvement by itself, but will also enable handling of non-standard header formats more easily. Signed-off-by: Ard Biesheuvel Reviewed-by: Matt Fleming Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20170602135207.21708-7-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/capsule-loader.c | 41 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 24 deletions(-) -- 2.12.3 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" 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/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index 37d3f6ec2d28..5b012a467d7d 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -21,13 +21,13 @@ #define NO_FURTHER_WRITE_ACTION -1 struct capsule_info { - bool header_obtained; - int reset_type; - long index; - size_t count; - size_t total_size; - struct page **pages; - size_t page_bytes_remain; + efi_capsule_header_t header; + int reset_type; + long index; + size_t count; + size_t total_size; + struct page **pages; + size_t page_bytes_remain; }; /** @@ -56,7 +56,6 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info) static int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, size_t hdr_bytes) { - efi_capsule_header_t *cap_hdr; size_t pages_needed; int ret; void *temp_page; @@ -66,8 +65,9 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info, return 0; /* Reset back to the correct offset of header */ - cap_hdr = kbuff - cap_info->count; - pages_needed = ALIGN(cap_hdr->imagesize, PAGE_SIZE) >> PAGE_SHIFT; + kbuff -= cap_info->count; + memcpy(&cap_info->header, kbuff, sizeof(cap_info->header)); + pages_needed = ALIGN(cap_info->header.imagesize, PAGE_SIZE) / PAGE_SIZE; if (pages_needed == 0) { pr_err("invalid capsule size"); @@ -75,15 +75,16 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info, } /* Check if the capsule binary supported */ - ret = efi_capsule_supported(cap_hdr->guid, cap_hdr->flags, - cap_hdr->imagesize, + ret = efi_capsule_supported(cap_info->header.guid, + cap_info->header.flags, + cap_info->header.imagesize, &cap_info->reset_type); if (ret) { pr_err("capsule not supported\n"); return ret; } - cap_info->total_size = cap_hdr->imagesize; + cap_info->total_size = cap_info->header.imagesize; temp_page = krealloc(cap_info->pages, pages_needed * sizeof(void *), GFP_KERNEL | __GFP_ZERO); @@ -91,7 +92,6 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info, return -ENOMEM; cap_info->pages = temp_page; - cap_info->header_obtained = true; return 0; } @@ -104,15 +104,8 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info, static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info) { int ret; - void *cap_hdr_temp; - cap_hdr_temp = vmap(cap_info->pages, cap_info->index, - VM_MAP, PAGE_KERNEL); - if (!cap_hdr_temp) - return -ENOMEM; - - ret = efi_capsule_update(cap_hdr_temp, cap_info->pages); - vunmap(cap_hdr_temp); + ret = efi_capsule_update(&cap_info->header, cap_info->pages); if (ret) { pr_err("capsule update failed\n"); return ret; @@ -192,7 +185,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, cap_info->page_bytes_remain -= write_byte; /* Setup capsule binary info structure */ - if (!cap_info->header_obtained) { + if (cap_info->header.headersize == 0) { ret = efi_capsule_setup_info(cap_info, kbuff, cap_info->count + write_byte); if (ret) @@ -203,7 +196,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, kunmap(page); /* Submit the full binary to efi_capsule_update() API */ - if (cap_info->header_obtained && + if (cap_info->header.headersize > 0 && cap_info->count >= cap_info->total_size) { if (cap_info->count > cap_info->total_size) { pr_err("capsule upload size exceeded header defined size\n"); From patchwork Wed Aug 30 19:13:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 111342 Delivered-To: patch@linaro.org Received: by 10.140.95.112 with SMTP id h103csp1410443qge; Wed, 30 Aug 2017 12:14:36 -0700 (PDT) X-Received: by 10.99.42.203 with SMTP id q194mr2481371pgq.378.1504120476822; Wed, 30 Aug 2017 12:14:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504120476; cv=none; d=google.com; s=arc-20160816; b=tt8TgtZnjsnKDKbXuA1jpPItY0FSvsrRNOrIJUgNoMsQnIrw/pLc3Bz6AqSEishDEz CbmoHOXnj7zJXHTxSwlDKTqraZd31m0/3gMf03W61kP6q/wAxE9bK3fis8YX5NwNPn8t k9twRLCGVGuYB5k63xDVJLu0WEXApvipcraNXYnADcmaWcg6fGtfyhkFYHNWD7ZMTK2Z 7ljJv71pRzDWpEsKJD7kmgUFnoiNH0h9FkFcAd0cClJsdYNpJh83iuvnb4ob72+RsmsT c0kSlHr+4KtjGolDTnt6aMeYvXAjGYyJF7NC5mqXFKGbQ4EljmQPHFhipUy0z3RPeCB0 iXEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=GNx9QMUzUuaqR+/FPZMfhKsEFOmUxTJ0g+jkS+7G+XA=; b=qwg0OL8LvE0OEe9Ov3jxwseIHwUEJmg51kIQ6ZZd1zLIaAlTgoD+CFXCjo1NodZ6Vc YoCKumy4TAZfMDDWAL4d9J7yWc9PLXAsgpqKWeC2FjEhJTN+rI+ICE6vG0hwu0H0vvj0 4QQelpwgRgkTVOopuR1n5ihvoJtExgVoH3NWw3U/P/EKGPqnOb//QcHJzcn1z6tNhRjG th/LwpJPVdHkON9gsWEiQn/grjK7tTW06/vZsa4QAvvgYYpMHsaagESxCpZoXueF66Ge 8gzdEHoxfL3tmkQuNQiKoUYTB1PAtUi5PNkZjm1v4VQ57xj4MHVk2m2sFfYB3e+7bJY/ FiHg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i188si2899624pgc.79.2017.08.30.12.14.36; Wed, 30 Aug 2017 12:14:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750814AbdH3TOg (ORCPT + 2 others); Wed, 30 Aug 2017 15:14:36 -0400 Received: from david.siemens.de ([192.35.17.14]:48989 "EHLO david.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750794AbdH3TOf (ORCPT ); Wed, 30 Aug 2017 15:14:35 -0400 Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by david.siemens.de (8.15.2/8.15.2) with ESMTPS id v7UJDwg5025196 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 30 Aug 2017 21:13:58 +0200 Received: from md1f2u6c.ww002.siemens.net.net ([139.25.68.37]) by mail1.siemens.de (8.15.2/8.15.2) with ESMTP id v7UJDvsB004213; Wed, 30 Aug 2017 21:13:58 +0200 From: Jan Kiszka To: Ben Hutchings Cc: cip-dev@lists.cip-project.org, Linus Torvalds , Matt Fleming , Peter Zijlstra , Thomas Gleixner , linux-efi@vger.kernel.org Subject: [PATCH 12/14] efi/capsule-loader: Redirect calls to efi_capsule_setup_info() via weak alias Date: Wed, 30 Aug 2017 21:13:54 +0200 Message-Id: <643351f334592960d2fa1a2d2eecf9c8df25745f.1504120436.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 2.12.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Ard Biesheuvel commit 3fabd628d5ea24b02ddb1230ffca1df0f779f84e upstream. To allow platform specific code to hook into the capsule loading routines, indirect calls to efi_capsule_setup_info() via a weak alias of __efi_capsule_setup_info(), allowing platforms to redefine the former but still use the latter. Tested-by: Bryan O'Donoghue Signed-off-by: Ard Biesheuvel Cc: Linus Torvalds Cc: Matt Fleming Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20170602135207.21708-9-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/capsule-loader.c | 56 +++++++++++++++++------------------ include/linux/efi.h | 12 ++++++++ 2 files changed, 39 insertions(+), 29 deletions(-) -- 2.12.3 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" 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/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index 5b012a467d7d..f7fdeab0bc37 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -20,16 +20,6 @@ #define NO_FURTHER_WRITE_ACTION -1 -struct capsule_info { - efi_capsule_header_t header; - int reset_type; - long index; - size_t count; - size_t total_size; - struct page **pages; - size_t page_bytes_remain; -}; - /** * efi_free_all_buff_pages - free all previous allocated buffer pages * @cap_info: pointer to current instance of capsule_info structure @@ -46,28 +36,13 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info) cap_info->index = NO_FURTHER_WRITE_ACTION; } -/** - * efi_capsule_setup_info - obtain the efi capsule header in the binary and - * setup capsule_info structure - * @cap_info: pointer to current instance of capsule_info structure - * @kbuff: a mapped first page buffer pointer - * @hdr_bytes: the total received number of bytes for efi header - **/ -static int efi_capsule_setup_info(struct capsule_info *cap_info, - void *kbuff, size_t hdr_bytes) +int __efi_capsule_setup_info(struct capsule_info *cap_info) { size_t pages_needed; int ret; void *temp_page; - /* Only process data block that is larger than efi header size */ - if (hdr_bytes < sizeof(efi_capsule_header_t)) - return 0; - - /* Reset back to the correct offset of header */ - kbuff -= cap_info->count; - memcpy(&cap_info->header, kbuff, sizeof(cap_info->header)); - pages_needed = ALIGN(cap_info->header.imagesize, PAGE_SIZE) / PAGE_SIZE; + pages_needed = ALIGN(cap_info->total_size, PAGE_SIZE) / PAGE_SIZE; if (pages_needed == 0) { pr_err("invalid capsule size"); @@ -84,7 +59,6 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info, return ret; } - cap_info->total_size = cap_info->header.imagesize; temp_page = krealloc(cap_info->pages, pages_needed * sizeof(void *), GFP_KERNEL | __GFP_ZERO); @@ -97,6 +71,30 @@ static int efi_capsule_setup_info(struct capsule_info *cap_info, } /** + * efi_capsule_setup_info - obtain the efi capsule header in the binary and + * setup capsule_info structure + * @cap_info: pointer to current instance of capsule_info structure + * @kbuff: a mapped first page buffer pointer + * @hdr_bytes: the total received number of bytes for efi header + * + * Platforms with non-standard capsule update mechanisms can override + * this __weak function so they can perform any required capsule + * image munging. See quark_quirk_function() for an example. + **/ +int __weak efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, + size_t hdr_bytes) +{ + /* Only process data block that is larger than efi header size */ + if (hdr_bytes < sizeof(efi_capsule_header_t)) + return 0; + + memcpy(&cap_info->header, kbuff, sizeof(cap_info->header)); + cap_info->total_size = cap_info->header.imagesize; + + return __efi_capsule_setup_info(cap_info); +} + +/** * efi_capsule_submit_update - invoke the efi_capsule_update API once binary * upload done * @cap_info: pointer to current instance of capsule_info structure @@ -186,7 +184,7 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, /* Setup capsule binary info structure */ if (cap_info->header.headersize == 0) { - ret = efi_capsule_setup_info(cap_info, kbuff, + ret = efi_capsule_setup_info(cap_info, kbuff - cap_info->count, cap_info->count + write_byte); if (ret) goto fail_unmap; diff --git a/include/linux/efi.h b/include/linux/efi.h index 5a0b8f7a54c8..b386097e45bc 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -129,6 +129,18 @@ typedef struct { #define EFI_CAPSULE_POPULATE_SYSTEM_TABLE 0x00020000 #define EFI_CAPSULE_INITIATE_RESET 0x00040000 +struct capsule_info { + efi_capsule_header_t header; + int reset_type; + long index; + size_t count; + size_t total_size; + struct page **pages; + size_t page_bytes_remain; +}; + +int __efi_capsule_setup_info(struct capsule_info *cap_info); + /* * Allocation types for calls to boottime->allocate_pages. */ From patchwork Wed Aug 30 19:13:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 111341 Delivered-To: patch@linaro.org Received: by 10.140.95.112 with SMTP id h103csp1410436qge; Wed, 30 Aug 2017 12:14:36 -0700 (PDT) X-Received: by 10.101.76.141 with SMTP id m13mr2534980pgt.231.1504120476512; Wed, 30 Aug 2017 12:14:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504120476; cv=none; d=google.com; s=arc-20160816; b=ki1u/V6Y6ZMfJRYNgpaOUnI8MW5MUug+r/aZPz5GlwQ0zmcZTfqe7n16QqFJP+ccGk EUBcg72/SndQPIrTPdwAHavzoYOk9mVMoyPEGarW6nudvzqTArDba4JMXfOEHfzlTQR8 WqeBFaW8H+I3qF1GT6Glc2iAoetLTlBeTdWsB1FjG+C2F8IsRsYv4uUPNDoy17Csm+zr emnik+UehDY5na14YGoEA4Du3CI/Wqy3RlGok49gyIBactCxmo2L9XPUjWeL/Ygnrmw2 wsWyNJGz3+24ardTqykraaBXzkyhScwPYRIvXcsPCVoUxH3qO4c+o3z8nZtf3nE8x6JJ WdAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=lhNO8/jx6ztYjE4ixgwoI6SqyCnq4x2Bge0yMuYcAyw=; b=W4iyAs4J6qNr6EtWn5WqxCBbNUJWcLIm2RBd+0TyUX8wRhDfJrTCQBwHauXittTGc7 AXbkBGGjf+c3DMlJMHS7fkkOG96zF+AKInJLPcbioZcSsaKGSnghz+KSuNXeRlUZkKYh LcK2/Ik/mZSaNfUlDu1R5dsMhWaON0qjrhWS51k/b2zh5hsDixdlzM8jpF6eDzYQT+g9 I3EbcGkz0jG5C57q5LOn2pMlR6vQkiJbndDjzFxH4/Ss7bmEFIa63medXYLYF0WYiKbJ 2gjRYosIjBUWMP+MHf7zog41bmni2f7+Qs+VZRQjD4PVg91CmMLGk8toXsCWbr+TmECs Y5iw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i188si2899624pgc.79.2017.08.30.12.14.36; Wed, 30 Aug 2017 12:14:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750828AbdH3TOf (ORCPT + 2 others); Wed, 30 Aug 2017 15:14:35 -0400 Received: from david.siemens.de ([192.35.17.14]:48985 "EHLO david.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750814AbdH3TOf (ORCPT ); Wed, 30 Aug 2017 15:14:35 -0400 Received: from mail1.siemens.de (mail1.siemens.de [139.23.33.14]) by david.siemens.de (8.15.2/8.15.2) with ESMTPS id v7UJDwNY025199 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 30 Aug 2017 21:13:58 +0200 Received: from md1f2u6c.ww002.siemens.net.net ([139.25.68.37]) by mail1.siemens.de (8.15.2/8.15.2) with ESMTP id v7UJDvsC004213; Wed, 30 Aug 2017 21:13:58 +0200 From: Jan Kiszka To: Ben Hutchings Cc: cip-dev@lists.cip-project.org, Linus Torvalds , Matt Fleming , Peter Zijlstra , Thomas Gleixner , linux-efi@vger.kernel.org Subject: [PATCH 13/14] efi/capsule-loader: Use page addresses rather than struct page pointers Date: Wed, 30 Aug 2017 21:13:55 +0200 Message-Id: <01f0bf4cd9c202d2c871295c3068ea22f05dd50e.1504120436.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 2.12.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Ard Biesheuvel commit 2a457fb31df62c6b482f78e4f74aaed99271f44d upstream. To give some leeway to code that handles non-standard capsule headers, let's keep an array of page addresses rather than struct page pointers. This gives special implementations of efi_capsule_setup_info() the opportunity to mangle the payload a bit before it is presented to the firmware, without putting any knowledge of the nature of such quirks into the generic code. Tested-by: Bryan O'Donoghue Signed-off-by: Ard Biesheuvel Cc: Linus Torvalds Cc: Matt Fleming Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20170602135207.21708-10-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/capsule-loader.c | 12 ++++++++---- drivers/firmware/efi/capsule.c | 7 ++++--- include/linux/efi.h | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) -- 2.12.3 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" 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/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index f7fdeab0bc37..feeafb673c07 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -20,6 +20,10 @@ #define NO_FURTHER_WRITE_ACTION -1 +#ifndef phys_to_page +#define phys_to_page(x) pfn_to_page((x) >> PAGE_SHIFT) +#endif + /** * efi_free_all_buff_pages - free all previous allocated buffer pages * @cap_info: pointer to current instance of capsule_info structure @@ -31,7 +35,7 @@ static void efi_free_all_buff_pages(struct capsule_info *cap_info) { while (cap_info->index > 0) - __free_page(cap_info->pages[--cap_info->index]); + __free_page(phys_to_page(cap_info->pages[--cap_info->index])); cap_info->index = NO_FURTHER_WRITE_ACTION; } @@ -161,12 +165,12 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, goto failed; } - cap_info->pages[cap_info->index++] = page; + cap_info->pages[cap_info->index++] = page_to_phys(page); cap_info->page_bytes_remain = PAGE_SIZE; + } else { + page = phys_to_page(cap_info->pages[cap_info->index - 1]); } - page = cap_info->pages[cap_info->index - 1]; - kbuff = kmap(page); if (!kbuff) { ret = -ENOMEM; diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c index 1106773468b2..4a867c65d740 100644 --- a/drivers/firmware/efi/capsule.c +++ b/drivers/firmware/efi/capsule.c @@ -218,7 +218,7 @@ efi_capsule_update_locked(efi_capsule_header_t *capsule, * * Return 0 on success, a converted EFI status code on failure. */ -int efi_capsule_update(efi_capsule_header_t *capsule, struct page **pages) +int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) { u32 imagesize = capsule->imagesize; efi_guid_t guid = capsule->guid; @@ -257,10 +257,11 @@ int efi_capsule_update(efi_capsule_header_t *capsule, struct page **pages) } for (j = 0; j < SGLIST_PER_PAGE && count > 0; j++) { - u64 sz = min_t(u64, imagesize, PAGE_SIZE); + u64 sz = min_t(u64, imagesize, + PAGE_SIZE - (u64)*pages % PAGE_SIZE); sglist[j].length = sz; - sglist[j].data = page_to_phys(*pages++); + sglist[j].data = *pages++; imagesize -= sz; count--; diff --git a/include/linux/efi.h b/include/linux/efi.h index b386097e45bc..23a2a274bc6c 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -135,7 +135,7 @@ struct capsule_info { long index; size_t count; size_t total_size; - struct page **pages; + phys_addr_t *pages; size_t page_bytes_remain; }; @@ -1246,7 +1246,7 @@ extern int efi_capsule_supported(efi_guid_t guid, u32 flags, size_t size, int *reset); extern int efi_capsule_update(efi_capsule_header_t *capsule, - struct page **pages); + phys_addr_t *pages); #ifdef CONFIG_EFI_RUNTIME_MAP int efi_runtime_map_init(struct kobject *);