From patchwork Wed Feb 15 06:15:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ben@skyportsystems.com X-Patchwork-Id: 9573415 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 E427F60209 for ; Wed, 15 Feb 2017 06:21:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D41D7283A6 for ; Wed, 15 Feb 2017 06:21:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C769A28427; Wed, 15 Feb 2017 06:21:07 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4B800283A6 for ; Wed, 15 Feb 2017 06:21:07 +0000 (UTC) Received: from localhost ([::1]:38703 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdsxe-0005nh-De for patchwork-qemu-devel@patchwork.kernel.org; Wed, 15 Feb 2017 01:21:06 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42520) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdssu-00023D-7w for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdssq-0007DD-Pa for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:12 -0500 Received: from mail-pg0-x22f.google.com ([2607:f8b0:400e:c05::22f]:36595) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdssq-0007Ch-Hp for qemu-devel@nongnu.org; Wed, 15 Feb 2017 01:16:08 -0500 Received: by mail-pg0-x22f.google.com with SMTP id v184so34070435pgv.3 for ; Tue, 14 Feb 2017 22:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=D/MVAaQRLDQOSkvx1dblY7eZ8zk7D/XEZqd9/NZOcwU=; b=avP/r1mCwXIf8WLRNHzeb7AftMlOw0oJtRya2OqVvfnWXkpkcWvKS5H7901/yX/gtN UK83ZpEbqPwLJoj7rQF7U14SY/rh75FAOu86U1SmyBi9qbyoiPKNTTOflwdWcHc09ysE 6UZDiTb8VwMjV4u+fLGX0FSYhVLaKNHB6jGzk= 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:in-reply-to:references; bh=D/MVAaQRLDQOSkvx1dblY7eZ8zk7D/XEZqd9/NZOcwU=; b=LbXZjzM3FNQYjO51qH5N+09gDE46EmBCrYiYDDnyK27TPa6fSmryqzpkzLGTomRDw9 Uw8itwy9SXAjnGOk3pba2rN9iqe5dmZkWGLAhUW/KNvL58NN5OrSGnpaeFAOWq+ui/E6 n3QkYh7n0yo1W+83SCJ068NQioiEcBH8xTFRnHGYGXIg3iMG/s+bQUHUNaQoND8PAL6s /bdsLm7ja5T7ET/hvKke+IIMXY9LL50E/oTqwqmOroD0CN2cYNDSJGLb+tlvhcRvXy3t j6k9JyPB8eWF0uEQzizXXCX1klKTzWepePm7+ALQTgTFSUedLK1Uox6WR7QNRnO59FuQ rCKQ== X-Gm-Message-State: AMke39m/GSYRTfm9h396k17JrsOsK7Yuq429cKP6lPTA/UjOVdIexs6hv1N3TQft7m12n/WX X-Received: by 10.99.227.5 with SMTP id f5mr37129682pgh.102.1487139366109; Tue, 14 Feb 2017 22:16:06 -0800 (PST) Received: from Arrow.corp.skyportsystems.com (76-236-31-201.lightspeed.sntcca.sbcglobal.net. [76.236.31.201]) by smtp.gmail.com with ESMTPSA id n70sm4690150pfg.34.2017.02.14.22.16.05 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 14 Feb 2017 22:16:05 -0800 (PST) From: ben@skyportsystems.com To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 22:15:43 -0800 Message-Id: <9dffe31a245cf6a717eef8227fe80ca666b168b5.1487139038.git.ben@skyportsystems.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c05::22f Subject: [Qemu-devel] [PATCH v6 1/7] linker-loader: Add new 'write pointer' command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: imammedo@redhat.com, lersek@redhat.com, Ben Warren , mst@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Ben Warren This is similar to the existing 'add pointer' functionality, but instead of instructing the guest (BIOS or UEFI) to patch memory, it instructs the guest to write the pointer back to QEMU via a writeable fw_cfg file. Signed-off-by: Ben Warren Reviewed-by: Laszlo Ersek --- hw/acpi/bios-linker-loader.c | 58 ++++++++++++++++++++++++++++++++++-- include/hw/acpi/bios-linker-loader.h | 6 ++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c index d963ebe..5030cf1 100644 --- a/hw/acpi/bios-linker-loader.c +++ b/hw/acpi/bios-linker-loader.c @@ -78,6 +78,19 @@ struct BiosLinkerLoaderEntry { uint32_t length; } cksum; + /* + * COMMAND_WRITE_POINTER - write the fw_cfg file (originating from + * @dest_file) at @wr_pointer.offset, by adding a pointer to the table + * originating from @src_file. 1,2,4 or 8 byte unsigned + * addition is used depending on @wr_pointer.size. + */ + struct { + char dest_file[BIOS_LINKER_LOADER_FILESZ]; + char src_file[BIOS_LINKER_LOADER_FILESZ]; + uint32_t offset; + uint8_t size; + } wr_pointer; + /* padding */ char pad[124]; }; @@ -85,9 +98,10 @@ struct BiosLinkerLoaderEntry { typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry; enum { - BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1, - BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2, - BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3, + BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1, + BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2, + BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3, + BIOS_LINKER_LOADER_COMMAND_WRITE_POINTER = 0x4, }; enum { @@ -278,3 +292,41 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker, g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); } + +/* + * bios_linker_loader_write_pointer: ask guest to write a pointer to the + * source file into the destination file, and write it back to QEMU via + * fw_cfg DMA. + * + * @linker: linker object instance + * @dest_file: destination file that must be written + * @dst_patched_offset: location within destination file blob to be patched + * with the pointer to @src_file, in bytes + * @dst_patched_offset_size: size of the pointer to be patched + * at @dst_patched_offset in @dest_file blob, in bytes + * @src_file: source file who's address must be taken + */ +void bios_linker_loader_write_pointer(BIOSLinker *linker, + const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, + const char *src_file) +{ + BiosLinkerLoaderEntry entry; + const BiosLinkerFileEntry *source_file = + bios_linker_find_file(linker, src_file); + + assert(source_file); + memset(&entry, 0, sizeof entry); + strncpy(entry.wr_pointer.dest_file, dest_file, + sizeof entry.wr_pointer.dest_file - 1); + strncpy(entry.wr_pointer.src_file, src_file, + sizeof entry.wr_pointer.src_file - 1); + entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_WRITE_POINTER); + entry.wr_pointer.offset = cpu_to_le32(dst_patched_offset); + entry.wr_pointer.size = dst_patched_size; + assert(dst_patched_size == 1 || dst_patched_size == 2 || + dst_patched_size == 4 || dst_patched_size == 8); + + g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); +} diff --git a/include/hw/acpi/bios-linker-loader.h b/include/hw/acpi/bios-linker-loader.h index fa1e5d1..f9ba5d6 100644 --- a/include/hw/acpi/bios-linker-loader.h +++ b/include/hw/acpi/bios-linker-loader.h @@ -26,5 +26,11 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker, const char *src_file, uint32_t src_offset); +void bios_linker_loader_write_pointer(BIOSLinker *linker, + const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, + const char *src_file); + void bios_linker_loader_cleanup(BIOSLinker *linker); #endif