xref: /kvmtool/arm/fdt.c (revision c2dad40280028f9e89a3451f29dd3aaa0bd2614f)
17c0e8b0cSWill Deacon #include "kvm/devices.h"
27c0e8b0cSWill Deacon #include "kvm/fdt.h"
37c0e8b0cSWill Deacon #include "kvm/kvm.h"
47c0e8b0cSWill Deacon #include "kvm/kvm-cpu.h"
57c0e8b0cSWill Deacon #include "kvm/virtio-mmio.h"
67c0e8b0cSWill Deacon 
77c0e8b0cSWill Deacon #include "arm-common/gic.h"
816242d27SWill Deacon #include "arm-common/pci.h"
97c0e8b0cSWill Deacon 
107c0e8b0cSWill Deacon #include <stdbool.h>
117c0e8b0cSWill Deacon 
127c0e8b0cSWill Deacon #include <asm/setup.h>
137c0e8b0cSWill Deacon #include <linux/byteorder.h>
147c0e8b0cSWill Deacon #include <linux/kernel.h>
157c0e8b0cSWill Deacon #include <linux/sizes.h>
16*c2dad402SAnup Patel #include <linux/psci.h>
177c0e8b0cSWill Deacon 
187c0e8b0cSWill Deacon static char kern_cmdline[COMMAND_LINE_SIZE];
197c0e8b0cSWill Deacon 
207c0e8b0cSWill Deacon bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
217c0e8b0cSWill Deacon {
227c0e8b0cSWill Deacon 	return false;
237c0e8b0cSWill Deacon }
247c0e8b0cSWill Deacon 
257c0e8b0cSWill Deacon int kvm__arch_setup_firmware(struct kvm *kvm)
267c0e8b0cSWill Deacon {
277c0e8b0cSWill Deacon 	return 0;
287c0e8b0cSWill Deacon }
297c0e8b0cSWill Deacon 
30ba27ff46SWill Deacon static void dump_fdt(const char *dtb_file, void *fdt)
317c0e8b0cSWill Deacon {
327c0e8b0cSWill Deacon 	int count, fd;
337c0e8b0cSWill Deacon 
34ba27ff46SWill Deacon 	fd = open(dtb_file, O_CREAT | O_TRUNC | O_RDWR, 0666);
357c0e8b0cSWill Deacon 	if (fd < 0)
36ba27ff46SWill Deacon 		die("Failed to write dtb to %s", dtb_file);
377c0e8b0cSWill Deacon 
387c0e8b0cSWill Deacon 	count = write(fd, fdt, FDT_MAX_SIZE);
397c0e8b0cSWill Deacon 	if (count < 0)
407c0e8b0cSWill Deacon 		die_perror("Failed to dump dtb");
417c0e8b0cSWill Deacon 
42ba27ff46SWill Deacon 	pr_info("Wrote %d bytes to dtb %s\n", count, dtb_file);
437c0e8b0cSWill Deacon 	close(fd);
447c0e8b0cSWill Deacon }
457c0e8b0cSWill Deacon 
46beff7ae0SMarc Zyngier #define CPU_NAME_MAX_LEN 8
47beff7ae0SMarc Zyngier static void generate_cpu_nodes(void *fdt, struct kvm *kvm)
48beff7ae0SMarc Zyngier {
49beff7ae0SMarc Zyngier 	int cpu;
50beff7ae0SMarc Zyngier 
51beff7ae0SMarc Zyngier 	_FDT(fdt_begin_node(fdt, "cpus"));
52beff7ae0SMarc Zyngier 	_FDT(fdt_property_cell(fdt, "#address-cells", 0x1));
53beff7ae0SMarc Zyngier 	_FDT(fdt_property_cell(fdt, "#size-cells", 0x0));
54beff7ae0SMarc Zyngier 
55beff7ae0SMarc Zyngier 	for (cpu = 0; cpu < kvm->nrcpus; ++cpu) {
56beff7ae0SMarc Zyngier 		char cpu_name[CPU_NAME_MAX_LEN];
57d06bc640SMarc Zyngier 		struct kvm_cpu *vcpu = kvm->cpus[cpu];
58d06bc640SMarc Zyngier 		unsigned long mpidr = kvm_cpu__get_vcpu_mpidr(vcpu);
59beff7ae0SMarc Zyngier 
60d06bc640SMarc Zyngier 		mpidr &= ARM_MPIDR_HWID_BITMASK;
61d06bc640SMarc Zyngier 		snprintf(cpu_name, CPU_NAME_MAX_LEN, "cpu@%lx", mpidr);
62beff7ae0SMarc Zyngier 
63beff7ae0SMarc Zyngier 		_FDT(fdt_begin_node(fdt, cpu_name));
64beff7ae0SMarc Zyngier 		_FDT(fdt_property_string(fdt, "device_type", "cpu"));
65d06bc640SMarc Zyngier 		_FDT(fdt_property_string(fdt, "compatible", vcpu->cpu_compatible));
66beff7ae0SMarc Zyngier 
67beff7ae0SMarc Zyngier 		if (kvm->nrcpus > 1)
68beff7ae0SMarc Zyngier 			_FDT(fdt_property_string(fdt, "enable-method", "psci"));
69beff7ae0SMarc Zyngier 
70d06bc640SMarc Zyngier 		_FDT(fdt_property_cell(fdt, "reg", mpidr));
71beff7ae0SMarc Zyngier 		_FDT(fdt_end_node(fdt));
72beff7ae0SMarc Zyngier 	}
73beff7ae0SMarc Zyngier 
74beff7ae0SMarc Zyngier 	_FDT(fdt_end_node(fdt));
75beff7ae0SMarc Zyngier }
76beff7ae0SMarc Zyngier 
772454c7dcSWill Deacon static void generate_irq_prop(void *fdt, u8 irq)
787c0e8b0cSWill Deacon {
797c0e8b0cSWill Deacon 	u32 irq_prop[] = {
807c0e8b0cSWill Deacon 		cpu_to_fdt32(GIC_FDT_IRQ_TYPE_SPI),
812454c7dcSWill Deacon 		cpu_to_fdt32(irq - GIC_SPI_IRQ_BASE),
827c0e8b0cSWill Deacon 		cpu_to_fdt32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
837c0e8b0cSWill Deacon 	};
847c0e8b0cSWill Deacon 
857c0e8b0cSWill Deacon 	_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
867c0e8b0cSWill Deacon }
877c0e8b0cSWill Deacon 
88*c2dad402SAnup Patel struct psci_fns {
89*c2dad402SAnup Patel 	u32 cpu_suspend;
90*c2dad402SAnup Patel 	u32 cpu_off;
91*c2dad402SAnup Patel 	u32 cpu_on;
92*c2dad402SAnup Patel 	u32 migrate;
93*c2dad402SAnup Patel };
94*c2dad402SAnup Patel 
95*c2dad402SAnup Patel static struct psci_fns psci_0_1_fns = {
96*c2dad402SAnup Patel 	.cpu_suspend = KVM_PSCI_FN_CPU_SUSPEND,
97*c2dad402SAnup Patel 	.cpu_off = KVM_PSCI_FN_CPU_OFF,
98*c2dad402SAnup Patel 	.cpu_on = KVM_PSCI_FN_CPU_ON,
99*c2dad402SAnup Patel 	.migrate = KVM_PSCI_FN_MIGRATE,
100*c2dad402SAnup Patel };
101*c2dad402SAnup Patel 
102*c2dad402SAnup Patel static struct psci_fns psci_0_2_aarch32_fns = {
103*c2dad402SAnup Patel 	.cpu_suspend = PSCI_0_2_FN_CPU_SUSPEND,
104*c2dad402SAnup Patel 	.cpu_off = PSCI_0_2_FN_CPU_OFF,
105*c2dad402SAnup Patel 	.cpu_on = PSCI_0_2_FN_CPU_ON,
106*c2dad402SAnup Patel 	.migrate = PSCI_0_2_FN_MIGRATE,
107*c2dad402SAnup Patel };
108*c2dad402SAnup Patel 
109*c2dad402SAnup Patel static struct psci_fns psci_0_2_aarch64_fns = {
110*c2dad402SAnup Patel 	.cpu_suspend = PSCI_0_2_FN64_CPU_SUSPEND,
111*c2dad402SAnup Patel 	.cpu_off = PSCI_0_2_FN_CPU_OFF,
112*c2dad402SAnup Patel 	.cpu_on = PSCI_0_2_FN64_CPU_ON,
113*c2dad402SAnup Patel 	.migrate = PSCI_0_2_FN64_MIGRATE,
114*c2dad402SAnup Patel };
115*c2dad402SAnup Patel 
1167c0e8b0cSWill Deacon static int setup_fdt(struct kvm *kvm)
1177c0e8b0cSWill Deacon {
1187c0e8b0cSWill Deacon 	struct device_header *dev_hdr;
1197c0e8b0cSWill Deacon 	u8 staging_fdt[FDT_MAX_SIZE];
1207c0e8b0cSWill Deacon 	u32 gic_phandle		= fdt__alloc_phandle();
1217c0e8b0cSWill Deacon 	u64 mem_reg_prop[]	= {
1227c0e8b0cSWill Deacon 		cpu_to_fdt64(kvm->arch.memory_guest_start),
1237c0e8b0cSWill Deacon 		cpu_to_fdt64(kvm->ram_size),
1247c0e8b0cSWill Deacon 	};
125*c2dad402SAnup Patel 	struct psci_fns *fns;
1267c0e8b0cSWill Deacon 	void *fdt		= staging_fdt;
1277c0e8b0cSWill Deacon 	void *fdt_dest		= guest_flat_to_host(kvm,
1287c0e8b0cSWill Deacon 						     kvm->arch.dtb_guest_start);
1292454c7dcSWill Deacon 	void (*generate_mmio_fdt_nodes)(void *, struct device_header *,
1302454c7dcSWill Deacon 					void (*)(void *, u8));
1312454c7dcSWill Deacon 	void (*generate_cpu_peripheral_fdt_nodes)(void *, struct kvm *, u32)
1327c0e8b0cSWill Deacon 					= kvm->cpus[0]->generate_fdt_nodes;
1337c0e8b0cSWill Deacon 
1347c0e8b0cSWill Deacon 	/* Create new tree without a reserve map */
1357c0e8b0cSWill Deacon 	_FDT(fdt_create(fdt, FDT_MAX_SIZE));
1367c0e8b0cSWill Deacon 	_FDT(fdt_finish_reservemap(fdt));
1377c0e8b0cSWill Deacon 
1387c0e8b0cSWill Deacon 	/* Header */
1397c0e8b0cSWill Deacon 	_FDT(fdt_begin_node(fdt, ""));
1407c0e8b0cSWill Deacon 	_FDT(fdt_property_cell(fdt, "interrupt-parent", gic_phandle));
1417c0e8b0cSWill Deacon 	_FDT(fdt_property_string(fdt, "compatible", "linux,dummy-virt"));
1427c0e8b0cSWill Deacon 	_FDT(fdt_property_cell(fdt, "#address-cells", 0x2));
1437c0e8b0cSWill Deacon 	_FDT(fdt_property_cell(fdt, "#size-cells", 0x2));
1447c0e8b0cSWill Deacon 
1457c0e8b0cSWill Deacon 	/* /chosen */
1467c0e8b0cSWill Deacon 	_FDT(fdt_begin_node(fdt, "chosen"));
1471fcf0d77SWill Deacon 	_FDT(fdt_property_cell(fdt, "linux,pci-probe-only", 1));
1487c0e8b0cSWill Deacon 	_FDT(fdt_property_string(fdt, "bootargs", kern_cmdline));
1497c0e8b0cSWill Deacon 
1507c0e8b0cSWill Deacon 	/* Initrd */
1517c0e8b0cSWill Deacon 	if (kvm->arch.initrd_size != 0) {
1527c0e8b0cSWill Deacon 		u32 ird_st_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start);
1537c0e8b0cSWill Deacon 		u32 ird_end_prop = cpu_to_fdt64(kvm->arch.initrd_guest_start +
1547c0e8b0cSWill Deacon 					       kvm->arch.initrd_size);
1557c0e8b0cSWill Deacon 
1567c0e8b0cSWill Deacon 		_FDT(fdt_property(fdt, "linux,initrd-start",
1577c0e8b0cSWill Deacon 				   &ird_st_prop, sizeof(ird_st_prop)));
1587c0e8b0cSWill Deacon 		_FDT(fdt_property(fdt, "linux,initrd-end",
1597c0e8b0cSWill Deacon 				   &ird_end_prop, sizeof(ird_end_prop)));
1607c0e8b0cSWill Deacon 	}
1617c0e8b0cSWill Deacon 	_FDT(fdt_end_node(fdt));
1627c0e8b0cSWill Deacon 
1637c0e8b0cSWill Deacon 	/* Memory */
1647c0e8b0cSWill Deacon 	_FDT(fdt_begin_node(fdt, "memory"));
1657c0e8b0cSWill Deacon 	_FDT(fdt_property_string(fdt, "device_type", "memory"));
1667c0e8b0cSWill Deacon 	_FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop)));
1677c0e8b0cSWill Deacon 	_FDT(fdt_end_node(fdt));
1687c0e8b0cSWill Deacon 
1697c0e8b0cSWill Deacon 	/* CPU and peripherals (interrupt controller, timers, etc) */
170beff7ae0SMarc Zyngier 	generate_cpu_nodes(fdt, kvm);
1712454c7dcSWill Deacon 	if (generate_cpu_peripheral_fdt_nodes)
1722454c7dcSWill Deacon 		generate_cpu_peripheral_fdt_nodes(fdt, kvm, gic_phandle);
1737c0e8b0cSWill Deacon 
1747c0e8b0cSWill Deacon 	/* Virtio MMIO devices */
1757c0e8b0cSWill Deacon 	dev_hdr = device__first_dev(DEVICE_BUS_MMIO);
1767c0e8b0cSWill Deacon 	while (dev_hdr) {
1772454c7dcSWill Deacon 		generate_mmio_fdt_nodes = dev_hdr->data;
1782454c7dcSWill Deacon 		generate_mmio_fdt_nodes(fdt, dev_hdr, generate_irq_prop);
1797c0e8b0cSWill Deacon 		dev_hdr = device__next_dev(dev_hdr);
1807c0e8b0cSWill Deacon 	}
1817c0e8b0cSWill Deacon 
182ed7b31c9SWill Deacon 	/* IOPORT devices (!) */
183ed7b31c9SWill Deacon 	dev_hdr = device__first_dev(DEVICE_BUS_IOPORT);
184ed7b31c9SWill Deacon 	while (dev_hdr) {
185ed7b31c9SWill Deacon 		generate_mmio_fdt_nodes = dev_hdr->data;
186ed7b31c9SWill Deacon 		generate_mmio_fdt_nodes(fdt, dev_hdr, generate_irq_prop);
187ed7b31c9SWill Deacon 		dev_hdr = device__next_dev(dev_hdr);
188ed7b31c9SWill Deacon 	}
189ed7b31c9SWill Deacon 
19016242d27SWill Deacon 	/* PCI host controller */
19116242d27SWill Deacon 	pci__generate_fdt_nodes(fdt, gic_phandle);
19216242d27SWill Deacon 
19361076240SWill Deacon 	/* PSCI firmware */
19461076240SWill Deacon 	_FDT(fdt_begin_node(fdt, "psci"));
195*c2dad402SAnup Patel 	if (kvm__supports_extension(kvm, KVM_CAP_ARM_PSCI_0_2)) {
196*c2dad402SAnup Patel 		const char compatible[] = "arm,psci-0.2\0arm,psci";
197*c2dad402SAnup Patel 		_FDT(fdt_property(fdt, "compatible",
198*c2dad402SAnup Patel 				  compatible, sizeof(compatible)));
199*c2dad402SAnup Patel 		if (kvm->cfg.arch.aarch32_guest)
200*c2dad402SAnup Patel 			fns = &psci_0_2_aarch32_fns;
201*c2dad402SAnup Patel 		else
202*c2dad402SAnup Patel 			fns = &psci_0_2_aarch64_fns;
203*c2dad402SAnup Patel 	} else {
20461076240SWill Deacon 		_FDT(fdt_property_string(fdt, "compatible", "arm,psci"));
205*c2dad402SAnup Patel 		fns = &psci_0_1_fns;
206*c2dad402SAnup Patel 	}
20761076240SWill Deacon 	_FDT(fdt_property_string(fdt, "method", "hvc"));
208*c2dad402SAnup Patel 	_FDT(fdt_property_cell(fdt, "cpu_suspend", fns->cpu_suspend));
209*c2dad402SAnup Patel 	_FDT(fdt_property_cell(fdt, "cpu_off", fns->cpu_off));
210*c2dad402SAnup Patel 	_FDT(fdt_property_cell(fdt, "cpu_on", fns->cpu_on));
211*c2dad402SAnup Patel 	_FDT(fdt_property_cell(fdt, "migrate", fns->migrate));
21261076240SWill Deacon 	_FDT(fdt_end_node(fdt));
21361076240SWill Deacon 
2147c0e8b0cSWill Deacon 	/* Finalise. */
2157c0e8b0cSWill Deacon 	_FDT(fdt_end_node(fdt));
2167c0e8b0cSWill Deacon 	_FDT(fdt_finish(fdt));
2177c0e8b0cSWill Deacon 
2187c0e8b0cSWill Deacon 	_FDT(fdt_open_into(fdt, fdt_dest, FDT_MAX_SIZE));
2197c0e8b0cSWill Deacon 	_FDT(fdt_pack(fdt_dest));
2207c0e8b0cSWill Deacon 
221ba27ff46SWill Deacon 	if (kvm->cfg.arch.dump_dtb_filename)
222ba27ff46SWill Deacon 		dump_fdt(kvm->cfg.arch.dump_dtb_filename, fdt_dest);
2237c0e8b0cSWill Deacon 	return 0;
2247c0e8b0cSWill Deacon }
2257c0e8b0cSWill Deacon late_init(setup_fdt);
2267c0e8b0cSWill Deacon 
2277c0e8b0cSWill Deacon static int read_image(int fd, void **pos, void *limit)
2287c0e8b0cSWill Deacon {
2297c0e8b0cSWill Deacon 	int count;
2307c0e8b0cSWill Deacon 
2317c0e8b0cSWill Deacon 	while (((count = xread(fd, *pos, SZ_64K)) > 0) && *pos <= limit)
2327c0e8b0cSWill Deacon 		*pos += count;
2337c0e8b0cSWill Deacon 
2347c0e8b0cSWill Deacon 	if (pos < 0)
2357c0e8b0cSWill Deacon 		die_perror("xread");
2367c0e8b0cSWill Deacon 
2377c0e8b0cSWill Deacon 	return *pos < limit ? 0 : -ENOMEM;
2387c0e8b0cSWill Deacon }
2397c0e8b0cSWill Deacon 
2407c0e8b0cSWill Deacon #define FDT_ALIGN	SZ_2M
2417c0e8b0cSWill Deacon #define INITRD_ALIGN	4
2427c0e8b0cSWill Deacon int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd,
2437c0e8b0cSWill Deacon 		     const char *kernel_cmdline)
2447c0e8b0cSWill Deacon {
2457c0e8b0cSWill Deacon 	void *pos, *kernel_end, *limit;
2467c0e8b0cSWill Deacon 	unsigned long guest_addr;
2477c0e8b0cSWill Deacon 
2487c0e8b0cSWill Deacon 	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
2497c0e8b0cSWill Deacon 		die_perror("lseek");
2507c0e8b0cSWill Deacon 
2517c0e8b0cSWill Deacon 	/*
25261076240SWill Deacon 	 * Linux requires the initrd and dtb to be mapped inside lowmem,
25361076240SWill Deacon 	 * so we can't just place them at the top of memory.
2547c0e8b0cSWill Deacon 	 */
2557c0e8b0cSWill Deacon 	limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1;
2567c0e8b0cSWill Deacon 
2571e0c135aSWill Deacon 	pos = kvm->ram_start + ARM_KERN_OFFSET(kvm);
2587c0e8b0cSWill Deacon 	kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos);
2597c0e8b0cSWill Deacon 	if (read_image(fd_kernel, &pos, limit) == -ENOMEM)
2607c0e8b0cSWill Deacon 		die("kernel image too big to contain in guest memory.");
2617c0e8b0cSWill Deacon 
2627c0e8b0cSWill Deacon 	kernel_end = pos;
2637c0e8b0cSWill Deacon 	pr_info("Loaded kernel to 0x%llx (%llu bytes)",
2647c0e8b0cSWill Deacon 		kvm->arch.kern_guest_start,
2657c0e8b0cSWill Deacon 		host_to_guest_flat(kvm, pos) - kvm->arch.kern_guest_start);
2667c0e8b0cSWill Deacon 
2677c0e8b0cSWill Deacon 	/*
2687c0e8b0cSWill Deacon 	 * Now load backwards from the end of memory so the kernel
2697c0e8b0cSWill Deacon 	 * decompressor has plenty of space to work with. First up is
27061076240SWill Deacon 	 * the device tree blob...
2717c0e8b0cSWill Deacon 	 */
2727c0e8b0cSWill Deacon 	pos = limit;
2737c0e8b0cSWill Deacon 	pos -= (FDT_MAX_SIZE + FDT_ALIGN);
2747c0e8b0cSWill Deacon 	guest_addr = ALIGN(host_to_guest_flat(kvm, pos), FDT_ALIGN);
2757c0e8b0cSWill Deacon 	pos = guest_flat_to_host(kvm, guest_addr);
2767c0e8b0cSWill Deacon 	if (pos < kernel_end)
2777c0e8b0cSWill Deacon 		die("fdt overlaps with kernel image.");
2787c0e8b0cSWill Deacon 
2797c0e8b0cSWill Deacon 	kvm->arch.dtb_guest_start = guest_addr;
2807c0e8b0cSWill Deacon 	pr_info("Placing fdt at 0x%llx - 0x%llx",
2817c0e8b0cSWill Deacon 		kvm->arch.dtb_guest_start,
2827c0e8b0cSWill Deacon 		host_to_guest_flat(kvm, limit));
2837c0e8b0cSWill Deacon 	limit = pos;
2847c0e8b0cSWill Deacon 
2857c0e8b0cSWill Deacon 	/* ... and finally the initrd, if we have one. */
2867c0e8b0cSWill Deacon 	if (fd_initrd != -1) {
2877c0e8b0cSWill Deacon 		struct stat sb;
2887c0e8b0cSWill Deacon 		unsigned long initrd_start;
2897c0e8b0cSWill Deacon 
2907c0e8b0cSWill Deacon 		if (lseek(fd_initrd, 0, SEEK_SET) < 0)
2917c0e8b0cSWill Deacon 			die_perror("lseek");
2927c0e8b0cSWill Deacon 
2937c0e8b0cSWill Deacon 		if (fstat(fd_initrd, &sb))
2947c0e8b0cSWill Deacon 			die_perror("fstat");
2957c0e8b0cSWill Deacon 
2967c0e8b0cSWill Deacon 		pos -= (sb.st_size + INITRD_ALIGN);
2977c0e8b0cSWill Deacon 		guest_addr = ALIGN(host_to_guest_flat(kvm, pos), INITRD_ALIGN);
2987c0e8b0cSWill Deacon 		pos = guest_flat_to_host(kvm, guest_addr);
2997c0e8b0cSWill Deacon 		if (pos < kernel_end)
3007c0e8b0cSWill Deacon 			die("initrd overlaps with kernel image.");
3017c0e8b0cSWill Deacon 
3027c0e8b0cSWill Deacon 		initrd_start = guest_addr;
3037c0e8b0cSWill Deacon 		if (read_image(fd_initrd, &pos, limit) == -ENOMEM)
3047c0e8b0cSWill Deacon 			die("initrd too big to contain in guest memory.");
3057c0e8b0cSWill Deacon 
3067c0e8b0cSWill Deacon 		kvm->arch.initrd_guest_start = initrd_start;
3077c0e8b0cSWill Deacon 		kvm->arch.initrd_size = host_to_guest_flat(kvm, pos) - initrd_start;
3087c0e8b0cSWill Deacon 		pr_info("Loaded initrd to 0x%llx (%llu bytes)",
3097c0e8b0cSWill Deacon 			kvm->arch.initrd_guest_start,
3107c0e8b0cSWill Deacon 			kvm->arch.initrd_size);
3117c0e8b0cSWill Deacon 	} else {
3127c0e8b0cSWill Deacon 		kvm->arch.initrd_size = 0;
3137c0e8b0cSWill Deacon 	}
3147c0e8b0cSWill Deacon 
3157c0e8b0cSWill Deacon 	strncpy(kern_cmdline, kernel_cmdline, COMMAND_LINE_SIZE);
3167c0e8b0cSWill Deacon 	kern_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
3177c0e8b0cSWill Deacon 
3187c0e8b0cSWill Deacon 	return true;
3197c0e8b0cSWill Deacon }
320