From patchwork Fri Aug 16 13:18:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 267635 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 67A742C0497 for ; Fri, 16 Aug 2013 23:19:15 +1000 (EST) Received: from localhost ([::1]:58959 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VAJvt-00030t-F2 for incoming@patchwork.ozlabs.org; Fri, 16 Aug 2013 09:19:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59058) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VAJvP-00030T-CZ for qemu-devel@nongnu.org; Fri, 16 Aug 2013 09:18:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VAJvJ-0005Pi-Bv for qemu-devel@nongnu.org; Fri, 16 Aug 2013 09:18:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:20365) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VAJvJ-0005Of-4s for qemu-devel@nongnu.org; Fri, 16 Aug 2013 09:18:37 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r7GDIa33015169 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 16 Aug 2013 09:18:36 -0400 Received: from blackfin.pond.sub.org (ovpn-116-31.ams2.redhat.com [10.36.116.31]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r7GDIZUa002397; Fri, 16 Aug 2013 09:18:35 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id DC2BB200B9; Fri, 16 Aug 2013 15:18:34 +0200 (CEST) From: armbru@redhat.com To: qemu-devel@nongnu.org Date: Fri, 16 Aug 2013 15:18:30 +0200 Message-Id: <1376659114-6630-4-git-send-email-armbru@redhat.com> In-Reply-To: <1376659114-6630-1-git-send-email-armbru@redhat.com> References: <1376659114-6630-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: lersek@redhat.com, aliguori@us.ibm.com, ehabkost@redhat.com Subject: [Qemu-devel] [PATCH v2 3/7] smbios: Improve diagnostics for conflicting entries X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Markus Armbruster We allow either tables or fields for the same type. Makes sense, because SeaBIOS uses fields only when no tables are present. We do this by searching the SMBIOS blob for a previously added table or field. Error messages look like this: qemu-system-x86_64: -smbios type=1,serial=42: SMBIOS type 1 table already defined, cannot add field User needs to know that "table" is defined by -smbios file=..., and "field" by -smbios type=... Instead of searching the blob, record additions of interest, and check that. Simpler, and makes better error messages possible: qemu-system-x86_64: -smbios file=smbios_type_1.bin: Can't mix file= and type= for same type qemu-system-x86_64: -smbios type=1,serial=42,serial=99: This is the conflicting setting Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- hw/i386/smbios.c | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index a113f8b..7908c47 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -48,6 +48,12 @@ static uint8_t *smbios_entries; static size_t smbios_entries_len; static int smbios_type4_count = 0; +static struct { + bool seen; + int headertype; + Location loc; +} first_opt[2]; + static QemuOptsList qemu_smbios_opts = { .name = "smbios", .head = QTAILQ_HEAD_INITIALIZER(qemu_smbios_opts.head), @@ -159,35 +165,20 @@ uint8_t *smbios_get_table(size_t *length) */ static void smbios_check_collision(int type, int entry) { - uint16_t *num_entries = (uint16_t *)smbios_entries; - struct smbios_header *header; - char *p; - int i; - - if (!num_entries) - return; - - p = (char *)(num_entries + 1); - - for (i = 0; i < *num_entries; i++) { - header = (struct smbios_header *)p; - if (entry == SMBIOS_TABLE_ENTRY && header->type == SMBIOS_FIELD_ENTRY) { - struct smbios_field *field = (void *)header; - if (type == field->type) { - error_report("SMBIOS type %d field already defined, " - "cannot add table", type); - exit(1); - } - } else if (entry == SMBIOS_FIELD_ENTRY && - header->type == SMBIOS_TABLE_ENTRY) { - struct smbios_structure_header *table = (void *)(header + 1); - if (type == table->type) { - error_report("SMBIOS type %d table already defined, " - "cannot add field", type); + if (type < ARRAY_SIZE(first_opt)) { + if (first_opt[type].seen) { + if (first_opt[type].headertype != entry) { + error_report("Can't mix file= and type= for same type"); + loc_push_restore(&first_opt[type].loc); + error_report("This is the conflicting setting"); + loc_pop(&first_opt[type].loc); exit(1); } + } else { + first_opt[type].seen = true; + first_opt[type].headertype = entry; + loc_save(&first_opt[type].loc); } - p += le16_to_cpu(header->length); } }