From: Julien Thierry <julien.thierry@arm.com>
To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu
Cc: Sami.Mujawar@arm.com, will.deacon@arm.com
Subject: [PATCH kvmtool 4/6] arm: Support firmware loading
Date: Tue, 4 Dec 2018 11:14:31 +0000 [thread overview]
Message-ID: <1543922073-55530-5-git-send-email-julien.thierry@arm.com> (raw)
In-Reply-To: <1543922073-55530-1-git-send-email-julien.thierry@arm.com>
Implement firmware image loading for arm and set the boot start address
to the firmware address.
Add an option for the user to specify where to map the firmware.
Signed-off-by: Julien Thierry <julien.thierry@arm.com>
---
arm/fdt.c | 14 +++++++-
arm/include/arm-common/kvm-config-arch.h | 5 ++-
arm/kvm.c | 58 +++++++++++++++++++++++++++++++-
3 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/arm/fdt.c b/arm/fdt.c
index 664bb62..2936986 100644
--- a/arm/fdt.c
+++ b/arm/fdt.c
@@ -131,7 +131,19 @@ static int setup_fdt(struct kvm *kvm)
/* /chosen */
_FDT(fdt_begin_node(fdt, "chosen"));
_FDT(fdt_property_cell(fdt, "linux,pci-probe-only", 1));
- _FDT(fdt_property_string(fdt, "bootargs", kvm->cfg.real_cmdline));
+
+ if (kvm->cfg.firmware_filename) {
+ /*
+ * When using a firmware, command line is not passed through DT,
+ * or the firmware can add it itself
+ */
+ if (kvm->cfg.kernel_cmdline)
+ pr_warning("Ignoring custom bootargs: %s\n",
+ kvm->cfg.kernel_cmdline);
+ } else
+ _FDT(fdt_property_string(fdt, "bootargs",
+ kvm->cfg.real_cmdline));
+
_FDT(fdt_property_u64(fdt, "kaslr-seed", kvm->cfg.arch.kaslr_seed));
/* Initrd */
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 6a196f1..5734c46 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -11,6 +11,7 @@ struct kvm_config_arch {
bool has_pmuv3;
u64 kaslr_seed;
enum irqchip_type irqchip;
+ u64 fw_addr;
};
int irqchip_parser(const struct option *opt, const char *arg, int unset);
@@ -30,6 +31,8 @@ int irqchip_parser(const struct option *opt, const char *arg, int unset);
OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip, \
"[gicv2|gicv2m|gicv3|gicv3-its]", \
"Type of interrupt controller to emulate in the guest", \
- irqchip_parser, NULL),
+ irqchip_parser, NULL), \
+ OPT_U64('\0', "firmware-address", &(cfg)->fw_addr, \
+ "Address where firmware should be loaded"),
#endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/arm/kvm.c b/arm/kvm.c
index c6843e5..d5bbbc3 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -169,9 +169,65 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
return true;
}
+static bool validate_fw_addr(struct kvm *kvm)
+{
+ u64 fw_addr = kvm->cfg.arch.fw_addr;
+ u64 ram_phys;
+
+ ram_phys = host_to_guest_flat(kvm, kvm->ram_start);
+
+ if (fw_addr < ram_phys || fw_addr >= ram_phys + kvm->ram_size) {
+ pr_err("Provide --firmware-address an address in RAM: "
+ "0x%016llx - 0x%016llx",
+ ram_phys, ram_phys + kvm->ram_size);
+
+ return false;
+ }
+
+ return true;
+}
+
bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
{
- return false;
+ u64 fw_addr = kvm->cfg.arch.fw_addr;
+ void *host_pos;
+ void *limit;
+ ssize_t fw_sz;
+ int fd;
+
+ limit = kvm->ram_start + kvm->ram_size;
+
+ if (!validate_fw_addr(kvm))
+ die("Bad firmware destination: 0x%016llx", fw_addr);
+
+ fd = open(firmware_filename, O_RDONLY);
+ if (fd < 0)
+ return false;
+
+ host_pos = guest_flat_to_host(kvm, fw_addr);
+ if (!host_pos || host_pos < kvm->ram_start)
+ return false;
+
+ fw_sz = read_file(fd, host_pos, limit - host_pos);
+ if (fw_sz < 0)
+ die("failed to load firmware");
+ close(fd);
+
+ /* Kernel isn't loaded by kvm, point start address to firmware */
+ kvm->arch.kern_guest_start = fw_addr;
+
+ /* Load dtb just after the firmware image*/
+ host_pos += fw_sz;
+ if (host_pos + FDT_MAX_SIZE > limit)
+ die("not enough space to load fdt");
+
+ kvm->arch.dtb_guest_start = ALIGN(host_to_guest_flat(kvm, host_pos),
+ FDT_ALIGN);
+ pr_info("Placing fdt at 0x%llx - 0x%llx",
+ kvm->arch.dtb_guest_start,
+ kvm->arch.dtb_guest_start + FDT_MAX_SIZE);
+
+ return true;
}
int kvm__arch_setup_firmware(struct kvm *kvm)
--
1.9.1
next prev parent reply other threads:[~2018-12-04 11:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-04 11:14 [PATCH kvmtool 0/6] arm: Add support for firmware booting Julien Thierry
2018-12-04 11:14 ` [PATCH kvmtool 1/6] rtc: Initialize the Register D for MC146818 RTC Julien Thierry
2018-12-12 18:16 ` Andre Przywara
2018-12-14 18:58 ` Sami Mujawar
2018-12-04 11:14 ` [PATCH kvmtool 2/6] arm: Move firmware function Julien Thierry
2018-12-12 18:16 ` Andre Przywara
2018-12-04 11:14 ` [PATCH kvmtool 3/6] builtin-run: Do not look for default kernel when firmware is provided Julien Thierry
2018-12-12 18:16 ` Andre Przywara
2018-12-04 11:14 ` Julien Thierry [this message]
2018-12-14 18:08 ` [PATCH kvmtool 4/6] arm: Support firmware loading Andre Przywara
2018-12-17 10:05 ` Julien Thierry
2018-12-17 12:01 ` André Przywara
2018-12-04 11:14 ` [PATCH kvmtool 5/6] kvm: Add arch specific reset Julien Thierry
2018-12-14 18:11 ` Andre Przywara
2018-12-17 10:25 ` Julien Thierry
2018-12-04 11:14 ` [PATCH kvmtool 6/6] arm: Support non-volatile memory Julien Thierry
2018-12-14 18:09 ` Andre Przywara
2018-12-17 10:31 ` Julien Thierry
2018-12-17 12:04 ` André Przywara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1543922073-55530-5-git-send-email-julien.thierry@arm.com \
--to=julien.thierry@arm.com \
--cc=Sami.Mujawar@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox