Hack for protected VMs to work

Change-Id: I202afbcf968eca33a5e219f9e0891fbdce95acef
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 56a0aed..fc4d486 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -79,5 +79,24 @@
 	if (ipa_bits > max_ipa_bits)
 		die("Memory too large for this system (needs %d bits, %d available)", ipa_bits, max_ipa_bits);
 
-	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
+	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits) | (1<<8);
 }
+
+/* HACK - HACK - HACK */
+#define KVM_CAP_ARM_PROTECTED_VM		206
+#define KVM_CAP_ARM_PROTECTED_VM_FLAGS_ENABLE	0
+#define KVM_CAP_ARM_PROTECTED_VM_FLAGS_INFO	1
+static int protected_vm_init(struct kvm *kvm)
+{
+	struct kvm_enable_cap pvm_cap = {
+		.cap = KVM_CAP_ARM_PROTECTED_VM,
+		.flags = KVM_CAP_ARM_PROTECTED_VM_FLAGS_ENABLE,
+		.args[0] = -1,
+	};
+	int ret;
+
+	ret = ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &pvm_cap);
+	printf("Protected vm init: %d\n", ret);
+	return 0;
+}
+dev_init(protected_vm_init);
diff --git a/arm/fdt.c b/arm/fdt.c
index 635de7f..0cd45d7 100644
--- a/arm/fdt.c
+++ b/arm/fdt.c
@@ -116,6 +116,7 @@
 					void (*)(void *, u8, enum irq_type));
 	void (*generate_cpu_peripheral_fdt_nodes)(void *, struct kvm *)
 					= kvm->cpus[0]->generate_fdt_nodes;
+	u64 resv_mem_prop;
 
 	/* Create new tree without a reserve map */
 	_FDT(fdt_create(fdt, FDT_MAX_SIZE));
@@ -163,6 +164,21 @@
 	_FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop)));
 	_FDT(fdt_end_node(fdt));
 
+	/* Reserved memory (restricted DMA) */
+	_FDT(fdt_begin_node(fdt, "reserved-memory"));
+	_FDT(fdt_property_cell(fdt, "#address-cells", 0x2));
+	_FDT(fdt_property_cell(fdt, "#size-cells", 0x2));
+	_FDT(fdt_property(fdt, "ranges", NULL, 0));
+
+	_FDT(fdt_begin_node(fdt, "restricted_dma_reserved"));
+	_FDT(fdt_property_string(fdt, "compatible", "restricted-dma-pool"));
+	resv_mem_prop = cpu_to_fdt64(SZ_2M);
+	_FDT(fdt_property(fdt, "size", &resv_mem_prop, sizeof(resv_mem_prop)));
+	_FDT(fdt_property_cell(fdt, "phandle", PHANDLE_DMA));
+	_FDT(fdt_end_node(fdt));
+
+	_FDT(fdt_end_node(fdt));
+
 	/* CPU and peripherals (interrupt controller, timers, etc) */
 	generate_cpu_nodes(fdt, kvm);
 	if (generate_cpu_peripheral_fdt_nodes)
diff --git a/arm/include/arm-common/fdt-arch.h b/arm/include/arm-common/fdt-arch.h
index 60c2d40..81df744 100644
--- a/arm/include/arm-common/fdt-arch.h
+++ b/arm/include/arm-common/fdt-arch.h
@@ -1,6 +1,6 @@
 #ifndef ARM__FDT_H
 #define ARM__FDT_H
 
-enum phandles {PHANDLE_RESERVED = 0, PHANDLE_GIC, PHANDLE_MSI, PHANDLES_MAX};
+enum phandles {PHANDLE_RESERVED = 0, PHANDLE_GIC, PHANDLE_MSI, PHANDLE_DMA, PHANDLES_MAX};
 
 #endif /* ARM__FDT_H */
diff --git a/arm/pci.c b/arm/pci.c
index 2251f62..c533e98 100644
--- a/arm/pci.c
+++ b/arm/pci.c
@@ -69,6 +69,7 @@
 	_FDT(fdt_property(fdt, "reg", &cfg_reg_prop, sizeof(cfg_reg_prop)));
 	_FDT(fdt_property(fdt, "ranges", ranges, sizeof(ranges)));
 	_FDT(fdt_property_cell(fdt, "msi-parent", PHANDLE_MSI));
+	_FDT(fdt_property_cell(fdt, "memory-region", PHANDLE_DMA));
 
 	/* Generate the interrupt map ... */
 	dev_hdr = device__first_dev(DEVICE_BUS_PCI);
diff --git a/builtin-run.c b/builtin-run.c
index 9a1a0c1..efa3638 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -524,6 +524,7 @@
 	static char default_name[20];
 	unsigned int nr_online_cpus;
 	struct kvm *kvm = kvm__new();
+	int ret;
 
 	if (IS_ERR(kvm))
 		return kvm;
@@ -685,6 +686,9 @@
 		       kvm->cfg.nrcpus, kvm->cfg.guest_name);
 	}
 
+	ret = mlock2(kvm->ram_start, kvm->ram_size, 0 | MLOCK_ONFAULT);
+	pr_info("mlock2() guest memory: (%d)", ret);
+
 	if (init_list__init(kvm) < 0)
 		die ("Initialisation failed");