* [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support
@ 2013-11-22 17:17 Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 01/11] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
` (12 more replies)
0 siblings, 13 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
This patchset combines the 'virt' machine definition and
-cpu host support patchsets I've posted previous versions
of. I think these are now ready to go in once 1.8 opens
up; review appreciated.
Changes since previous versions:
* added in -cpu host patchset, since it really only makes
sense with mach-virt
* rearranged virt address space a bit to allow space
for a reasonable sized boot flash device and possible
PCI window if a PCI controller model ever becomes possible
* fixed bug where we weren't starting secondary CPUs in
"PSCI power-down" state (by adding a CPU property which
lets the board specify that the CPU starts powered down)
[thanks to Giridhar Maruthy for tracking this down]
* includes a KVM header update against current mainline
* includes (previously RFC'd) patch which provides defines
of some kernel KVM constants we can use even if not CONFIG_KVM
* put the KVM CPU type into the CPU object rather than having
a silly 'QOM object type => constant' lookup table
* put dtb 'compatible' string into CPU object rather than
having the board model need to know about it
* abstracted out the "create a scratch vcpu for querying
for capabilities" code; this is currently only called in
one place, but the abstraction will be needed for 64 bit
KVM ARM support
Mostly this is cleanup and streamlining which I noticed
was either possible or necessary in the course of putting
64 bit KVM ARM control on top of this patchset.
The kernel patch to get the PL011 to work is still needed
(Christoffer tells me he's working on getting a proper fix
done for this):
diff --git a/arch/arm/mach-virt/virt.c b/arch/arm/mach-virt/virt.c
index b184e57..2b6aceb 100644
--- a/arch/arm/mach-virt/virt.c
+++ b/arch/arm/mach-virt/virt.c
@@ -21,11 +21,13 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/smp.h>
+#include <linux/clk-provider.h>
#include <asm/mach/arch.h>
static void __init virt_init(void)
{
+ of_clk_init(NULL);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
John Rigby (1):
hw/arm/boot: Allow boards to provide an fdt blob
Peter Maydell (10):
target-arm: Provide mechanism for getting KVM constants even if not
CONFIG_KVM
device_tree.c: Terminate the empty reservemap in create_device_tree()
target-arm: Provide PSCI constants to generic QEMU code
target-arm: Add ARMCPU field for Linux device-tree 'compatible'
string
target-arm: Allow secondary KVM CPUs to be booted via PSCI
hw/arm: Add 'virt' platform
linux-headers: Update from mainline
target-arm: Don't hardcode KVM target CPU to be A15
target-arm: Provide '-cpu host' when running KVM
hw/arm/virt: Support -cpu host
device_tree.c | 4 +
hw/arm/Makefile.objs | 2 +-
hw/arm/boot.c | 32 ++-
hw/arm/virt.c | 452 ++++++++++++++++++++++++++++++
include/hw/arm/arm.h | 7 +
linux-headers/asm-arm/kvm.h | 3 +-
linux-headers/asm-powerpc/epapr_hcalls.h | 4 +-
linux-headers/asm-powerpc/kvm.h | 86 +++++-
linux-headers/asm-x86/hyperv.h | 19 ++
linux-headers/asm-x86/kvm.h | 6 +-
linux-headers/linux/kvm.h | 11 +
target-arm/cpu-qom.h | 11 +
target-arm/cpu.c | 59 ++++
target-arm/cpu.h | 13 +-
target-arm/helper.c | 6 +
target-arm/kvm-consts.h | 64 +++++
target-arm/kvm.c | 243 +++++++++++++++-
target-arm/kvm_arm.h | 55 ++++
18 files changed, 1033 insertions(+), 44 deletions(-)
create mode 100644 hw/arm/virt.c
create mode 100644 target-arm/kvm-consts.h
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 01/11] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 02/11] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
` (11 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
There are a number of places where it would be convenient for ARM
code to have working definitions of KVM constants even in code
which is compiled with CONFIG_KVM not set. In this situation we
can't simply include the kernel KVM headers (which might conflict
with host header definitions or not even compile on the compiler
we're using) so we have to redefine equivalent constants.
Provide a mechanism for doing this and checking that the values
match, and use it for the constants we're currently exposing
via an ad-hoc mechanism.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu.h | 13 ++-----------
target-arm/kvm-consts.h | 41 +++++++++++++++++++++++++++++++++++++++++
target-arm/kvm.c | 9 ---------
3 files changed, 43 insertions(+), 20 deletions(-)
create mode 100644 target-arm/kvm-consts.h
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 9f110f1..c3f007f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -21,6 +21,8 @@
#include "config.h"
+#include "kvm-consts.h"
+
#if defined(TARGET_AARCH64)
/* AArch64 definitions */
# define TARGET_LONG_BITS 64
@@ -497,17 +499,6 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
(((cp) << 16) | ((is64) << 15) | ((crn) << 11) | \
((crm) << 7) | ((opc1) << 3) | (opc2))
-/* Note that these must line up with the KVM/ARM register
- * ID field definitions (kvm.c will check this, but we
- * can't just use the KVM defines here as the kvm headers
- * are unavailable to non-KVM-specific files)
- */
-#define CP_REG_SIZE_SHIFT 52
-#define CP_REG_SIZE_MASK 0x00f0000000000000ULL
-#define CP_REG_SIZE_U32 0x0020000000000000ULL
-#define CP_REG_SIZE_U64 0x0030000000000000ULL
-#define CP_REG_ARM 0x4000000000000000ULL
-
/* Convert a full 64 bit KVM register ID to the truncated 32 bit
* version used as a key for the coprocessor register hashtable
*/
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
new file mode 100644
index 0000000..6f56f72
--- /dev/null
+++ b/target-arm/kvm-consts.h
@@ -0,0 +1,41 @@
+/*
+ * KVM ARM ABI constant definitions
+ *
+ * Copyright (c) 2013 Linaro Limited
+ *
+ * Provide versions of KVM constant defines that can be used even
+ * when CONFIG_KVM is not set and we don't have access to the
+ * KVM headers. If CONFIG_KVM is set, we do a compile-time check
+ * that we haven't got out of sync somehow.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef ARM_KVM_CONSTS_H
+#define ARM_KVM_CONSTS_H
+
+#ifdef CONFIG_KVM
+#include "qemu/compiler.h"
+#include <linux/kvm.h>
+
+#define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(X != Y)
+
+#else
+#define MISMATCH_CHECK(X, Y)
+#endif
+
+#define CP_REG_SIZE_SHIFT 52
+#define CP_REG_SIZE_MASK 0x00f0000000000000ULL
+#define CP_REG_SIZE_U32 0x0020000000000000ULL
+#define CP_REG_SIZE_U64 0x0030000000000000ULL
+#define CP_REG_ARM 0x4000000000000000ULL
+
+MISMATCH_CHECK(CP_REG_SIZE_SHIFT, KVM_REG_SIZE_SHIFT)
+MISMATCH_CHECK(CP_REG_SIZE_MASK, KVM_REG_SIZE_MASK)
+MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32)
+MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
+MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
+
+#undef MISMATCH_CHECK
+
+#endif
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 6e5cd36..3098456 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -23,15 +23,6 @@
#include "cpu.h"
#include "hw/arm/arm.h"
-/* Check that cpu.h's idea of coprocessor fields matches KVM's */
-#if (CP_REG_SIZE_SHIFT != KVM_REG_SIZE_SHIFT) || \
- (CP_REG_SIZE_MASK != KVM_REG_SIZE_MASK) || \
- (CP_REG_SIZE_U32 != KVM_REG_SIZE_U32) || \
- (CP_REG_SIZE_U64 != KVM_REG_SIZE_U64) || \
- (CP_REG_ARM != KVM_REG_ARM)
-#error mismatch between cpu.h and KVM header definitions
-#endif
-
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 02/11] device_tree.c: Terminate the empty reservemap in create_device_tree()
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 01/11] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-24 8:04 ` Peter Crosthwaite
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 03/11] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
` (10 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Device trees created with create_device_tree() may not have any
entries in their reservemap, because the FDT API requires that the
reservemap is completed before any FDT nodes are added, and
create_device_tree() itself creates a node. However we were not
calling fdt_finish_reservemap(), which meant that there was no
terminator in the reservemap list and whatever happened to be at the
start of the FDT data section would end up being interpreted as
reservemap entries. Avoid this by calling fdt_finish_reservemap()
to add the terminator.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Alexander Graf <agraf@suse.de>
---
device_tree.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/device_tree.c b/device_tree.c
index ffec99a..391da8c 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -41,6 +41,10 @@ void *create_device_tree(int *sizep)
if (ret < 0) {
goto fail;
}
+ ret = fdt_finish_reservemap(fdt);
+ if (ret < 0) {
+ goto fail;
+ }
ret = fdt_begin_node(fdt, "");
if (ret < 0) {
goto fail;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 03/11] hw/arm/boot: Allow boards to provide an fdt blob
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 01/11] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 02/11] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 04/11] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
` (9 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
From: John Rigby <john.rigby@linaro.org>
If no fdt is provided on command line and the new field
get_dtb in struct arm_boot_info is set then call it to
get a device tree blob.
Signed-off-by: John Rigby <john.rigby@linaro.org>
[PMM: minor tweaks and cleanup]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/boot.c | 32 ++++++++++++++++++++------------
include/hw/arm/arm.h | 7 +++++++
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 583ec79..55d552f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -228,23 +228,31 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
{
void *fdt = NULL;
- char *filename;
int size, rc;
uint32_t acells, scells;
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
- if (!filename) {
- fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
- goto fail;
- }
+ if (binfo->dtb_filename) {
+ char *filename;
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
+ if (!filename) {
+ fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
+ goto fail;
+ }
- fdt = load_device_tree(filename, &size);
- if (!fdt) {
- fprintf(stderr, "Couldn't open dtb file %s\n", filename);
+ fdt = load_device_tree(filename, &size);
+ if (!fdt) {
+ fprintf(stderr, "Couldn't open dtb file %s\n", filename);
+ g_free(filename);
+ goto fail;
+ }
g_free(filename);
- goto fail;
+ } else if (binfo->get_dtb) {
+ fdt = binfo->get_dtb(binfo, &size);
+ if (!fdt) {
+ fprintf(stderr, "Board was unable to create a dtb blob\n");
+ goto fail;
+ }
}
- g_free(filename);
acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells");
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
@@ -438,7 +446,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
/* for device tree boot, we pass the DTB directly in r2. Otherwise
* we point to the kernel args.
*/
- if (info->dtb_filename) {
+ if (info->dtb_filename || info->get_dtb) {
/* Place the DTB after the initrd in memory. Note that some
* kernels will trash anything in the 4K page the initrd
* ends in, so make sure the DTB isn't caught up in that.
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index ecbbba8..cbbf4ca 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -50,6 +50,13 @@ struct arm_boot_info {
const struct arm_boot_info *info);
void (*secondary_cpu_reset_hook)(ARMCPU *cpu,
const struct arm_boot_info *info);
+ /* if a board is able to create a dtb without a dtb file then it
+ * sets get_dtb. This will only be used if no dtb file is provided
+ * by the user. On success, sets *size to the length of the created
+ * dtb, and returns a pointer to it. (The caller must free this memory
+ * with g_free() when it has finished with it.) On failure, returns NULL.
+ */
+ void *(*get_dtb)(const struct arm_boot_info *info, int *size);
/* if a board needs to be able to modify a device tree provided by
* the user it should implement this hook.
*/
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 04/11] target-arm: Provide PSCI constants to generic QEMU code
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (2 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 03/11] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 17:52 ` Christoffer Dall
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 05/11] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
` (8 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Provide versions of the KVM PSCI constants to non-KVM code;
this will allow us to avoid an ifdef in boards which set up
a PSCI node in the device tree.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/kvm-consts.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 6f56f72..4062f11 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -36,6 +36,18 @@ MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32)
MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
+#define PSCI_FN_BASE 0x95c1ba5e
+#define PSCI_FN(n) (PSCI_FN_BASE + (n))
+#define PSCI_FN_CPU_SUSPEND PSCI_FN(0)
+#define PSCI_FN_CPU_OFF PSCI_FN(1)
+#define PSCI_FN_CPU_ON PSCI_FN(2)
+#define PSCI_FN_MIGRATE PSCI_FN(3)
+
+MISMATCH_CHECK(PSCI_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND)
+MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
+MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
+MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
+
#undef MISMATCH_CHECK
#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 05/11] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (3 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 04/11] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 06/11] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
` (7 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Linux requires device tree CPU nodes to include a 'compatible'
string describing the CPU. Add a field in the ARMCPU struct for
this so that boards which construct a device tree can insert
the correct CPU nodes.
Note that there is currently no officially specified 'compatible'
string for the TI925T, Cortex-M3 or SA1110 CPUs.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu-qom.h | 3 +++
target-arm/cpu.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index b55306a..cbb9eec 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -91,6 +91,9 @@ typedef struct ARMCPU {
/* GPIO outputs for generic timer */
qemu_irq gt_timer_outputs[NUM_GTIMERS];
+ /* 'compatible' string for this CPU for Linux device trees */
+ const char *dtb_compatible;
+
/* The instance init functions for implementation-specific subclasses
* set these fields to specify the implementation-dependent values of
* various constant registers and reset values of non-constant
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index d40f2a7..4c8d9c7 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -217,6 +217,12 @@ static void arm_cpu_initfn(Object *obj)
ARRAY_SIZE(cpu->gt_timer_outputs));
#endif
+ /* DTB consumers generally don't in fact care what the 'compatible'
+ * string is, so always provide some string and trust that a hypothetical
+ * picky DTB consumer will also provide a helpful error message.
+ */
+ cpu->dtb_compatible = "qemu,unknown";
+
if (tcg_enabled() && !inited) {
inited = true;
arm_translate_init();
@@ -318,6 +324,8 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
static void arm926_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,arm926";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
@@ -331,6 +339,8 @@ static void arm926_initfn(Object *obj)
static void arm946_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,arm946";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_MPU);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
@@ -342,6 +352,8 @@ static void arm946_initfn(Object *obj)
static void arm1026_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,arm1026";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
@@ -374,6 +386,8 @@ static void arm1136_r2_initfn(Object *obj)
* for 1136_r2 (in particular r0p2 does not actually implement most
* of the ID registers).
*/
+
+ cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
@@ -403,6 +417,8 @@ static void arm1136_r2_initfn(Object *obj)
static void arm1136_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_VFP);
@@ -433,6 +449,8 @@ static void arm1136_initfn(Object *obj)
static void arm1176_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,arm1176";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_VAPA);
@@ -463,6 +481,8 @@ static void arm1176_initfn(Object *obj)
static void arm11mpcore_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,arm11mpcore";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_VAPA);
@@ -516,6 +536,8 @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
static void cortex_a8_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,cortex-a8";
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_VFP3);
set_feature(&cpu->env, ARM_FEATURE_NEON);
@@ -580,6 +602,8 @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
static void cortex_a9_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,cortex-a9";
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_VFP3);
set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
@@ -649,6 +673,8 @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
static void cortex_a15_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "arm,cortex-a15";
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
@@ -697,6 +723,8 @@ static void ti925t_initfn(Object *obj)
static void sa1100_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "intel,sa1100";
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x4401A11B;
@@ -715,6 +743,8 @@ static void sa1110_initfn(Object *obj)
static void pxa250_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052100;
@@ -725,6 +755,8 @@ static void pxa250_initfn(Object *obj)
static void pxa255_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d00;
@@ -735,6 +767,8 @@ static void pxa255_initfn(Object *obj)
static void pxa260_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052903;
@@ -745,6 +779,8 @@ static void pxa260_initfn(Object *obj)
static void pxa261_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d05;
@@ -755,6 +791,8 @@ static void pxa261_initfn(Object *obj)
static void pxa262_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d06;
@@ -765,6 +803,8 @@ static void pxa262_initfn(Object *obj)
static void pxa270a0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -776,6 +816,8 @@ static void pxa270a0_initfn(Object *obj)
static void pxa270a1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -787,6 +829,8 @@ static void pxa270a1_initfn(Object *obj)
static void pxa270b0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -798,6 +842,8 @@ static void pxa270b0_initfn(Object *obj)
static void pxa270b1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -809,6 +855,8 @@ static void pxa270b1_initfn(Object *obj)
static void pxa270c0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
@@ -820,6 +868,8 @@ static void pxa270c0_initfn(Object *obj)
static void pxa270c5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
+
+ cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 06/11] target-arm: Allow secondary KVM CPUs to be booted via PSCI
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (4 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 05/11] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform Peter Maydell
` (6 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
New ARM boards are generally expected to boot their secondary CPUs
via the PSCI interface, rather than ad-hoc "loop around in holding
pen code" as hw/arm/boot.c implements. In particular this is
necessary for mach-virt kernels. For KVM we achieve this by creating
the VCPUs with a feature flag marking them as starting in PSCI
powered-down state; the guest kernel will then make a PSCI call
(implemented in the host kernel) to start the secondaries at
an address of its choosing once it has got the primary CPU up.
Implement this setting of the feature flag, controlled by a
qdev property for ARMCPU, which board code can set if it is a
PSCI system.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu-qom.h | 3 +++
target-arm/cpu.c | 7 +++++++
target-arm/kvm.c | 3 +++
3 files changed, 13 insertions(+)
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index cbb9eec..8bd3e36 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -94,6 +94,9 @@ typedef struct ARMCPU {
/* 'compatible' string for this CPU for Linux device trees */
const char *dtb_compatible;
+ /* Should CPU start in PSCI powered-off state? */
+ bool start_powered_off;
+
/* The instance init functions for implementation-specific subclasses
* set these fields to specify the implementation-dependent values of
* various constant registers and reset values of non-constant
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 4c8d9c7..0325815 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -20,6 +20,7 @@
#include "cpu.h"
#include "qemu-common.h"
+#include "hw/qdev-properties.h"
#if !defined(CONFIG_USER_ONLY)
#include "hw/loader.h"
#endif
@@ -944,6 +945,11 @@ static const ARMCPUInfo arm_cpus[] = {
#endif
};
+static Property arm_cpu_properties[] = {
+ DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
+ DEFINE_PROP_END_OF_LIST()
+};
+
static void arm_cpu_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
@@ -952,6 +958,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
acc->parent_realize = dc->realize;
dc->realize = arm_cpu_realizefn;
+ dc->props = arm_cpu_properties;
acc->parent_reset = cc->reset;
cc->reset = arm_cpu_reset;
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 3098456..80c58c5 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -79,6 +79,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
init.target = KVM_ARM_TARGET_CORTEX_A15;
memset(init.features, 0, sizeof(init.features));
+ if (cpu->start_powered_off) {
+ init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
+ }
ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
if (ret) {
return ret;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (5 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 06/11] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 18:11 ` Christoffer Dall
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 08/11] linux-headers: Update from mainline Peter Maydell
` (5 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Add 'virt' platform support corresponding to arch/arm/mach-virt
in the Linux kernel tree. This has no platform-specific code but
can use any device whose kernel driver is is able to work purely
from a device tree node. We use this to instantiate a minimal
set of devices: a GIC and some virtio-mmio transports.
Signed-off-by: John Rigby <john.rigby@linaro.org>
[PMM:
Significantly overhauled:
* renamed user-facing machine to just "virt"
* removed the A9 support (it can't work since the A9 has no
generic timers)
* added virtio-mmio transports instead of random set of 'soc' devices
(though we retain a pl011 UART)
* instead of updating io_base as we step through adding devices,
define a memory map with an array (similar to vexpress)
* similarly, define irqmap with an array
* folded in some minor fixes from John's aarch64-support patch
* rather than explicitly doing endian-swapping on FDT cells,
use fdt APIs that let us just pass in host-endian values
and let the fdt layer take care of the swapping
* miscellaneous minor code cleanups and style fixes
]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/Makefile.objs | 2 +-
hw/arm/virt.c | 444 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 445 insertions(+), 1 deletion(-)
create mode 100644 hw/arm/virt.c
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 3671b42..78b5614 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,7 +1,7 @@
obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
-obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
+obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
obj-y += omap1.o omap2.o strongarm.o
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
new file mode 100644
index 0000000..1e42cc2
--- /dev/null
+++ b/hw/arm/virt.c
@@ -0,0 +1,444 @@
+/*
+ * ARM mach-virt emulation
+ *
+ * Copyright (c) 2013 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Emulate a virtual board which works by passing Linux all the information
+ * it needs about what devices are present via the device tree.
+ * There are some restrictions about what we can do here:
+ * + we can only present devices whose Linux drivers will work based
+ * purely on the device tree with no platform data at all
+ * + we want to present a very stripped-down minimalist platform,
+ * both because this reduces the security attack surface from the guest
+ * and also because it reduces our exposure to being broken when
+ * the kernel updates its device tree bindings and requires further
+ * information in a device binding that we aren't providing.
+ * This is essentially the same approach kvmtool uses.
+ */
+
+#include "hw/sysbus.h"
+#include "hw/arm/arm.h"
+#include "hw/arm/primecell.h"
+#include "hw/devices.h"
+#include "net/net.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+
+#define NUM_VIRTIO_TRANSPORTS 32
+
+/* Number of external interrupt lines to configure the GIC with */
+#define NUM_IRQS 128
+
+#define GIC_FDT_IRQ_TYPE_SPI 0
+#define GIC_FDT_IRQ_TYPE_PPI 1
+
+#define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1
+#define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2
+#define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4
+#define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8
+
+#define GIC_FDT_IRQ_PPI_CPU_START 8
+#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
+
+enum {
+ VIRT_FLASH,
+ VIRT_MEM,
+ VIRT_CPUPERIPHS,
+ VIRT_GIC_DIST,
+ VIRT_GIC_CPU,
+ VIRT_UART,
+ VIRT_MMIO,
+};
+
+typedef struct MemMapEntry {
+ hwaddr base;
+ hwaddr size;
+} MemMapEntry;
+
+typedef struct VirtBoardInfo {
+ struct arm_boot_info bootinfo;
+ const char *cpu_model;
+ const char *qdevname;
+ const char *gic_compatible;
+ const MemMapEntry *memmap;
+ const int *irqmap;
+ int smp_cpus;
+ void *fdt;
+ int fdt_size;
+ uint32_t clock_phandle;
+} VirtBoardInfo;
+
+/* Addresses and sizes of our components.
+ * 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
+ * 128MB..256MB is used for miscellaneous device I/O.
+ * 256MB..1GB is reserved for possible future PCI support (ie where the
+ * PCI memory window will go if we add a PCI host controller).
+ * 1GB and up is RAM (which may happily spill over into the
+ * high memory region beyond 4GB).
+ * This represents a compromise between how much RAM can be given to
+ * a 32 bit VM and leaving space for expansion and in particular for PCI.
+ */
+static const MemMapEntry a15memmap[] = {
+ /* Space up to 0x8000000 is reserved for a boot ROM */
+ [VIRT_FLASH] = { 0, 0x8000000 },
+ [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 },
+ /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
+ [VIRT_GIC_DIST] = { 0x8001000, 0x1000 },
+ [VIRT_GIC_CPU] = { 0x8002000, 0x1000 },
+ [VIRT_UART] = { 0x9000000, 0x1000 },
+ [VIRT_MMIO] = { 0xa000000, 0x200 },
+ /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
+ /* 0x10000000 .. 0x40000000 reserved for PCI */
+ [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
+};
+
+static const int a15irqmap[] = {
+ [VIRT_UART] = 1,
+ [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
+};
+
+static VirtBoardInfo machines[] = {
+ {
+ .cpu_model = "cortex-a15",
+ .qdevname = "a15mpcore_priv",
+ .gic_compatible = "arm,cortex-a15-gic",
+ .memmap = a15memmap,
+ .irqmap = a15irqmap,
+ },
+};
+
+static VirtBoardInfo *find_machine_info(const char *cpu)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(machines); i++) {
+ if (strcmp(cpu, machines[i].cpu_model) == 0) {
+ return &machines[i];
+ }
+ }
+ return NULL;
+}
+
+static void create_fdt(VirtBoardInfo *vbi)
+{
+ void *fdt = create_device_tree(&vbi->fdt_size);
+
+ if (!fdt) {
+ error_report("create_device_tree() failed");
+ exit(1);
+ }
+
+ vbi->fdt = fdt;
+
+ /* Header */
+ qemu_devtree_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
+ qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 0x2);
+ qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 0x2);
+
+ /*
+ * /chosen and /memory nodes must exist for load_dtb
+ * to fill in necessary properties later
+ */
+ qemu_devtree_add_subnode(fdt, "/chosen");
+ qemu_devtree_add_subnode(fdt, "/memory");
+ qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
+
+ /* Clock node, for the benefit of the UART. The kernel device tree
+ * binding documentation claims the PL011 node clock properties are
+ * optional but in practice if you omit them the kernel refuses to
+ * probe for the device.
+ */
+ vbi->clock_phandle = qemu_devtree_alloc_phandle(fdt);
+ qemu_devtree_add_subnode(fdt, "/apb-pclk");
+ qemu_devtree_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
+ qemu_devtree_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
+ qemu_devtree_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
+ qemu_devtree_setprop_string(fdt, "/apb-pclk", "clock-output-names",
+ "clk24mhz");
+ qemu_devtree_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
+
+ /* No PSCI for TCG yet */
+ if (kvm_enabled()) {
+ qemu_devtree_add_subnode(fdt, "/psci");
+ qemu_devtree_setprop_string(fdt, "/psci", "compatible", "arm,psci");
+ qemu_devtree_setprop_string(fdt, "/psci", "method", "hvc");
+ qemu_devtree_setprop_cell(fdt, "/psci", "cpu_suspend",
+ PSCI_FN_CPU_SUSPEND);
+ qemu_devtree_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
+ qemu_devtree_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
+ qemu_devtree_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
+ }
+}
+
+static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
+{
+ /* Note that on A15 h/w these interrupts are level-triggered,
+ * but for the GIC implementation provided by both QEMU and KVM
+ * they are edge-triggered.
+ */
+ uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
+
+ irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
+ GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
+
+ qemu_devtree_add_subnode(vbi->fdt, "/timer");
+ qemu_devtree_setprop_string(vbi->fdt, "/timer",
+ "compatible", "arm,armv7-timer");
+ qemu_devtree_setprop_cells(vbi->fdt, "/timer", "interrupts",
+ GIC_FDT_IRQ_TYPE_PPI, 13, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, 14, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, 11, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, 10, irqflags);
+}
+
+static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
+{
+ int cpu;
+
+ qemu_devtree_add_subnode(vbi->fdt, "/cpus");
+ qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
+ qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
+
+ for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
+ char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+
+ qemu_devtree_add_subnode(vbi->fdt, nodename);
+ qemu_devtree_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
+ qemu_devtree_setprop_string(vbi->fdt, nodename, "compatible",
+ armcpu->dtb_compatible);
+
+ if (vbi->smp_cpus > 1) {
+ qemu_devtree_setprop_string(vbi->fdt, nodename,
+ "enable-method", "psci");
+ }
+
+ qemu_devtree_setprop_cell(vbi->fdt, nodename, "reg", cpu);
+ g_free(nodename);
+ }
+}
+
+static void fdt_add_gic_node(const VirtBoardInfo *vbi)
+{
+ uint32_t gic_phandle;
+
+ gic_phandle = qemu_devtree_alloc_phandle(vbi->fdt);
+ qemu_devtree_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
+
+ qemu_devtree_add_subnode(vbi->fdt, "/intc");
+ qemu_devtree_setprop_string(vbi->fdt, "/intc", "compatible",
+ vbi->gic_compatible);
+ qemu_devtree_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
+ qemu_devtree_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
+ qemu_devtree_setprop_sized_cells(vbi->fdt, "/intc", "reg",
+ 2, vbi->memmap[VIRT_GIC_DIST].base,
+ 2, vbi->memmap[VIRT_GIC_DIST].size,
+ 2, vbi->memmap[VIRT_GIC_CPU].base,
+ 2, vbi->memmap[VIRT_GIC_CPU].size);
+ qemu_devtree_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
+}
+
+static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+ char *nodename;
+ hwaddr base = vbi->memmap[VIRT_UART].base;
+ hwaddr size = vbi->memmap[VIRT_UART].size;
+ int irq = vbi->irqmap[VIRT_UART];
+ const char compat[] = "arm,pl011\0arm,primecell";
+ const char clocknames[] = "uartclk\0apb_pclk";
+
+ sysbus_create_simple("pl011", base, pic[irq]);
+
+ nodename = g_strdup_printf("/pl011@%" PRIx64, base);
+ qemu_devtree_add_subnode(vbi->fdt, nodename);
+ /* Note that we can't use setprop_string because of the embedded NUL */
+ qemu_devtree_setprop(vbi->fdt, nodename, "compatible",
+ compat, sizeof(compat));
+ qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
+ 2, base, 2, size);
+ qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
+ GIC_FDT_IRQ_TYPE_SPI, irq,
+ GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+ qemu_devtree_setprop_cells(vbi->fdt, nodename, "clocks",
+ vbi->clock_phandle, vbi->clock_phandle);
+ qemu_devtree_setprop(vbi->fdt, nodename, "clock-names",
+ clocknames, sizeof(clocknames));
+ g_free(nodename);
+}
+
+static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
+{
+ int i;
+ hwaddr size = vbi->memmap[VIRT_MMIO].size;
+
+ /* Note that we have to create the transports in forwards order
+ * so that command line devices are inserted lowest address first,
+ * and then add dtb nodes in reverse order so that they appear in
+ * the finished device tree lowest address first.
+ */
+ for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
+ int irq = vbi->irqmap[VIRT_MMIO] + i;
+ hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
+
+ sysbus_create_simple("virtio-mmio", base, pic[irq]);
+ }
+
+ for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
+ char *nodename;
+ int irq = vbi->irqmap[VIRT_MMIO] + i;
+ hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
+
+ nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
+ qemu_devtree_add_subnode(vbi->fdt, nodename);
+ qemu_devtree_setprop_string(vbi->fdt, nodename,
+ "compatible", "virtio,mmio");
+ qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
+ 2, base, 2, size);
+ qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
+ GIC_FDT_IRQ_TYPE_SPI, irq,
+ GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+ g_free(nodename);
+ }
+}
+
+static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+{
+ const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
+
+ *fdt_size = board->fdt_size;
+ return board->fdt;
+}
+
+static void machvirt_init(QEMUMachineInitArgs *args)
+{
+ qemu_irq pic[NUM_IRQS];
+ MemoryRegion *sysmem = get_system_memory();
+ int n;
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
+ DeviceState *dev;
+ SysBusDevice *busdev;
+ const char *cpu_model = args->cpu_model;
+ VirtBoardInfo *vbi;
+
+ if (!cpu_model) {
+ cpu_model = "cortex-a15";
+ }
+
+ vbi = find_machine_info(cpu_model);
+
+ if (!vbi) {
+ error_report("mach-virt: CPU %s not supported", cpu_model);
+ exit(1);
+ }
+
+ vbi->smp_cpus = smp_cpus;
+
+ /*
+ * Only supported method of starting secondary CPUs is PSCI and
+ * PSCI is not yet supported with TCG, so limit smp_cpus to 1
+ * if we're not using KVM.
+ */
+ if (!kvm_enabled() && smp_cpus > 1) {
+ error_report("mach-virt: must enable KVM to use multiple CPUs");
+ exit(1);
+ }
+
+ if (args->ram_size > vbi->memmap[VIRT_MEM].size) {
+ error_report("mach-virt: cannot model more than 30GB RAM");
+ exit(1);
+ }
+
+ create_fdt(vbi);
+ fdt_add_timer_nodes(vbi);
+
+ for (n = 0; n < smp_cpus; n++) {
+ ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
+ Object *cpuobj;
+
+ if (!oc) {
+ fprintf(stderr, "Unable to find CPU definition\n");
+ exit(1);
+ }
+ cpuobj = object_new(object_class_get_name(oc));
+
+ /* Secondary CPUs start in PSCI powered-down state */
+ if (n > 0) {
+ object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
+ }
+ object_property_set_bool(cpuobj, true, "realized", NULL);
+ }
+ fdt_add_cpu_nodes(vbi);
+
+ memory_region_init_ram(ram, NULL, "mach-virt.ram", args->ram_size);
+ vmstate_register_ram_global(ram);
+ memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
+
+ dev = qdev_create(NULL, vbi->qdevname);
+ qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
+ /* Note that the num-irq property counts both internal and external
+ * interrupts; there are always 32 of the former (mandated by GIC spec).
+ */
+ qdev_prop_set_uint32(dev, "num-irq", NUM_IRQS + 32);
+ qdev_init_nofail(dev);
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, vbi->memmap[VIRT_CPUPERIPHS].base);
+ fdt_add_gic_node(vbi);
+ for (n = 0; n < smp_cpus; n++) {
+ DeviceState *cpudev = DEVICE(qemu_get_cpu(n));
+
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+ }
+
+ for (n = 0; n < NUM_IRQS; n++) {
+ pic[n] = qdev_get_gpio_in(dev, n);
+ }
+
+ create_uart(vbi, pic);
+
+ /* Create mmio transports, so the user can create virtio backends
+ * (which will be automatically plugged in to the transports). If
+ * no backend is created the transport will just sit harmlessly idle.
+ */
+ create_virtio_devices(vbi, pic);
+
+ vbi->bootinfo.ram_size = args->ram_size;
+ vbi->bootinfo.kernel_filename = args->kernel_filename;
+ vbi->bootinfo.kernel_cmdline = args->kernel_cmdline;
+ vbi->bootinfo.initrd_filename = args->initrd_filename;
+ vbi->bootinfo.nb_cpus = smp_cpus;
+ vbi->bootinfo.board_id = -1;
+ vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;
+ vbi->bootinfo.get_dtb = machvirt_dtb;
+ arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
+}
+
+static QEMUMachine machvirt_a15_machine = {
+ .name = "virt",
+ .desc = "ARM Virtual Machine",
+ .init = machvirt_init,
+ .max_cpus = 4,
+};
+
+static void machvirt_machine_init(void)
+{
+ qemu_register_machine(&machvirt_a15_machine);
+}
+
+machine_init(machvirt_machine_init);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 08/11] linux-headers: Update from mainline
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (6 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-12-02 13:35 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 09/11] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
` (4 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Update Linux KVM headers from mainline commit 5d6e63323fe779.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
| 3 +-
| 4 +-
| 86 ++++++++++++++++++++++++++++--
| 19 +++++++
| 6 +--
| 11 ++++
6 files changed, 119 insertions(+), 10 deletions(-)
--git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
index c1ee007..c498b60 100644
--- a/linux-headers/asm-arm/kvm.h
+++ b/linux-headers/asm-arm/kvm.h
@@ -63,7 +63,8 @@ struct kvm_regs {
/* Supported Processor Types */
#define KVM_ARM_TARGET_CORTEX_A15 0
-#define KVM_ARM_NUM_TARGETS 1
+#define KVM_ARM_TARGET_CORTEX_A7 1
+#define KVM_ARM_NUM_TARGETS 2
/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
#define KVM_ARM_DEVICE_TYPE_SHIFT 0
--git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h
index 33b3f89..06f7247 100644
--- a/linux-headers/asm-powerpc/epapr_hcalls.h
+++ b/linux-headers/asm-powerpc/epapr_hcalls.h
@@ -78,7 +78,7 @@
#define EV_SUCCESS 0
#define EV_EPERM 1 /* Operation not permitted */
#define EV_ENOENT 2 /* Entry Not Found */
-#define EV_EIO 3 /* I/O error occurred */
+#define EV_EIO 3 /* I/O error occured */
#define EV_EAGAIN 4 /* The operation had insufficient
* resources to complete and should be
* retried
@@ -89,7 +89,7 @@
#define EV_ENODEV 7 /* No such device */
#define EV_EINVAL 8 /* An argument supplied to the hcall
was out of range or invalid */
-#define EV_INTERNAL 9 /* An internal error occurred */
+#define EV_INTERNAL 9 /* An internal error occured */
#define EV_CONFIG 10 /* A configuration error was detected */
#define EV_INVALID_STATE 11 /* The object is in an invalid state */
#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
--git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index 0fb1a6e..6836ec7 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -27,6 +27,7 @@
#define __KVM_HAVE_PPC_SMT
#define __KVM_HAVE_IRQCHIP
#define __KVM_HAVE_IRQ_LINE
+#define __KVM_HAVE_GUEST_DEBUG
struct kvm_regs {
__u64 pc;
@@ -269,7 +270,24 @@ struct kvm_fpu {
__u64 fpr[32];
};
+/*
+ * Defines for h/w breakpoint, watchpoint (read, write or both) and
+ * software breakpoint.
+ * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
+ * for KVM_DEBUG_EXIT.
+ */
+#define KVMPPC_DEBUG_NONE 0x0
+#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1)
+#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2)
+#define KVMPPC_DEBUG_WATCH_READ (1UL << 3)
struct kvm_debug_exit_arch {
+ __u64 address;
+ /*
+ * exiting to userspace because of h/w breakpoint, watchpoint
+ * (read, write or both) and software breakpoint.
+ */
+ __u32 status;
+ __u32 reserved;
};
/* for KVM_SET_GUEST_DEBUG */
@@ -281,10 +299,6 @@ struct kvm_guest_debug_arch {
* Type denotes h/w breakpoint, read watchpoint, write
* watchpoint or watchpoint (both read and write).
*/
-#define KVMPPC_DEBUG_NONE 0x0
-#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1)
-#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2)
-#define KVMPPC_DEBUG_WATCH_READ (1UL << 3)
__u32 type;
__u32 reserved;
} bp[16];
@@ -429,6 +443,11 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_MMCR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10)
#define KVM_REG_PPC_MMCR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11)
#define KVM_REG_PPC_MMCRA (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12)
+#define KVM_REG_PPC_MMCR2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x13)
+#define KVM_REG_PPC_MMCRS (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x14)
+#define KVM_REG_PPC_SIAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x15)
+#define KVM_REG_PPC_SDAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x16)
+#define KVM_REG_PPC_SIER (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x17)
#define KVM_REG_PPC_PMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18)
#define KVM_REG_PPC_PMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19)
@@ -499,6 +518,65 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_TLB3PS (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9a)
#define KVM_REG_PPC_EPTCFG (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9b)
+/* Timebase offset */
+#define KVM_REG_PPC_TB_OFFSET (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9c)
+
+/* POWER8 registers */
+#define KVM_REG_PPC_SPMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9d)
+#define KVM_REG_PPC_SPMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x9e)
+#define KVM_REG_PPC_IAMR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9f)
+#define KVM_REG_PPC_TFHAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa0)
+#define KVM_REG_PPC_TFIAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa1)
+#define KVM_REG_PPC_TEXASR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa2)
+#define KVM_REG_PPC_FSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa3)
+#define KVM_REG_PPC_PSPB (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xa4)
+#define KVM_REG_PPC_EBBHR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa5)
+#define KVM_REG_PPC_EBBRR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa6)
+#define KVM_REG_PPC_BESCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa7)
+#define KVM_REG_PPC_TAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa8)
+#define KVM_REG_PPC_DPDES (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa9)
+#define KVM_REG_PPC_DAWR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xaa)
+#define KVM_REG_PPC_DAWRX (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xab)
+#define KVM_REG_PPC_CIABR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xac)
+#define KVM_REG_PPC_IC (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xad)
+#define KVM_REG_PPC_VTB (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xae)
+#define KVM_REG_PPC_CSIGR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xaf)
+#define KVM_REG_PPC_TACR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb0)
+#define KVM_REG_PPC_TCSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb1)
+#define KVM_REG_PPC_PID (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb2)
+#define KVM_REG_PPC_ACOP (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb3)
+
+#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4)
+#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5)
+#define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6)
+
+/* Architecture compatibility level */
+#define KVM_REG_PPC_ARCH_COMPAT (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb7)
+
+/* Transactional Memory checkpointed state:
+ * This is all GPRs, all VSX regs and a subset of SPRs
+ */
+#define KVM_REG_PPC_TM (KVM_REG_PPC | 0x80000000)
+/* TM GPRs */
+#define KVM_REG_PPC_TM_GPR0 (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0)
+#define KVM_REG_PPC_TM_GPR(n) (KVM_REG_PPC_TM_GPR0 + (n))
+#define KVM_REG_PPC_TM_GPR31 (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x1f)
+/* TM VSX */
+#define KVM_REG_PPC_TM_VSR0 (KVM_REG_PPC_TM | KVM_REG_SIZE_U128 | 0x20)
+#define KVM_REG_PPC_TM_VSR(n) (KVM_REG_PPC_TM_VSR0 + (n))
+#define KVM_REG_PPC_TM_VSR63 (KVM_REG_PPC_TM | KVM_REG_SIZE_U128 | 0x5f)
+/* TM SPRS */
+#define KVM_REG_PPC_TM_CR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x60)
+#define KVM_REG_PPC_TM_LR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x61)
+#define KVM_REG_PPC_TM_CTR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x62)
+#define KVM_REG_PPC_TM_FPSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x63)
+#define KVM_REG_PPC_TM_AMR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x64)
+#define KVM_REG_PPC_TM_PPR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x65)
+#define KVM_REG_PPC_TM_VRSAVE (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x66)
+#define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)
+#define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)
+#define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69)
+
/* PPC64 eXternal Interrupt Controller Specification */
#define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */
--git a/linux-headers/asm-x86/hyperv.h b/linux-headers/asm-x86/hyperv.h
index b80420b..b8f1c01 100644
--- a/linux-headers/asm-x86/hyperv.h
+++ b/linux-headers/asm-x86/hyperv.h
@@ -27,6 +27,19 @@
#define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0)
/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
+
+/*
+ * There is a single feature flag that signifies the presence of the MSR
+ * that can be used to retrieve both the local APIC Timer frequency as
+ * well as the TSC frequency.
+ */
+
+/* Local APIC timer frequency MSR (HV_X64_MSR_APIC_FREQUENCY) is available */
+#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11)
+
+/* TSC frequency MSR (HV_X64_MSR_TSC_FREQUENCY) is available */
+#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11)
+
/*
* Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
* and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
@@ -136,6 +149,12 @@
/* MSR used to read the per-partition time reference counter */
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
+/* MSR used to retrieve the TSC frequency */
+#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
+
+/* MSR used to retrieve the local APIC timer frequency */
+#define HV_X64_MSR_APIC_FREQUENCY 0x40000023
+
/* Define the virtual APIC registers */
#define HV_X64_MSR_EOI 0x40000070
#define HV_X64_MSR_ICR 0x40000071
--git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
index 5d9a303..d3a8778 100644
--- a/linux-headers/asm-x86/kvm.h
+++ b/linux-headers/asm-x86/kvm.h
@@ -211,9 +211,9 @@ struct kvm_cpuid_entry2 {
__u32 padding[3];
};
-#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1
-#define KVM_CPUID_FLAG_STATEFUL_FUNC 2
-#define KVM_CPUID_FLAG_STATE_READ_NEXT 4
+#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX BIT(0)
+#define KVM_CPUID_FLAG_STATEFUL_FUNC BIT(1)
+#define KVM_CPUID_FLAG_STATE_READ_NEXT BIT(2)
/* for KVM_SET_CPUID2 */
struct kvm_cpuid2 {
--git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 13e890c..5a49671 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -518,6 +518,10 @@ struct kvm_ppc_smmu_info {
/* machine type bits, to be used as argument to KVM_CREATE_VM */
#define KVM_VM_S390_UCONTROL 1
+/* on ppc, 0 indicate default, 1 should force HV and 2 PR */
+#define KVM_VM_PPC_HV 1
+#define KVM_VM_PPC_PR 2
+
#define KVM_S390_SIE_PAGE_OFFSET 1
/*
@@ -541,6 +545,7 @@ struct kvm_ppc_smmu_info {
#define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06
#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07
#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08
+#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
/*
* Extension capability list.
@@ -668,6 +673,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_IRQ_XICS 92
#define KVM_CAP_ARM_EL1_32BIT 93
#define KVM_CAP_SPAPR_MULTITCE 94
+#define KVM_CAP_EXT_EMUL_CPUID 95
#ifdef KVM_CAP_IRQ_ROUTING
@@ -843,6 +849,10 @@ struct kvm_device_attr {
#define KVM_DEV_TYPE_FSL_MPIC_20 1
#define KVM_DEV_TYPE_FSL_MPIC_42 2
#define KVM_DEV_TYPE_XICS 3
+#define KVM_DEV_TYPE_VFIO 4
+#define KVM_DEV_VFIO_GROUP 1
+#define KVM_DEV_VFIO_GROUP_ADD 1
+#define KVM_DEV_VFIO_GROUP_DEL 2
/*
* ioctls for VM fds
@@ -1012,6 +1022,7 @@ struct kvm_s390_ucas_mapping {
/* VM is being stopped by host */
#define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad)
#define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init)
+#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init)
#define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 09/11] target-arm: Don't hardcode KVM target CPU to be A15
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (7 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 08/11] linux-headers: Update from mainline Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM Peter Maydell
` (3 subsequent siblings)
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Instead of assuming that a KVM target CPU must always be a
Cortex-A15 and hardcoding this in kvm_arch_init_vcpu(),
store the KVM_ARM_TARGET_* value in the ARMCPU class,
and use that.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu-qom.h | 5 +++++
target-arm/cpu.c | 2 ++
target-arm/kvm-consts.h | 11 +++++++++++
target-arm/kvm.c | 7 ++++++-
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 8bd3e36..f32178a 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -97,6 +97,11 @@ typedef struct ARMCPU {
/* Should CPU start in PSCI powered-off state? */
bool start_powered_off;
+ /* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
+ * QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
+ */
+ uint32_t kvm_target;
+
/* The instance init functions for implementation-specific subclasses
* set these fields to specify the implementation-dependent values of
* various constant registers and reset values of non-constant
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 0325815..0635e78 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -223,6 +223,7 @@ static void arm_cpu_initfn(Object *obj)
* picky DTB consumer will also provide a helpful error message.
*/
cpu->dtb_compatible = "qemu,unknown";
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
if (tcg_enabled() && !inited) {
inited = true;
@@ -685,6 +686,7 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_LPAE);
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
cpu->midr = 0x412fc0f1;
cpu->reset_fpsid = 0x410430f0;
cpu->mvfr0 = 0x10110222;
diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
index 4062f11..2bba0bd 100644
--- a/target-arm/kvm-consts.h
+++ b/target-arm/kvm-consts.h
@@ -48,6 +48,17 @@ MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
+#define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
+
+/* There's no kernel define for this: sentinel value which
+ * matches no KVM target value for either 64 or 32 bit
+ */
+#define QEMU_KVM_ARM_TARGET_NONE UINT_MAX
+
+#ifndef TARGET_AARCH64
+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15)
+#endif
+
#undef MISMATCH_CHECK
#endif
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 80c58c5..182db85 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -77,7 +77,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
struct kvm_reg_list *rlp;
ARMCPU *cpu = ARM_CPU(cs);
- init.target = KVM_ARM_TARGET_CORTEX_A15;
+ if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE) {
+ fprintf(stderr, "KVM is not supported for this guest CPU type\n");
+ return -EINVAL;
+ }
+
+ init.target = cpu->kvm_target;
memset(init.features, 0, sizeof(init.features));
if (cpu->start_powered_off) {
init.features[0] = 1 << KVM_ARM_VCPU_POWER_OFF;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (8 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 09/11] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 18:25 ` Christoffer Dall
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 11/11] hw/arm/virt: Support -cpu host Peter Maydell
` (2 subsequent siblings)
12 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Implement '-cpu host' for ARM when we're using KVM, broadly
in line with other KVM-supporting architectures.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 6 ++
target-arm/kvm.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-arm/kvm_arm.h | 55 +++++++++++++
3 files changed, 285 insertions(+)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 3445813..263dbbf 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1842,6 +1842,12 @@ void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
(*cpu_fprintf)(f, "Available CPUs:\n");
g_slist_foreach(list, arm_cpu_list_entry, &s);
g_slist_free(list);
+#ifdef CONFIG_KVM
+ /* The 'host' CPU type is dynamically registered only if KVM is
+ * enabled, so we have to special-case it here:
+ */
+ (*cpu_fprintf)(f, " host (only available in KVM mode)\n");
+#endif
}
static void arm_cpu_add_definition(gpointer data, gpointer user_data)
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 182db85..f865dac 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -27,12 +27,236 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
KVM_CAP_LAST_INFO
};
+bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
+ int *fdarray,
+ struct kvm_vcpu_init *init)
+{
+ int ret, kvmfd = -1, vmfd = -1, cpufd = -1;
+
+ kvmfd = qemu_open("/dev/kvm", O_RDWR);
+ if (kvmfd < 0) {
+ goto err;
+ }
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
+ if (vmfd < 0) {
+ goto err;
+ }
+ cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
+ if (cpufd < 0) {
+ goto err;
+ }
+
+ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init);
+ if (ret >= 0) {
+ ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
+ if (ret < 0) {
+ goto err;
+ }
+ } else {
+ /* Old kernel which doesn't know about the
+ * PREFERRED_TARGET ioctl: we know it will only support
+ * creating one kind of guest CPU which is its preferred
+ * CPU type.
+ */
+ while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
+ init->target = *cpus_to_try++;
+ memset(init->features, 0, sizeof(init->features));
+ ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
+ if (ret >= 0) {
+ break;
+ }
+ }
+ if (ret < 0) {
+ goto err;
+ }
+ }
+
+ fdarray[0] = kvmfd;
+ fdarray[1] = vmfd;
+ fdarray[2] = cpufd;
+
+ return true;
+
+err:
+ if (cpufd >= 0) {
+ close(cpufd);
+ }
+ if (vmfd >= 0) {
+ close(vmfd);
+ }
+ if (kvmfd >= 0) {
+ close(kvmfd);
+ }
+
+ return false;
+}
+
+void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
+{
+ int i;
+
+ for (i = 2; i >= 0; i--) {
+ close(fdarray[i]);
+ }
+}
+
+static inline void set_feature(uint64_t *features, int feature)
+{
+ *features |= 1ULL << feature;
+}
+
+bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
+{
+ /* Identify the feature bits corresponding to the host CPU, and
+ * fill out the ARMHostCPUClass fields accordingly. To do this
+ * we have to create a scratch VM, create a single CPU inside it,
+ * and then query that CPU for the relevant ID registers.
+ */
+ int i, ret, fdarray[3];
+ uint32_t midr, id_pfr0, id_isar0, mvfr1;
+ uint64_t features = 0;
+ /* Old kernels may not know about the PREFERRED_TARGET ioctl: however
+ * we know these will only support creating one kind of guest CPU,
+ * which is its preferred CPU type.
+ */
+ static const uint32_t cpus_to_try[] = {
+ QEMU_KVM_ARM_TARGET_CORTEX_A15,
+ QEMU_KVM_ARM_TARGET_NONE
+ };
+ struct kvm_vcpu_init init;
+ struct kvm_one_reg idregs[] = {
+ {
+ .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+ | ENCODE_CP_REG(15, 0, 0, 0, 0, 0),
+ .addr = (uintptr_t)&midr,
+ },
+ {
+ .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+ | ENCODE_CP_REG(15, 0, 0, 1, 0, 0),
+ .addr = (uintptr_t)&id_pfr0,
+ },
+ {
+ .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+ | ENCODE_CP_REG(15, 0, 0, 2, 0, 0),
+ .addr = (uintptr_t)&id_isar0,
+ },
+ {
+ .id = KVM_REG_ARM | KVM_REG_SIZE_U32
+ | KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
+ .addr = (uintptr_t)&mvfr1,
+ },
+ };
+
+ if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
+ return false;
+ }
+
+ ahcc->target = init.target;
+
+ /* This is not strictly blessed by the device tree binding docs yet,
+ * but in practice the kernel does not care about this string so
+ * there is no point maintaining an KVM_ARM_TARGET_* -> string table.
+ */
+ ahcc->dtb_compatible = "arm,arm-v7";
+
+ for (i = 0; i < ARRAY_SIZE(idregs); i++) {
+ ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
+ if (ret) {
+ break;
+ }
+ }
+
+ kvm_arm_destroy_scratch_host_vcpu(fdarray);
+
+ if (ret) {
+ return false;
+ }
+
+ /* Now we've retrieved all the register information we can
+ * set the feature bits based on the ID register fields.
+ * We can assume any KVM supporting CPU is at least a v7
+ * with VFPv3, LPAE and the generic timers; this in turn implies
+ * most of the other feature bits, but a few must be tested.
+ */
+ set_feature(&features, ARM_FEATURE_V7);
+ set_feature(&features, ARM_FEATURE_VFP3);
+ set_feature(&features, ARM_FEATURE_LPAE);
+ set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
+
+ switch (extract32(id_isar0, 24, 4)) {
+ case 1:
+ set_feature(&features, ARM_FEATURE_THUMB_DIV);
+ break;
+ case 2:
+ set_feature(&features, ARM_FEATURE_ARM_DIV);
+ set_feature(&features, ARM_FEATURE_THUMB_DIV);
+ break;
+ default:
+ break;
+ }
+
+ if (extract32(id_pfr0, 12, 4) == 1) {
+ set_feature(&features, ARM_FEATURE_THUMB2EE);
+ }
+ if (extract32(mvfr1, 20, 4) == 1) {
+ set_feature(&features, ARM_FEATURE_VFP_FP16);
+ }
+ if (extract32(mvfr1, 12, 4) == 1) {
+ set_feature(&features, ARM_FEATURE_NEON);
+ }
+ if (extract32(mvfr1, 28, 4) == 1) {
+ /* FMAC support implies VFPv4 */
+ set_feature(&features, ARM_FEATURE_VFP4);
+ }
+
+ ahcc->features = features;
+
+ return true;
+}
+
+static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
+{
+ ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
+
+ /* All we really need to set up for the 'host' CPU
+ * is the feature bits -- we rely on the fact that the
+ * various ID register values in ARMCPU are only used for
+ * TCG CPUs.
+ */
+ if (!kvm_arm_get_host_cpu_features(ahcc)) {
+ fprintf(stderr, "Failed to retrieve host CPU features!\n");
+ abort();
+ }
+}
+
+static void kvm_arm_host_cpu_initfn(Object *obj)
+{
+ ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
+ ARMCPU *cpu = ARM_CPU(obj);
+ CPUARMState *env = &cpu->env;
+
+ cpu->kvm_target = ahcc->target;
+ cpu->dtb_compatible = ahcc->dtb_compatible;
+ env->features = ahcc->features;
+}
+
+static const TypeInfo host_arm_cpu_type_info = {
+ .name = TYPE_ARM_HOST_CPU,
+ .parent = TYPE_ARM_CPU,
+ .instance_init = kvm_arm_host_cpu_initfn,
+ .class_init = kvm_arm_host_cpu_class_init,
+ .class_size = sizeof(ARMHostCPUClass),
+};
+
int kvm_arch_init(KVMState *s)
{
/* For ARM interrupt delivery is always asynchronous,
* whether we are using an in-kernel VGIC or not.
*/
kvm_async_interrupts_allowed = true;
+
+ type_register_static(&host_arm_cpu_type_info);
+
return 0;
}
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
index 5d14887..cd3d13c 100644
--- a/target-arm/kvm_arm.h
+++ b/target-arm/kvm_arm.h
@@ -62,4 +62,59 @@ bool write_list_to_kvmstate(ARMCPU *cpu);
*/
bool write_kvmstate_to_list(ARMCPU *cpu);
+#ifdef CONFIG_KVM
+/**
+ * kvm_arm_create_scratch_host_vcpu:
+ * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with
+ * QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not
+ * know the PREFERRED_TARGET ioctl
+ * @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order
+ * @init: filled in with the necessary values for creating a host vcpu
+ *
+ * Create a scratch vcpu in its own VM of the type preferred by the host
+ * kernel (as would be used for '-cpu host'), for purposes of probing it
+ * for capabilities.
+ *
+ * Returns: true on success (and fdarray and init are filled in),
+ * false on failure (and fdarray and init are not valid).
+ */
+bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
+ int *fdarray,
+ struct kvm_vcpu_init *init);
+
+/**
+ * kvm_arm_destroy_scratch_host_vcpu:
+ * @fdarray: array of fds as set up by kvm_arm_create_scratch_host_vcpu
+ *
+ * Tear down the scratch vcpu created by kvm_arm_create_scratch_host_vcpu.
+ */
+void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
+
+#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
+#define ARM_HOST_CPU_CLASS(klass) \
+ OBJECT_CLASS_CHECK(ARMHostCPUClass, (klass), TYPE_ARM_HOST_CPU)
+#define ARM_HOST_CPU_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(ARMHostCPUClass, (obj), TYPE_ARM_HOST_CPU)
+
+typedef struct ARMHostCPUClass {
+ /*< private >*/
+ ARMCPUClass parent_class;
+ /*< public >*/
+
+ uint64_t features;
+ uint32_t target;
+ const char *dtb_compatible;
+} ARMHostCPUClass;
+
+/**
+ * kvm_arm_get_host_cpu_features:
+ * @ahcc: ARMHostCPUClass to fill in
+ *
+ * Probe the capabilities of the host kernel's preferred CPU and fill
+ * in the ARMHostCPUClass struct accordingly.
+ */
+bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc);
+
+#endif
+
#endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [Qemu-devel] [PATCH v9 11/11] hw/arm/virt: Support -cpu host
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (9 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM Peter Maydell
@ 2013-11-22 17:17 ` Peter Maydell
2013-11-22 18:26 ` [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Christoffer Dall
2013-12-02 13:46 ` Peter Maydell
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 17:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kvmarm, patches
Support -cpu host in virt machine (treating it like an A15, ie
with a GIC v2 and the A15's private peripherals.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm/virt.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1e42cc2..9531b5a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -122,6 +122,14 @@ static VirtBoardInfo machines[] = {
.memmap = a15memmap,
.irqmap = a15irqmap,
},
+ {
+ .cpu_model = "host",
+ /* We use the A15 private peripheral model to get a V2 GIC */
+ .qdevname = "a15mpcore_priv",
+ .gic_compatible = "arm,cortex-a15-gic",
+ .memmap = a15memmap,
+ .irqmap = a15irqmap,
+ },
};
static VirtBoardInfo *find_machine_info(const char *cpu)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 04/11] target-arm: Provide PSCI constants to generic QEMU code
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 04/11] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
@ 2013-11-22 17:52 ` Christoffer Dall
0 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2013-11-22 17:52 UTC (permalink / raw)
To: Peter Maydell; +Cc: patches, qemu-devel, kvmarm
On Fri, Nov 22, 2013 at 05:17:11PM +0000, Peter Maydell wrote:
> Provide versions of the KVM PSCI constants to non-KVM code;
> this will allow us to avoid an ifdef in boards which set up
> a PSCI node in the device tree.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target-arm/kvm-consts.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/target-arm/kvm-consts.h b/target-arm/kvm-consts.h
> index 6f56f72..4062f11 100644
> --- a/target-arm/kvm-consts.h
> +++ b/target-arm/kvm-consts.h
> @@ -36,6 +36,18 @@ MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32)
> MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64)
> MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM)
>
> +#define PSCI_FN_BASE 0x95c1ba5e
> +#define PSCI_FN(n) (PSCI_FN_BASE + (n))
> +#define PSCI_FN_CPU_SUSPEND PSCI_FN(0)
> +#define PSCI_FN_CPU_OFF PSCI_FN(1)
> +#define PSCI_FN_CPU_ON PSCI_FN(2)
> +#define PSCI_FN_MIGRATE PSCI_FN(3)
> +
> +MISMATCH_CHECK(PSCI_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND)
> +MISMATCH_CHECK(PSCI_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF)
> +MISMATCH_CHECK(PSCI_FN_CPU_ON, KVM_PSCI_FN_CPU_ON)
> +MISMATCH_CHECK(PSCI_FN_MIGRATE, KVM_PSCI_FN_MIGRATE)
> +
> #undef MISMATCH_CHECK
>
> #endif
> --
> 1.7.9.5
>
These are the defines specifially chosen for the KVM implementation of
PSCI 0.1 right? I wonder if we should name them as such, but then it
conflicts with the actual KVM defines I guess. Also, perhaps unrelated,
I guess it makes sense to reuse this base and these function IDs if we
add PSCI support to QEMU itself for TCG. Hmmm.
-Christoffer
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform Peter Maydell
@ 2013-11-22 18:11 ` Christoffer Dall
2013-11-22 18:17 ` Peter Maydell
0 siblings, 1 reply; 23+ messages in thread
From: Christoffer Dall @ 2013-11-22 18:11 UTC (permalink / raw)
To: Peter Maydell; +Cc: patches, qemu-devel, kvmarm
On Fri, Nov 22, 2013 at 05:17:14PM +0000, Peter Maydell wrote:
> Add 'virt' platform support corresponding to arch/arm/mach-virt
> in the Linux kernel tree. This has no platform-specific code but
> can use any device whose kernel driver is is able to work purely
> from a device tree node. We use this to instantiate a minimal
> set of devices: a GIC and some virtio-mmio transports.
>
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> [PMM:
> Significantly overhauled:
> * renamed user-facing machine to just "virt"
> * removed the A9 support (it can't work since the A9 has no
> generic timers)
> * added virtio-mmio transports instead of random set of 'soc' devices
> (though we retain a pl011 UART)
> * instead of updating io_base as we step through adding devices,
> define a memory map with an array (similar to vexpress)
> * similarly, define irqmap with an array
> * folded in some minor fixes from John's aarch64-support patch
> * rather than explicitly doing endian-swapping on FDT cells,
> use fdt APIs that let us just pass in host-endian values
> and let the fdt layer take care of the swapping
> * miscellaneous minor code cleanups and style fixes
> ]
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> hw/arm/Makefile.objs | 2 +-
> hw/arm/virt.c | 444 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 445 insertions(+), 1 deletion(-)
> create mode 100644 hw/arm/virt.c
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 3671b42..78b5614 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -1,7 +1,7 @@
> obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
> obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
> obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
> -obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
> +obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
>
> obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
> obj-y += omap1.o omap2.o strongarm.o
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> new file mode 100644
> index 0000000..1e42cc2
> --- /dev/null
> +++ b/hw/arm/virt.c
> @@ -0,0 +1,444 @@
> +/*
> + * ARM mach-virt emulation
> + *
> + * Copyright (c) 2013 Linaro Limited
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Emulate a virtual board which works by passing Linux all the information
> + * it needs about what devices are present via the device tree.
> + * There are some restrictions about what we can do here:
> + * + we can only present devices whose Linux drivers will work based
> + * purely on the device tree with no platform data at all
> + * + we want to present a very stripped-down minimalist platform,
> + * both because this reduces the security attack surface from the guest
> + * and also because it reduces our exposure to being broken when
> + * the kernel updates its device tree bindings and requires further
> + * information in a device binding that we aren't providing.
> + * This is essentially the same approach kvmtool uses.
nit: questionable value of this last line in the comment.
> + */
> +
> +#include "hw/sysbus.h"
> +#include "hw/arm/arm.h"
> +#include "hw/arm/primecell.h"
> +#include "hw/devices.h"
> +#include "net/net.h"
> +#include "sysemu/device_tree.h"
> +#include "sysemu/sysemu.h"
> +#include "sysemu/kvm.h"
> +#include "hw/boards.h"
> +#include "exec/address-spaces.h"
> +#include "qemu/bitops.h"
> +#include "qemu/error-report.h"
> +
> +#define NUM_VIRTIO_TRANSPORTS 32
> +
> +/* Number of external interrupt lines to configure the GIC with */
> +#define NUM_IRQS 128
> +
> +#define GIC_FDT_IRQ_TYPE_SPI 0
> +#define GIC_FDT_IRQ_TYPE_PPI 1
> +
> +#define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1
> +#define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2
> +#define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4
> +#define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8
> +
> +#define GIC_FDT_IRQ_PPI_CPU_START 8
> +#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
> +
> +enum {
> + VIRT_FLASH,
> + VIRT_MEM,
> + VIRT_CPUPERIPHS,
> + VIRT_GIC_DIST,
> + VIRT_GIC_CPU,
> + VIRT_UART,
> + VIRT_MMIO,
> +};
> +
> +typedef struct MemMapEntry {
> + hwaddr base;
> + hwaddr size;
> +} MemMapEntry;
> +
> +typedef struct VirtBoardInfo {
> + struct arm_boot_info bootinfo;
> + const char *cpu_model;
> + const char *qdevname;
> + const char *gic_compatible;
> + const MemMapEntry *memmap;
> + const int *irqmap;
> + int smp_cpus;
> + void *fdt;
> + int fdt_size;
> + uint32_t clock_phandle;
> +} VirtBoardInfo;
> +
> +/* Addresses and sizes of our components.
> + * 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
> + * 128MB..256MB is used for miscellaneous device I/O.
> + * 256MB..1GB is reserved for possible future PCI support (ie where the
> + * PCI memory window will go if we add a PCI host controller).
> + * 1GB and up is RAM (which may happily spill over into the
> + * high memory region beyond 4GB).
> + * This represents a compromise between how much RAM can be given to
> + * a 32 bit VM and leaving space for expansion and in particular for PCI.
> + */
> +static const MemMapEntry a15memmap[] = {
> + /* Space up to 0x8000000 is reserved for a boot ROM */
> + [VIRT_FLASH] = { 0, 0x8000000 },
> + [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 },
> + /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
> + [VIRT_GIC_DIST] = { 0x8001000, 0x1000 },
> + [VIRT_GIC_CPU] = { 0x8002000, 0x1000 },
> + [VIRT_UART] = { 0x9000000, 0x1000 },
> + [VIRT_MMIO] = { 0xa000000, 0x200 },
> + /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
> + /* 0x10000000 .. 0x40000000 reserved for PCI */
> + [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
> +};
> +
> +static const int a15irqmap[] = {
> + [VIRT_UART] = 1,
> + [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
> +};
> +
> +static VirtBoardInfo machines[] = {
> + {
> + .cpu_model = "cortex-a15",
> + .qdevname = "a15mpcore_priv",
> + .gic_compatible = "arm,cortex-a15-gic",
> + .memmap = a15memmap,
> + .irqmap = a15irqmap,
> + },
> +};
> +
> +static VirtBoardInfo *find_machine_info(const char *cpu)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(machines); i++) {
> + if (strcmp(cpu, machines[i].cpu_model) == 0) {
> + return &machines[i];
> + }
> + }
> + return NULL;
> +}
> +
> +static void create_fdt(VirtBoardInfo *vbi)
> +{
> + void *fdt = create_device_tree(&vbi->fdt_size);
> +
> + if (!fdt) {
> + error_report("create_device_tree() failed");
> + exit(1);
> + }
> +
> + vbi->fdt = fdt;
> +
> + /* Header */
> + qemu_devtree_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
> + qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 0x2);
> + qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 0x2);
> +
> + /*
> + * /chosen and /memory nodes must exist for load_dtb
> + * to fill in necessary properties later
> + */
> + qemu_devtree_add_subnode(fdt, "/chosen");
> + qemu_devtree_add_subnode(fdt, "/memory");
> + qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
> +
> + /* Clock node, for the benefit of the UART. The kernel device tree
> + * binding documentation claims the PL011 node clock properties are
> + * optional but in practice if you omit them the kernel refuses to
> + * probe for the device.
> + */
> + vbi->clock_phandle = qemu_devtree_alloc_phandle(fdt);
> + qemu_devtree_add_subnode(fdt, "/apb-pclk");
> + qemu_devtree_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
> + qemu_devtree_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
> + qemu_devtree_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
> + qemu_devtree_setprop_string(fdt, "/apb-pclk", "clock-output-names",
> + "clk24mhz");
> + qemu_devtree_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
> +
> + /* No PSCI for TCG yet */
> + if (kvm_enabled()) {
> + qemu_devtree_add_subnode(fdt, "/psci");
> + qemu_devtree_setprop_string(fdt, "/psci", "compatible", "arm,psci");
> + qemu_devtree_setprop_string(fdt, "/psci", "method", "hvc");
> + qemu_devtree_setprop_cell(fdt, "/psci", "cpu_suspend",
> + PSCI_FN_CPU_SUSPEND);
> + qemu_devtree_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
> + qemu_devtree_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
> + qemu_devtree_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
> + }
> +}
> +
> +static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
> +{
> + /* Note that on A15 h/w these interrupts are level-triggered,
> + * but for the GIC implementation provided by both QEMU and KVM
> + * they are edge-triggered.
> + */
> + uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
> +
> + irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
> + GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
> +
> + qemu_devtree_add_subnode(vbi->fdt, "/timer");
> + qemu_devtree_setprop_string(vbi->fdt, "/timer",
> + "compatible", "arm,armv7-timer");
> + qemu_devtree_setprop_cells(vbi->fdt, "/timer", "interrupts",
> + GIC_FDT_IRQ_TYPE_PPI, 13, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, 14, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, 11, irqflags,
> + GIC_FDT_IRQ_TYPE_PPI, 10, irqflags);
> +}
> +
> +static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
> +{
> + int cpu;
> +
> + qemu_devtree_add_subnode(vbi->fdt, "/cpus");
> + qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
> + qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
> +
> + for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
> + char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
> + ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
> +
> + qemu_devtree_add_subnode(vbi->fdt, nodename);
> + qemu_devtree_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
> + qemu_devtree_setprop_string(vbi->fdt, nodename, "compatible",
> + armcpu->dtb_compatible);
> +
> + if (vbi->smp_cpus > 1) {
> + qemu_devtree_setprop_string(vbi->fdt, nodename,
> + "enable-method", "psci");
> + }
> +
> + qemu_devtree_setprop_cell(vbi->fdt, nodename, "reg", cpu);
> + g_free(nodename);
> + }
> +}
> +
> +static void fdt_add_gic_node(const VirtBoardInfo *vbi)
> +{
> + uint32_t gic_phandle;
> +
> + gic_phandle = qemu_devtree_alloc_phandle(vbi->fdt);
> + qemu_devtree_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
> +
> + qemu_devtree_add_subnode(vbi->fdt, "/intc");
> + qemu_devtree_setprop_string(vbi->fdt, "/intc", "compatible",
> + vbi->gic_compatible);
> + qemu_devtree_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
> + qemu_devtree_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
> + qemu_devtree_setprop_sized_cells(vbi->fdt, "/intc", "reg",
> + 2, vbi->memmap[VIRT_GIC_DIST].base,
> + 2, vbi->memmap[VIRT_GIC_DIST].size,
> + 2, vbi->memmap[VIRT_GIC_CPU].base,
> + 2, vbi->memmap[VIRT_GIC_CPU].size);
> + qemu_devtree_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
> +}
> +
> +static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
> +{
> + char *nodename;
> + hwaddr base = vbi->memmap[VIRT_UART].base;
> + hwaddr size = vbi->memmap[VIRT_UART].size;
> + int irq = vbi->irqmap[VIRT_UART];
> + const char compat[] = "arm,pl011\0arm,primecell";
> + const char clocknames[] = "uartclk\0apb_pclk";
> +
> + sysbus_create_simple("pl011", base, pic[irq]);
> +
> + nodename = g_strdup_printf("/pl011@%" PRIx64, base);
> + qemu_devtree_add_subnode(vbi->fdt, nodename);
> + /* Note that we can't use setprop_string because of the embedded NUL */
> + qemu_devtree_setprop(vbi->fdt, nodename, "compatible",
> + compat, sizeof(compat));
> + qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
> + 2, base, 2, size);
> + qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
> + GIC_FDT_IRQ_TYPE_SPI, irq,
> + GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
> + qemu_devtree_setprop_cells(vbi->fdt, nodename, "clocks",
> + vbi->clock_phandle, vbi->clock_phandle);
> + qemu_devtree_setprop(vbi->fdt, nodename, "clock-names",
> + clocknames, sizeof(clocknames));
> + g_free(nodename);
> +}
> +
> +static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
> +{
> + int i;
> + hwaddr size = vbi->memmap[VIRT_MMIO].size;
> +
> + /* Note that we have to create the transports in forwards order
> + * so that command line devices are inserted lowest address first,
> + * and then add dtb nodes in reverse order so that they appear in
> + * the finished device tree lowest address first.
> + */
> + for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
> + int irq = vbi->irqmap[VIRT_MMIO] + i;
> + hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
> +
> + sysbus_create_simple("virtio-mmio", base, pic[irq]);
> + }
> +
> + for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
> + char *nodename;
> + int irq = vbi->irqmap[VIRT_MMIO] + i;
> + hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
> +
> + nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
> + qemu_devtree_add_subnode(vbi->fdt, nodename);
> + qemu_devtree_setprop_string(vbi->fdt, nodename,
> + "compatible", "virtio,mmio");
> + qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
> + 2, base, 2, size);
> + qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
> + GIC_FDT_IRQ_TYPE_SPI, irq,
> + GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
> + g_free(nodename);
> + }
> +}
> +
> +static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
> +{
> + const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
> +
> + *fdt_size = board->fdt_size;
> + return board->fdt;
> +}
> +
> +static void machvirt_init(QEMUMachineInitArgs *args)
> +{
> + qemu_irq pic[NUM_IRQS];
> + MemoryRegion *sysmem = get_system_memory();
> + int n;
> + MemoryRegion *ram = g_new(MemoryRegion, 1);
> + DeviceState *dev;
> + SysBusDevice *busdev;
> + const char *cpu_model = args->cpu_model;
> + VirtBoardInfo *vbi;
> +
> + if (!cpu_model) {
> + cpu_model = "cortex-a15";
> + }
> +
> + vbi = find_machine_info(cpu_model);
> +
> + if (!vbi) {
> + error_report("mach-virt: CPU %s not supported", cpu_model);
> + exit(1);
> + }
> +
> + vbi->smp_cpus = smp_cpus;
> +
> + /*
> + * Only supported method of starting secondary CPUs is PSCI and
> + * PSCI is not yet supported with TCG, so limit smp_cpus to 1
> + * if we're not using KVM.
> + */
> + if (!kvm_enabled() && smp_cpus > 1) {
> + error_report("mach-virt: must enable KVM to use multiple CPUs");
> + exit(1);
> + }
> +
> + if (args->ram_size > vbi->memmap[VIRT_MEM].size) {
> + error_report("mach-virt: cannot model more than 30GB RAM");
> + exit(1);
> + }
> +
> + create_fdt(vbi);
> + fdt_add_timer_nodes(vbi);
> +
> + for (n = 0; n < smp_cpus; n++) {
> + ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
> + Object *cpuobj;
> +
> + if (!oc) {
> + fprintf(stderr, "Unable to find CPU definition\n");
> + exit(1);
> + }
> + cpuobj = object_new(object_class_get_name(oc));
> +
> + /* Secondary CPUs start in PSCI powered-down state */
> + if (n > 0) {
> + object_property_set_bool(cpuobj, true, "start-powered-off", NULL);
> + }
> + object_property_set_bool(cpuobj, true, "realized", NULL);
> + }
> + fdt_add_cpu_nodes(vbi);
> +
> + memory_region_init_ram(ram, NULL, "mach-virt.ram", args->ram_size);
> + vmstate_register_ram_global(ram);
> + memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
> +
> + dev = qdev_create(NULL, vbi->qdevname);
> + qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
> + /* Note that the num-irq property counts both internal and external
> + * interrupts; there are always 32 of the former (mandated by GIC spec).
> + */
> + qdev_prop_set_uint32(dev, "num-irq", NUM_IRQS + 32);
> + qdev_init_nofail(dev);
> + busdev = SYS_BUS_DEVICE(dev);
> + sysbus_mmio_map(busdev, 0, vbi->memmap[VIRT_CPUPERIPHS].base);
> + fdt_add_gic_node(vbi);
> + for (n = 0; n < smp_cpus; n++) {
> + DeviceState *cpudev = DEVICE(qemu_get_cpu(n));
> +
> + sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
> + }
> +
> + for (n = 0; n < NUM_IRQS; n++) {
> + pic[n] = qdev_get_gpio_in(dev, n);
> + }
> +
> + create_uart(vbi, pic);
> +
> + /* Create mmio transports, so the user can create virtio backends
> + * (which will be automatically plugged in to the transports). If
> + * no backend is created the transport will just sit harmlessly idle.
> + */
> + create_virtio_devices(vbi, pic);
> +
> + vbi->bootinfo.ram_size = args->ram_size;
> + vbi->bootinfo.kernel_filename = args->kernel_filename;
> + vbi->bootinfo.kernel_cmdline = args->kernel_cmdline;
> + vbi->bootinfo.initrd_filename = args->initrd_filename;
> + vbi->bootinfo.nb_cpus = smp_cpus;
> + vbi->bootinfo.board_id = -1;
board_id = -1 ?
> + vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;
> + vbi->bootinfo.get_dtb = machvirt_dtb;
> + arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
> +}
> +
> +static QEMUMachine machvirt_a15_machine = {
> + .name = "virt",
> + .desc = "ARM Virtual Machine",
> + .init = machvirt_init,
> + .max_cpus = 4,
> +};
> +
> +static void machvirt_machine_init(void)
> +{
> + qemu_register_machine(&machvirt_a15_machine);
> +}
> +
> +machine_init(machvirt_machine_init);
> --
> 1.7.9.5
>
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform
2013-11-22 18:11 ` Christoffer Dall
@ 2013-11-22 18:17 ` Peter Maydell
2013-11-22 18:24 ` Christoffer Dall
0 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 18:17 UTC (permalink / raw)
To: Christoffer Dall
Cc: Patch Tracking, QEMU Developers, kvmarm@lists.cs.columbia.edu
On 22 November 2013 18:11, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> On Fri, Nov 22, 2013 at 05:17:14PM +0000, Peter Maydell wrote:
>> + * Emulate a virtual board which works by passing Linux all the information
>> + * it needs about what devices are present via the device tree.
>> + * There are some restrictions about what we can do here:
>> + * + we can only present devices whose Linux drivers will work based
>> + * purely on the device tree with no platform data at all
>> + * + we want to present a very stripped-down minimalist platform,
>> + * both because this reduces the security attack surface from the guest
>> + * and also because it reduces our exposure to being broken when
>> + * the kernel updates its device tree bindings and requires further
>> + * information in a device binding that we aren't providing.
>> + * This is essentially the same approach kvmtool uses.
>
> nit: questionable value of this last line in the comment.
Well, it says we're not doing something completely bonkers
of our own devising ;-)
> + vbi->bootinfo.board_id = -1;
>
> board_id = -1 ?
This is what the kernel's boot protocol says you should
pass as the board ID register for boards which are new
enough that they only support booting via device tree
and not the old-style board ID number system.
-- PMM
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform
2013-11-22 18:17 ` Peter Maydell
@ 2013-11-22 18:24 ` Christoffer Dall
0 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2013-11-22 18:24 UTC (permalink / raw)
To: Peter Maydell
Cc: Patch Tracking, QEMU Developers, kvmarm@lists.cs.columbia.edu
On Fri, Nov 22, 2013 at 06:17:51PM +0000, Peter Maydell wrote:
> On 22 November 2013 18:11, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> > On Fri, Nov 22, 2013 at 05:17:14PM +0000, Peter Maydell wrote:
> >> + * Emulate a virtual board which works by passing Linux all the information
> >> + * it needs about what devices are present via the device tree.
> >> + * There are some restrictions about what we can do here:
> >> + * + we can only present devices whose Linux drivers will work based
> >> + * purely on the device tree with no platform data at all
> >> + * + we want to present a very stripped-down minimalist platform,
> >> + * both because this reduces the security attack surface from the guest
> >> + * and also because it reduces our exposure to being broken when
> >> + * the kernel updates its device tree bindings and requires further
> >> + * information in a device binding that we aren't providing.
> >> + * This is essentially the same approach kvmtool uses.
> >
> > nit: questionable value of this last line in the comment.
>
> Well, it says we're not doing something completely bonkers
> of our own devising ;-)
>
;)
> > + vbi->bootinfo.board_id = -1;
> >
> > board_id = -1 ?
>
> This is what the kernel's boot protocol says you should
> pass as the board ID register for boards which are new
> enough that they only support booting via device tree
> and not the old-style board ID number system.
>
ok, thanks.
-Christoffer
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM Peter Maydell
@ 2013-11-22 18:25 ` Christoffer Dall
2013-11-22 18:50 ` Peter Maydell
0 siblings, 1 reply; 23+ messages in thread
From: Christoffer Dall @ 2013-11-22 18:25 UTC (permalink / raw)
To: Peter Maydell; +Cc: patches, qemu-devel, kvmarm
On Fri, Nov 22, 2013 at 05:17:17PM +0000, Peter Maydell wrote:
> Implement '-cpu host' for ARM when we're using KVM, broadly
> in line with other KVM-supporting architectures.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> target-arm/helper.c | 6 ++
> target-arm/kvm.c | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++
> target-arm/kvm_arm.h | 55 +++++++++++++
> 3 files changed, 285 insertions(+)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 3445813..263dbbf 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1842,6 +1842,12 @@ void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
> (*cpu_fprintf)(f, "Available CPUs:\n");
> g_slist_foreach(list, arm_cpu_list_entry, &s);
> g_slist_free(list);
> +#ifdef CONFIG_KVM
> + /* The 'host' CPU type is dynamically registered only if KVM is
> + * enabled, so we have to special-case it here:
> + */
> + (*cpu_fprintf)(f, " host (only available in KVM mode)\n");
> +#endif
> }
>
> static void arm_cpu_add_definition(gpointer data, gpointer user_data)
> diff --git a/target-arm/kvm.c b/target-arm/kvm.c
> index 182db85..f865dac 100644
> --- a/target-arm/kvm.c
> +++ b/target-arm/kvm.c
> @@ -27,12 +27,236 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
> KVM_CAP_LAST_INFO
> };
>
> +bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
> + int *fdarray,
> + struct kvm_vcpu_init *init)
> +{
> + int ret, kvmfd = -1, vmfd = -1, cpufd = -1;
> +
> + kvmfd = qemu_open("/dev/kvm", O_RDWR);
> + if (kvmfd < 0) {
> + goto err;
> + }
> + vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
> + if (vmfd < 0) {
> + goto err;
> + }
> + cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
> + if (cpufd < 0) {
> + goto err;
> + }
> +
> + ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init);
> + if (ret >= 0) {
> + ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
> + if (ret < 0) {
> + goto err;
> + }
> + } else {
> + /* Old kernel which doesn't know about the
> + * PREFERRED_TARGET ioctl: we know it will only support
> + * creating one kind of guest CPU which is its preferred
> + * CPU type.
> + */
> + while (*cpus_to_try != QEMU_KVM_ARM_TARGET_NONE) {
> + init->target = *cpus_to_try++;
> + memset(init->features, 0, sizeof(init->features));
> + ret = ioctl(cpufd, KVM_ARM_VCPU_INIT, init);
> + if (ret >= 0) {
> + break;
> + }
> + }
> + if (ret < 0) {
> + goto err;
> + }
> + }
> +
> + fdarray[0] = kvmfd;
> + fdarray[1] = vmfd;
> + fdarray[2] = cpufd;
you could consider using a define/enum/struct for this instead of an
array, but bah, not important.
> +
> + return true;
> +
> +err:
> + if (cpufd >= 0) {
> + close(cpufd);
> + }
> + if (vmfd >= 0) {
> + close(vmfd);
> + }
> + if (kvmfd >= 0) {
> + close(kvmfd);
> + }
> +
> + return false;
> +}
> +
> +void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
> +{
> + int i;
> +
> + for (i = 2; i >= 0; i--) {
> + close(fdarray[i]);
> + }
> +}
> +
> +static inline void set_feature(uint64_t *features, int feature)
> +{
> + *features |= 1ULL << feature;
> +}
> +
> +bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
> +{
> + /* Identify the feature bits corresponding to the host CPU, and
> + * fill out the ARMHostCPUClass fields accordingly. To do this
> + * we have to create a scratch VM, create a single CPU inside it,
> + * and then query that CPU for the relevant ID registers.
> + */
> + int i, ret, fdarray[3];
> + uint32_t midr, id_pfr0, id_isar0, mvfr1;
> + uint64_t features = 0;
> + /* Old kernels may not know about the PREFERRED_TARGET ioctl: however
> + * we know these will only support creating one kind of guest CPU,
> + * which is its preferred CPU type.
> + */
> + static const uint32_t cpus_to_try[] = {
> + QEMU_KVM_ARM_TARGET_CORTEX_A15,
> + QEMU_KVM_ARM_TARGET_NONE
> + };
> + struct kvm_vcpu_init init;
> + struct kvm_one_reg idregs[] = {
> + {
> + .id = KVM_REG_ARM | KVM_REG_SIZE_U32
> + | ENCODE_CP_REG(15, 0, 0, 0, 0, 0),
> + .addr = (uintptr_t)&midr,
> + },
> + {
> + .id = KVM_REG_ARM | KVM_REG_SIZE_U32
> + | ENCODE_CP_REG(15, 0, 0, 1, 0, 0),
> + .addr = (uintptr_t)&id_pfr0,
> + },
> + {
> + .id = KVM_REG_ARM | KVM_REG_SIZE_U32
> + | ENCODE_CP_REG(15, 0, 0, 2, 0, 0),
> + .addr = (uintptr_t)&id_isar0,
> + },
> + {
> + .id = KVM_REG_ARM | KVM_REG_SIZE_U32
> + | KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
> + .addr = (uintptr_t)&mvfr1,
> + },
> + };
> +
> + if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) {
> + return false;
> + }
> +
> + ahcc->target = init.target;
> +
> + /* This is not strictly blessed by the device tree binding docs yet,
> + * but in practice the kernel does not care about this string so
> + * there is no point maintaining an KVM_ARM_TARGET_* -> string table.
> + */
> + ahcc->dtb_compatible = "arm,arm-v7";
> +
> + for (i = 0; i < ARRAY_SIZE(idregs); i++) {
> + ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
> + if (ret) {
> + break;
> + }
> + }
> +
> + kvm_arm_destroy_scratch_host_vcpu(fdarray);
> +
> + if (ret) {
> + return false;
> + }
> +
> + /* Now we've retrieved all the register information we can
> + * set the feature bits based on the ID register fields.
> + * We can assume any KVM supporting CPU is at least a v7
> + * with VFPv3, LPAE and the generic timers; this in turn implies
> + * most of the other feature bits, but a few must be tested.
> + */
> + set_feature(&features, ARM_FEATURE_V7);
> + set_feature(&features, ARM_FEATURE_VFP3);
> + set_feature(&features, ARM_FEATURE_LPAE);
> + set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
> +
> + switch (extract32(id_isar0, 24, 4)) {
> + case 1:
> + set_feature(&features, ARM_FEATURE_THUMB_DIV);
> + break;
> + case 2:
> + set_feature(&features, ARM_FEATURE_ARM_DIV);
> + set_feature(&features, ARM_FEATURE_THUMB_DIV);
> + break;
> + default:
> + break;
> + }
> +
> + if (extract32(id_pfr0, 12, 4) == 1) {
> + set_feature(&features, ARM_FEATURE_THUMB2EE);
> + }
> + if (extract32(mvfr1, 20, 4) == 1) {
> + set_feature(&features, ARM_FEATURE_VFP_FP16);
> + }
> + if (extract32(mvfr1, 12, 4) == 1) {
> + set_feature(&features, ARM_FEATURE_NEON);
> + }
> + if (extract32(mvfr1, 28, 4) == 1) {
> + /* FMAC support implies VFPv4 */
> + set_feature(&features, ARM_FEATURE_VFP4);
> + }
> +
> + ahcc->features = features;
> +
> + return true;
> +}
> +
> +static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
> +{
> + ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
> +
> + /* All we really need to set up for the 'host' CPU
> + * is the feature bits -- we rely on the fact that the
> + * various ID register values in ARMCPU are only used for
> + * TCG CPUs.
> + */
> + if (!kvm_arm_get_host_cpu_features(ahcc)) {
> + fprintf(stderr, "Failed to retrieve host CPU features!\n");
> + abort();
> + }
> +}
> +
> +static void kvm_arm_host_cpu_initfn(Object *obj)
> +{
> + ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
> + ARMCPU *cpu = ARM_CPU(obj);
> + CPUARMState *env = &cpu->env;
> +
> + cpu->kvm_target = ahcc->target;
> + cpu->dtb_compatible = ahcc->dtb_compatible;
> + env->features = ahcc->features;
> +}
> +
> +static const TypeInfo host_arm_cpu_type_info = {
> + .name = TYPE_ARM_HOST_CPU,
> + .parent = TYPE_ARM_CPU,
> + .instance_init = kvm_arm_host_cpu_initfn,
> + .class_init = kvm_arm_host_cpu_class_init,
> + .class_size = sizeof(ARMHostCPUClass),
> +};
> +
> int kvm_arch_init(KVMState *s)
> {
> /* For ARM interrupt delivery is always asynchronous,
> * whether we are using an in-kernel VGIC or not.
> */
> kvm_async_interrupts_allowed = true;
> +
> + type_register_static(&host_arm_cpu_type_info);
> +
> return 0;
> }
>
> diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
> index 5d14887..cd3d13c 100644
> --- a/target-arm/kvm_arm.h
> +++ b/target-arm/kvm_arm.h
> @@ -62,4 +62,59 @@ bool write_list_to_kvmstate(ARMCPU *cpu);
> */
> bool write_kvmstate_to_list(ARMCPU *cpu);
>
> +#ifdef CONFIG_KVM
> +/**
> + * kvm_arm_create_scratch_host_vcpu:
> + * @cpus_to_try: array of QEMU_KVM_ARM_TARGET_* values (terminated with
> + * QEMU_KVM_ARM_TARGET_NONE) to try as fallback if the kernel does not
> + * know the PREFERRED_TARGET ioctl
> + * @fdarray: filled in with kvmfd, vmfd, cpufd file descriptors in that order
> + * @init: filled in with the necessary values for creating a host vcpu
> + *
> + * Create a scratch vcpu in its own VM of the type preferred by the host
> + * kernel (as would be used for '-cpu host'), for purposes of probing it
> + * for capabilities.
> + *
> + * Returns: true on success (and fdarray and init are filled in),
> + * false on failure (and fdarray and init are not valid).
> + */
> +bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
> + int *fdarray,
> + struct kvm_vcpu_init *init);
why do we need to export this at all?
> +
> +/**
> + * kvm_arm_destroy_scratch_host_vcpu:
> + * @fdarray: array of fds as set up by kvm_arm_create_scratch_host_vcpu
> + *
> + * Tear down the scratch vcpu created by kvm_arm_create_scratch_host_vcpu.
> + */
> +void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
> +
> +#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
> +#define ARM_HOST_CPU_CLASS(klass) \
> + OBJECT_CLASS_CHECK(ARMHostCPUClass, (klass), TYPE_ARM_HOST_CPU)
> +#define ARM_HOST_CPU_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(ARMHostCPUClass, (obj), TYPE_ARM_HOST_CPU)
> +
> +typedef struct ARMHostCPUClass {
> + /*< private >*/
> + ARMCPUClass parent_class;
> + /*< public >*/
> +
> + uint64_t features;
> + uint32_t target;
> + const char *dtb_compatible;
> +} ARMHostCPUClass;
> +
> +/**
> + * kvm_arm_get_host_cpu_features:
> + * @ahcc: ARMHostCPUClass to fill in
> + *
> + * Probe the capabilities of the host kernel's preferred CPU and fill
> + * in the ARMHostCPUClass struct accordingly.
> + */
> +bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc);
> +
> +#endif
> +
> #endif
> --
> 1.7.9.5
>
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (10 preceding siblings ...)
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 11/11] hw/arm/virt: Support -cpu host Peter Maydell
@ 2013-11-22 18:26 ` Christoffer Dall
2013-12-02 13:46 ` Peter Maydell
12 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2013-11-22 18:26 UTC (permalink / raw)
To: Peter Maydell; +Cc: patches, qemu-devel, kvmarm
On Fri, Nov 22, 2013 at 05:17:07PM +0000, Peter Maydell wrote:
> This patchset combines the 'virt' machine definition and
> -cpu host support patchsets I've posted previous versions
> of. I think these are now ready to go in once 1.8 opens
> up; review appreciated.
>
> Changes since previous versions:
> * added in -cpu host patchset, since it really only makes
> sense with mach-virt
> * rearranged virt address space a bit to allow space
> for a reasonable sized boot flash device and possible
> PCI window if a PCI controller model ever becomes possible
> * fixed bug where we weren't starting secondary CPUs in
> "PSCI power-down" state (by adding a CPU property which
> lets the board specify that the CPU starts powered down)
> [thanks to Giridhar Maruthy for tracking this down]
> * includes a KVM header update against current mainline
> * includes (previously RFC'd) patch which provides defines
> of some kernel KVM constants we can use even if not CONFIG_KVM
> * put the KVM CPU type into the CPU object rather than having
> a silly 'QOM object type => constant' lookup table
> * put dtb 'compatible' string into CPU object rather than
> having the board model need to know about it
> * abstracted out the "create a scratch vcpu for querying
> for capabilities" code; this is currently only called in
> one place, but the abstraction will be needed for 64 bit
> KVM ARM support
>
> Mostly this is cleanup and streamlining which I noticed
> was either possible or necessary in the course of putting
> 64 bit KVM ARM control on top of this patchset.
>
>
> The kernel patch to get the PL011 to work is still needed
> (Christoffer tells me he's working on getting a proper fix
> done for this):
>
I tell myself that too...
Anyway, looked over the series and it looks good to me.
So except for some of the QOM that I can't really wrap around my brain
yet:
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM
2013-11-22 18:25 ` Christoffer Dall
@ 2013-11-22 18:50 ` Peter Maydell
2013-11-22 19:00 ` Christoffer Dall
0 siblings, 1 reply; 23+ messages in thread
From: Peter Maydell @ 2013-11-22 18:50 UTC (permalink / raw)
To: Christoffer Dall
Cc: Patch Tracking, QEMU Developers, kvmarm@lists.cs.columbia.edu
On 22 November 2013 18:25, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> On Fri, Nov 22, 2013 at 05:17:17PM +0000, Peter Maydell wrote:
>> +bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
>> + int *fdarray,
>> + struct kvm_vcpu_init *init);
>
> why do we need to export this at all?
For 64 bit KVM support the 32 bit code moves into kvm32.c
and then we have two users of this function, one in
kvm32.c and one in kvm64.c. It seemed easiest to just
make the function public with the proper doc comment
from the start, rather than starting it private and
then having a patch which makes it public.
thanks
-- PMM
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM
2013-11-22 18:50 ` Peter Maydell
@ 2013-11-22 19:00 ` Christoffer Dall
0 siblings, 0 replies; 23+ messages in thread
From: Christoffer Dall @ 2013-11-22 19:00 UTC (permalink / raw)
To: Peter Maydell
Cc: Patch Tracking, QEMU Developers, kvmarm@lists.cs.columbia.edu
On Fri, Nov 22, 2013 at 06:50:47PM +0000, Peter Maydell wrote:
> On 22 November 2013 18:25, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> > On Fri, Nov 22, 2013 at 05:17:17PM +0000, Peter Maydell wrote:
> >> +bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
> >> + int *fdarray,
> >> + struct kvm_vcpu_init *init);
> >
> > why do we need to export this at all?
>
> For 64 bit KVM support the 32 bit code moves into kvm32.c
> and then we have two users of this function, one in
> kvm32.c and one in kvm64.c. It seemed easiest to just
> make the function public with the proper doc comment
> from the start, rather than starting it private and
> then having a patch which makes it public.
>
Yes, that does make sense.
Thanks.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 02/11] device_tree.c: Terminate the empty reservemap in create_device_tree()
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 02/11] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
@ 2013-11-24 8:04 ` Peter Crosthwaite
0 siblings, 0 replies; 23+ messages in thread
From: Peter Crosthwaite @ 2013-11-24 8:04 UTC (permalink / raw)
To: Peter Maydell; +Cc: patches, qemu-devel@nongnu.org Developers, kvmarm
On Sat, Nov 23, 2013 at 3:17 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Device trees created with create_device_tree() may not have any
> entries in their reservemap, because the FDT API requires that the
> reservemap is completed before any FDT nodes are added, and
> create_device_tree() itself creates a node. However we were not
> calling fdt_finish_reservemap(), which meant that there was no
> terminator in the reservemap list and whatever happened to be at the
> start of the FDT data section would end up being interpreted as
> reservemap entries. Avoid this by calling fdt_finish_reservemap()
> to add the terminator.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Acked-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> ---
> device_tree.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/device_tree.c b/device_tree.c
> index ffec99a..391da8c 100644
> --- a/device_tree.c
> +++ b/device_tree.c
> @@ -41,6 +41,10 @@ void *create_device_tree(int *sizep)
> if (ret < 0) {
> goto fail;
> }
> + ret = fdt_finish_reservemap(fdt);
> + if (ret < 0) {
> + goto fail;
> + }
> ret = fdt_begin_node(fdt, "");
> if (ret < 0) {
> goto fail;
> --
> 1.7.9.5
>
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 08/11] linux-headers: Update from mainline
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 08/11] linux-headers: Update from mainline Peter Maydell
@ 2013-12-02 13:35 ` Peter Maydell
0 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-12-02 13:35 UTC (permalink / raw)
To: QEMU Developers
Cc: Paolo Bonzini, kvmarm@lists.cs.columbia.edu, Patch Tracking
On 22 November 2013 17:17, Peter Maydell <peter.maydell@linaro.org> wrote:
> Update Linux KVM headers from mainline commit 5d6e63323fe779.
Accidentally missed the leading char off the commit hash,
it should be: a5d6e63323fe779. Will fix commit message when
I queue these on target-arm.next.
thanks
-- PMM
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
` (11 preceding siblings ...)
2013-11-22 18:26 ` [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Christoffer Dall
@ 2013-12-02 13:46 ` Peter Maydell
12 siblings, 0 replies; 23+ messages in thread
From: Peter Maydell @ 2013-12-02 13:46 UTC (permalink / raw)
To: QEMU Developers; +Cc: kvmarm@lists.cs.columbia.edu, Patch Tracking
On 22 November 2013 17:17, Peter Maydell <peter.maydell@linaro.org> wrote:
> This patchset combines the 'virt' machine definition and
> -cpu host support patchsets I've posted previous versions
> of. I think these are now ready to go in once 1.8 opens
> up; review appreciated.
I'm applying this series to target-arm.next (with the typo of
the kernel commit hash in the 'update headers' patch fixed).
thanks!
-- PMM
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2013-12-02 13:46 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-22 17:17 [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 01/11] target-arm: Provide mechanism for getting KVM constants even if not CONFIG_KVM Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 02/11] device_tree.c: Terminate the empty reservemap in create_device_tree() Peter Maydell
2013-11-24 8:04 ` Peter Crosthwaite
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 03/11] hw/arm/boot: Allow boards to provide an fdt blob Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 04/11] target-arm: Provide PSCI constants to generic QEMU code Peter Maydell
2013-11-22 17:52 ` Christoffer Dall
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 05/11] target-arm: Add ARMCPU field for Linux device-tree 'compatible' string Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 06/11] target-arm: Allow secondary KVM CPUs to be booted via PSCI Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 07/11] hw/arm: Add 'virt' platform Peter Maydell
2013-11-22 18:11 ` Christoffer Dall
2013-11-22 18:17 ` Peter Maydell
2013-11-22 18:24 ` Christoffer Dall
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 08/11] linux-headers: Update from mainline Peter Maydell
2013-12-02 13:35 ` Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 09/11] target-arm: Don't hardcode KVM target CPU to be A15 Peter Maydell
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 10/11] target-arm: Provide '-cpu host' when running KVM Peter Maydell
2013-11-22 18:25 ` Christoffer Dall
2013-11-22 18:50 ` Peter Maydell
2013-11-22 19:00 ` Christoffer Dall
2013-11-22 17:17 ` [Qemu-devel] [PATCH v9 11/11] hw/arm/virt: Support -cpu host Peter Maydell
2013-11-22 18:26 ` [Qemu-devel] [PATCH v9 00/11] target-arm: mach virt and -cpu host support Christoffer Dall
2013-12-02 13:46 ` Peter Maydell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).