From: Will Deacon <will@xxxxxxxxxx> For Testing Even when pkvm is enabled, guests are not protected by default. This allows the creation of protected guests with kvmtool. This is based on the current pKVM proposal [1, 2], and is likely to be different in the final version. [1] https://lore.kernel.org/kvmarm/20220519134204.5379-1-will@xxxxxxxxxx/ [2] https://lore.kernel.org/all/20221110190259.26861-1-will@xxxxxxxxxx/ Signed-off-by: Will Deacon <will@xxxxxxxxxx> Signed-off-by: Fuad Tabba <tabba@xxxxxxxxxx> --- arm/aarch64/kvm.c | 3 +++ arm/fdt.c | 18 ++++++++++++++++++ arm/include/arm-common/fdt-arch.h | 2 +- arm/pci.c | 3 +++ builtin-run.c | 2 ++ include/kvm/kvm-config.h | 1 + virtio/pci-modern.c | 3 +++ 7 files changed, 31 insertions(+), 1 deletion(-) diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c index 54200c9..f65c9c1 100644 --- a/arm/aarch64/kvm.c +++ b/arm/aarch64/kvm.c @@ -131,6 +131,9 @@ int kvm__get_vm_type(struct kvm *kvm) if (ipa_bits > max_ipa_bits) die("Memory too large for this system (needs %d bits, %d available)", ipa_bits, max_ipa_bits); + if (kvm->cfg.pkvm) + return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits) | (1U << 8); + return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits); } diff --git a/arm/fdt.c b/arm/fdt.c index 286ccad..0049bef 100644 --- a/arm/fdt.c +++ b/arm/fdt.c @@ -116,6 +116,7 @@ static int setup_fdt(struct kvm *kvm) 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,23 @@ static int setup_fdt(struct kvm *kvm) _FDT(fdt_property(fdt, "reg", mem_reg_prop, sizeof(mem_reg_prop))); _FDT(fdt_end_node(fdt)); + if (kvm->cfg.pkvm) { + /* 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_8M); + _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 5bd82d4..d183177 100644 --- a/arm/pci.c +++ b/arm/pci.c @@ -74,6 +74,9 @@ void pci__generate_fdt_nodes(void *fdt, struct kvm *kvm) if (irqchip == IRQCHIP_GICV2M || irqchip == IRQCHIP_GICV3_ITS) _FDT(fdt_property_cell(fdt, "msi-parent", PHANDLE_MSI)); + if (kvm->cfg.pkvm) + _FDT(fdt_property_cell(fdt, "memory-region", PHANDLE_DMA)); + /* Generate the interrupt map ... */ dev_hdr = device__first_dev(DEVICE_BUS_PCI); while (dev_hdr && nentries < ARRAY_SIZE(irq_map)) { diff --git a/builtin-run.c b/builtin-run.c index 4642bc4..9ec5701 100644 --- a/builtin-run.c +++ b/builtin-run.c @@ -204,6 +204,8 @@ static int mem_parser(const struct option *opt, const char *arg, int unset) "Use legacy virtio transport"), \ OPT_BOOLEAN('\0', "restricted_mem", &(cfg)->restricted_mem, \ "Use restricted memory for guests"), \ + OPT_BOOLEAN('\0', "pkvm", &(cfg)->pkvm, \ + "Spawn a protected VM (pkvm)"), \ \ OPT_GROUP("Kernel options:"), \ OPT_STRING('k', "kernel", &(cfg)->kernel_filename, "kernel", \ diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h index ea5f3ea..a18b8a3 100644 --- a/include/kvm/kvm-config.h +++ b/include/kvm/kvm-config.h @@ -66,6 +66,7 @@ struct kvm_config { bool mmio_debug; bool virtio_legacy; bool restricted_mem; + bool pkvm; }; #endif diff --git a/virtio/pci-modern.c b/virtio/pci-modern.c index c5b4bc5..84af042 100644 --- a/virtio/pci-modern.c +++ b/virtio/pci-modern.c @@ -150,6 +150,9 @@ static bool virtio_pci__common_read(struct virtio_device *vdev, struct virtio_pci *vpci = vdev->virtio; u64 features = 1ULL << VIRTIO_F_VERSION_1; + if (vpci->kvm->cfg.pkvm) + features |= 1ULL << VIRTIO_F_ACCESS_PLATFORM; + switch (offset - VPCI_CFG_COMMON_START) { case VIRTIO_PCI_COMMON_DFSELECT: val = vpci->device_features_sel; -- 2.39.0.rc0.267.gcb52ba06e7-goog