From patchwork Fri Jun 2 13:52:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 101255 Delivered-To: patch@linaro.org Received: by 10.182.202.35 with SMTP id kf3csp204895obc; Fri, 2 Jun 2017 06:55:04 -0700 (PDT) X-Received: by 10.99.114.72 with SMTP id c8mr7239730pgn.81.1496411703835; Fri, 02 Jun 2017 06:55:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496411703; cv=none; d=google.com; s=arc-20160816; b=YmGj4Q1lHuHEBe98n/vGNmivdzAnzm2+MYsHZeoHNZb8P0S9sYVyu+J6Q7OuwUxZSR nPa2SqKI+51mI/BUxDAgL+oDSS7anCSzVa0ZGFVzpNzK9DNxmUkzHger6qM6NMO5+1m1 FDpp2LvQJ6/OgfT2eTNHPyZkrb3Mt+c2C2zvKXNXCmWbuWIOEnd8z8dWSFxpghzBfKWo w/7JiU+Xpi2Clr1QpYMN3lApcmZhmQgVu3+CUUnlXvZQe3IPINXeZK52nfIqZgrqarYv 9+52iizWboYEHuLOXgUtEuTsy4+zLaPufVDsW+joPL2IK/CSMahzfKVnlWSQ/84jWcR2 wV7A== 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:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=Hd3YQfQri7NEPN/Fl8JuahJQ8MZF8/5qb1WE3WMOmZE=; b=qZOdIDBLBQJwuisvxdRhVH2M3mylyJq+NXwQyvF56KGuK9/8Syx+Np09ZK1W1pSC5t QqBM2RIWCdKzkssKghIKb/nZm/Utkuo6V6nadNa9BXikUqValRBEkbYyFCXZZ7ugftas dfXF9/UZwq2CFoyKk3meUxigFGbeUFjg8upCGJUjyrW2nQdVZNRBFJAJhRTbWo3IBQzo s+A6BoTxRCJy8g0oVoRatHaG9O0uyVSzKSTa3ik1iDA92zRcJbJoRnbqptfLwUqQ8Si5 KGO5iotQ+pv+yWItNkk0I/CrwrWYI2ZuLszZV+8qMMNi+cCapLv/uxBL0W/1/6jSDIIh Ekpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 3si960203pfj.110.2017.06.02.06.55.03; Fri, 02 Jun 2017 06:55:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751538AbdFBNy7 (ORCPT + 25 others); Fri, 2 Jun 2017 09:54:59 -0400 Received: from mail-wm0-f48.google.com ([74.125.82.48]:36604 "EHLO mail-wm0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751125AbdFBNy4 (ORCPT ); Fri, 2 Jun 2017 09:54:56 -0400 Received: by mail-wm0-f48.google.com with SMTP id 7so26352931wmo.1 for ; Fri, 02 Jun 2017 06:54:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Hd3YQfQri7NEPN/Fl8JuahJQ8MZF8/5qb1WE3WMOmZE=; b=jDeEloT65cPSHxhT6O106WXqzNJ6iU8LK4l0CDBbbRdGZAbilfKbj6doox0zQhj8It AvY3jou5ZyJzZSq4jLCq8oErSsEIBetqMT0qEMEEgXjw10Kr2mkh7rsj+s+8VKi1/DZF kWT3ESfjPgir61ENARnLcoLi8NGp8kG4O1bkw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Hd3YQfQri7NEPN/Fl8JuahJQ8MZF8/5qb1WE3WMOmZE=; b=dIRdouKpPAMqxUHedcVj6OSZGKpjwBHKDG4UVAwDkA9yW76bTuLKdcyvh0h9C52TpF EZEZ8r/czdkLk0t+F/kkPW4+e8IPJla6bhYUKH2vUxxKMDx3Q9lKbqUupzDRruZnlo/C +1bYdwVg40WdNnVhG7Y0viiTSB9O54yU57NoP/FNToE4I2IaSIXkJacNAmRMSpmz5GVi YWHdpMyPYfAhBSUywMS5tjyRN6yMABQPQ2YL0W2G7bgqOZVuXMfyYjCZa5oWWU92AdF2 bb4LcfLRQtr3jsLt+YlO8220E63W9bSzqnnOAiNsZ4mNkMdjnaFWs+iByjLjeAWW2jFt 6Dlg== X-Gm-Message-State: AODbwcA4ZTZ4APBUcbIwuxJPSjnZE4yZP9x8oEmAOVy6i69ThyFwt/bO krGfcI3wMR5XJJUZ X-Received: by 10.80.144.118 with SMTP id z51mr6028941edz.143.1496411694958; Fri, 02 Jun 2017 06:54:54 -0700 (PDT) Received: from localhost.localdomain ([105.151.155.95]) by smtp.gmail.com with ESMTPSA id g48sm9756076edc.8.2017.06.02.06.54.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Jun 2017 06:54:54 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org Subject: [PATCH 06/13] efi/capsule-loader: Use a cached copy of the capsule header Date: Fri, 2 Jun 2017 13:52:00 +0000 Message-Id: <20170602135207.21708-7-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170602135207.21708-1-ard.biesheuvel@linaro.org> References: <20170602135207.21708-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Reviewed-by: Matt Fleming Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/capsule-loader.c | 41 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 24 deletions(-) -- 2.9.3 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");