From patchwork Wed Jan 14 09:41:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 428885 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 060DA14012C for ; Wed, 14 Jan 2015 20:42:43 +1100 (AEDT) Received: from localhost ([::1]:45226 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YBKTJ-00040Y-39 for incoming@patchwork.ozlabs.org; Wed, 14 Jan 2015 04:42:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39949) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YBKSY-0002jA-I6 for qemu-devel@nongnu.org; Wed, 14 Jan 2015 04:41:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YBKSW-00009Z-1o for qemu-devel@nongnu.org; Wed, 14 Jan 2015 04:41:54 -0500 Received: from mail-wi0-x22c.google.com ([2a00:1450:400c:c05::22c]:35377) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YBKSV-00009R-OE for qemu-devel@nongnu.org; Wed, 14 Jan 2015 04:41:51 -0500 Received: by mail-wi0-f172.google.com with SMTP id n3so26780832wiv.5 for ; Wed, 14 Jan 2015 01:41:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=6AZzmCr/8FMz3wF/wa3So5bJnNiD68Z0vKtDQ5WvKKA=; b=pTf7kJPJi3oiOl1f5TOTD647W3Fjbi+Ex0vjIh3VatWaP1uw1GRSI+upw+xQYsYDuy 5sLPrJCnNePzXKzMNeurgbiTpw7VO2fphpD9uKl+xblpdsv36HKRagVJ3HAfPlOwq+Rz opftnhy24cue+f2drqeEkn5hXaATaAzCcQtvinZXpUzN7SLB2zXe43LW4JWfM7Xjsaoi 5Weku2R0nzqzjtT3ZPY1ERu83xfPVSgw/ldeMo43HJQnLFnvajhDTmp2V0I6YfDB3BGO x/k/RZLgMcOK3CovCRc6XsV6/cDzLG8YnDXMaXn/dWDhlVNUD4rhzSPzU1Gv4w02nb5B fw9w== X-Received: by 10.180.21.206 with SMTP id x14mr12590907wie.64.1421228511078; Wed, 14 Jan 2015 01:41:51 -0800 (PST) Received: from playground.station (net-37-117-129-192.cust.vodafonedsl.it. [37.117.129.192]) by mx.google.com with ESMTPSA id hn2sm29298235wjc.5.2015.01.14.01.41.49 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Jan 2015 01:41:49 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 14 Jan 2015 10:41:24 +0100 Message-Id: <1421228492-19856-8-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1421228492-19856-1-git-send-email-pbonzini@redhat.com> References: <1421228492-19856-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::22c Cc: Marcel Apfelbaum Subject: [Qemu-devel] [PULL 07/15] vl.c: fix regression when reading memory size from config file 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: Marcel Apfelbaum This is happening because an actual logic is performed on the memory arguments inside the main's switch, disregarding the config file content. Solved by extracting the logic on a separate function and calling it after the switch. Signed-off-by: Marcel Apfelbaum Signed-off-by: Paolo Bonzini --- vl.c | 181 +++++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 94 insertions(+), 87 deletions(-) diff --git a/vl.c b/vl.c index f6b24c4..54e6bbd 100644 --- a/vl.c +++ b/vl.c @@ -2648,6 +2648,96 @@ out: return 0; } +static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size) +{ + uint64_t sz; + const char *mem_str; + const char *maxmem_str, *slots_str; + const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE * + 1024 * 1024; + QemuOpts *opts = qemu_find_opts_singleton("memory"); + + ram_size = default_ram_size; + *maxram_size = default_ram_size; + + mem_str = qemu_opt_get(opts, "size"); + if (!mem_str) { + goto done; + } + if (!*mem_str) { + error_report("missing 'size' option value"); + exit(EXIT_FAILURE); + } + + sz = qemu_opt_get_size(opts, "size", ram_size); + + /* Fix up legacy suffix-less format */ + if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) { + uint64_t overflow_check = sz; + + sz <<= 20; + if ((sz >> 20) != overflow_check) { + error_report("too large 'size' option value"); + exit(EXIT_FAILURE); + } + } + + /* backward compatibility behaviour for case "-m 0" */ + if (sz == 0) { + sz = default_ram_size; + } + + sz = QEMU_ALIGN_UP(sz, 8192); + ram_size = sz; + if (ram_size != sz) { + error_report("ram size too large"); + exit(EXIT_FAILURE); + } + *maxram_size = ram_size; + + maxmem_str = qemu_opt_get(opts, "maxmem"); + slots_str = qemu_opt_get(opts, "slots"); + if (maxmem_str && slots_str) { + uint64_t slots; + + sz = qemu_opt_get_size(opts, "maxmem", 0); + if (sz < ram_size) { + error_report("invalid -m option value: maxmem " + "(0x%" PRIx64 ") <= initial memory (0x" + RAM_ADDR_FMT ")", sz, ram_size); + exit(EXIT_FAILURE); + } + + slots = qemu_opt_get_number(opts, "slots", 0); + if ((sz > ram_size) && !slots) { + error_report("invalid -m option value: maxmem " + "(0x%" PRIx64 ") more than initial memory (0x" + RAM_ADDR_FMT ") but no hotplug slots where " + "specified", sz, ram_size); + exit(EXIT_FAILURE); + } + + if ((sz <= ram_size) && slots) { + error_report("invalid -m option value: %" + PRIu64 " hotplug slots where specified but " + "maxmem (0x%" PRIx64 ") <= initial memory (0x" + RAM_ADDR_FMT ")", slots, sz, ram_size); + exit(EXIT_FAILURE); + } + *maxram_size = sz; + *ram_slots = slots; + } else if ((!maxmem_str && slots_str) || + (maxmem_str && !slots_str)) { + error_report("invalid -m option value: missing " + "'%s' option", slots_str ? "maxmem" : "slots"); + exit(EXIT_FAILURE); + } + +done: + /* store value for the future use */ + qemu_opt_set_number(opts, "size", ram_size); +} + int main(int argc, char **argv, char **envp) { int i; @@ -2683,9 +2773,7 @@ int main(int argc, char **argv, char **envp) }; const char *trace_events = NULL; const char *trace_file = NULL; - const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE * - 1024 * 1024; - ram_addr_t maxram_size = default_ram_size; + ram_addr_t maxram_size; uint64_t ram_slots = 0; FILE *vmstate_dump_file = NULL; Error *main_loop_err = NULL; @@ -2736,7 +2824,6 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_MACHINE); machine_class = find_default_machine(); cpu_model = NULL; - ram_size = default_ram_size; snapshot = 0; cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; @@ -3023,92 +3110,13 @@ int main(int argc, char **argv, char **envp) version(); exit(0); break; - case QEMU_OPTION_m: { - uint64_t sz; - const char *mem_str; - const char *maxmem_str, *slots_str; - + case QEMU_OPTION_m: opts = qemu_opts_parse(qemu_find_opts("memory"), optarg, 1); if (!opts) { exit(EXIT_FAILURE); } - - mem_str = qemu_opt_get(opts, "size"); - if (!mem_str) { - error_report("invalid -m option, missing 'size' option"); - exit(EXIT_FAILURE); - } - if (!*mem_str) { - error_report("missing 'size' option value"); - exit(EXIT_FAILURE); - } - - sz = qemu_opt_get_size(opts, "size", ram_size); - - /* Fix up legacy suffix-less format */ - if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) { - uint64_t overflow_check = sz; - - sz <<= 20; - if ((sz >> 20) != overflow_check) { - error_report("too large 'size' option value"); - exit(EXIT_FAILURE); - } - } - - /* backward compatibility behaviour for case "-m 0" */ - if (sz == 0) { - sz = default_ram_size; - } - - sz = QEMU_ALIGN_UP(sz, 8192); - ram_size = sz; - if (ram_size != sz) { - error_report("ram size too large"); - exit(EXIT_FAILURE); - } - maxram_size = ram_size; - - maxmem_str = qemu_opt_get(opts, "maxmem"); - slots_str = qemu_opt_get(opts, "slots"); - if (maxmem_str && slots_str) { - uint64_t slots; - - sz = qemu_opt_get_size(opts, "maxmem", 0); - if (sz < ram_size) { - error_report("invalid -m option value: maxmem " - "(0x%" PRIx64 ") <= initial memory (0x" - RAM_ADDR_FMT ")", sz, ram_size); - exit(EXIT_FAILURE); - } - - slots = qemu_opt_get_number(opts, "slots", 0); - if ((sz > ram_size) && !slots) { - error_report("invalid -m option value: maxmem " - "(0x%" PRIx64 ") more than initial memory (0x" - RAM_ADDR_FMT ") but no hotplug slots where " - "specified", sz, ram_size); - exit(EXIT_FAILURE); - } - - if ((sz <= ram_size) && slots) { - error_report("invalid -m option value: %" - PRIu64 " hotplug slots where specified but " - "maxmem (0x%" PRIx64 ") <= initial memory (0x" - RAM_ADDR_FMT ")", slots, sz, ram_size); - exit(EXIT_FAILURE); - } - maxram_size = sz; - ram_slots = slots; - } else if ((!maxmem_str && slots_str) || - (maxmem_str && !slots_str)) { - error_report("invalid -m option value: missing " - "'%s' option", slots_str ? "maxmem" : "slots"); - exit(EXIT_FAILURE); - } break; - } #ifdef CONFIG_TPM case QEMU_OPTION_tpmdev: if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) { @@ -3757,6 +3765,8 @@ int main(int argc, char **argv, char **envp) machine_class = machine_parse(optarg); } + set_memory_options(&ram_slots, &maxram_size); + loc_set_none(); os_daemonize(); @@ -4006,9 +4016,6 @@ int main(int argc, char **argv, char **envp) exit(1); } - /* store value for the future use */ - qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size); - if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) != 0) { exit(0);