* [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool
@ 2013-01-07 18:43 Will Deacon
2013-01-07 18:43 ` [PATCH 1/2] kvm tools: add support for ARMv8 processors Will Deacon
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Will Deacon @ 2013-01-07 18:43 UTC (permalink / raw)
To: kvm; +Cc: penberg, marc.zyngier, c.dall, kvmarm, Will Deacon
Hello again,
These two patches add support for ARMv8 processors running an AArch64 instance
of kvm to kvmtool. Both AArch32 and AArch64 guests are supported and, in the
case of the latter, the guest page size may be either 64k or 4k.
This depends on the ARM updates series I just posted:
https://lists.cs.columbia.edu/pipermail/kvmarm/2013-January/004505.html
Feedback welcome,
Will
Will Deacon (2):
kvm tools: add support for ARMv8 processors
kvm tools: arm: align guest memory buffer to maximum page size
tools/kvm/Makefile | 14 +-
tools/kvm/arm/aarch32/include/kvm/kvm-arch.h | 20 +--
.../kvm/arm/aarch32/include/kvm/kvm-config-arch.h | 8 ++
tools/kvm/arm/aarch64/cortex-a57.c | 95 ++++++++++++
tools/kvm/arm/aarch64/include/kvm/barrier.h | 8 ++
tools/kvm/arm/aarch64/include/kvm/kvm-arch.h | 17 +++
.../kvm/arm/aarch64/include/kvm/kvm-config-arch.h | 10 ++
tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h | 13 ++
tools/kvm/arm/aarch64/kvm-cpu.c | 160 +++++++++++++++++++++
tools/kvm/arm/fdt.c | 2 +-
tools/kvm/arm/include/arm-common/kvm-arch.h | 32 ++++-
.../include/{kvm => arm-common}/kvm-config-arch.h | 8 +-
tools/kvm/arm/kvm.c | 26 +++-
13 files changed, 381 insertions(+), 32 deletions(-)
create mode 100644 tools/kvm/arm/aarch32/include/kvm/kvm-config-arch.h
create mode 100644 tools/kvm/arm/aarch64/cortex-a57.c
create mode 100644 tools/kvm/arm/aarch64/include/kvm/barrier.h
create mode 100644 tools/kvm/arm/aarch64/include/kvm/kvm-arch.h
create mode 100644 tools/kvm/arm/aarch64/include/kvm/kvm-config-arch.h
create mode 100644 tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
create mode 100644 tools/kvm/arm/aarch64/kvm-cpu.c
rename tools/kvm/arm/include/{kvm => arm-common}/kvm-config-arch.h (61%)
--
1.8.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] kvm tools: add support for ARMv8 processors
2013-01-07 18:43 [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Will Deacon
@ 2013-01-07 18:43 ` Will Deacon
2013-01-07 18:43 ` [PATCH 2/2] kvm tools: arm: align guest memory buffer to maximum page size Will Deacon
2013-01-09 11:16 ` [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Pekka Enberg
2 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2013-01-07 18:43 UTC (permalink / raw)
To: kvm; +Cc: penberg, marc.zyngier, c.dall, kvmarm, Will Deacon
This patch adds support for ARMv8 processors (more specifically,
Cortex-A57) to kvmtool. Both AArch64 and AArch32 guests are supported,
so the existing AArch32 code is slightly restructured to allow for
re-use of much of the current code.
The implementation closely follows the ARMv7 code and reuses much of the
work written there.
Tested-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
tools/kvm/Makefile | 14 +-
tools/kvm/arm/aarch32/include/kvm/kvm-arch.h | 20 +--
.../kvm/arm/aarch32/include/kvm/kvm-config-arch.h | 8 ++
tools/kvm/arm/aarch64/cortex-a57.c | 95 ++++++++++++
tools/kvm/arm/aarch64/include/kvm/barrier.h | 8 ++
tools/kvm/arm/aarch64/include/kvm/kvm-arch.h | 17 +++
.../kvm/arm/aarch64/include/kvm/kvm-config-arch.h | 10 ++
tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h | 13 ++
tools/kvm/arm/aarch64/kvm-cpu.c | 160 +++++++++++++++++++++
tools/kvm/arm/fdt.c | 2 +-
tools/kvm/arm/include/arm-common/kvm-arch.h | 22 ++-
.../include/{kvm => arm-common}/kvm-config-arch.h | 8 +-
tools/kvm/arm/kvm.c | 2 +-
13 files changed, 353 insertions(+), 26 deletions(-)
create mode 100644 tools/kvm/arm/aarch32/include/kvm/kvm-config-arch.h
create mode 100644 tools/kvm/arm/aarch64/cortex-a57.c
create mode 100644 tools/kvm/arm/aarch64/include/kvm/barrier.h
create mode 100644 tools/kvm/arm/aarch64/include/kvm/kvm-arch.h
create mode 100644 tools/kvm/arm/aarch64/include/kvm/kvm-config-arch.h
create mode 100644 tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
create mode 100644 tools/kvm/arm/aarch64/kvm-cpu.c
rename tools/kvm/arm/include/{kvm => arm-common}/kvm-config-arch.h (61%)
diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 33aa4d8..0c59faa 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -103,7 +103,7 @@ OBJS += virtio/mmio.o
# Translate uname -m into ARCH string
ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \
- -e s/armv7.*/arm/)
+ -e s/armv7.*/arm/ -e s/aarch64.*/arm64/)
ifeq ($(ARCH),i386)
ARCH := x86
@@ -174,6 +174,18 @@ ifeq ($(ARCH), arm)
OTHEROBJS += $(LIBFDT_OBJS)
endif
+# ARM64
+ifeq ($(ARCH), arm64)
+ DEFINES += -DCONFIG_ARM64
+ OBJS += $(OBJS_ARM_COMMON)
+ OBJS += arm/aarch64/cortex-a57.o
+ OBJS += arm/aarch64/kvm-cpu.o
+ ARCH_INCLUDE := $(HDRS_ARM_COMMON)
+ ARCH_INCLUDE += -Iarm/aarch64/include
+ CFLAGS += -I../../scripts/dtc/libfdt
+ OTHEROBJS += $(LIBFDT_OBJS)
+endif
+
###
ifeq (,$(ARCH_INCLUDE))
diff --git a/tools/kvm/arm/aarch32/include/kvm/kvm-arch.h b/tools/kvm/arm/aarch32/include/kvm/kvm-arch.h
index ca79b24..1632e3c 100644
--- a/tools/kvm/arm/aarch32/include/kvm/kvm-arch.h
+++ b/tools/kvm/arm/aarch32/include/kvm/kvm-arch.h
@@ -1,28 +1,12 @@
#ifndef KVM__KVM_ARCH_H
#define KVM__KVM_ARCH_H
-#include <linux/const.h>
-
-#define ARM_LOMAP_MMIO_AREA _AC(0x00000000, UL)
-#define ARM_LOMAP_AXI_AREA _AC(0x40000000, UL)
-#define ARM_LOMAP_MEMORY_AREA _AC(0x80000000, UL)
-#define ARM_LOMAP_MAX_MEMORY _AC(0x7fffffff, UL)
-
#define ARM_GIC_DIST_SIZE 0x1000
-#define ARM_GIC_DIST_BASE (ARM_LOMAP_AXI_AREA - ARM_GIC_DIST_SIZE)
#define ARM_GIC_CPUI_SIZE 0x2000
-#define ARM_GIC_CPUI_BASE (ARM_GIC_DIST_BASE - ARM_GIC_CPUI_SIZE)
-
-#define ARM_KERN_OFFSET 0x8000
-
-#define ARM_VIRTIO_MMIO_SIZE (ARM_GIC_DIST_BASE - ARM_LOMAP_MMIO_AREA)
-#define ARM_PCI_MMIO_SIZE (ARM_LOMAP_MEMORY_AREA - ARM_LOMAP_AXI_AREA)
-#define ARM_MEMORY_AREA ARM_LOMAP_MEMORY_AREA
-#define ARM_MAX_MEMORY ARM_LOMAP_MAX_MEMORY
+#define ARM_KERN_OFFSET(...) 0x8000
-#define KVM_PCI_MMIO_AREA ARM_LOMAP_AXI_AREA
-#define KVM_VIRTIO_MMIO_AREA ARM_LOMAP_MMIO_AREA
+#define ARM_MAX_MEMORY(...) ARM_LOMAP_MAX_MEMORY
#include "arm-common/kvm-arch.h"
diff --git a/tools/kvm/arm/aarch32/include/kvm/kvm-config-arch.h b/tools/kvm/arm/aarch32/include/kvm/kvm-config-arch.h
new file mode 100644
index 0000000..acf0d23
--- /dev/null
+++ b/tools/kvm/arm/aarch32/include/kvm/kvm-config-arch.h
@@ -0,0 +1,8 @@
+#ifndef KVM__KVM_CONFIG_ARCH_H
+#define KVM__KVM_CONFIG_ARCH_H
+
+#define ARM_OPT_ARCH_RUN(...)
+
+#include "arm-common/kvm-config-arch.h"
+
+#endif /* KVM__KVM_CONFIG_ARCH_H */
diff --git a/tools/kvm/arm/aarch64/cortex-a57.c b/tools/kvm/arm/aarch64/cortex-a57.c
new file mode 100644
index 0000000..4fd11ba
--- /dev/null
+++ b/tools/kvm/arm/aarch64/cortex-a57.c
@@ -0,0 +1,95 @@
+#include "kvm/fdt.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+
+#include "arm-common/gic.h"
+
+#include <linux/byteorder.h>
+#include <linux/types.h>
+
+#define CPU_NAME_MAX_LEN 8
+static void generate_cpu_nodes(void *fdt, struct kvm *kvm)
+{
+ int cpu;
+
+ _FDT(fdt_begin_node(fdt, "cpus"));
+ _FDT(fdt_property_cell(fdt, "#address-cells", 0x1));
+ _FDT(fdt_property_cell(fdt, "#size-cells", 0x0));
+
+ for (cpu = 0; cpu < kvm->nrcpus; ++cpu) {
+ char cpu_name[CPU_NAME_MAX_LEN];
+
+ if (kvm->cpus[cpu]->cpu_type != KVM_ARM_TARGET_CORTEX_A57) {
+ pr_warning("Ignoring unknown type for CPU %d\n", cpu);
+ continue;
+ }
+
+ snprintf(cpu_name, CPU_NAME_MAX_LEN, "cpu@%d", cpu);
+
+ _FDT(fdt_begin_node(fdt, cpu_name));
+ _FDT(fdt_property_string(fdt, "device_type", "cpu"));
+ _FDT(fdt_property_string(fdt, "compatible", "arm,cortex-a57"));
+
+ if (kvm->nrcpus > 1)
+ _FDT(fdt_property_string(fdt, "enable-method", "psci"));
+
+ _FDT(fdt_property_cell(fdt, "reg", cpu));
+ _FDT(fdt_end_node(fdt));
+ }
+
+ _FDT(fdt_end_node(fdt));
+}
+
+static void generate_timer_nodes(void *fdt, struct kvm *kvm)
+{
+ u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \
+ & GIC_FDT_IRQ_PPI_CPU_MASK;
+ u32 irq_prop[] = {
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(13),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(14),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(11),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+
+ cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI),
+ cpu_to_fdt32(10),
+ cpu_to_fdt32(cpu_mask | GIC_FDT_IRQ_FLAGS_EDGE_LO_HI),
+ };
+
+ _FDT(fdt_begin_node(fdt, "timer"));
+ _FDT(fdt_property_string(fdt, "compatible", "arm,armv8-timer"));
+ _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
+ _FDT(fdt_end_node(fdt));
+}
+
+static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle)
+{
+ generate_cpu_nodes(fdt, kvm);
+ gic__generate_fdt_nodes(fdt, gic_phandle);
+ generate_timer_nodes(fdt, kvm);
+}
+
+
+static int cortex_a57__vcpu_init(struct kvm_cpu *vcpu)
+{
+ vcpu->generate_fdt_nodes = generate_fdt_nodes;
+ return 0;
+}
+
+static struct kvm_arm_target target_cortex_a57 = {
+ .id = KVM_ARM_TARGET_CORTEX_A57,
+ .init = cortex_a57__vcpu_init,
+};
+
+static int cortex_a57__core_init(struct kvm *kvm)
+{
+ return kvm_cpu__register_kvm_arm_target(&target_cortex_a57);
+}
+core_init(cortex_a57__core_init);
diff --git a/tools/kvm/arm/aarch64/include/kvm/barrier.h b/tools/kvm/arm/aarch64/include/kvm/barrier.h
new file mode 100644
index 0000000..97ab252
--- /dev/null
+++ b/tools/kvm/arm/aarch64/include/kvm/barrier.h
@@ -0,0 +1,8 @@
+#ifndef KVM__KVM_BARRIER_H
+#define KVM__KVM_BARRIER_H
+
+#define mb() asm volatile ("dmb ish" : : : "memory")
+#define rmb() asm volatile ("dmb ishld" : : : "memory")
+#define wmb() asm volatile ("dmb ishst" : : : "memory")
+
+#endif /* KVM__KVM_BARRIER_H */
diff --git a/tools/kvm/arm/aarch64/include/kvm/kvm-arch.h b/tools/kvm/arm/aarch64/include/kvm/kvm-arch.h
new file mode 100644
index 0000000..2f08a26
--- /dev/null
+++ b/tools/kvm/arm/aarch64/include/kvm/kvm-arch.h
@@ -0,0 +1,17 @@
+#ifndef KVM__KVM_ARCH_H
+#define KVM__KVM_ARCH_H
+
+#define ARM_GIC_DIST_SIZE 0x10000
+#define ARM_GIC_CPUI_SIZE 0x10000
+
+#define ARM_KERN_OFFSET(kvm) ((kvm)->cfg.arch.aarch32_guest ? \
+ 0x8000 : \
+ 0x80000)
+
+#define ARM_MAX_MEMORY(kvm) ((kvm)->cfg.arch.aarch32_guest ? \
+ ARM_LOMAP_MAX_MEMORY : \
+ ARM_HIMAP_MAX_MEMORY)
+
+#include "arm-common/kvm-arch.h"
+
+#endif /* KVM__KVM_ARCH_H */
diff --git a/tools/kvm/arm/aarch64/include/kvm/kvm-config-arch.h b/tools/kvm/arm/aarch64/include/kvm/kvm-config-arch.h
new file mode 100644
index 0000000..89860ae
--- /dev/null
+++ b/tools/kvm/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -0,0 +1,10 @@
+#ifndef KVM__KVM_CONFIG_ARCH_H
+#define KVM__KVM_CONFIG_ARCH_H
+
+#define ARM_OPT_ARCH_RUN(cfg) \
+ OPT_BOOLEAN('\0', "aarch32", &(cfg)->aarch32_guest, \
+ "Run AArch32 guest"),
+
+#include "arm-common/kvm-config-arch.h"
+
+#endif /* KVM__KVM_CONFIG_ARCH_H */
diff --git a/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h b/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
new file mode 100644
index 0000000..d85c583
--- /dev/null
+++ b/tools/kvm/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -0,0 +1,13 @@
+#ifndef KVM__KVM_CPU_ARCH_H
+#define KVM__KVM_CPU_ARCH_H
+
+#include "kvm/kvm.h"
+
+#include "arm-common/kvm-cpu-arch.h"
+
+#define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid) { \
+ [0] = ((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) | \
+ (!!(kvm)->cfg.arch.aarch32_guest << KVM_ARM_VCPU_EL1_32BIT)) \
+}
+
+#endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/tools/kvm/arm/aarch64/kvm-cpu.c b/tools/kvm/arm/aarch64/kvm-cpu.c
new file mode 100644
index 0000000..2eb06ea
--- /dev/null
+++ b/tools/kvm/arm/aarch64/kvm-cpu.c
@@ -0,0 +1,160 @@
+#include "kvm/kvm-cpu.h"
+#include "kvm/kvm.h"
+
+#include <asm/ptrace.h>
+
+#define COMPAT_PSR_F_BIT 0x00000040
+#define COMPAT_PSR_I_BIT 0x00000080
+#define COMPAT_PSR_MODE_SVC 0x00000013
+
+#define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
+
+static void reset_vcpu_aarch32(struct kvm_cpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_one_reg reg;
+ u64 data;
+
+ reg.addr = (u64)&data;
+
+ /* pstate = all interrupts masked */
+ data = COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT | COMPAT_PSR_MODE_SVC;
+ reg.id = ARM64_CORE_REG(regs.pstate);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
+
+ /* Secondary cores are stopped awaiting PSCI wakeup */
+ if (vcpu->cpu_id != 0)
+ return;
+
+ /* r0 = 0 */
+ data = 0;
+ reg.id = ARM64_CORE_REG(regs.regs[0]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (r0)");
+
+ /* r1 = machine type (-1) */
+ data = -1;
+ reg.id = ARM64_CORE_REG(regs.regs[1]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (r1)");
+
+ /* r2 = physical address of the device tree blob */
+ data = kvm->arch.dtb_guest_start;
+ reg.id = ARM64_CORE_REG(regs.regs[2]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (r2)");
+
+ /* pc = start of kernel image */
+ data = kvm->arch.kern_guest_start;
+ reg.id = ARM64_CORE_REG(regs.pc);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (pc)");
+}
+
+static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_one_reg reg;
+ u64 data;
+
+ reg.addr = (u64)&data;
+
+ /* pstate = all interrupts masked */
+ data = PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | PSR_MODE_EL1h;
+ reg.id = ARM64_CORE_REG(regs.pstate);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (spsr[EL1])");
+
+ /* x1...x3 = 0 */
+ data = 0;
+ reg.id = ARM64_CORE_REG(regs.regs[1]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (x1)");
+
+ reg.id = ARM64_CORE_REG(regs.regs[2]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (x2)");
+
+ reg.id = ARM64_CORE_REG(regs.regs[3]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (x3)");
+
+ /* Secondary cores are stopped awaiting PSCI wakeup */
+ if (vcpu->cpu_id == 0) {
+ /* x0 = physical address of the device tree blob */
+ data = kvm->arch.dtb_guest_start;
+ reg.id = ARM64_CORE_REG(regs.regs[0]);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (x0)");
+
+ /* pc = start of kernel image */
+ data = kvm->arch.kern_guest_start;
+ reg.id = ARM64_CORE_REG(regs.pc);
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ die_perror("KVM_SET_ONE_REG failed (pc)");
+ }
+}
+
+void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
+{
+ if (vcpu->kvm->cfg.arch.aarch32_guest)
+ return reset_vcpu_aarch32(vcpu);
+ else
+ return reset_vcpu_aarch64(vcpu);
+}
+
+void kvm_cpu__show_code(struct kvm_cpu *vcpu)
+{
+ struct kvm_one_reg reg;
+ unsigned long data;
+
+ reg.addr = (u64)&data;
+
+ printf("*pc:\n");
+ reg.id = ARM64_CORE_REG(regs.pc);
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
+ die("KVM_GET_ONE_REG failed (show_code @ PC)");
+
+ kvm__dump_mem(vcpu->kvm, data, 32);
+ printf("\n");
+
+ printf("*lr:\n");
+ reg.id = ARM64_CORE_REG(regs.regs[30]);
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
+ die("KVM_GET_ONE_REG failed (show_code @ LR)");
+
+ kvm__dump_mem(vcpu->kvm, data, 32);
+ printf("\n");
+}
+
+void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
+{
+ struct kvm_one_reg reg;
+ unsigned long data;
+ int debug_fd = kvm_cpu__get_debug_fd();
+
+ reg.addr = (u64)&data;
+ dprintf(debug_fd, "\n Registers:\n");
+
+ reg.id = ARM64_CORE_REG(regs.pc);
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
+ die("KVM_GET_ONE_REG failed (pc)");
+ dprintf(debug_fd, " PC: 0x%lx\n", data);
+
+ reg.id = ARM64_CORE_REG(regs.pstate);
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
+ die("KVM_GET_ONE_REG failed (pstate)");
+ dprintf(debug_fd, " PSTATE: 0x%lx\n", data);
+
+ reg.id = ARM64_CORE_REG(sp_el1);
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
+ die("KVM_GET_ONE_REG failed (sp_el1)");
+ dprintf(debug_fd, " SP_EL1: 0x%lx\n", data);
+
+ reg.id = ARM64_CORE_REG(regs.regs[30]);
+ if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
+ die("KVM_GET_ONE_REG failed (lr)");
+ dprintf(debug_fd, " LR: 0x%lx\n", data);
+}
diff --git a/tools/kvm/arm/fdt.c b/tools/kvm/arm/fdt.c
index 6c12e79..20e0308 100644
--- a/tools/kvm/arm/fdt.c
+++ b/tools/kvm/arm/fdt.c
@@ -178,7 +178,7 @@ int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd,
*/
limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1;
- pos = kvm->ram_start + ARM_KERN_OFFSET;
+ pos = kvm->ram_start + ARM_KERN_OFFSET(kvm);
kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos);
if (read_image(fd_kernel, &pos, limit) == -ENOMEM)
die("kernel image too big to contain in guest memory.");
diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h
index 798af59..46ee7e2 100644
--- a/tools/kvm/arm/include/arm-common/kvm-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-arch.h
@@ -1,11 +1,29 @@
#ifndef ARM_COMMON__KVM_ARCH_H
#define ARM_COMMON__KVM_ARCH_H
-#define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO
-
#include <stdbool.h>
+#include <linux/const.h>
#include <linux/types.h>
+#define ARM_MMIO_AREA _AC(0x0000000000000000, UL)
+#define ARM_AXI_AREA _AC(0x0000000040000000, UL)
+#define ARM_MEMORY_AREA _AC(0x0000000080000000, UL)
+
+#define ARM_LOMAP_MAX_MEMORY ((1ULL << 32) - ARM_MEMORY_AREA)
+#define ARM_HIMAP_MAX_MEMORY ((1ULL << 40) - ARM_MEMORY_AREA)
+
+#define ARM_GIC_DIST_BASE (ARM_AXI_AREA - ARM_GIC_DIST_SIZE)
+#define ARM_GIC_CPUI_BASE (ARM_GIC_DIST_BASE - ARM_GIC_CPUI_SIZE)
+#define ARM_GIC_SIZE (ARM_GIC_DIST_SIZE + ARM_GIC_CPUI_SIZE)
+
+#define ARM_VIRTIO_MMIO_SIZE (ARM_AXI_AREA - ARM_GIC_SIZE)
+#define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - ARM_AXI_AREA)
+
+#define KVM_PCI_MMIO_AREA ARM_AXI_AREA
+#define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA
+
+#define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO
+
static inline bool arm_addr_in_virtio_mmio_region(u64 phys_addr)
{
u64 limit = KVM_VIRTIO_MMIO_AREA + ARM_VIRTIO_MMIO_SIZE;
diff --git a/tools/kvm/arm/include/kvm/kvm-config-arch.h b/tools/kvm/arm/include/arm-common/kvm-config-arch.h
similarity index 61%
rename from tools/kvm/arm/include/kvm/kvm-config-arch.h
rename to tools/kvm/arm/include/arm-common/kvm-config-arch.h
index f63f302..7ac6f6e 100644
--- a/tools/kvm/arm/include/kvm/kvm-config-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-config-arch.h
@@ -1,15 +1,17 @@
-#ifndef KVM__KVM_CONFIG_ARCH_H
-#define KVM__KVM_CONFIG_ARCH_H
+#ifndef ARM_COMMON__KVM_CONFIG_ARCH_H
+#define ARM_COMMON__KVM_CONFIG_ARCH_H
#include "kvm/parse-options.h"
struct kvm_config_arch {
const char *dump_dtb_filename;
+ bool aarch32_guest;
};
#define OPT_ARCH_RUN(pfx, cfg) \
pfx, \
+ ARM_OPT_ARCH_RUN(cfg) \
OPT_STRING('\0', "dump-dtb", &(cfg)->dump_dtb_filename, \
".dtb file", "Dump generated .dtb to specified file"),
-#endif /* KVM__KVM_CONFIG_ARCH_H */
+#endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
diff --git a/tools/kvm/arm/kvm.c b/tools/kvm/arm/kvm.c
index b10c857..9eff927 100644
--- a/tools/kvm/arm/kvm.c
+++ b/tools/kvm/arm/kvm.c
@@ -57,7 +57,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
{
/* Allocate guest memory. */
- kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY);
+ kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, kvm->ram_size);
if (kvm->ram_start == MAP_FAILED)
die("Failed to map %lld bytes for guest memory (%d)",
--
1.8.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] kvm tools: arm: align guest memory buffer to maximum page size
2013-01-07 18:43 [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Will Deacon
2013-01-07 18:43 ` [PATCH 1/2] kvm tools: add support for ARMv8 processors Will Deacon
@ 2013-01-07 18:43 ` Will Deacon
2013-01-09 11:16 ` [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Pekka Enberg
2 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2013-01-07 18:43 UTC (permalink / raw)
To: kvm; +Cc: penberg, marc.zyngier, c.dall, kvmarm, Will Deacon
If we're running a guest with a larger page size than the host,
interesting things start to happen when communicating via a virtio-mmio
device because the idea of buffer alignment between the guest and the
host will be off by the misalignment of the guest memory buffer allocated
by the host. This causes things like the index field of vring.used to
be accessed at different addresses on the guest and the host, leading
to deadlock.
Fix this problem by allocating guest memory aligned to the maximum
possible page size for the architecture (64K).
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
tools/kvm/arm/include/arm-common/kvm-arch.h | 10 ++++++++++
tools/kvm/arm/kvm.c | 24 ++++++++++++++++++------
2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/tools/kvm/arm/include/arm-common/kvm-arch.h b/tools/kvm/arm/include/arm-common/kvm-arch.h
index 46ee7e2..7860e17 100644
--- a/tools/kvm/arm/include/arm-common/kvm-arch.h
+++ b/tools/kvm/arm/include/arm-common/kvm-arch.h
@@ -37,6 +37,16 @@ static inline bool arm_addr_in_pci_mmio_region(u64 phys_addr)
}
struct kvm_arch {
+ /*
+ * We may have to align the guest memory for virtio, so keep the
+ * original pointers here for munmap.
+ */
+ void *ram_alloc_start;
+ u64 ram_alloc_size;
+
+ /*
+ * Guest addresses for memory layout.
+ */
u64 memory_guest_start;
u64 kern_guest_start;
u64 initrd_guest_start;
diff --git a/tools/kvm/arm/kvm.c b/tools/kvm/arm/kvm.c
index 9eff927..1bcfce3 100644
--- a/tools/kvm/arm/kvm.c
+++ b/tools/kvm/arm/kvm.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/kvm.h>
+#include <linux/sizes.h>
struct kvm_ext kvm_req_ext[] = {
{ DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) },
@@ -41,7 +42,7 @@ void kvm__init_ram(struct kvm *kvm)
void kvm__arch_delete_ram(struct kvm *kvm)
{
- munmap(kvm->ram_start, kvm->ram_size);
+ munmap(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size);
}
void kvm__arch_periodic_poll(struct kvm *kvm)
@@ -56,13 +57,24 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
{
- /* Allocate guest memory. */
+ /*
+ * Allocate guest memory. We must align out buffer to 64K to
+ * correlate with the maximum guest page size for virtio-mmio.
+ */
kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
- kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, kvm->ram_size);
- if (kvm->ram_start == MAP_FAILED)
+ kvm->arch.ram_alloc_size = kvm->ram_size + SZ_64K;
+ kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+ kvm->arch.ram_alloc_size);
+
+ if (kvm->arch.ram_alloc_start == MAP_FAILED)
die("Failed to map %lld bytes for guest memory (%d)",
- kvm->ram_size, errno);
- madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+ kvm->arch.ram_alloc_size, errno);
+
+ kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
+ SZ_64K);
+
+ madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+ MADV_MERGEABLE);
/* Initialise the virtual GIC. */
if (gic__init_irqchip(kvm))
--
1.8.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool
2013-01-07 18:43 [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Will Deacon
2013-01-07 18:43 ` [PATCH 1/2] kvm tools: add support for ARMv8 processors Will Deacon
2013-01-07 18:43 ` [PATCH 2/2] kvm tools: arm: align guest memory buffer to maximum page size Will Deacon
@ 2013-01-09 11:16 ` Pekka Enberg
2013-01-09 11:33 ` Will Deacon
2 siblings, 1 reply; 6+ messages in thread
From: Pekka Enberg @ 2013-01-09 11:16 UTC (permalink / raw)
To: Will Deacon
Cc: kvm, marc.zyngier, c.dall, kvmarm, Sasha Levin, Cyrill Gorcunov,
Asias He, Ingo Molnar
Hi Will,
On Mon, Jan 7, 2013 at 8:43 PM, Will Deacon <will.deacon@arm.com> wrote:
> Hello again,
>
> These two patches add support for ARMv8 processors running an AArch64 instance
> of kvm to kvmtool. Both AArch32 and AArch64 guests are supported and, in the
> case of the latter, the guest page size may be either 64k or 4k.
>
> This depends on the ARM updates series I just posted:
>
> https://lists.cs.columbia.edu/pipermail/kvmarm/2013-January/004505.html
>
> Feedback welcome,
So will ARMv7 continue to work after this patch even without the ARM
updates? If so, I'm happy to merge the patch before the updates hit
v3.9.
Pekka
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool
2013-01-09 11:16 ` [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Pekka Enberg
@ 2013-01-09 11:33 ` Will Deacon
2013-01-09 12:00 ` Pekka Enberg
0 siblings, 1 reply; 6+ messages in thread
From: Will Deacon @ 2013-01-09 11:33 UTC (permalink / raw)
To: Pekka Enberg
Cc: kvm@vger.kernel.org, Marc Zyngier, c.dall@virtualopensystems.com,
kvmarm@lists.cs.columbia.edu, Sasha Levin, Cyrill Gorcunov,
Asias He, Ingo Molnar
On Wed, Jan 09, 2013 at 11:16:42AM +0000, Pekka Enberg wrote:
> Hi Will,
Hello,
> On Mon, Jan 7, 2013 at 8:43 PM, Will Deacon <will.deacon@arm.com> wrote:
> > These two patches add support for ARMv8 processors running an AArch64 instance
> > of kvm to kvmtool. Both AArch32 and AArch64 guests are supported and, in the
> > case of the latter, the guest page size may be either 64k or 4k.
> >
> > This depends on the ARM updates series I just posted:
> >
> > https://lists.cs.columbia.edu/pipermail/kvmarm/2013-January/004505.html
> >
> > Feedback welcome,
>
> So will ARMv7 continue to work after this patch even without the ARM
> updates? If so, I'm happy to merge the patch before the updates hit
> v3.9.
I think we're getting our wires crossed a bit here, so I'll try to explain
my madness:
- Mainline ARM kernels cannot be booted by kvmtool yet, you
currently have to use my virt/mach branch from
git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git
I hope to upstream this for 3.9 (it has gone through the necessary
review on the ARM kernel list).
- As part of the review mentioned above, some kvmtool changes were
required to support SMP with the latest virt/mach. You just merged
these in my ARM updates series.
- The ARMv8 kvmtool code builds on top of the series you just merged
and won't apply without it. Applying it won't have any adverse
effects on ARMv7 (AArch32). In fact, the two series sit together
on my kvmtool/arm branch from
git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
but I posted them separately to avoid holding up the ARM updates.
Does that answer you question or have I made things worse?!
Cheers,
Will
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool
2013-01-09 11:33 ` Will Deacon
@ 2013-01-09 12:00 ` Pekka Enberg
0 siblings, 0 replies; 6+ messages in thread
From: Pekka Enberg @ 2013-01-09 12:00 UTC (permalink / raw)
To: Will Deacon
Cc: kvm@vger.kernel.org, Marc Zyngier, c.dall@virtualopensystems.com,
kvmarm@lists.cs.columbia.edu, Sasha Levin, Cyrill Gorcunov,
Asias He, Ingo Molnar
On Wed, Jan 9, 2013 at 1:33 PM, Will Deacon <will.deacon@arm.com> wrote:
> I think we're getting our wires crossed a bit here, so I'll try to explain
> my madness:
>
> - Mainline ARM kernels cannot be booted by kvmtool yet, you
> currently have to use my virt/mach branch from
>
> git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git
>
> I hope to upstream this for 3.9 (it has gone through the necessary
> review on the ARM kernel list).
>
> - As part of the review mentioned above, some kvmtool changes were
> required to support SMP with the latest virt/mach. You just merged
> these in my ARM updates series.
>
> - The ARMv8 kvmtool code builds on top of the series you just merged
> and won't apply without it. Applying it won't have any adverse
> effects on ARMv7 (AArch32). In fact, the two series sit together
> on my kvmtool/arm branch from
>
> git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
>
> but I posted them separately to avoid holding up the ARM updates.
>
> Does that answer you question or have I made things worse?!
Yes, it answers my question. I'll go ahead and apply the ARMv8 patches.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-01-09 12:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-07 18:43 [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Will Deacon
2013-01-07 18:43 ` [PATCH 1/2] kvm tools: add support for ARMv8 processors Will Deacon
2013-01-07 18:43 ` [PATCH 2/2] kvm tools: arm: align guest memory buffer to maximum page size Will Deacon
2013-01-09 11:16 ` [PATCH 0/2] Add support for ARMv8 CPUs to kvmtool Pekka Enberg
2013-01-09 11:33 ` Will Deacon
2013-01-09 12:00 ` Pekka Enberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox