From patchwork Mon May 16 15:55:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru Elisei X-Patchwork-Id: 12851024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AD863C433EF for ; Mon, 16 May 2022 15:59:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Cc:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ZVykDBfJ/72x0Gv47eH/2dRn+wTgvEQamysvaY4KGMo=; b=Ou0BWSxNRTfBKG SkGmeDYmUk+zcGt7y9gJKMjzjMAAlWVwoNWJ6sDyI4OIfDzdcet8p4cTCGxNcSQ5G/QgsOk+33rC5 UTNm2U2FyQQGU5vv2Ae+3GGKEIXy/GmHTo8lYL9wEzQmu2YZ/RSXzpvWCunVPnscjRIRudxsSnWDh Pt/1nfS4+40IiD4maWz8+bApsI8v/M4aTtmn8b/ZP9tKtjFo2KFfkMf3T24x7RzHW8vm+5oBawR2B jXmHEC9s767Ra5ZL1ur0R28ySbkj73XXfSeDhGGY8OzSs/b8crWu+E4w9JcOE7b2B5Cqq6ha3M9If 2NdTq88V67pSQFyJrmzQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nqd6p-008mAu-GX; Mon, 16 May 2022 15:58:11 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nqd4R-008kqZ-Tk for linux-arm-kernel@lists.infradead.org; Mon, 16 May 2022 15:55:45 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 617171063; Mon, 16 May 2022 08:55:43 -0700 (PDT) Received: from monolith.localdoman (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F092E3F73D; Mon, 16 May 2022 08:55:41 -0700 (PDT) From: Alexandru Elisei To: will@kernel.org, julien.thierry.kdev@gmail.com, maz@kernel.org, suzuki.poulose@arm.com, julien@xen.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, james.morse@arm.com Subject: [PATCH v2 kvmtool 12/12] arm64: Allow the user to specify the RAM base address Date: Mon, 16 May 2022 16:55:26 +0100 Message-Id: <20220516155526.181694-13-alexandru.elisei@arm.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220516155526.181694-1-alexandru.elisei@arm.com> References: <20220516155526.181694-1-alexandru.elisei@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220516_085544_077365_004DC349 X-CRM114-Status: GOOD ( 14.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Allow the user to specify the RAM base address by using -m/--mem size@addr command line argument. The base address must be above 2GB, as to not overlap with the MMIO I/O region. Signed-off-by: Alexandru Elisei --- arm/aarch64/include/kvm/kvm-arch.h | 2 ++ arm/aarch64/kvm.c | 5 ++++- arm/kvm.c | 7 +++++-- builtin-run.c | 29 +++++++++++++++++++++++++---- include/kvm/kvm-config.h | 1 + include/kvm/kvm.h | 12 ++++++++++++ 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h index ff857ca6e7b4..02d09a413831 100644 --- a/arm/aarch64/include/kvm/kvm-arch.h +++ b/arm/aarch64/include/kvm/kvm-arch.h @@ -10,6 +10,8 @@ void kvm__arch_enable_mte(struct kvm *kvm); #define MAX_PAGE_SIZE SZ_64K +#define ARCH_HAS_CFG_RAM_ADDRESS 1 + #include "arm-common/kvm-arch.h" #endif /* KVM__KVM_ARCH_H */ diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c index af8e7eae0da2..14ffae9e39dc 100644 --- a/arm/aarch64/kvm.c +++ b/arm/aarch64/kvm.c @@ -44,6 +44,9 @@ void kvm__arch_validate_cfg(struct kvm *kvm) die("RAM size 0x%llx exceeds maximum allowed 0x%llx", kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY); } + + if (kvm->cfg.ram_addr < ARM_MEMORY_AREA) + die("RAM address is below %luGB", ARM_MEMORY_AREA >> 30); } u64 kvm__arch_default_ram_address(void) @@ -117,7 +120,7 @@ int kvm__get_vm_type(struct kvm *kvm) return 0; /* Otherwise, compute the minimal required IPA size */ - max_ipa = ARM_MEMORY_AREA + kvm->cfg.ram_size - 1; + max_ipa = kvm->cfg.ram_addr + kvm->cfg.ram_size - 1; ipa_bits = max(32, fls_long(max_ipa)); pr_debug("max_ipa %lx ipa_bits %d max_ipa_bits %d", max_ipa, ipa_bits, max_ipa_bits); diff --git a/arm/kvm.c b/arm/kvm.c index abcccfabf59e..d51cc15d8b1c 100644 --- a/arm/kvm.c +++ b/arm/kvm.c @@ -55,7 +55,7 @@ void kvm__init_ram(struct kvm *kvm) madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size, MADV_HUGEPAGE); - phys_start = ARM_MEMORY_AREA; + phys_start = kvm->cfg.ram_addr; phys_size = kvm->ram_size; host_mem = kvm->ram_start; @@ -65,6 +65,9 @@ void kvm__init_ram(struct kvm *kvm) "address 0x%llx [err %d]", phys_size, phys_start, err); kvm->arch.memory_guest_start = phys_start; + + pr_debug("RAM created at 0x%llx - 0x%llx", + phys_start, phys_start + phys_size - 1); } void kvm__arch_delete_ram(struct kvm *kvm) @@ -201,7 +204,7 @@ bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) /* For default firmware address, lets load it at the begining of RAM */ if (fw_addr == 0) - fw_addr = ARM_MEMORY_AREA; + fw_addr = kvm->arch.memory_guest_start; if (!validate_fw_addr(kvm, fw_addr)) die("Bad firmware destination: 0x%016llx", fw_addr); diff --git a/builtin-run.c b/builtin-run.c index 57c58be55159..26e6e9974009 100644 --- a/builtin-run.c +++ b/builtin-run.c @@ -131,12 +131,22 @@ static u64 parse_mem_option(const char *nptr, char **next) static int mem_parser(const struct option *opt, const char *arg, int unset) { struct kvm *kvm = opt->ptr; - char *next; + char *next, *nptr; kvm->cfg.ram_size = parse_mem_option(arg, &next); if (kvm->cfg.ram_size == 0) die("Invalid RAM size: %s", arg); + kvm->cfg.ram_addr = kvm__arch_default_ram_address(); + if (kvm__arch_has_cfg_ram_address() && *next == '@') { + next++; + if (*next == '\0') + die("Missing memory address: %s", arg); + + nptr = next; + kvm->cfg.ram_addr = parse_mem_option(nptr, &next); + } + if (*next != '\0') die("Invalid memory specifier: %s", arg); @@ -147,15 +157,26 @@ static int mem_parser(const struct option *opt, const char *arg, int unset) #define OPT_ARCH_RUN(...) #endif +#ifdef ARCH_HAS_CFG_RAM_ADDRESS +#define MEM_OPT_HELP_SHORT "size[BKMGTP][@addr[BKMGTP]]" +#define MEM_OPT_HELP_LONG \ + "Virtual machine memory size and optional base address, both" \ + " measured by default in megabytes (M)" +#else +#define MEM_OPT_HELP_SHORT "size[BKMGTP]" +#define MEM_OPT_HELP_LONG \ + "Virtual machine memory size, by default measured in" \ + " in megabytes (M)" +#endif + #define BUILD_OPTIONS(name, cfg, kvm) \ struct option name[] = { \ OPT_GROUP("Basic options:"), \ OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name", \ "A name for the guest"), \ OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"), \ - OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]", \ - "Virtual machine memory size, by default measured" \ - " in megabytes (M)", mem_parser, kvm), \ + OPT_CALLBACK('m', "mem", NULL, MEM_OPT_HELP_SHORT, \ + MEM_OPT_HELP_LONG, mem_parser, kvm), \ OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk " \ " image or rootfs directory", img_name_parser, \ kvm), \ diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h index 31bc89520d52..45fe1caaebce 100644 --- a/include/kvm/kvm-config.h +++ b/include/kvm/kvm-config.h @@ -23,6 +23,7 @@ struct kvm_config { struct kvm_config_arch arch; struct disk_image_params disk_image[MAX_DISK_IMAGES]; struct vfio_device_params *vfio_devices; + u64 ram_addr; /* Guest memory physical base address, in bytes */ u64 ram_size; /* Guest memory size, in bytes */ u8 num_net_devices; u8 num_vfio_devices; diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h index 360430b78b1e..eb23e2f77310 100644 --- a/include/kvm/kvm.h +++ b/include/kvm/kvm.h @@ -197,6 +197,18 @@ int kvm__arch_free_firmware(struct kvm *kvm); bool kvm__arch_cpu_supports_vm(void); void kvm__arch_read_term(struct kvm *kvm); +#ifdef ARCH_HAS_CFG_RAM_ADDRESS +static inline bool kvm__arch_has_cfg_ram_address(void) +{ + return true; +} +#else +static inline bool kvm__arch_has_cfg_ram_address(void) +{ + return false; +} +#endif + void *guest_flat_to_host(struct kvm *kvm, u64 offset); u64 host_to_guest_flat(struct kvm *kvm, void *ptr);