qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support)
@ 2013-03-05  1:11 Peter Maydell
  2013-03-05  1:11 ` [Qemu-devel] [PATCH 01/13] target-arm: Factor out handling of SRS instruction Peter Maydell
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:11 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Hi; here's a target-arm pullre. Major business here is the KVM
support patchset, though there are a couple of SRS bugfixes too.
Please pull.

thanks
-- PMM

The following changes since commit 26135ead80fa1fd13e95c162dacfd06f2ba82981:

  target-mips: Fix accumulator selection for MIPS16 and microMIPS (2013-03-05 01:02:09 +0100)

are available in the git repository at:

  git://git.linaro.org/people/pmaydell/qemu-arm.git target-arm.next

for you to fetch changes up to ed4659d10fa2ec16ace367e4fffe6f7ced73112c:

  MAINTAINERS: add entry for ARM KVM guest cores (2013-03-05 00:45:43 +0000)

----------------------------------------------------------------
Christoffer Dall (1):
      ARM: KVM: Add support for KVM on ARM architecture

Peter Maydell (12):
      target-arm: Factor out handling of SRS instruction
      target-arm: Don't decode RFE or SRS on M profile cores
      oslib-posix: Align to permit transparent hugepages on ARM Linux
      linux-headers: resync from mainline to add ARM KVM headers
      target-arm: Drop CPUARMState* argument from bank_number()
      ARM KVM: save and load VFP registers from kernel
      hw/arm_gic: Add presave/postload hooks
      hw/arm_gic: Convert ARM GIC classes to use init/realize
      target-arm: Use MemoryListener to identify GIC base address for KVM
      hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC
      configure: Enable KVM on ARM
      MAINTAINERS: add entry for ARM KVM guest cores

 MAINTAINERS                          |    5 +
 configure                            |    2 +-
 hw/a15mpcore.c                       |    8 +-
 hw/arm/Makefile.objs                 |    1 +
 hw/arm_gic.c                         |   23 +-
 hw/arm_gic_common.c                  |   36 ++-
 hw/arm_gic_internal.h                |    4 +-
 hw/arm_pic.c                         |   26 ++
 hw/armv7m_nvic.c                     |   15 +-
 hw/kvm/arm_gic.c                     |  167 ++++++++++++
 linux-headers/asm-arm/kvm.h          |  180 +++++++++++++
 linux-headers/asm-arm/kvm_para.h     |    1 +
 linux-headers/asm-generic/kvm_para.h |    4 +
 linux-headers/linux/kvm.h            |   17 ++
 target-arm/Makefile.objs             |    1 +
 target-arm/cpu.h                     |    1 +
 target-arm/helper.c                  |   13 +-
 target-arm/kvm.c                     |  493 ++++++++++++++++++++++++++++++++++
 target-arm/kvm_arm.h                 |   32 +++
 target-arm/translate.c               |  141 +++++-----
 util/oslib-posix.c                   |    2 +-
 21 files changed, 1064 insertions(+), 108 deletions(-)
 create mode 100644 hw/kvm/arm_gic.c
 create mode 100644 linux-headers/asm-arm/kvm.h
 create mode 100644 linux-headers/asm-arm/kvm_para.h
 create mode 100644 linux-headers/asm-generic/kvm_para.h
 create mode 100644 target-arm/kvm.c
 create mode 100644 target-arm/kvm_arm.h

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 01/13] target-arm: Factor out handling of SRS instruction
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
@ 2013-03-05  1:11 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 02/13] target-arm: Don't decode RFE or SRS on M profile cores Peter Maydell
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:11 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Factor out the handling of the SRS instruction rather than
duplicating it between the Thumb and ARM decoders. This in
passing fixes two bugs in the Thumb decoder's SRS handling
which didn't exist in the ARM decoder:
 * (LP:1079080) storing CPSR rather than SPSR (fixed in the
   ARM decoder in commit c67b6b71 in 2009)
 * failing to free the 'addr' TCG temp in the writeback case

Reported-by: Cesson Vincent <vcesson@stmi.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c |  136 ++++++++++++++++++++++++------------------------
 1 file changed, 69 insertions(+), 67 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index db63c6e..e16c113 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6601,6 +6601,70 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
 }
 #endif
 
+/* gen_srs:
+ * @env: CPUARMState
+ * @s: DisasContext
+ * @mode: mode field from insn (which stack to store to)
+ * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
+ * @writeback: true if writeback bit set
+ *
+ * Generate code for the SRS (Store Return State) insn.
+ */
+static void gen_srs(DisasContext *s,
+                    uint32_t mode, uint32_t amode, bool writeback)
+{
+    int32_t offset;
+    TCGv_i32 addr = tcg_temp_new_i32();
+    TCGv_i32 tmp = tcg_const_i32(mode);
+    gen_helper_get_r13_banked(addr, cpu_env, tmp);
+    tcg_temp_free_i32(tmp);
+    switch (amode) {
+    case 0: /* DA */
+        offset = -4;
+        break;
+    case 1: /* IA */
+        offset = 0;
+        break;
+    case 2: /* DB */
+        offset = -8;
+        break;
+    case 3: /* IB */
+        offset = 4;
+        break;
+    default:
+        abort();
+    }
+    tcg_gen_addi_i32(addr, addr, offset);
+    tmp = load_reg(s, 14);
+    gen_st32(tmp, addr, 0);
+    tmp = load_cpu_field(spsr);
+    tcg_gen_addi_i32(addr, addr, 4);
+    gen_st32(tmp, addr, 0);
+    if (writeback) {
+        switch (amode) {
+        case 0:
+            offset = -8;
+            break;
+        case 1:
+            offset = 4;
+            break;
+        case 2:
+            offset = -4;
+            break;
+        case 3:
+            offset = 0;
+            break;
+        default:
+            abort();
+        }
+        tcg_gen_addi_i32(addr, addr, offset);
+        tmp = tcg_const_i32(mode);
+        gen_helper_set_r13_banked(cpu_env, tmp, addr);
+        tcg_temp_free_i32(tmp);
+    }
+    tcg_temp_free_i32(addr);
+}
+
 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
 {
     unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
@@ -6693,49 +6757,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             }
         } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
             /* srs */
-            int32_t offset;
-            if (IS_USER(s))
+            if (IS_USER(s)) {
                 goto illegal_op;
-            ARCH(6);
-            op1 = (insn & 0x1f);
-            addr = tcg_temp_new_i32();
-            tmp = tcg_const_i32(op1);
-            gen_helper_get_r13_banked(addr, cpu_env, tmp);
-            tcg_temp_free_i32(tmp);
-            i = (insn >> 23) & 3;
-            switch (i) {
-            case 0: offset = -4; break; /* DA */
-            case 1: offset = 0; break; /* IA */
-            case 2: offset = -8; break; /* DB */
-            case 3: offset = 4; break; /* IB */
-            default: abort();
             }
-            if (offset)
-                tcg_gen_addi_i32(addr, addr, offset);
-            tmp = load_reg(s, 14);
-            gen_st32(tmp, addr, 0);
-            tmp = load_cpu_field(spsr);
-            tcg_gen_addi_i32(addr, addr, 4);
-            gen_st32(tmp, addr, 0);
-            if (insn & (1 << 21)) {
-                /* Base writeback.  */
-                switch (i) {
-                case 0: offset = -8; break;
-                case 1: offset = 4; break;
-                case 2: offset = -4; break;
-                case 3: offset = 0; break;
-                default: abort();
-                }
-                if (offset)
-                    tcg_gen_addi_i32(addr, addr, offset);
-                tmp = tcg_const_i32(op1);
-                gen_helper_set_r13_banked(cpu_env, tmp, addr);
-                tcg_temp_free_i32(tmp);
-                tcg_temp_free_i32(addr);
-            } else {
-                tcg_temp_free_i32(addr);
-            }
-            return;
+            ARCH(6);
+            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
         } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
             /* rfe */
             int32_t offset;
@@ -8180,32 +8206,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     gen_rfe(s, tmp, tmp2);
                 } else {
                     /* srs */
-                    op = (insn & 0x1f);
-                    addr = tcg_temp_new_i32();
-                    tmp = tcg_const_i32(op);
-                    gen_helper_get_r13_banked(addr, cpu_env, tmp);
-                    tcg_temp_free_i32(tmp);
-                    if ((insn & (1 << 24)) == 0) {
-                        tcg_gen_addi_i32(addr, addr, -8);
-                    }
-                    tmp = load_reg(s, 14);
-                    gen_st32(tmp, addr, 0);
-                    tcg_gen_addi_i32(addr, addr, 4);
-                    tmp = tcg_temp_new_i32();
-                    gen_helper_cpsr_read(tmp, cpu_env);
-                    gen_st32(tmp, addr, 0);
-                    if (insn & (1 << 21)) {
-                        if ((insn & (1 << 24)) == 0) {
-                            tcg_gen_addi_i32(addr, addr, -4);
-                        } else {
-                            tcg_gen_addi_i32(addr, addr, 4);
-                        }
-                        tmp = tcg_const_i32(op);
-                        gen_helper_set_r13_banked(cpu_env, tmp, addr);
-                        tcg_temp_free_i32(tmp);
-                    } else {
-                        tcg_temp_free_i32(addr);
-                    }
+                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
+                            insn & (1 << 21));
                 }
             } else {
                 int i, loaded_base = 0;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 02/13] target-arm: Don't decode RFE or SRS on M profile cores
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
  2013-03-05  1:11 ` [Qemu-devel] [PATCH 01/13] target-arm: Factor out handling of SRS instruction Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 03/13] oslib-posix: Align to permit transparent hugepages on ARM Linux Peter Maydell
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

M profile cores do not have the RFE or SRS instructions, so
correctly UNDEF these insn patterns on those cores.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/translate.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index e16c113..35a21be 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8180,9 +8180,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
         } else {
             /* Load/store multiple, RFE, SRS.  */
             if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
-                /* Not available in user mode.  */
-                if (IS_USER(s))
+                /* RFE, SRS: not available in user mode or on M profile */
+                if (IS_USER(s) || IS_M(env)) {
                     goto illegal_op;
+                }
                 if (insn & (1 << 20)) {
                     /* rfe */
                     addr = load_reg(s, rn);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 03/13] oslib-posix: Align to permit transparent hugepages on ARM Linux
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
  2013-03-05  1:11 ` [Qemu-devel] [PATCH 01/13] target-arm: Factor out handling of SRS instruction Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 02/13] target-arm: Don't decode RFE or SRS on M profile cores Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 04/13] linux-headers: resync from mainline to add ARM KVM headers Peter Maydell
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

ARM Linux (like x86-64 Linux) can use transparent hugepages for
KVM if memory blocks are 2MiB aligned; set QEMU_VMALLOC_ALIGN
accordingly.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 util/oslib-posix.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index b4152fb..433dd68 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -35,7 +35,7 @@
 extern int daemon(int, int);
 #endif
 
-#if defined(__linux__) && defined(__x86_64__)
+#if defined(__linux__) && (defined(__x86_64__) || defined(__arm__))
    /* Use 2 MiB alignment so transparent hugepages can be used by KVM.
       Valgrind does not support alignments larger than 1 MiB,
       therefore we need special code which handles running on Valgrind. */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 04/13] linux-headers: resync from mainline to add ARM KVM headers
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (2 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 03/13] oslib-posix: Align to permit transparent hugepages on ARM Linux Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 05/13] target-arm: Drop CPUARMState* argument from bank_number() Peter Maydell
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Resync QEMU's copy of the Linux kernel headers from
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
commit 2ef14f4. This adds the ARM KVM headers, since ARM KVM
support has just hit mainline via Russell's ARM tree.

This is not a pure sync -- I have removed by hand some changes
that would have reverted updates for s390x and ppc which have not
yet hit mainline.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 linux-headers/asm-arm/kvm.h          |  180 ++++++++++++++++++++++++++++++++++
 linux-headers/asm-arm/kvm_para.h     |    1 +
 linux-headers/asm-generic/kvm_para.h |    4 +
 linux-headers/linux/kvm.h            |   17 ++++
 4 files changed, 202 insertions(+)
 create mode 100644 linux-headers/asm-arm/kvm.h
 create mode 100644 linux-headers/asm-arm/kvm_para.h
 create mode 100644 linux-headers/asm-generic/kvm_para.h

diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
new file mode 100644
index 0000000..023bfeb
--- /dev/null
+++ b/linux-headers/asm-arm/kvm.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall <c.dall@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __ARM_KVM_H__
+#define __ARM_KVM_H__
+
+#include <linux/types.h>
+#include <asm/ptrace.h>
+
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_IRQ_LINE
+
+#define KVM_REG_SIZE(id)						\
+	(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+/* Valid for svc_regs, abt_regs, und_regs, irq_regs in struct kvm_regs */
+#define KVM_ARM_SVC_sp		svc_regs[0]
+#define KVM_ARM_SVC_lr		svc_regs[1]
+#define KVM_ARM_SVC_spsr	svc_regs[2]
+#define KVM_ARM_ABT_sp		abt_regs[0]
+#define KVM_ARM_ABT_lr		abt_regs[1]
+#define KVM_ARM_ABT_spsr	abt_regs[2]
+#define KVM_ARM_UND_sp		und_regs[0]
+#define KVM_ARM_UND_lr		und_regs[1]
+#define KVM_ARM_UND_spsr	und_regs[2]
+#define KVM_ARM_IRQ_sp		irq_regs[0]
+#define KVM_ARM_IRQ_lr		irq_regs[1]
+#define KVM_ARM_IRQ_spsr	irq_regs[2]
+
+/* Valid only for fiq_regs in struct kvm_regs */
+#define KVM_ARM_FIQ_r8		fiq_regs[0]
+#define KVM_ARM_FIQ_r9		fiq_regs[1]
+#define KVM_ARM_FIQ_r10		fiq_regs[2]
+#define KVM_ARM_FIQ_fp		fiq_regs[3]
+#define KVM_ARM_FIQ_ip		fiq_regs[4]
+#define KVM_ARM_FIQ_sp		fiq_regs[5]
+#define KVM_ARM_FIQ_lr		fiq_regs[6]
+#define KVM_ARM_FIQ_spsr	fiq_regs[7]
+
+struct kvm_regs {
+	struct pt_regs usr_regs;/* R0_usr - R14_usr, PC, CPSR */
+	__u32 svc_regs[3];	/* SP_svc, LR_svc, SPSR_svc */
+	__u32 abt_regs[3];	/* SP_abt, LR_abt, SPSR_abt */
+	__u32 und_regs[3];	/* SP_und, LR_und, SPSR_und */
+	__u32 irq_regs[3];	/* SP_irq, LR_irq, SPSR_irq */
+	__u32 fiq_regs[8];	/* R8_fiq - R14_fiq, SPSR_fiq */
+};
+
+/* Supported Processor Types */
+#define KVM_ARM_TARGET_CORTEX_A15	0
+#define KVM_ARM_NUM_TARGETS		1
+
+/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
+#define KVM_ARM_DEVICE_TYPE_SHIFT	0
+#define KVM_ARM_DEVICE_TYPE_MASK	(0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_ID_SHIFT		16
+#define KVM_ARM_DEVICE_ID_MASK		(0xffff << KVM_ARM_DEVICE_ID_SHIFT)
+
+/* Supported device IDs */
+#define KVM_ARM_DEVICE_VGIC_V2		0
+
+/* Supported VGIC address types  */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST	0
+#define KVM_VGIC_V2_ADDR_TYPE_CPU	1
+
+#define KVM_VGIC_V2_DIST_SIZE		0x1000
+#define KVM_VGIC_V2_CPU_SIZE		0x2000
+
+#define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
+
+struct kvm_vcpu_init {
+	__u32 target;
+	__u32 features[7];
+};
+
+struct kvm_sregs {
+};
+
+struct kvm_fpu {
+};
+
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+struct kvm_sync_regs {
+};
+
+struct kvm_arch_memory_slot {
+};
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_ARM_COPROC_MASK		0x000000000FFF0000
+#define KVM_REG_ARM_COPROC_SHIFT	16
+#define KVM_REG_ARM_32_OPC2_MASK	0x0000000000000007
+#define KVM_REG_ARM_32_OPC2_SHIFT	0
+#define KVM_REG_ARM_OPC1_MASK		0x0000000000000078
+#define KVM_REG_ARM_OPC1_SHIFT		3
+#define KVM_REG_ARM_CRM_MASK		0x0000000000000780
+#define KVM_REG_ARM_CRM_SHIFT		7
+#define KVM_REG_ARM_32_CRN_MASK		0x0000000000007800
+#define KVM_REG_ARM_32_CRN_SHIFT	11
+
+/* Normal registers are mapped as coprocessor 16. */
+#define KVM_REG_ARM_CORE		(0x0010 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_CORE_REG(name)	(offsetof(struct kvm_regs, name) / 4)
+
+/* Some registers need more space to represent values. */
+#define KVM_REG_ARM_DEMUX		(0x0011 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_DEMUX_ID_MASK	0x000000000000FF00
+#define KVM_REG_ARM_DEMUX_ID_SHIFT	8
+#define KVM_REG_ARM_DEMUX_ID_CCSIDR	(0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+#define KVM_REG_ARM_DEMUX_VAL_MASK	0x00000000000000FF
+#define KVM_REG_ARM_DEMUX_VAL_SHIFT	0
+
+/* VFP registers: we could overload CP10 like ARM does, but that's ugly. */
+#define KVM_REG_ARM_VFP			(0x0012 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_VFP_MASK		0x000000000000FFFF
+#define KVM_REG_ARM_VFP_BASE_REG	0x0
+#define KVM_REG_ARM_VFP_FPSID		0x1000
+#define KVM_REG_ARM_VFP_FPSCR		0x1001
+#define KVM_REG_ARM_VFP_MVFR1		0x1006
+#define KVM_REG_ARM_VFP_MVFR0		0x1007
+#define KVM_REG_ARM_VFP_FPEXC		0x1008
+#define KVM_REG_ARM_VFP_FPINST		0x1009
+#define KVM_REG_ARM_VFP_FPINST2		0x100A
+
+
+/* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_TYPE_SHIFT		24
+#define KVM_ARM_IRQ_TYPE_MASK		0xff
+#define KVM_ARM_IRQ_VCPU_SHIFT		16
+#define KVM_ARM_IRQ_VCPU_MASK		0xff
+#define KVM_ARM_IRQ_NUM_SHIFT		0
+#define KVM_ARM_IRQ_NUM_MASK		0xffff
+
+/* irq_type field */
+#define KVM_ARM_IRQ_TYPE_CPU		0
+#define KVM_ARM_IRQ_TYPE_SPI		1
+#define KVM_ARM_IRQ_TYPE_PPI		2
+
+/* out-of-kernel GIC cpu interrupt injection irq_number field */
+#define KVM_ARM_IRQ_CPU_IRQ		0
+#define KVM_ARM_IRQ_CPU_FIQ		1
+
+/* Highest supported SPI, from VGIC_NR_IRQS */
+#define KVM_ARM_IRQ_GIC_MAX		127
+
+/* PSCI interface */
+#define KVM_PSCI_FN_BASE		0x95c1ba5e
+#define KVM_PSCI_FN(n)			(KVM_PSCI_FN_BASE + (n))
+
+#define KVM_PSCI_FN_CPU_SUSPEND		KVM_PSCI_FN(0)
+#define KVM_PSCI_FN_CPU_OFF		KVM_PSCI_FN(1)
+#define KVM_PSCI_FN_CPU_ON		KVM_PSCI_FN(2)
+#define KVM_PSCI_FN_MIGRATE		KVM_PSCI_FN(3)
+
+#define KVM_PSCI_RET_SUCCESS		0
+#define KVM_PSCI_RET_NI			((unsigned long)-1)
+#define KVM_PSCI_RET_INVAL		((unsigned long)-2)
+#define KVM_PSCI_RET_DENIED		((unsigned long)-3)
+
+#endif /* __ARM_KVM_H__ */
diff --git a/linux-headers/asm-arm/kvm_para.h b/linux-headers/asm-arm/kvm_para.h
new file mode 100644
index 0000000..14fab8f
--- /dev/null
+++ b/linux-headers/asm-arm/kvm_para.h
@@ -0,0 +1 @@
+#include <asm-generic/kvm_para.h>
diff --git a/linux-headers/asm-generic/kvm_para.h b/linux-headers/asm-generic/kvm_para.h
new file mode 100644
index 0000000..486f0af
--- /dev/null
+++ b/linux-headers/asm-generic/kvm_para.h
@@ -0,0 +1,4 @@
+/*
+ * There isn't anything here, but the file must not be empty or patch
+ * will delete it.
+ */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 5af9357..caca979 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -115,6 +115,7 @@ struct kvm_irq_level {
 	 * ACPI gsi notion of irq.
 	 * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47..
 	 * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23..
+	 * For ARM: See Documentation/virtual/kvm/api.txt
 	 */
 	union {
 		__u32 irq;
@@ -662,6 +663,8 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_HTAB_FD 84
 #define KVM_CAP_S390_CSS_SUPPORT 85
 #define KVM_CAP_PPC_EPR 86
+#define KVM_CAP_ARM_PSCI 87
+#define KVM_CAP_ARM_SET_DEVICE_ADDR 88
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -791,6 +794,11 @@ struct kvm_dirty_tlb {
 #define KVM_REG_SIZE_U512	0x0060000000000000ULL
 #define KVM_REG_SIZE_U1024	0x0070000000000000ULL
 
+struct kvm_reg_list {
+	__u64 n; /* number of regs */
+	__u64 reg[0];
+};
+
 struct kvm_one_reg {
 	__u64 id;
 	__u64 addr;
@@ -804,6 +812,11 @@ struct kvm_msi {
 	__u8  pad[16];
 };
 
+struct kvm_arm_device_addr {
+	__u64 id;
+	__u64 addr;
+};
+
 /*
  * ioctls for VM fds
  */
@@ -889,6 +902,8 @@ struct kvm_s390_ucas_mapping {
 #define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
 /* Available with KVM_CAP_PPC_HTAB_FD */
 #define KVM_PPC_GET_HTAB_FD	  _IOW(KVMIO,  0xaa, struct kvm_get_htab_fd)
+/* Available with KVM_CAP_ARM_SET_DEVICE_ADDR */
+#define KVM_ARM_SET_DEVICE_ADDR	  _IOW(KVMIO,  0xab, struct kvm_arm_device_addr)
 
 /*
  * ioctls for vcpu fds
@@ -959,6 +974,8 @@ struct kvm_s390_ucas_mapping {
 #define KVM_SET_ONE_REG		  _IOW(KVMIO,  0xac, struct kvm_one_reg)
 /* 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_GET_REG_LIST	  _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 05/13] target-arm: Drop CPUARMState* argument from bank_number()
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (3 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 04/13] linux-headers: resync from mainline to add ARM KVM headers Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 06/13] ARM: KVM: Add support for KVM on ARM architecture Peter Maydell
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Drop the CPUARMState* argument from bank_number(), since we only
use it for passing to cpu_abort(). Use hw_error() instead.
This avoids propagating further interfaces using env pointers.

In the long term this function's callers need auditing to fix
problems where badly behaved guests can pass invalid bank numbers.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
---
 target-arm/helper.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index e97e1a5..7fa4ba0 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1617,7 +1617,7 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
 #else
 
 /* Map CPU modes onto saved register banks.  */
-static inline int bank_number(CPUARMState *env, int mode)
+static inline int bank_number(int mode)
 {
     switch (mode) {
     case ARM_CPU_MODE_USR:
@@ -1634,8 +1634,7 @@ static inline int bank_number(CPUARMState *env, int mode)
     case ARM_CPU_MODE_FIQ:
         return 5;
     }
-    cpu_abort(env, "Bad mode %x\n", mode);
-    return -1;
+    hw_error("bank number requested for bad CPSR mode value 0x%x\n", mode);
 }
 
 void switch_mode(CPUARMState *env, int mode)
@@ -1655,12 +1654,12 @@ void switch_mode(CPUARMState *env, int mode)
         memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
     }
 
-    i = bank_number(env, old_mode);
+    i = bank_number(old_mode);
     env->banked_r13[i] = env->regs[13];
     env->banked_r14[i] = env->regs[14];
     env->banked_spsr[i] = env->spsr;
 
-    i = bank_number(env, mode);
+    i = bank_number(mode);
     env->regs[13] = env->banked_r13[i];
     env->regs[14] = env->banked_r14[i];
     env->spsr = env->banked_spsr[i];
@@ -2530,7 +2529,7 @@ void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
     if ((env->uncached_cpsr & CPSR_M) == mode) {
         env->regs[13] = val;
     } else {
-        env->banked_r13[bank_number(env, mode)] = val;
+        env->banked_r13[bank_number(mode)] = val;
     }
 }
 
@@ -2539,7 +2538,7 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
     if ((env->uncached_cpsr & CPSR_M) == mode) {
         return env->regs[13];
     } else {
-        return env->banked_r13[bank_number(env, mode)];
+        return env->banked_r13[bank_number(mode)];
     }
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 06/13] ARM: KVM: Add support for KVM on ARM architecture
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (4 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 05/13] target-arm: Drop CPUARMState* argument from bank_number() Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 07/13] ARM KVM: save and load VFP registers from kernel Peter Maydell
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

From: Christoffer Dall <cdall@cs.columbia.edu>

Add basic support for KVM on ARM architecture.

Signed-off-by: Christoffer Dall <cdall@cs.columbia.edu>
[PMM: Minor tweaks and code cleanup, switch to ONE_REG]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/arm_pic.c             |   26 ++++
 target-arm/Makefile.objs |    1 +
 target-arm/cpu.h         |    1 +
 target-arm/helper.c      |    2 +-
 target-arm/kvm.c         |  334 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 363 insertions(+), 1 deletion(-)
 create mode 100644 target-arm/kvm.c

diff --git a/hw/arm_pic.c b/hw/arm_pic.c
index ffb4d41..394bc93 100644
--- a/hw/arm_pic.c
+++ b/hw/arm_pic.c
@@ -9,6 +9,7 @@
 
 #include "hw.h"
 #include "arm-misc.h"
+#include "sysemu/kvm.h"
 
 /* Input 0 is IRQ and input 1 is FIQ.  */
 static void arm_pic_cpu_handler(void *opaque, int irq, int level)
@@ -34,7 +35,32 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level)
     }
 }
 
+static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
+{
+#ifdef CONFIG_KVM
+    ARMCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
+
+    switch (irq) {
+    case ARM_PIC_CPU_IRQ:
+        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
+        break;
+    case ARM_PIC_CPU_FIQ:
+        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
+        break;
+    default:
+        hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
+    }
+    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
+    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
+#endif
+}
+
 qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
 {
+    if (kvm_enabled()) {
+        return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2);
+    }
     return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2);
 }
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index b6f1a9e..d89b57c 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,4 +1,5 @@
 obj-y += arm-semi.o
 obj-$(CONFIG_SOFTMMU) += machine.o
+obj-$(CONFIG_KVM) += kvm.o
 obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += neon_helper.o iwmmxt_helper.o
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 2902ba5..c28a0d9 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -237,6 +237,7 @@ void arm_translate_init(void);
 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
 int cpu_arm_exec(CPUARMState *s);
 void do_interrupt(CPUARMState *);
+int bank_number(int mode);
 void switch_mode(CPUARMState *, int);
 uint32_t do_arm_semihosting(CPUARMState *env);
 
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 7fa4ba0..6cad936 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1617,7 +1617,7 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
 #else
 
 /* Map CPU modes onto saved register banks.  */
-static inline int bank_number(int mode)
+int bank_number(int mode)
 {
     switch (mode) {
     case ARM_CPU_MODE_USR:
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
new file mode 100644
index 0000000..499b427
--- /dev/null
+++ b/target-arm/kvm.c
@@ -0,0 +1,334 @@
+/*
+ * ARM implementation of KVM hooks
+ *
+ * Copyright Christoffer Dall 2009-2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/kvm.h>
+
+#include "qemu-common.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
+#include "cpu.h"
+#include "hw/arm-misc.h"
+
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
+    KVM_CAP_LAST_INFO
+};
+
+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;
+    return 0;
+}
+
+unsigned long kvm_arch_vcpu_id(CPUState *cpu)
+{
+    return cpu->cpu_index;
+}
+
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+    struct kvm_vcpu_init init;
+
+    init.target = KVM_ARM_TARGET_CORTEX_A15;
+    memset(init.features, 0, sizeof(init.features));
+    return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+}
+
+typedef struct Reg {
+    uint64_t id;
+    int offset;
+} Reg;
+
+#define COREREG(KERNELNAME, QEMUFIELD)                       \
+    {                                                        \
+        KVM_REG_ARM | KVM_REG_SIZE_U32 |                     \
+        KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(KERNELNAME), \
+        offsetof(CPUARMState, QEMUFIELD)                     \
+    }
+
+#define CP15REG(CRN, CRM, OPC1, OPC2, QEMUFIELD) \
+    {                                            \
+        KVM_REG_ARM | KVM_REG_SIZE_U32 |         \
+        (15 << KVM_REG_ARM_COPROC_SHIFT) |       \
+        ((CRN) << KVM_REG_ARM_32_CRN_SHIFT) |    \
+        ((CRM) << KVM_REG_ARM_CRM_SHIFT) |       \
+        ((OPC1) << KVM_REG_ARM_OPC1_SHIFT) |     \
+        ((OPC2) << KVM_REG_ARM_32_OPC2_SHIFT),   \
+        offsetof(CPUARMState, QEMUFIELD)         \
+    }
+
+static const Reg regs[] = {
+    /* R0_usr .. R14_usr */
+    COREREG(usr_regs.uregs[0], regs[0]),
+    COREREG(usr_regs.uregs[1], regs[1]),
+    COREREG(usr_regs.uregs[2], regs[2]),
+    COREREG(usr_regs.uregs[3], regs[3]),
+    COREREG(usr_regs.uregs[4], regs[4]),
+    COREREG(usr_regs.uregs[5], regs[5]),
+    COREREG(usr_regs.uregs[6], regs[6]),
+    COREREG(usr_regs.uregs[7], regs[7]),
+    COREREG(usr_regs.uregs[8], usr_regs[0]),
+    COREREG(usr_regs.uregs[9], usr_regs[1]),
+    COREREG(usr_regs.uregs[10], usr_regs[2]),
+    COREREG(usr_regs.uregs[11], usr_regs[3]),
+    COREREG(usr_regs.uregs[12], usr_regs[4]),
+    COREREG(usr_regs.uregs[13], banked_r13[0]),
+    COREREG(usr_regs.uregs[14], banked_r14[0]),
+    /* R13, R14, SPSR for SVC, ABT, UND, IRQ banks */
+    COREREG(svc_regs[0], banked_r13[1]),
+    COREREG(svc_regs[1], banked_r14[1]),
+    COREREG(svc_regs[2], banked_spsr[1]),
+    COREREG(abt_regs[0], banked_r13[2]),
+    COREREG(abt_regs[1], banked_r14[2]),
+    COREREG(abt_regs[2], banked_spsr[2]),
+    COREREG(und_regs[0], banked_r13[3]),
+    COREREG(und_regs[1], banked_r14[3]),
+    COREREG(und_regs[2], banked_spsr[3]),
+    COREREG(irq_regs[0], banked_r13[4]),
+    COREREG(irq_regs[1], banked_r14[4]),
+    COREREG(irq_regs[2], banked_spsr[4]),
+    /* R8_fiq .. R14_fiq and SPSR_fiq */
+    COREREG(fiq_regs[0], fiq_regs[0]),
+    COREREG(fiq_regs[1], fiq_regs[1]),
+    COREREG(fiq_regs[2], fiq_regs[2]),
+    COREREG(fiq_regs[3], fiq_regs[3]),
+    COREREG(fiq_regs[4], fiq_regs[4]),
+    COREREG(fiq_regs[5], banked_r13[5]),
+    COREREG(fiq_regs[6], banked_r14[5]),
+    COREREG(fiq_regs[7], banked_spsr[5]),
+    /* R15 */
+    COREREG(usr_regs.uregs[15], regs[15]),
+    /* A non-comprehensive set of cp15 registers.
+     * TODO: drive this from the cp_regs hashtable instead.
+     */
+    CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */
+    CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */
+    CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */
+};
+
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    struct kvm_one_reg r;
+    int mode, bn;
+    int ret, i;
+    uint32_t cpsr;
+    uint64_t ttbr;
+
+    /* Make sure the banked regs are properly set */
+    mode = env->uncached_cpsr & CPSR_M;
+    bn = bank_number(mode);
+    if (mode == ARM_CPU_MODE_FIQ) {
+        memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
+    } else {
+        memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
+    }
+    env->banked_r13[bn] = env->regs[13];
+    env->banked_r14[bn] = env->regs[14];
+    env->banked_spsr[bn] = env->spsr;
+
+    /* Now we can safely copy stuff down to the kernel */
+    for (i = 0; i < ARRAY_SIZE(regs); i++) {
+        r.id = regs[i].id;
+        r.addr = (uintptr_t)(env) + regs[i].offset;
+        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+        if (ret) {
+            return ret;
+        }
+    }
+
+    /* Special cases which aren't a single CPUARMState field */
+    cpsr = cpsr_read(env);
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 |
+        KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr);
+    r.addr = (uintptr_t)(&cpsr);
+    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+
+    /* TTBR0: cp15 crm=2 opc1=0 */
+    ttbr = ((uint64_t)env->cp15.c2_base0_hi << 32) | env->cp15.c2_base0;
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+        (2 << KVM_REG_ARM_CRM_SHIFT) | (0 << KVM_REG_ARM_OPC1_SHIFT);
+    r.addr = (uintptr_t)(&ttbr);
+    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+
+    /* TTBR1: cp15 crm=2 opc1=1 */
+    ttbr = ((uint64_t)env->cp15.c2_base1_hi << 32) | env->cp15.c2_base1;
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+        (2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
+    r.addr = (uintptr_t)(&ttbr);
+    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+
+    return ret;
+}
+
+int kvm_arch_get_registers(CPUState *cs)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    struct kvm_one_reg r;
+    int mode, bn;
+    int ret, i;
+    uint32_t cpsr;
+    uint64_t ttbr;
+
+    for (i = 0; i < ARRAY_SIZE(regs); i++) {
+        r.id = regs[i].id;
+        r.addr = (uintptr_t)(env) + regs[i].offset;
+        ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+        if (ret) {
+            return ret;
+        }
+    }
+
+    /* Special cases which aren't a single CPUARMState field */
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 |
+        KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr);
+    r.addr = (uintptr_t)(&cpsr);
+    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+    cpsr_write(env, cpsr, 0xffffffff);
+
+    /* TTBR0: cp15 crm=2 opc1=0 */
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+        (2 << KVM_REG_ARM_CRM_SHIFT) | (0 << KVM_REG_ARM_OPC1_SHIFT);
+    r.addr = (uintptr_t)(&ttbr);
+    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+    env->cp15.c2_base0_hi = ttbr >> 32;
+    env->cp15.c2_base0 = ttbr;
+
+    /* TTBR1: cp15 crm=2 opc1=1 */
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | (15 << KVM_REG_ARM_COPROC_SHIFT) |
+        (2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
+    r.addr = (uintptr_t)(&ttbr);
+    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+    env->cp15.c2_base1_hi = ttbr >> 32;
+    env->cp15.c2_base1 = ttbr;
+
+    /* Make sure the current mode regs are properly set */
+    mode = env->uncached_cpsr & CPSR_M;
+    bn = bank_number(mode);
+    if (mode == ARM_CPU_MODE_FIQ) {
+        memcpy(env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
+    } else {
+        memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
+    }
+    env->regs[13] = env->banked_r13[bn];
+    env->regs[14] = env->banked_r14[bn];
+    env->spsr = env->banked_spsr[bn];
+
+    /* The main GET_ONE_REG loop above set c2_control, but we need to
+     * update some extra cached precomputed values too.
+     * When this is driven from the cp_regs hashtable then this ugliness
+     * can disappear because we'll use the access function which sets
+     * these values automatically.
+     */
+    env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control);
+    env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control);
+
+    return 0;
+}
+
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
+{
+}
+
+void kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
+{
+}
+
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
+{
+    return 0;
+}
+
+void kvm_arch_reset_vcpu(CPUState *cs)
+{
+}
+
+bool kvm_arch_stop_on_emulation_error(CPUState *cs)
+{
+    return true;
+}
+
+int kvm_arch_process_async_events(CPUState *cs)
+{
+    return 0;
+}
+
+int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr)
+{
+    return 1;
+}
+
+int kvm_arch_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
+
+void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+}
+
+int kvm_arch_insert_sw_breakpoint(CPUState *cs,
+                                  struct kvm_sw_breakpoint *bp)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+    return -EINVAL;
+}
+
+int kvm_arch_insert_hw_breakpoint(target_ulong addr,
+                                  target_ulong len, int type)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+    return -EINVAL;
+}
+
+int kvm_arch_remove_hw_breakpoint(target_ulong addr,
+                                  target_ulong len, int type)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+    return -EINVAL;
+}
+
+int kvm_arch_remove_sw_breakpoint(CPUState *cs,
+                                  struct kvm_sw_breakpoint *bp)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+    return -EINVAL;
+}
+
+void kvm_arch_remove_all_hw_breakpoints(void)
+{
+    qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__);
+}
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 07/13] ARM KVM: save and load VFP registers from kernel
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (5 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 06/13] ARM: KVM: Add support for KVM on ARM architecture Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 08/13] hw/arm_gic: Add presave/postload hooks Peter Maydell
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Add support for saving and restoring VFP register state from the
kernel. This includes a check that the KVM-created CPU has full
VFP support (as the TCG Cortex-A15 model always does), since for
the moment ARM QEMU doesn't have any way to tweak optional features
on created CPUs.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-arm/kvm.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 75 insertions(+), 3 deletions(-)

diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 499b427..9173d0a 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -43,10 +43,28 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 int kvm_arch_init_vcpu(CPUState *cs)
 {
     struct kvm_vcpu_init init;
+    int ret;
+    uint64_t v;
+    struct kvm_one_reg r;
 
     init.target = KVM_ARM_TARGET_CORTEX_A15;
     memset(init.features, 0, sizeof(init.features));
-    return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+    ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+    if (ret) {
+        return ret;
+    }
+    /* Query the kernel to make sure it supports 32 VFP
+     * registers: QEMU's "cortex-a15" CPU is always a
+     * VFP-D32 core. The simplest way to do this is just
+     * to attempt to read register d31.
+     */
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;
+    r.addr = (uintptr_t)(&v);
+    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+    if (ret == ENOENT) {
+        return EINVAL;
+    }
+    return ret;
 }
 
 typedef struct Reg {
@@ -72,6 +90,13 @@ typedef struct Reg {
         offsetof(CPUARMState, QEMUFIELD)         \
     }
 
+#define VFPSYSREG(R)                                       \
+    {                                                      \
+        KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \
+        KVM_REG_ARM_VFP_##R,                               \
+        offsetof(CPUARMState, vfp.xregs[ARM_VFP_##R])      \
+    }
+
 static const Reg regs[] = {
     /* R0_usr .. R14_usr */
     COREREG(usr_regs.uregs[0], regs[0]),
@@ -119,6 +144,13 @@ static const Reg regs[] = {
     CP15REG(1, 0, 0, 0, cp15.c1_sys), /* SCTLR */
     CP15REG(2, 0, 0, 2, cp15.c2_control), /* TTBCR */
     CP15REG(3, 0, 0, 0, cp15.c3), /* DACR */
+    /* VFP system registers */
+    VFPSYSREG(FPSID),
+    VFPSYSREG(MVFR1),
+    VFPSYSREG(MVFR0),
+    VFPSYSREG(FPEXC),
+    VFPSYSREG(FPINST),
+    VFPSYSREG(FPINST2),
 };
 
 int kvm_arch_put_registers(CPUState *cs, int level)
@@ -128,7 +160,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
     struct kvm_one_reg r;
     int mode, bn;
     int ret, i;
-    uint32_t cpsr;
+    uint32_t cpsr, fpscr;
     uint64_t ttbr;
 
     /* Make sure the banked regs are properly set */
@@ -179,6 +211,26 @@ int kvm_arch_put_registers(CPUState *cs, int level)
         (2 << KVM_REG_ARM_CRM_SHIFT) | (1 << KVM_REG_ARM_OPC1_SHIFT);
     r.addr = (uintptr_t)(&ttbr);
     ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+
+    /* VFP registers */
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+    for (i = 0; i < 32; i++) {
+        r.addr = (uintptr_t)(&env->vfp.regs[i]);
+        ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+        if (ret) {
+            return ret;
+        }
+        r.id++;
+    }
+
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
+        KVM_REG_ARM_VFP_FPSCR;
+    fpscr = vfp_get_fpscr(env);
+    r.addr = (uintptr_t)&fpscr;
+    ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
 
     return ret;
 }
@@ -190,7 +242,7 @@ int kvm_arch_get_registers(CPUState *cs)
     struct kvm_one_reg r;
     int mode, bn;
     int ret, i;
-    uint32_t cpsr;
+    uint32_t cpsr, fpscr;
     uint64_t ttbr;
 
     for (i = 0; i < ARRAY_SIZE(regs); i++) {
@@ -255,6 +307,26 @@ int kvm_arch_get_registers(CPUState *cs)
     env->cp15.c2_mask = ~(0xffffffffu >> env->cp15.c2_control);
     env->cp15.c2_base_mask = ~(0x3fffu >> env->cp15.c2_control);
 
+    /* VFP registers */
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
+    for (i = 0; i < 32; i++) {
+        r.addr = (uintptr_t)(&env->vfp.regs[i]);
+        ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+        if (ret) {
+            return ret;
+        }
+        r.id++;
+    }
+
+    r.id = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP |
+        KVM_REG_ARM_VFP_FPSCR;
+    r.addr = (uintptr_t)&fpscr;
+    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+    if (ret) {
+        return ret;
+    }
+    vfp_set_fpscr(env, fpscr);
+
     return 0;
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 08/13] hw/arm_gic: Add presave/postload hooks
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (6 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 07/13] ARM KVM: save and load VFP registers from kernel Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 09/13] hw/arm_gic: Convert ARM GIC classes to use init/realize Peter Maydell
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Add presave/postload hooks to the ARM GIC common base class.
These will be used by the KVM in-kernel GIC subclass to sync
state between kernel and userspace when migrating.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/arm_gic_common.c   |   10 ++++++++++
 hw/arm_gic_internal.h |    2 ++
 2 files changed, 12 insertions(+)

diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
index 40e8dd7..2947622 100644
--- a/hw/arm_gic_common.c
+++ b/hw/arm_gic_common.c
@@ -23,9 +23,14 @@
 static void gic_save(QEMUFile *f, void *opaque)
 {
     GICState *s = (GICState *)opaque;
+    ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);
     int i;
     int j;
 
+    if (c->pre_save) {
+        c->pre_save(s);
+    }
+
     qemu_put_be32(f, s->enabled);
     for (i = 0; i < s->num_cpu; i++) {
         qemu_put_be32(f, s->cpu_enabled[i]);
@@ -57,6 +62,7 @@ static void gic_save(QEMUFile *f, void *opaque)
 static int gic_load(QEMUFile *f, void *opaque, int version_id)
 {
     GICState *s = (GICState *)opaque;
+    ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);
     int i;
     int j;
 
@@ -91,6 +97,10 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
         s->irq_state[i].trigger = qemu_get_byte(f);
     }
 
+    if (c->post_load) {
+        c->post_load(s);
+    }
+
     return 0;
 }
 
diff --git a/hw/arm_gic_internal.h b/hw/arm_gic_internal.h
index 699352c..3640be0 100644
--- a/hw/arm_gic_internal.h
+++ b/hw/arm_gic_internal.h
@@ -118,6 +118,8 @@ void gic_init_irqs_and_distributor(GICState *s, int num_irq);
 
 typedef struct ARMGICCommonClass {
     SysBusDeviceClass parent_class;
+    void (*pre_save)(GICState *s);
+    void (*post_load)(GICState *s);
 } ARMGICCommonClass;
 
 #define TYPE_ARM_GIC "arm_gic"
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 09/13] hw/arm_gic: Convert ARM GIC classes to use init/realize
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (7 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 08/13] hw/arm_gic: Add presave/postload hooks Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 10/13] target-arm: Use MemoryListener to identify GIC base address for KVM Peter Maydell
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Convert the ARM GIC classes to use init/realize rather than
SysBusDevice::init. (We have to do them all in one patch to
avoid unconverted subclasses calling a nonexistent SysBusDevice
init function in the base class and crashing.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
---
 hw/arm_gic.c          |   23 +++++++++++++----------
 hw/arm_gic_common.c   |   26 +++++++++++++++-----------
 hw/arm_gic_internal.h |    2 +-
 hw/armv7m_nvic.c      |   15 ++++++++-------
 4 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 90e43d0..250e720 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -659,14 +659,18 @@ void gic_init_irqs_and_distributor(GICState *s, int num_irq)
     memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
 }
 
-static int arm_gic_init(SysBusDevice *dev)
+static void arm_gic_realize(DeviceState *dev, Error **errp)
 {
-    /* Device instance init function for the GIC sysbus device */
+    /* Device instance realize function for the GIC sysbus device */
     int i;
-    GICState *s = FROM_SYSBUS(GICState, dev);
+    GICState *s = ARM_GIC(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
 
-    agc->parent_init(dev);
+    agc->parent_realize(dev, errp);
+    if (error_is_set(errp)) {
+        return;
+    }
 
     gic_init_irqs_and_distributor(s, s->num_irq);
 
@@ -686,22 +690,21 @@ static int arm_gic_init(SysBusDevice *dev)
                               "gic_cpu", 0x100);
     }
     /* Distributor */
-    sysbus_init_mmio(dev, &s->iomem);
+    sysbus_init_mmio(sbd, &s->iomem);
     /* cpu interfaces (one for "current cpu" plus one per cpu) */
     for (i = 0; i <= NUM_CPU(s); i++) {
-        sysbus_init_mmio(dev, &s->cpuiomem[i]);
+        sysbus_init_mmio(sbd, &s->cpuiomem[i]);
     }
-    return 0;
 }
 
 static void arm_gic_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
     ARMGICClass *agc = ARM_GIC_CLASS(klass);
-    agc->parent_init = sbc->init;
-    sbc->init = arm_gic_init;
+
     dc->no_user = 1;
+    agc->parent_realize = dc->realize;
+    dc->realize = arm_gic_realize;
 }
 
 static const TypeInfo arm_gic_info = {
diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
index 2947622..20da9d2 100644
--- a/hw/arm_gic_common.c
+++ b/hw/arm_gic_common.c
@@ -104,31 +104,35 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static int arm_gic_common_init(SysBusDevice *dev)
+static void arm_gic_common_realize(DeviceState *dev, Error **errp)
 {
-    GICState *s = FROM_SYSBUS(GICState, dev);
+    GICState *s = ARM_GIC_COMMON(dev);
     int num_irq = s->num_irq;
 
     if (s->num_cpu > NCPU) {
-        hw_error("requested %u CPUs exceeds GIC maximum %d\n",
-                 s->num_cpu, NCPU);
+        error_setg(errp, "requested %u CPUs exceeds GIC maximum %d",
+                   s->num_cpu, NCPU);
+        return;
     }
     s->num_irq += GIC_BASE_IRQ;
     if (s->num_irq > GIC_MAXIRQ) {
-        hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
-                 num_irq, GIC_MAXIRQ);
+        error_setg(errp,
+                   "requested %u interrupt lines exceeds GIC maximum %d",
+                   num_irq, GIC_MAXIRQ);
+        return;
     }
     /* ITLinesNumber is represented as (N / 32) - 1 (see
      * gic_dist_readb) so this is an implementation imposed
      * restriction, not an architectural one:
      */
     if (s->num_irq < 32 || (s->num_irq % 32)) {
-        hw_error("%d interrupt lines unsupported: not divisible by 32\n",
-                 num_irq);
+        error_setg(errp,
+                   "%d interrupt lines unsupported: not divisible by 32",
+                   num_irq);
+        return;
     }
 
     register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s);
-    return 0;
 }
 
 static void arm_gic_common_reset(DeviceState *dev)
@@ -173,12 +177,12 @@ static Property arm_gic_common_properties[] = {
 
 static void arm_gic_common_class_init(ObjectClass *klass, void *data)
 {
-    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
+
     dc->reset = arm_gic_common_reset;
+    dc->realize = arm_gic_common_realize;
     dc->props = arm_gic_common_properties;
     dc->no_user = 1;
-    sc->init = arm_gic_common_init;
 }
 
 static const TypeInfo arm_gic_common_type = {
diff --git a/hw/arm_gic_internal.h b/hw/arm_gic_internal.h
index 3640be0..3ba37f3 100644
--- a/hw/arm_gic_internal.h
+++ b/hw/arm_gic_internal.h
@@ -132,7 +132,7 @@ typedef struct ARMGICCommonClass {
 
 typedef struct ARMGICClass {
     ARMGICCommonClass parent_class;
-    int (*parent_init)(SysBusDevice *dev);
+    DeviceRealize parent_realize;
 } ARMGICClass;
 
 #endif /* !QEMU_ARM_GIC_INTERNAL_H */
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index d5798d0..3c79674 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -41,7 +41,7 @@ typedef struct NVICClass {
     /*< private >*/
     ARMGICClass parent_class;
     /*< public >*/
-    int (*parent_init)(SysBusDevice *dev);
+    DeviceRealize parent_realize;
     void (*parent_reset)(DeviceState *dev);
 } NVICClass;
 
@@ -465,7 +465,7 @@ static void armv7m_nvic_reset(DeviceState *dev)
     systick_reset(s);
 }
 
-static int armv7m_nvic_init(SysBusDevice *dev)
+static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
 {
     nvic_state *s = NVIC(dev);
     NVICClass *nc = NVIC_GET_CLASS(s);
@@ -475,7 +475,10 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     /* Tell the common code we're an NVIC */
     s->gic.revision = 0xffffffff;
     s->num_irq = s->gic.num_irq;
-    nc->parent_init(dev);
+    nc->parent_realize(dev, errp);
+    if (error_is_set(errp)) {
+        return;
+    }
     gic_init_irqs_and_distributor(&s->gic, s->num_irq);
     /* The NVIC and system controller register area looks like this:
      *  0..0xff : system control registers, including systick
@@ -503,7 +506,6 @@ static int armv7m_nvic_init(SysBusDevice *dev)
      */
     memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
     s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
-    return 0;
 }
 
 static void armv7m_nvic_instance_init(Object *obj)
@@ -526,13 +528,12 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
 {
     NVICClass *nc = NVIC_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
     nc->parent_reset = dc->reset;
-    nc->parent_init = sdc->init;
-    sdc->init = armv7m_nvic_init;
+    nc->parent_realize = dc->realize;
     dc->vmsd  = &vmstate_nvic;
     dc->reset = armv7m_nvic_reset;
+    dc->realize = armv7m_nvic_realize;
 }
 
 static const TypeInfo armv7m_nvic_info = {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 10/13] target-arm: Use MemoryListener to identify GIC base address for KVM
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (8 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 09/13] hw/arm_gic: Convert ARM GIC classes to use init/realize Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 11/13] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC Peter Maydell
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

When using an in-kernel GIC with KVM, we need to tell the kernel where
the GIC's memory mapped registers live. Do this by registering a
MemoryListener which tracks where the board model maps the A15's
private peripherals, so we can finish the GIC initialisation
when the GIC is actually mapped.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-arm/kvm.c     |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++
 target-arm/kvm_arm.h |   32 +++++++++++++++++++
 2 files changed, 119 insertions(+)
 create mode 100644 target-arm/kvm_arm.h

diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 9173d0a..82e2e08 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -19,6 +19,7 @@
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
+#include "kvm_arm.h"
 #include "cpu.h"
 #include "hw/arm-misc.h"
 
@@ -67,6 +68,92 @@ int kvm_arch_init_vcpu(CPUState *cs)
     return ret;
 }
 
+/* We track all the KVM devices which need their memory addresses
+ * passing to the kernel in a list of these structures.
+ * When board init is complete we run through the list and
+ * tell the kernel the base addresses of the memory regions.
+ * We use a MemoryListener to track mapping and unmapping of
+ * the regions during board creation, so the board models don't
+ * need to do anything special for the KVM case.
+ */
+typedef struct KVMDevice {
+    struct kvm_arm_device_addr kda;
+    MemoryRegion *mr;
+    QSLIST_ENTRY(KVMDevice) entries;
+} KVMDevice;
+
+static QSLIST_HEAD(kvm_devices_head, KVMDevice) kvm_devices_head;
+
+static void kvm_arm_devlistener_add(MemoryListener *listener,
+                                    MemoryRegionSection *section)
+{
+    KVMDevice *kd;
+
+    QSLIST_FOREACH(kd, &kvm_devices_head, entries) {
+        if (section->mr == kd->mr) {
+            kd->kda.addr = section->offset_within_address_space;
+        }
+    }
+}
+
+static void kvm_arm_devlistener_del(MemoryListener *listener,
+                                    MemoryRegionSection *section)
+{
+    KVMDevice *kd;
+
+    QSLIST_FOREACH(kd, &kvm_devices_head, entries) {
+        if (section->mr == kd->mr) {
+            kd->kda.addr = -1;
+        }
+    }
+}
+
+static MemoryListener devlistener = {
+    .region_add = kvm_arm_devlistener_add,
+    .region_del = kvm_arm_devlistener_del,
+};
+
+static void kvm_arm_machine_init_done(Notifier *notifier, void *data)
+{
+    KVMDevice *kd, *tkd;
+
+    memory_listener_unregister(&devlistener);
+    QSLIST_FOREACH_SAFE(kd, &kvm_devices_head, entries, tkd) {
+        if (kd->kda.addr != -1) {
+            if (kvm_vm_ioctl(kvm_state, KVM_ARM_SET_DEVICE_ADDR,
+                             &kd->kda) < 0) {
+                fprintf(stderr, "KVM_ARM_SET_DEVICE_ADDRESS failed: %s\n",
+                        strerror(errno));
+                abort();
+            }
+        }
+        g_free(kd);
+    }
+}
+
+static Notifier notify = {
+    .notify = kvm_arm_machine_init_done,
+};
+
+void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid)
+{
+    KVMDevice *kd;
+
+    if (!kvm_irqchip_in_kernel()) {
+        return;
+    }
+
+    if (QSLIST_EMPTY(&kvm_devices_head)) {
+        memory_listener_register(&devlistener, NULL);
+        qemu_add_machine_init_done_notifier(&notify);
+    }
+    kd = g_new0(KVMDevice, 1);
+    kd->mr = mr;
+    kd->kda.id = devid;
+    kd->kda.addr = -1;
+    QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries);
+}
+
 typedef struct Reg {
     uint64_t id;
     int offset;
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
new file mode 100644
index 0000000..b1c54ff
--- /dev/null
+++ b/target-arm/kvm_arm.h
@@ -0,0 +1,32 @@
+/*
+ * QEMU KVM support -- ARM specific functions.
+ *
+ * Copyright (c) 2012 Linaro Limited
+ *
+ * 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 QEMU_KVM_ARM_H
+#define QEMU_KVM_ARM_H
+
+#include "sysemu/kvm.h"
+#include "exec/memory.h"
+
+/**
+ * kvm_arm_register_device:
+ * @mr: memory region for this device
+ * @devid: the KVM device ID
+ *
+ * Remember the memory region @mr, and when it is mapped by the
+ * machine model, tell the kernel that base address using the
+ * KVM_SET_DEVICE_ADDRESS ioctl. @devid should be the ID of
+ * the device as defined by KVM_SET_DEVICE_ADDRESS.
+ * The machine model may map and unmap the device multiple times;
+ * the kernel will only be told the final address at the point
+ * where machine init is complete.
+ */
+void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid);
+
+#endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 11/13] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (9 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 10/13] target-arm: Use MemoryListener to identify GIC base address for KVM Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 12/13] configure: Enable KVM on ARM Peter Maydell
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Implement support for using the KVM in-kernel GIC for ARM.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
---
 hw/a15mpcore.c       |    8 ++-
 hw/arm/Makefile.objs |    1 +
 hw/kvm/arm_gic.c     |  167 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 hw/kvm/arm_gic.c

diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index fe6c34c..97abe41 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -19,6 +19,7 @@
  */
 
 #include "sysbus.h"
+#include "sysemu/kvm.h"
 
 /* A15MP private memory region.  */
 
@@ -40,8 +41,13 @@ static int a15mp_priv_init(SysBusDevice *dev)
 {
     A15MPPrivState *s = FROM_SYSBUS(A15MPPrivState, dev);
     SysBusDevice *busdev;
+    const char *gictype = "arm_gic";
 
-    s->gic = qdev_create(NULL, "arm_gic");
+    if (kvm_irqchip_in_kernel()) {
+        gictype = "kvm-arm-gic";
+    }
+
+    s->gic = qdev_create(NULL, gictype);
     qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
     qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
     qdev_prop_set_uint32(s->gic, "revision", 2);
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 4c10985..0e7df60 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -32,5 +32,6 @@ obj-y += collie.o
 obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
 obj-y += kzm.o
 obj-$(CONFIG_FDT) += ../device_tree.o
+obj-$(CONFIG_KVM) += kvm/arm_gic.o
 
 obj-y := $(addprefix ../,$(obj-y))
diff --git a/hw/kvm/arm_gic.c b/hw/kvm/arm_gic.c
new file mode 100644
index 0000000..22b40b4
--- /dev/null
+++ b/hw/kvm/arm_gic.c
@@ -0,0 +1,167 @@
+/*
+ * ARM Generic Interrupt Controller using KVM in-kernel support
+ *
+ * Copyright (c) 2012 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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/>.
+ */
+
+#include "hw/sysbus.h"
+#include "sysemu/kvm.h"
+#include "kvm_arm.h"
+#include "hw/arm_gic_internal.h"
+
+#define TYPE_KVM_ARM_GIC "kvm-arm-gic"
+#define KVM_ARM_GIC(obj) \
+     OBJECT_CHECK(GICState, (obj), TYPE_KVM_ARM_GIC)
+#define KVM_ARM_GIC_CLASS(klass) \
+     OBJECT_CLASS_CHECK(KVMARMGICClass, (klass), TYPE_KVM_ARM_GIC)
+#define KVM_ARM_GIC_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(KVMARMGICClass, (obj), TYPE_KVM_ARM_GIC)
+
+typedef struct KVMARMGICClass {
+    ARMGICCommonClass parent_class;
+    DeviceRealize parent_realize;
+    void (*parent_reset)(DeviceState *dev);
+} KVMARMGICClass;
+
+static void kvm_arm_gic_set_irq(void *opaque, int irq, int level)
+{
+    /* Meaning of the 'irq' parameter:
+     *  [0..N-1] : external interrupts
+     *  [N..N+31] : PPI (internal) interrupts for CPU 0
+     *  [N+32..N+63] : PPI (internal interrupts for CPU 1
+     *  ...
+     * Convert this to the kernel's desired encoding, which
+     * has separate fields in the irq number for type,
+     * CPU number and interrupt number.
+     */
+    GICState *s = (GICState *)opaque;
+    int kvm_irq, irqtype, cpu;
+
+    if (irq < (s->num_irq - GIC_INTERNAL)) {
+        /* External interrupt. The kernel numbers these like the GIC
+         * hardware, with external interrupt IDs starting after the
+         * internal ones.
+         */
+        irqtype = KVM_ARM_IRQ_TYPE_SPI;
+        cpu = 0;
+        irq += GIC_INTERNAL;
+    } else {
+        /* Internal interrupt: decode into (cpu, interrupt id) */
+        irqtype = KVM_ARM_IRQ_TYPE_PPI;
+        irq -= (s->num_irq - GIC_INTERNAL);
+        cpu = irq / GIC_INTERNAL;
+        irq %= GIC_INTERNAL;
+    }
+    kvm_irq = (irqtype << KVM_ARM_IRQ_TYPE_SHIFT)
+        | (cpu << KVM_ARM_IRQ_VCPU_SHIFT) | irq;
+
+    kvm_set_irq(kvm_state, kvm_irq, !!level);
+}
+
+static void kvm_arm_gic_put(GICState *s)
+{
+    /* TODO: there isn't currently a kernel interface to set the GIC state */
+}
+
+static void kvm_arm_gic_get(GICState *s)
+{
+    /* TODO: there isn't currently a kernel interface to get the GIC state */
+}
+
+static void kvm_arm_gic_reset(DeviceState *dev)
+{
+    GICState *s = ARM_GIC_COMMON(dev);
+    KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
+
+    kgc->parent_reset(dev);
+    kvm_arm_gic_put(s);
+}
+
+static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
+{
+    int i;
+    GICState *s = KVM_ARM_GIC(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
+
+    kgc->parent_realize(dev, errp);
+    if (error_is_set(errp)) {
+        return;
+    }
+
+    i = s->num_irq - GIC_INTERNAL;
+    /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
+     * GPIO array layout is thus:
+     *  [0..N-1] SPIs
+     *  [N..N+31] PPIs for CPU 0
+     *  [N+32..N+63] PPIs for CPU 1
+     *   ...
+     */
+    i += (GIC_INTERNAL * s->num_cpu);
+    qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i);
+    /* We never use our outbound IRQ lines but provide them so that
+     * we maintain the same interface as the non-KVM GIC.
+     */
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->parent_irq[i]);
+    }
+    /* Distributor */
+    memory_region_init_reservation(&s->iomem, "kvm-gic_dist", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+    kvm_arm_register_device(&s->iomem,
+                            (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
+                            | KVM_VGIC_V2_ADDR_TYPE_DIST);
+    /* CPU interface for current core. Unlike arm_gic, we don't
+     * provide the "interface for core #N" memory regions, because
+     * cores with a VGIC don't have those.
+     */
+    memory_region_init_reservation(&s->cpuiomem[0], "kvm-gic_cpu", 0x1000);
+    sysbus_init_mmio(sbd, &s->cpuiomem[0]);
+    kvm_arm_register_device(&s->cpuiomem[0],
+                            (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
+                            | KVM_VGIC_V2_ADDR_TYPE_CPU);
+}
+
+static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ARMGICCommonClass *agcc = ARM_GIC_COMMON_CLASS(klass);
+    KVMARMGICClass *kgc = KVM_ARM_GIC_CLASS(klass);
+
+    agcc->pre_save = kvm_arm_gic_get;
+    agcc->post_load = kvm_arm_gic_put;
+    kgc->parent_realize = dc->realize;
+    kgc->parent_reset = dc->reset;
+    dc->realize = kvm_arm_gic_realize;
+    dc->reset = kvm_arm_gic_reset;
+    dc->no_user = 1;
+}
+
+static const TypeInfo kvm_arm_gic_info = {
+    .name = TYPE_KVM_ARM_GIC,
+    .parent = TYPE_ARM_GIC_COMMON,
+    .instance_size = sizeof(GICState),
+    .class_init = kvm_arm_gic_class_init,
+    .class_size = sizeof(KVMARMGICClass),
+};
+
+static void kvm_arm_gic_register_types(void)
+{
+    type_register_static(&kvm_arm_gic_info);
+}
+
+type_init(kvm_arm_gic_register_types)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 12/13] configure: Enable KVM on ARM
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (10 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 11/13] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 13/13] MAINTAINERS: add entry for ARM KVM guest cores Peter Maydell
  2013-03-05 14:19 ` [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Aurelien Jarno
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Enable KVM on ARM hosts, now that all the necessary components
for it exist.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 19738ac..b4deb9b 100755
--- a/configure
+++ b/configure
@@ -4129,7 +4129,7 @@ case "$target_arch2" in
     echo "CONFIG_NO_XEN=y" >> $config_target_mak
 esac
 case "$target_arch2" in
-  i386|x86_64|ppcemb|ppc|ppc64|s390x)
+  arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
     # Make sure the target and host cpus are compatible
     if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
       \( "$target_arch2" = "$cpu" -o \
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 13/13] MAINTAINERS: add entry for ARM KVM guest cores
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (11 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 12/13] configure: Enable KVM on ARM Peter Maydell
@ 2013-03-05  1:12 ` Peter Maydell
  2013-03-05 14:19 ` [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Aurelien Jarno
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2013-03-05  1:12 UTC (permalink / raw)
  To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook

Add an entry indicating maintainer status for the ARM KVM code.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 MAINTAINERS |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 21043e4..2439614 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -140,6 +140,11 @@ S: Supported
 F: kvm-*
 F: */kvm.*
 
+ARM
+M: Peter Maydell <peter.maydell@linaro.org>
+S: Maintained
+F: target-arm/kvm.c
+
 PPC
 M: Alexander Graf <agraf@suse.de>
 S: Maintained
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support)
  2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
                   ` (12 preceding siblings ...)
  2013-03-05  1:12 ` [Qemu-devel] [PATCH 13/13] MAINTAINERS: add entry for ARM KVM guest cores Peter Maydell
@ 2013-03-05 14:19 ` Aurelien Jarno
  13 siblings, 0 replies; 15+ messages in thread
From: Aurelien Jarno @ 2013-03-05 14:19 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Blue Swirl, Anthony Liguori, qemu-devel, Paul Brook

On Tue, Mar 05, 2013 at 01:11:58AM +0000, Peter Maydell wrote:
> Hi; here's a target-arm pullre. Major business here is the KVM
> support patchset, though there are a couple of SRS bugfixes too.
> Please pull.
> 
> thanks
> -- PMM
> 
> The following changes since commit 26135ead80fa1fd13e95c162dacfd06f2ba82981:
> 
>   target-mips: Fix accumulator selection for MIPS16 and microMIPS (2013-03-05 01:02:09 +0100)
> 
> are available in the git repository at:
> 
>   git://git.linaro.org/people/pmaydell/qemu-arm.git target-arm.next
> 
> for you to fetch changes up to ed4659d10fa2ec16ace367e4fffe6f7ced73112c:
> 
>   MAINTAINERS: add entry for ARM KVM guest cores (2013-03-05 00:45:43 +0000)
> 
> ----------------------------------------------------------------
> Christoffer Dall (1):
>       ARM: KVM: Add support for KVM on ARM architecture
> 
> Peter Maydell (12):
>       target-arm: Factor out handling of SRS instruction
>       target-arm: Don't decode RFE or SRS on M profile cores
>       oslib-posix: Align to permit transparent hugepages on ARM Linux
>       linux-headers: resync from mainline to add ARM KVM headers
>       target-arm: Drop CPUARMState* argument from bank_number()
>       ARM KVM: save and load VFP registers from kernel
>       hw/arm_gic: Add presave/postload hooks
>       hw/arm_gic: Convert ARM GIC classes to use init/realize
>       target-arm: Use MemoryListener to identify GIC base address for KVM
>       hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC
>       configure: Enable KVM on ARM
>       MAINTAINERS: add entry for ARM KVM guest cores
> 
>  MAINTAINERS                          |    5 +
>  configure                            |    2 +-
>  hw/a15mpcore.c                       |    8 +-
>  hw/arm/Makefile.objs                 |    1 +
>  hw/arm_gic.c                         |   23 +-
>  hw/arm_gic_common.c                  |   36 ++-
>  hw/arm_gic_internal.h                |    4 +-
>  hw/arm_pic.c                         |   26 ++
>  hw/armv7m_nvic.c                     |   15 +-
>  hw/kvm/arm_gic.c                     |  167 ++++++++++++
>  linux-headers/asm-arm/kvm.h          |  180 +++++++++++++
>  linux-headers/asm-arm/kvm_para.h     |    1 +
>  linux-headers/asm-generic/kvm_para.h |    4 +
>  linux-headers/linux/kvm.h            |   17 ++
>  target-arm/Makefile.objs             |    1 +
>  target-arm/cpu.h                     |    1 +
>  target-arm/helper.c                  |   13 +-
>  target-arm/kvm.c                     |  493 ++++++++++++++++++++++++++++++++++
>  target-arm/kvm_arm.h                 |   32 +++
>  target-arm/translate.c               |  141 +++++-----
>  util/oslib-posix.c                   |    2 +-
>  21 files changed, 1064 insertions(+), 108 deletions(-)
>  create mode 100644 hw/kvm/arm_gic.c
>  create mode 100644 linux-headers/asm-arm/kvm.h
>  create mode 100644 linux-headers/asm-arm/kvm_para.h
>  create mode 100644 linux-headers/asm-generic/kvm_para.h
>  create mode 100644 target-arm/kvm.c
>  create mode 100644 target-arm/kvm_arm.h
> 

Thanks, pulled.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2013-03-05 14:19 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-05  1:11 [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Peter Maydell
2013-03-05  1:11 ` [Qemu-devel] [PATCH 01/13] target-arm: Factor out handling of SRS instruction Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 02/13] target-arm: Don't decode RFE or SRS on M profile cores Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 03/13] oslib-posix: Align to permit transparent hugepages on ARM Linux Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 04/13] linux-headers: resync from mainline to add ARM KVM headers Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 05/13] target-arm: Drop CPUARMState* argument from bank_number() Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 06/13] ARM: KVM: Add support for KVM on ARM architecture Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 07/13] ARM KVM: save and load VFP registers from kernel Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 08/13] hw/arm_gic: Add presave/postload hooks Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 09/13] hw/arm_gic: Convert ARM GIC classes to use init/realize Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 10/13] target-arm: Use MemoryListener to identify GIC base address for KVM Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 11/13] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 12/13] configure: Enable KVM on ARM Peter Maydell
2013-03-05  1:12 ` [Qemu-devel] [PATCH 13/13] MAINTAINERS: add entry for ARM KVM guest cores Peter Maydell
2013-03-05 14:19 ` [Qemu-devel] [PULL 00/13] target-arm queue (feat.ARM KVM support) Aurelien Jarno

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).