* [Qemu-devel] [PULL 0/8] target-arm queue
@ 2012-10-05 14:35 Peter Maydell
2012-10-06 18:35 ` Aurelien Jarno
0 siblings, 1 reply; 18+ messages in thread
From: Peter Maydell @ 2012-10-05 14:35 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: qemu-devel, Paul Brook
Usual target-arm pullreq; mostly Aurelien's performance
improvement patches. The 'drop macro' patch has only been on
the list a few days but it's completely trivial so I threw it
in too. Please pull.
thanks
-- PMM
The following changes since commit a14c74928ba1fdaada515717f4d3c3fa3275d6f7:
Merge remote-tracking branch 'sstabellini/xen-2012-10-03' into staging (2012-10-04 19:56:26 -0500)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git target-arm.for-upstream
for you to fetch changes up to 1273d9ca09e91bb290d10f704055f6abec363dd6:
target-arm: Drop unused DECODE_CPREG_CRN macro (2012-10-05 15:04:45 +0100)
----------------------------------------------------------------
Aurelien Jarno (5):
target-arm: use globals for CC flags
target-arm: convert add_cc and sub_cc helpers to TCG
target-arm: convert sar, shl and shr helpers to TCG
target-arm: mark a few integer helpers const and pure
target-arm: use deposit instead of hardcoded version
Peter Maydell (3):
cpu_dump_state: move DUMP_FPU and DUMP_CCOP flags from x86-only to generic
target-arm: Reinstate display of VFP registers in cpu_dump_state
target-arm: Drop unused DECODE_CPREG_CRN macro
cpu-all.h | 3 +
cpu-exec.c | 2 +-
cpus.c | 6 +-
exec.c | 12 +-
monitor.c | 8 +-
target-arm/cpu.h | 2 -
target-arm/helper.h | 24 ++--
target-arm/op_helper.c | 44 -------
target-arm/translate.c | 302 ++++++++++++++++++++++++----------------------
target-i386/cpu.c | 2 +-
target-i386/cpu.h | 4 -
target-i386/helper.c | 4 +-
target-i386/seg_helper.c | 4 +-
target-i386/smm_helper.c | 4 +-
14 files changed, 183 insertions(+), 238 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] target-arm queue
2012-10-05 14:35 Peter Maydell
@ 2012-10-06 18:35 ` Aurelien Jarno
0 siblings, 0 replies; 18+ messages in thread
From: Aurelien Jarno @ 2012-10-06 18:35 UTC (permalink / raw)
To: Peter Maydell; +Cc: Blue Swirl, qemu-devel, Paul Brook
On Fri, Oct 05, 2012 at 03:35:18PM +0100, Peter Maydell wrote:
> Usual target-arm pullreq; mostly Aurelien's performance
> improvement patches. The 'drop macro' patch has only been on
> the list a few days but it's completely trivial so I threw it
> in too. Please pull.
>
> thanks
> -- PMM
>
> The following changes since commit a14c74928ba1fdaada515717f4d3c3fa3275d6f7:
>
> Merge remote-tracking branch 'sstabellini/xen-2012-10-03' into staging (2012-10-04 19:56:26 -0500)
>
> are available in the git repository at:
>
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git target-arm.for-upstream
>
> for you to fetch changes up to 1273d9ca09e91bb290d10f704055f6abec363dd6:
>
> target-arm: Drop unused DECODE_CPREG_CRN macro (2012-10-05 15:04:45 +0100)
>
> ----------------------------------------------------------------
> Aurelien Jarno (5):
> target-arm: use globals for CC flags
> target-arm: convert add_cc and sub_cc helpers to TCG
> target-arm: convert sar, shl and shr helpers to TCG
> target-arm: mark a few integer helpers const and pure
> target-arm: use deposit instead of hardcoded version
>
> Peter Maydell (3):
> cpu_dump_state: move DUMP_FPU and DUMP_CCOP flags from x86-only to generic
> target-arm: Reinstate display of VFP registers in cpu_dump_state
> target-arm: Drop unused DECODE_CPREG_CRN macro
>
> cpu-all.h | 3 +
> cpu-exec.c | 2 +-
> cpus.c | 6 +-
> exec.c | 12 +-
> monitor.c | 8 +-
> target-arm/cpu.h | 2 -
> target-arm/helper.h | 24 ++--
> target-arm/op_helper.c | 44 -------
> target-arm/translate.c | 302 ++++++++++++++++++++++++----------------------
> target-i386/cpu.c | 2 +-
> target-i386/cpu.h | 4 -
> target-i386/helper.c | 4 +-
> target-i386/seg_helper.c | 4 +-
> target-i386/smm_helper.c | 4 +-
> 14 files changed, 183 insertions(+), 238 deletions(-)
>
Thanks, pulled.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 0/8] target-arm queue
@ 2013-06-25 17:33 Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 1/8] target-arm: Allow special cpregs to have flags set Peter Maydell
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
Hi; this is the usual target-arm pullreq, mostly just the cpregs
migration patchset that I posted a while back.
NB: I've updated my make-pullreq script to create a GPG-signed
pull request, but I'm not sure if I got it right -- feedback
welcome :-)
In particular, target-arm.for-upstream is still a branch name
as usual; the signed tag is "pull-target-arm-20130625"; I'm
not sure whether the tag should be the thing named in the
'available at' line below rather than the branch.
The following changes since commit baf8673ca802cb3ea2cdbe94813441d23bde223b:
Merge remote-tracking branch 'stefanha/block' into staging (2013-06-24 14:33:17 -0500)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git target-arm.for-upstream
for you to fetch changes up to bdcc150dc44ea96152f05f9e68970b63508d5ae7:
target-arm: Make LPAE feature imply V7MP (2013-06-25 18:16:10 +0100)
----------------------------------------------------------------
target-arm queue
----------------------------------------------------------------
Peter Maydell (8):
target-arm: Allow special cpregs to have flags set
target-arm: Add raw_readfn and raw_writefn to ARMCPRegInfo
target-arm: mark up cpregs for no-migrate or raw access
target-arm: Convert TCG to using (index,value) list for cp migration
target-arm: Initialize cpreg list from KVM when using KVM
target-arm: Reinitialize all KVM VCPU registers on reset
target-arm: Use tuple list to sync cp regs with KVM
target-arm: Make LPAE feature imply V7MP
target-arm/Makefile.objs | 1 +
target-arm/cpu-qom.h | 24 ++++
target-arm/cpu.c | 4 +-
target-arm/cpu.h | 89 ++++++++++++-
target-arm/helper.c | 327 +++++++++++++++++++++++++++++++++++++++-------
target-arm/kvm-stub.c | 23 ++++
target-arm/kvm.c | 292 +++++++++++++++++++++++++++++++----------
target-arm/kvm_arm.h | 33 +++++
target-arm/machine.c | 134 ++++++++++++-------
9 files changed, 760 insertions(+), 167 deletions(-)
create mode 100644 target-arm/kvm-stub.c
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 1/8] target-arm: Allow special cpregs to have flags set
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 2/8] target-arm: Add raw_readfn and raw_writefn to ARMCPRegInfo Peter Maydell
` (6 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
Relax the "is this a valid ARMCPRegInfo type value?" check to permit
"special" cpregs to have flags other than ARM_CP_SPECIAL set. At
the moment none of the other flags are relevant for special regs,
but the migration related flag we're about to introduce can apply
here too.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5438444..737c00c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -456,7 +456,7 @@ static inline bool cptype_valid(int cptype)
{
return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
|| ((cptype & ARM_CP_SPECIAL) &&
- (cptype <= ARM_LAST_SPECIAL));
+ ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
}
/* Access rights:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 2/8] target-arm: Add raw_readfn and raw_writefn to ARMCPRegInfo
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 1/8] target-arm: Allow special cpregs to have flags set Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 3/8] target-arm: mark up cpregs for no-migrate or raw access Peter Maydell
` (5 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
For reading and writing register values from the kernel for KVM,
we need to provide accessor functions which are guaranteed to succeed
and don't impose access checks, mask out unwritable bits, etc.
Define new fields raw_readfn and raw_writefn for this purpose;
these only need to be provided if there is a readfn or writefn
already and it is not suitable.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu.h | 18 +++++++++++++++++-
target-arm/helper.c | 13 +++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 737c00c..1d8eba5 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -434,19 +434,22 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
* a register definition to override a previous definition for the
* same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
* old must have the OVERRIDE bit set.
+ * NO_MIGRATE indicates that this register should be ignored for migration;
+ * (eg because any state is accessed via some other coprocessor register).
*/
#define ARM_CP_SPECIAL 1
#define ARM_CP_CONST 2
#define ARM_CP_64BIT 4
#define ARM_CP_SUPPRESS_TB_END 8
#define ARM_CP_OVERRIDE 16
+#define ARM_CP_NO_MIGRATE 32
#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
#define ARM_LAST_SPECIAL ARM_CP_WFI
/* Used only as a terminator for ARMCPRegInfo lists */
#define ARM_CP_SENTINEL 0xffff
/* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0x1f
+#define ARM_CP_FLAG_MASK 0x3f
/* Return true if cptype is a valid type field. This is used to try to
* catch errors where the sentinel has been accidentally left off the end
@@ -562,6 +565,19 @@ struct ARMCPRegInfo {
* by fieldoffset.
*/
CPWriteFn *writefn;
+ /* Function for doing a "raw" read; used when we need to copy
+ * coprocessor state to the kernel for KVM or out for
+ * migration. This only needs to be provided if there is also a
+ * readfn and it makes an access permission check.
+ */
+ CPReadFn *raw_readfn;
+ /* Function for doing a "raw" write; used when we need to copy KVM
+ * kernel coprocessor state into userspace, or for inbound
+ * migration. This only needs to be provided if there is also a
+ * writefn and it makes an access permission check or masks out
+ * "unwritable" bits or has write-one-to-clear or similar behaviour.
+ */
+ CPWriteFn *raw_writefn;
/* Function for resetting the register. If NULL, then reset will be done
* by writing resetvalue to the field specified in fieldoffset. If
* fieldoffset is 0 then no reset will be done.
diff --git a/target-arm/helper.c b/target-arm/helper.c
index fd055e8..2585d59 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1392,6 +1392,19 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
r2->crm = crm;
r2->opc1 = opc1;
r2->opc2 = opc2;
+ /* By convention, for wildcarded registers only the first
+ * entry is used for migration; the others are marked as
+ * NO_MIGRATE so we don't try to transfer the register
+ * multiple times. Special registers (ie NOP/WFI) are
+ * never migratable.
+ */
+ if ((r->type & ARM_CP_SPECIAL) ||
+ ((r->crm == CP_ANY) && crm != 0) ||
+ ((r->opc1 == CP_ANY) && opc1 != 0) ||
+ ((r->opc2 == CP_ANY) && opc2 != 0)) {
+ r2->type |= ARM_CP_NO_MIGRATE;
+ }
+
/* Overriding of an existing definition must be explicitly
* requested.
*/
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 3/8] target-arm: mark up cpregs for no-migrate or raw access
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 1/8] target-arm: Allow special cpregs to have flags set Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 2/8] target-arm: Add raw_readfn and raw_writefn to ARMCPRegInfo Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 4/8] target-arm: Convert TCG to using (index, value) list for cp migration Peter Maydell
` (4 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
Mark up coprocessor register definitions to add raw access
functions or mark the register as non-migratable where necessary.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/helper.c | 140 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 94 insertions(+), 46 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2585d59..baf7576 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -64,6 +64,20 @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
return 0;
}
+static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t *value)
+{
+ *value = CPREG_FIELD32(env, ri);
+ return 0;
+}
+
+static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPREG_FIELD32(env, ri) = value;
+ return 0;
+}
+
static int dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
env->cp15.c3 = value;
@@ -139,13 +153,13 @@ static const ARMCPRegInfo cp_reginfo[] = {
{ .name = "DACR", .cp = 15,
.crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3),
- .resetvalue = 0, .writefn = dacr_write },
+ .resetvalue = 0, .writefn = dacr_write, .raw_writefn = raw_write, },
{ .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
- .resetvalue = 0, .writefn = fcse_write },
+ .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
{ .name = "CONTEXTIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse),
- .resetvalue = 0, .writefn = contextidr_write },
+ .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
/* ??? This covers not just the impdef TLB lockdown registers but also
* some v7VMSA registers relating to TEX remap, so it is overly broad.
*/
@@ -155,13 +169,17 @@ static const ARMCPRegInfo cp_reginfo[] = {
* the unified TLB ops but also the dside/iside/inner-shareable variants.
*/
{ .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY,
- .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, },
+ .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write,
+ .type = ARM_CP_NO_MIGRATE },
{ .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY,
- .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, },
+ .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write,
+ .type = ARM_CP_NO_MIGRATE },
{ .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY,
- .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, },
+ .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write,
+ .type = ARM_CP_NO_MIGRATE },
{ .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY,
- .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, },
+ .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write,
+ .type = ARM_CP_NO_MIGRATE },
/* Cache maintenance ops; some of this space may be overridden later. */
{ .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
.opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
@@ -196,7 +214,8 @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
.resetvalue = 0 },
/* v6 doesn't have the cache ID registers but Linux reads them anyway */
{ .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY,
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -235,6 +254,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
REGINFO_SENTINEL
};
+
static int pmreg_read(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t *value)
{
@@ -366,13 +386,16 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
{ .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
.access = PL0_RW, .resetvalue = 0,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
- .readfn = pmreg_read, .writefn = pmcntenset_write },
+ .readfn = pmreg_read, .writefn = pmcntenset_write,
+ .raw_readfn = raw_read, .raw_writefn = raw_write },
{ .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
- .readfn = pmreg_read, .writefn = pmcntenclr_write },
+ .readfn = pmreg_read, .writefn = pmcntenclr_write,
+ .type = ARM_CP_NO_MIGRATE },
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
- .readfn = pmreg_read, .writefn = pmovsr_write },
+ .readfn = pmreg_read, .writefn = pmovsr_write,
+ .raw_readfn = raw_read, .raw_writefn = raw_write },
/* Unimplemented so WI. Strictly speaking write accesses in PL0 should
* respect PMUSERENR.
*/
@@ -389,7 +412,8 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
.access = PL0_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
- .readfn = pmreg_read, .writefn = pmxevtyper_write },
+ .readfn = pmreg_read, .writefn = pmxevtyper_write,
+ .raw_readfn = raw_read, .raw_writefn = raw_write },
/* Unimplemented, RAZ/WI. XXX PMUSERENR */
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
.access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
@@ -397,22 +421,21 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.access = PL0_R | PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
.resetvalue = 0,
- .writefn = pmuserenr_write },
+ .writefn = pmuserenr_write, .raw_writefn = raw_write },
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
.access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
.resetvalue = 0,
- .writefn = pmintenset_write },
+ .writefn = pmintenset_write, .raw_writefn = raw_write },
{ .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
- .access = PL1_RW,
+ .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
- .resetvalue = 0,
- .writefn = pmintenclr_write },
+ .resetvalue = 0, .writefn = pmintenclr_write, },
{ .name = "SCR", .cp = 15, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_scr),
.resetvalue = 0, },
{ .name = "CCSIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
- .access = PL1_R, .readfn = ccsidr_read },
+ .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_MIGRATE },
{ .name = "CSSELR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c0_cssel),
.writefn = csselr_write, .resetvalue = 0 },
@@ -461,7 +484,7 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
.writefn = teecr_write },
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
- .resetvalue = 0,
+ .resetvalue = 0, .raw_readfn = raw_read, .raw_writefn = raw_write,
.readfn = teehbr_read, .writefn = teehbr_write },
REGINFO_SENTINEL
};
@@ -486,7 +509,8 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
/* Dummy implementation: RAZ/WI the whole crn=14 space */
{ .name = "GENERIC_TIMER", .cp = 15, .crn = 14,
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = 0 },
REGINFO_SENTINEL
};
@@ -579,7 +603,7 @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
.writefn = par_write },
#ifndef CONFIG_USER_ONLY
{ .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
- .access = PL1_W, .writefn = ats_write },
+ .access = PL1_W, .writefn = ats_write, .type = ARM_CP_NO_MIGRATE },
#endif
REGINFO_SENTINEL
};
@@ -664,11 +688,11 @@ static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
{ .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW,
+ .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
.fieldoffset = offsetof(CPUARMState, cp15.c5_data), .resetvalue = 0,
.readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, },
{ .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
- .access = PL1_RW,
+ .access = PL1_RW, .type = ARM_CP_NO_MIGRATE,
.fieldoffset = offsetof(CPUARMState, cp15.c5_insn), .resetvalue = 0,
.readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, },
{ .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 2,
@@ -690,15 +714,11 @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
REGINFO_SENTINEL
};
-static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static int vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
if (arm_feature(env, ARM_FEATURE_LPAE)) {
value &= ~((7 << 19) | (3 << 14) | (0xf << 3));
- /* With LPAE the TTBCR could result in a change of ASID
- * via the TTBCR.A1 bit, so do a TLB flush.
- */
- tlb_flush(env, 1);
} else {
value &= 7;
}
@@ -713,6 +733,18 @@ static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
return 0;
}
+static int vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ if (arm_feature(env, ARM_FEATURE_LPAE)) {
+ /* With LPAE the TTBCR could result in a change of ASID
+ * via the TTBCR.A1 bit, so do a TLB flush.
+ */
+ tlb_flush(env, 1);
+ }
+ return vmsa_ttbcr_raw_write(env, ri, value);
+}
+
static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
{
env->cp15.c2_base_mask = 0xffffc000u;
@@ -735,7 +767,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
.fieldoffset = offsetof(CPUARMState, cp15.c2_base1), .resetvalue = 0, },
{ .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL1_RW, .writefn = vmsa_ttbcr_write,
- .resetfn = vmsa_ttbcr_reset,
+ .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
.fieldoffset = offsetof(CPUARMState, cp15.c2_control) },
{ .name = "DFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c6_data),
@@ -801,6 +833,7 @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
.writefn = omap_threadid_write },
{ .name = "TI925T_STATUS", .cp = 15, .crn = 15,
.crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
+ .type = ARM_CP_NO_MIGRATE,
.readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
/* TODO: Peripheral port remap register:
* On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
@@ -808,7 +841,8 @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
* when MMU is off.
*/
{ .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
- .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W, .type = ARM_CP_OVERRIDE,
+ .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
+ .type = ARM_CP_OVERRIDE | ARM_CP_NO_MIGRATE,
.writefn = omap_cachemaint_write },
{ .name = "C9", .cp = 15, .crn = 9,
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
@@ -848,21 +882,24 @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
*/
{ .name = "C15_IMPDEF", .cp = 15, .crn = 15,
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = 0 },
REGINFO_SENTINEL
};
static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
/* Cache status: RAZ because we have no cache so it's always clean */
{ .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = 0 },
REGINFO_SENTINEL
};
static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
/* We never have a a block transfer operation in progress */
{ .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4,
- .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = 0 },
/* The cache ops themselves: these all NOP for QEMU */
{ .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
.access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
@@ -884,9 +921,11 @@ static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
* to indicate that there are no dirty cache lines.
*/
{ .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
- .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = (1 << 30) },
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = (1 << 30) },
{ .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
- .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = (1 << 30) },
+ .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
+ .resetvalue = (1 << 30) },
REGINFO_SENTINEL
};
@@ -894,8 +933,8 @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
/* Ignore ReadBuffer accesses */
{ .name = "C9_READBUFFER", .cp = 15, .crn = 9,
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_OVERRIDE,
- .resetvalue = 0 },
+ .access = PL1_RW, .resetvalue = 0,
+ .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_MIGRATE },
REGINFO_SENTINEL
};
@@ -921,7 +960,7 @@ static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
static const ARMCPRegInfo mpidr_cp_reginfo[] = {
{ .name = "MPIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
- .access = PL1_R, .readfn = mpidr_read },
+ .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_MIGRATE },
REGINFO_SENTINEL
};
@@ -951,14 +990,20 @@ static int ttbr064_read(CPUARMState *env, const ARMCPRegInfo *ri,
return 0;
}
-static int ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static int ttbr064_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
{
env->cp15.c2_base0_hi = value >> 32;
env->cp15.c2_base0 = value;
+ return 0;
+}
+
+static int ttbr064_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
/* Writes to the 64 bit format TTBRs may change the ASID */
tlb_flush(env, 1);
- return 0;
+ return ttbr064_raw_write(env, ri, value);
}
static void ttbr064_reset(CPUARMState *env, const ARMCPRegInfo *ri)
@@ -1008,7 +1053,8 @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
.readfn = par64_read, .writefn = par64_write, .resetfn = par64_reset },
{ .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
.access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr064_read,
- .writefn = ttbr064_write, .resetfn = ttbr064_reset },
+ .writefn = ttbr064_write, .raw_writefn = ttbr064_raw_write,
+ .resetfn = ttbr064_reset },
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
.access = PL1_RW, .type = ARM_CP_64BIT, .readfn = ttbr164_read,
.writefn = ttbr164_write, .resetfn = ttbr164_reset },
@@ -1104,7 +1150,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
.access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
- .readfn = pmreg_read, .writefn = pmcr_write
+ .readfn = pmreg_read, .writefn = pmcr_write,
+ .raw_readfn = raw_read, .raw_writefn = raw_write,
};
ARMCPRegInfo clidr = {
.name = "CLIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
@@ -1176,7 +1223,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "MIDR",
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_R, .resetvalue = cpu->midr,
- .writefn = arm_cp_write_ignore,
+ .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid) },
{ .name = "CTR",
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
@@ -1245,7 +1292,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
ARMCPRegInfo sctlr = {
.name = "SCTLR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c1_sys),
- .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr
+ .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
+ .raw_writefn = raw_write,
};
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
/* Normally we would always end the TB on an SCTLR write, but Linux
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 4/8] target-arm: Convert TCG to using (index, value) list for cp migration
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
` (2 preceding siblings ...)
2013-06-25 17:33 ` [Qemu-devel] [PULL 3/8] target-arm: mark up cpregs for no-migrate or raw access Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 5/8] target-arm: Initialize cpreg list from KVM when using KVM Peter Maydell
` (3 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
Convert the TCG ARM target to using an (index,value) list for migrating
coprocessors. The primary benefit of the (index,value) list is for
passing state between KVM and QEMU, but it works for TCG-to-TCG
migration as well and is a useful self-contained first step.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu-qom.h | 20 ++++++
target-arm/cpu.c | 2 +
target-arm/cpu.h | 69 ++++++++++++++++++++
target-arm/helper.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++
target-arm/kvm.c | 9 +++
target-arm/machine.c | 114 +++++++++++++++++++--------------
6 files changed, 341 insertions(+), 47 deletions(-)
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 12fcefe..2242eee 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -62,6 +62,25 @@ typedef struct ARMCPU {
/* Coprocessor information */
GHashTable *cp_regs;
+ /* For marshalling (mostly coprocessor) register state between the
+ * kernel and QEMU (for KVM) and between two QEMUs (for migration),
+ * we use these arrays.
+ */
+ /* List of register indexes managed via these arrays; (full KVM style
+ * 64 bit indexes, not CPRegInfo 32 bit indexes)
+ */
+ uint64_t *cpreg_indexes;
+ /* Values of the registers (cpreg_indexes[i]'s value is cpreg_values[i]) */
+ uint64_t *cpreg_values;
+ /* Length of the indexes, values arrays */
+ int32_t cpreg_array_len;
+ /* These are used only for migration: incoming data arrives in
+ * these fields and is sanity checked in post_load before copying
+ * to the working data structures above.
+ */
+ uint64_t *cpreg_vmstate_indexes;
+ uint64_t *cpreg_vmstate_values;
+ int32_t cpreg_vmstate_array_len;
/* The instance init functions for implementation-specific subclasses
* set these fields to specify the implementation-dependent values of
@@ -116,6 +135,7 @@ extern const struct VMStateDescription vmstate_arm_cpu;
#endif
void register_cp_regs_for_features(ARMCPU *cpu);
+void init_cpreg_list(ARMCPU *cpu);
void arm_cpu_do_interrupt(CPUState *cpu);
void arm_v7m_cpu_do_interrupt(CPUState *cpu);
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 496a59f..241f032 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -204,6 +204,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
register_cp_regs_for_features(cpu);
arm_cpu_register_gdb_regs_for_features(cpu);
+ init_cpreg_list(cpu);
+
cpu_reset(CPU(cpu));
qemu_init_vcpu(env);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1d8eba5..abcc0b4 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -424,6 +424,43 @@ 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
+ */
+static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
+{
+ uint32_t cpregid = kvmid;
+ if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
+ cpregid |= (1 << 15);
+ }
+ return cpregid;
+}
+
+/* Convert a truncated 32 bit hashtable key into the full
+ * 64 bit KVM register ID.
+ */
+static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
+{
+ uint64_t kvmid = cpregid & ~(1 << 15);
+ if (cpregid & (1 << 15)) {
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
+ } else {
+ kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
+ }
+ return kvmid;
+}
+
/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
* special-behaviour cp reg and bits [15..8] indicate what behaviour
* it has. Otherwise it is a simple cp reg, where CONST indicates that
@@ -621,6 +658,38 @@ static inline bool cp_access_ok(CPUARMState *env,
return (ri->access >> ((arm_current_pl(env) * 2) + isread)) & 1;
}
+/**
+ * write_list_to_cpustate
+ * @cpu: ARMCPU
+ *
+ * For each register listed in the ARMCPU cpreg_indexes list, write
+ * its value from the cpreg_values list into the ARMCPUState structure.
+ * This updates TCG's working data structures from KVM data or
+ * from incoming migration state.
+ *
+ * Returns: true if all register values were updated correctly,
+ * false if some register was unknown or could not be written.
+ * Note that we do not stop early on failure -- we will attempt
+ * writing all registers in the list.
+ */
+bool write_list_to_cpustate(ARMCPU *cpu);
+
+/**
+ * write_cpustate_to_list:
+ * @cpu: ARMCPU
+ *
+ * For each register listed in the ARMCPU cpreg_indexes list, write
+ * its value from the ARMCPUState structure into the cpreg_values list.
+ * This is used to copy info from TCG's working data structures into
+ * KVM or for outbound migration.
+ *
+ * Returns: true if all register values were read correctly,
+ * false if some register was unknown or could not be read.
+ * Note that we do not stop early on failure -- we will attempt
+ * reading all registers in the list.
+ */
+bool write_cpustate_to_list(ARMCPU *cpu);
+
/* Does the core conform to the the "MicroController" profile. e.g. Cortex-M3.
Note the M in older cores (eg. ARM7TDMI) stands for Multiply. These are
conventional cores (ie. Application or Realtime profile). */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index baf7576..5f639fd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -78,6 +78,180 @@ static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
return 0;
}
+static bool read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t *v)
+{
+ /* Raw read of a coprocessor register (as needed for migration, etc)
+ * return true on success, false if the read is impossible for some reason.
+ */
+ if (ri->type & ARM_CP_CONST) {
+ *v = ri->resetvalue;
+ } else if (ri->raw_readfn) {
+ return (ri->raw_readfn(env, ri, v) == 0);
+ } else if (ri->readfn) {
+ return (ri->readfn(env, ri, v) == 0);
+ } else {
+ if (ri->type & ARM_CP_64BIT) {
+ *v = CPREG_FIELD64(env, ri);
+ } else {
+ *v = CPREG_FIELD32(env, ri);
+ }
+ }
+ return true;
+}
+
+static bool write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
+ int64_t v)
+{
+ /* Raw write of a coprocessor register (as needed for migration, etc).
+ * Return true on success, false if the write is impossible for some reason.
+ * Note that constant registers are treated as write-ignored; the
+ * caller should check for success by whether a readback gives the
+ * value written.
+ */
+ if (ri->type & ARM_CP_CONST) {
+ return true;
+ } else if (ri->raw_writefn) {
+ return (ri->raw_writefn(env, ri, v) == 0);
+ } else if (ri->writefn) {
+ return (ri->writefn(env, ri, v) == 0);
+ } else {
+ if (ri->type & ARM_CP_64BIT) {
+ CPREG_FIELD64(env, ri) = v;
+ } else {
+ CPREG_FIELD32(env, ri) = v;
+ }
+ }
+ return true;
+}
+
+bool write_cpustate_to_list(ARMCPU *cpu)
+{
+ /* Write the coprocessor state from cpu->env to the (index,value) list. */
+ int i;
+ bool ok = true;
+
+ for (i = 0; i < cpu->cpreg_array_len; i++) {
+ uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+ const ARMCPRegInfo *ri;
+ uint64_t v;
+ ri = get_arm_cp_reginfo(cpu, regidx);
+ if (!ri) {
+ ok = false;
+ continue;
+ }
+ if (ri->type & ARM_CP_NO_MIGRATE) {
+ continue;
+ }
+ if (!read_raw_cp_reg(&cpu->env, ri, &v)) {
+ ok = false;
+ continue;
+ }
+ cpu->cpreg_values[i] = v;
+ }
+ return ok;
+}
+
+bool write_list_to_cpustate(ARMCPU *cpu)
+{
+ int i;
+ bool ok = true;
+
+ for (i = 0; i < cpu->cpreg_array_len; i++) {
+ uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
+ uint64_t v = cpu->cpreg_values[i];
+ uint64_t readback;
+ const ARMCPRegInfo *ri;
+
+ ri = get_arm_cp_reginfo(cpu, regidx);
+ if (!ri) {
+ ok = false;
+ continue;
+ }
+ if (ri->type & ARM_CP_NO_MIGRATE) {
+ continue;
+ }
+ /* Write value and confirm it reads back as written
+ * (to catch read-only registers and partially read-only
+ * registers where the incoming migration value doesn't match)
+ */
+ if (!write_raw_cp_reg(&cpu->env, ri, v) ||
+ !read_raw_cp_reg(&cpu->env, ri, &readback) ||
+ readback != v) {
+ ok = false;
+ }
+ }
+ return ok;
+}
+
+static void add_cpreg_to_list(gpointer key, gpointer opaque)
+{
+ ARMCPU *cpu = opaque;
+ uint64_t regidx;
+ const ARMCPRegInfo *ri;
+
+ regidx = *(uint32_t *)key;
+ ri = get_arm_cp_reginfo(cpu, regidx);
+
+ if (!(ri->type & ARM_CP_NO_MIGRATE)) {
+ cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
+ /* The value array need not be initialized at this point */
+ cpu->cpreg_array_len++;
+ }
+}
+
+static void count_cpreg(gpointer key, gpointer opaque)
+{
+ ARMCPU *cpu = opaque;
+ uint64_t regidx;
+ const ARMCPRegInfo *ri;
+
+ regidx = *(uint32_t *)key;
+ ri = get_arm_cp_reginfo(cpu, regidx);
+
+ if (!(ri->type & ARM_CP_NO_MIGRATE)) {
+ cpu->cpreg_array_len++;
+ }
+}
+
+static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
+{
+ uint32_t aidx = *(uint32_t *)a;
+ uint32_t bidx = *(uint32_t *)b;
+
+ return aidx - bidx;
+}
+
+void init_cpreg_list(ARMCPU *cpu)
+{
+ /* Initialise the cpreg_tuples[] array based on the cp_regs hash.
+ * Note that we require cpreg_tuples[] to be sorted by key ID.
+ */
+ GList *keys;
+ int arraylen;
+
+ keys = g_hash_table_get_keys(cpu->cp_regs);
+ keys = g_list_sort(keys, cpreg_key_compare);
+
+ cpu->cpreg_array_len = 0;
+
+ g_list_foreach(keys, count_cpreg, cpu);
+
+ arraylen = cpu->cpreg_array_len;
+ cpu->cpreg_indexes = g_new(uint64_t, arraylen);
+ cpu->cpreg_values = g_new(uint64_t, arraylen);
+ cpu->cpreg_vmstate_indexes = g_new(uint64_t, arraylen);
+ cpu->cpreg_vmstate_values = g_new(uint64_t, arraylen);
+ cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len;
+ cpu->cpreg_array_len = 0;
+
+ g_list_foreach(keys, add_cpreg_to_list, cpu);
+
+ assert(cpu->cpreg_array_len == arraylen);
+
+ g_list_free(keys);
+}
+
static int dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
env->cp15.c3 = value;
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 27dcab9..f427537 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -23,6 +23,15 @@
#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
};
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 4dd057c..076dc16 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -148,11 +148,65 @@ static const VMStateInfo vmstate_cpsr = {
.put = put_cpsr,
};
+static void cpu_pre_save(void *opaque)
+{
+ ARMCPU *cpu = opaque;
+
+ if (!write_cpustate_to_list(cpu)) {
+ /* This should never fail. */
+ abort();
+ }
+
+ cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len;
+ memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes,
+ cpu->cpreg_array_len * sizeof(uint64_t));
+ memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values,
+ cpu->cpreg_array_len * sizeof(uint64_t));
+}
+
+static int cpu_post_load(void *opaque, int version_id)
+{
+ ARMCPU *cpu = opaque;
+ int i, v;
+
+ /* Update the values list from the incoming migration data.
+ * Anything in the incoming data which we don't know about is
+ * a migration failure; anything we know about but the incoming
+ * data doesn't specify retains its current (reset) value.
+ * The indexes list remains untouched -- we only inspect the
+ * incoming migration index list so we can match the values array
+ * entries with the right slots in our own values array.
+ */
+
+ for (i = 0, v = 0; i < cpu->cpreg_array_len
+ && v < cpu->cpreg_vmstate_array_len; i++) {
+ if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) {
+ /* register in our list but not incoming : skip it */
+ continue;
+ }
+ if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) {
+ /* register in their list but not ours: fail migration */
+ return -1;
+ }
+ /* matching register, copy the value over */
+ cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v];
+ v++;
+ }
+
+ if (!write_list_to_cpustate(cpu)) {
+ return -1;
+ }
+
+ return 0;
+}
+
const VMStateDescription vmstate_arm_cpu = {
.name = "cpu",
- .version_id = 11,
- .minimum_version_id = 11,
- .minimum_version_id_old = 11,
+ .version_id = 12,
+ .minimum_version_id = 12,
+ .minimum_version_id_old = 12,
+ .pre_save = cpu_pre_save,
+ .post_load = cpu_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
{
@@ -169,50 +223,16 @@ const VMStateDescription vmstate_arm_cpu = {
VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
- VMSTATE_UINT32(env.cp15.c0_cpuid, ARMCPU),
- VMSTATE_UINT32(env.cp15.c0_cssel, ARMCPU),
- VMSTATE_UINT32(env.cp15.c1_sys, ARMCPU),
- VMSTATE_UINT32(env.cp15.c1_coproc, ARMCPU),
- VMSTATE_UINT32(env.cp15.c1_xscaleauxcr, ARMCPU),
- VMSTATE_UINT32(env.cp15.c1_scr, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_base0, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_base0_hi, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_base1, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_base1_hi, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_control, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_mask, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_base_mask, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_data, ARMCPU),
- VMSTATE_UINT32(env.cp15.c2_insn, ARMCPU),
- VMSTATE_UINT32(env.cp15.c3, ARMCPU),
- VMSTATE_UINT32(env.cp15.c5_insn, ARMCPU),
- VMSTATE_UINT32(env.cp15.c5_data, ARMCPU),
- VMSTATE_UINT32_ARRAY(env.cp15.c6_region, ARMCPU, 8),
- VMSTATE_UINT32(env.cp15.c6_insn, ARMCPU),
- VMSTATE_UINT32(env.cp15.c6_data, ARMCPU),
- VMSTATE_UINT32(env.cp15.c7_par, ARMCPU),
- VMSTATE_UINT32(env.cp15.c7_par_hi, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_insn, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_data, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_pmcr, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_pmcnten, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_pmovsr, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_pmxevtyper, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_pmuserenr, ARMCPU),
- VMSTATE_UINT32(env.cp15.c9_pminten, ARMCPU),
- VMSTATE_UINT32(env.cp15.c13_fcse, ARMCPU),
- VMSTATE_UINT32(env.cp15.c13_context, ARMCPU),
- VMSTATE_UINT32(env.cp15.c13_tls1, ARMCPU),
- VMSTATE_UINT32(env.cp15.c13_tls2, ARMCPU),
- VMSTATE_UINT32(env.cp15.c13_tls3, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_cpar, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_ticonfig, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_i_max, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_i_min, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_threadid, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_power_control, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_diagnostic, ARMCPU),
- VMSTATE_UINT32(env.cp15.c15_power_diagnostic, ARMCPU),
+ /* The length-check must come before the arrays to avoid
+ * incoming data possibly overflowing the array.
+ */
+ VMSTATE_INT32_LE(cpreg_vmstate_array_len, ARMCPU),
+ VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU,
+ cpreg_vmstate_array_len,
+ 0, vmstate_info_uint64, uint64_t),
+ VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU,
+ cpreg_vmstate_array_len,
+ 0, vmstate_info_uint64, uint64_t),
VMSTATE_UINT32(env.exclusive_addr, ARMCPU),
VMSTATE_UINT32(env.exclusive_val, ARMCPU),
VMSTATE_UINT32(env.exclusive_high, ARMCPU),
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 5/8] target-arm: Initialize cpreg list from KVM when using KVM
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
` (3 preceding siblings ...)
2013-06-25 17:33 ` [Qemu-devel] [PULL 4/8] target-arm: Convert TCG to using (index, value) list for cp migration Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 6/8] target-arm: Reinitialize all KVM VCPU registers on reset Peter Maydell
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
When using KVM, use the kernel's initial state to set up the
cpreg list, and sync to and from the kernel when doing
migration.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/Makefile.objs | 1 +
target-arm/kvm-stub.c | 23 +++++++
target-arm/kvm.c | 164 +++++++++++++++++++++++++++++++++++++++++++++-
target-arm/kvm_arm.h | 33 ++++++++++
target-arm/machine.c | 30 +++++++--
5 files changed, 245 insertions(+), 6 deletions(-)
create mode 100644 target-arm/kvm-stub.c
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index d89b57c..4a6e52e 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,5 +1,6 @@
obj-y += arm-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
+obj-$(CONFIG_NO_KVM) += kvm-stub.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/kvm-stub.c b/target-arm/kvm-stub.c
new file mode 100644
index 0000000..cd1849f
--- /dev/null
+++ b/target-arm/kvm-stub.c
@@ -0,0 +1,23 @@
+/*
+ * QEMU KVM ARM specific function stubs
+ *
+ * Copyright Linaro Limited 2013
+ *
+ * Author: Peter Maydell <peter.maydell@linaro.org>
+ *
+ * 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 "qemu-common.h"
+#include "kvm_arm.h"
+
+bool write_kvmstate_to_list(ARMCPU *cpu)
+{
+ abort();
+}
+
+bool write_list_to_kvmstate(ARMCPU *cpu)
+{
+ abort();
+}
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index f427537..66ce67a 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -50,12 +50,35 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
return cpu->cpu_index;
}
+static bool reg_syncs_via_tuple_list(uint64_t regidx)
+{
+ /* Return true if the regidx is a register we should synchronize
+ * via the cpreg_tuples array (ie is not a core reg we sync by
+ * hand in kvm_arch_get/put_registers())
+ */
+ switch (regidx & KVM_REG_ARM_COPROC_MASK) {
+ case KVM_REG_ARM_CORE:
+ case KVM_REG_ARM_VFP:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static int compare_u64(const void *a, const void *b)
+{
+ return *(uint64_t *)a - *(uint64_t *)b;
+}
+
int kvm_arch_init_vcpu(CPUState *cs)
{
struct kvm_vcpu_init init;
- int ret;
+ int i, ret, arraylen;
uint64_t v;
struct kvm_one_reg r;
+ struct kvm_reg_list rl;
+ struct kvm_reg_list *rlp;
+ ARMCPU *cpu = ARM_CPU(cs);
init.target = KVM_ARM_TARGET_CORTEX_A15;
memset(init.features, 0, sizeof(init.features));
@@ -74,6 +97,73 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (ret == -ENOENT) {
return -EINVAL;
}
+
+ /* Populate the cpreg list based on the kernel's idea
+ * of what registers exist (and throw away the TCG-created list).
+ */
+ rl.n = 0;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);
+ if (ret != -E2BIG) {
+ return ret;
+ }
+ rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));
+ rlp->n = rl.n;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);
+ if (ret) {
+ goto out;
+ }
+ /* Sort the list we get back from the kernel, since cpreg_tuples
+ * must be in strictly ascending order.
+ */
+ qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64);
+
+ for (i = 0, arraylen = 0; i < rlp->n; i++) {
+ if (!reg_syncs_via_tuple_list(rlp->reg[i])) {
+ continue;
+ }
+ switch (rlp->reg[i] & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ case KVM_REG_SIZE_U64:
+ break;
+ default:
+ fprintf(stderr, "Can't handle size of register in kernel list\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ arraylen++;
+ }
+
+ cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen);
+ cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen);
+ cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,
+ arraylen);
+ cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,
+ arraylen);
+ cpu->cpreg_array_len = arraylen;
+ cpu->cpreg_vmstate_array_len = arraylen;
+
+ for (i = 0, arraylen = 0; i < rlp->n; i++) {
+ uint64_t regidx = rlp->reg[i];
+ if (!reg_syncs_via_tuple_list(regidx)) {
+ continue;
+ }
+ cpu->cpreg_indexes[arraylen] = regidx;
+ arraylen++;
+ }
+ assert(cpu->cpreg_array_len == arraylen);
+
+ if (!write_kvmstate_to_list(cpu)) {
+ /* Shouldn't happen unless kernel is inconsistent about
+ * what registers exist.
+ */
+ fprintf(stderr, "Initial read of kernel register state failed\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+out:
+ g_free(rlp);
return ret;
}
@@ -163,6 +253,78 @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid)
QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries);
}
+bool write_kvmstate_to_list(ARMCPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+ int i;
+ bool ok = true;
+
+ for (i = 0; i < cpu->cpreg_array_len; i++) {
+ struct kvm_one_reg r;
+ uint64_t regidx = cpu->cpreg_indexes[i];
+ uint32_t v32;
+ int ret;
+
+ r.id = regidx;
+
+ switch (regidx & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ r.addr = (uintptr_t)&v32;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ if (!ret) {
+ cpu->cpreg_values[i] = v32;
+ }
+ break;
+ case KVM_REG_SIZE_U64:
+ r.addr = (uintptr_t)(cpu->cpreg_values + i);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
+ break;
+ default:
+ abort();
+ }
+ if (ret) {
+ ok = false;
+ }
+ }
+ return ok;
+}
+
+bool write_list_to_kvmstate(ARMCPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+ int i;
+ bool ok = true;
+
+ for (i = 0; i < cpu->cpreg_array_len; i++) {
+ struct kvm_one_reg r;
+ uint64_t regidx = cpu->cpreg_indexes[i];
+ uint32_t v32;
+ int ret;
+
+ r.id = regidx;
+ switch (regidx & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ v32 = cpu->cpreg_values[i];
+ r.addr = (uintptr_t)&v32;
+ break;
+ case KVM_REG_SIZE_U64:
+ r.addr = (uintptr_t)(cpu->cpreg_values + i);
+ break;
+ default:
+ abort();
+ }
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ /* We might fail for "unknown register" and also for
+ * "you tried to set a register which is constant with
+ * a different value from what it actually contains".
+ */
+ ok = false;
+ }
+ }
+ return ok;
+}
+
typedef struct Reg {
uint64_t id;
int offset;
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
index b1c54ff..5d14887 100644
--- a/target-arm/kvm_arm.h
+++ b/target-arm/kvm_arm.h
@@ -29,4 +29,37 @@
*/
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid);
+/**
+ * write_list_to_kvmstate:
+ * @cpu: ARMCPU
+ *
+ * For each register listed in the ARMCPU cpreg_indexes list, write
+ * its value from the cpreg_values list into the kernel (via ioctl).
+ * This updates KVM's working data structures from TCG data or
+ * from incoming migration state.
+ *
+ * Returns: true if all register values were updated correctly,
+ * false if some register was unknown to the kernel or could not
+ * be written (eg constant register with the wrong value).
+ * Note that we do not stop early on failure -- we will attempt
+ * writing all registers in the list.
+ */
+bool write_list_to_kvmstate(ARMCPU *cpu);
+
+/**
+ * write_kvmstate_to_list:
+ * @cpu: ARMCPU
+ *
+ * For each register listed in the ARMCPU cpreg_indexes list, write
+ * its value from the kernel into the cpreg_values list. This is used to
+ * copy info from KVM's working data structures into TCG or
+ * for outbound migration.
+ *
+ * Returns: true if all register values were read correctly,
+ * false if some register was unknown or could not be read.
+ * Note that we do not stop early on failure -- we will attempt
+ * reading all registers in the list.
+ */
+bool write_kvmstate_to_list(ARMCPU *cpu);
+
#endif
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 076dc16..6d4c2d4 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -1,5 +1,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
+#include "sysemu/kvm.h"
+#include "kvm_arm.h"
static bool vfp_needed(void *opaque)
{
@@ -152,9 +154,16 @@ static void cpu_pre_save(void *opaque)
{
ARMCPU *cpu = opaque;
- if (!write_cpustate_to_list(cpu)) {
- /* This should never fail. */
- abort();
+ if (kvm_enabled()) {
+ if (!write_kvmstate_to_list(cpu)) {
+ /* This should never fail */
+ abort();
+ }
+ } else {
+ if (!write_cpustate_to_list(cpu)) {
+ /* This should never fail. */
+ abort();
+ }
}
cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len;
@@ -193,8 +202,19 @@ static int cpu_post_load(void *opaque, int version_id)
v++;
}
- if (!write_list_to_cpustate(cpu)) {
- return -1;
+ if (kvm_enabled()) {
+ if (!write_list_to_kvmstate(cpu)) {
+ return -1;
+ }
+ /* Note that it's OK for the TCG side not to know about
+ * every register in the list; KVM is authoritative if
+ * we're using it.
+ */
+ write_list_to_cpustate(cpu);
+ } else {
+ if (!write_list_to_cpustate(cpu)) {
+ return -1;
+ }
}
return 0;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 6/8] target-arm: Reinitialize all KVM VCPU registers on reset
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
` (4 preceding siblings ...)
2013-06-25 17:33 ` [Qemu-devel] [PULL 5/8] target-arm: Initialize cpreg list from KVM when using KVM Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 7/8] target-arm: Use tuple list to sync cp regs with KVM Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 8/8] target-arm: Make LPAE feature imply V7MP Peter Maydell
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
Since the ARM KVM API doesn't include a "reset this VCPU"
ioctl, we have to capture the initial values of every
register it knows about so that we can reset the VCPU
by feeding those values back again.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/cpu-qom.h | 6 +++++-
target-arm/kvm.c | 16 ++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 2242eee..25239b8 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -72,7 +72,11 @@ typedef struct ARMCPU {
uint64_t *cpreg_indexes;
/* Values of the registers (cpreg_indexes[i]'s value is cpreg_values[i]) */
uint64_t *cpreg_values;
- /* Length of the indexes, values arrays */
+ /* When using KVM, keeps a copy of the initial state of the VCPU,
+ * so that on reset we can feed the reset values back into the kernel.
+ */
+ uint64_t *cpreg_reset_values;
+ /* Length of the indexes, values, reset_values arrays */
int32_t cpreg_array_len;
/* These are used only for migration: incoming data arrives in
* these fields and is sanity checked in post_load before copying
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 66ce67a..49108cf 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -162,6 +162,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
goto out;
}
+ /* Save a copy of the initial register values so that we can
+ * feed it back to the kernel on VCPU reset.
+ */
+ cpu->cpreg_reset_values = g_memdup(cpu->cpreg_values,
+ cpu->cpreg_array_len *
+ sizeof(cpu->cpreg_values[0]));
+
out:
g_free(rlp);
return ret;
@@ -603,6 +610,15 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
void kvm_arch_reset_vcpu(CPUState *cs)
{
+ /* Feed the kernel back its initial register state */
+ ARMCPU *cpu = ARM_CPU(cs);
+
+ memmove(cpu->cpreg_values, cpu->cpreg_reset_values,
+ cpu->cpreg_array_len * sizeof(cpu->cpreg_values[0]));
+
+ if (!write_list_to_kvmstate(cpu)) {
+ abort();
+ }
}
bool kvm_arch_stop_on_emulation_error(CPUState *cs)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 7/8] target-arm: Use tuple list to sync cp regs with KVM
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
` (5 preceding siblings ...)
2013-06-25 17:33 ` [Qemu-devel] [PULL 6/8] target-arm: Reinitialize all KVM VCPU registers on reset Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 8/8] target-arm: Make LPAE feature imply V7MP Peter Maydell
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
Use the tuple list of cp registers for syncing KVM state to QEMU,
rather than only syncing a very minimal set by hand.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target-arm/kvm.c | 103 +++++++++++++++++-------------------------------------
1 file changed, 33 insertions(+), 70 deletions(-)
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 49108cf..d3937a2 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -344,17 +344,6 @@ typedef struct Reg {
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) \
- }
-
#define VFPSYSREG(R) \
{ \
KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | \
@@ -403,12 +392,6 @@ static const Reg regs[] = {
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 */
/* VFP system registers */
VFPSYSREG(FPSID),
VFPSYSREG(MVFR1),
@@ -426,7 +409,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
int mode, bn;
int ret, i;
uint32_t cpsr, fpscr;
- uint64_t ttbr;
/* Make sure the banked regs are properly set */
mode = env->uncached_cpsr & CPSR_M;
@@ -460,26 +442,6 @@ int kvm_arch_put_registers(CPUState *cs, int level)
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);
- 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++) {
@@ -496,6 +458,31 @@ int kvm_arch_put_registers(CPUState *cs, int level)
fpscr = vfp_get_fpscr(env);
r.addr = (uintptr_t)&fpscr;
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
+ if (ret) {
+ return ret;
+ }
+
+ /* Note that we do not call write_cpustate_to_list()
+ * here, so we are only writing the tuple list back to
+ * KVM. This is safe because nothing can change the
+ * CPUARMState cp15 fields (in particular gdb accesses cannot)
+ * and so there are no changes to sync. In fact syncing would
+ * be wrong at this point: for a constant register where TCG and
+ * KVM disagree about its value, the preceding write_list_to_cpustate()
+ * would not have had any effect on the CPUARMState value (since the
+ * register is read-only), and a write_cpustate_to_list() here would
+ * then try to write the TCG value back into KVM -- this would either
+ * fail or incorrectly change the value the guest sees.
+ *
+ * If we ever want to allow the user to modify cp15 registers via
+ * the gdb stub, we would need to be more clever here (for instance
+ * tracking the set of registers kvm_arch_get_registers() successfully
+ * managed to update the CPUARMState with, and only allowing those
+ * to be written back up into the kernel).
+ */
+ if (!write_list_to_kvmstate(cpu)) {
+ return EINVAL;
+ }
return ret;
}
@@ -508,7 +495,6 @@ int kvm_arch_get_registers(CPUState *cs)
int mode, bn;
int ret, i;
uint32_t cpsr, fpscr;
- uint64_t ttbr;
for (i = 0; i < ARRAY_SIZE(regs); i++) {
r.id = regs[i].id;
@@ -529,28 +515,6 @@ int kvm_arch_get_registers(CPUState *cs)
}
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);
@@ -563,15 +527,6 @@ int kvm_arch_get_registers(CPUState *cs)
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);
-
/* VFP registers */
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
for (i = 0; i < 32; i++) {
@@ -592,6 +547,14 @@ int kvm_arch_get_registers(CPUState *cs)
}
vfp_set_fpscr(env, fpscr);
+ if (!write_kvmstate_to_list(cpu)) {
+ return EINVAL;
+ }
+ /* Note that it's OK to have registers which aren't in CPUState,
+ * so we can ignore a failure return here.
+ */
+ write_list_to_cpustate(cpu);
+
return 0;
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 8/8] target-arm: Make LPAE feature imply V7MP
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
` (6 preceding siblings ...)
2013-06-25 17:33 ` [Qemu-devel] [PULL 7/8] target-arm: Use tuple list to sync cp regs with KVM Peter Maydell
@ 2013-06-25 17:33 ` Peter Maydell
7 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-06-25 17:33 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
The v7 ARM ARM specifies that the Large Physical Address
Extension requires implementation of the Multiprocessing
Extensions, so make our LPAE feature imply V7MP rather
than specifying both in the A15 CPU initfn.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-id: 1371127899-10364-1-git-send-email-peter.maydell@linaro.org
---
target-arm/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 241f032..2371f48 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -198,6 +198,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
set_feature(env, ARM_FEATURE_VFP);
}
if (arm_feature(env, ARM_FEATURE_LPAE)) {
+ set_feature(env, ARM_FEATURE_V7MP);
set_feature(env, ARM_FEATURE_PXN);
}
@@ -573,7 +574,6 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_NEON);
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
- set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_LPAE);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 0/8] target-arm queue
@ 2013-07-15 16:16 Peter Maydell
0 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2013-07-15 16:16 UTC (permalink / raw)
To: Aurelien Jarno, Blue Swirl; +Cc: Anthony Liguori, qemu-devel, Paul Brook
target-arm pullreq for softfreeze: bugfixes and cleanups and
the first traces of ARMv8 support in the shape of LDA/STL
instructions. (There will be more of that in QEMU 1.7, I'm sure.)
Please pull.
thanks
-- PMM
The following changes since commit c3cb8e77804313e1be99b5f28a34a346736707a5:
ioport: remove LITTLE_ENDIAN mark for portio (2013-07-12 14:37:47 -0500)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20130715-1
for you to fetch changes up to 82a3a11897308b606120f7235001e87809708f85:
target-arm: Avoid g_hash_table_get_keys() (2013-07-15 17:13:51 +0100)
----------------------------------------------------------------
target-arm queue
----------------------------------------------------------------
Mans Rullgard (3):
target-arm: add feature flag for ARMv8
target-arm: implement LDA/STL instructions
target-arm: explicitly decode SEVL instruction
Peter Crosthwaite (3):
target-arm/helper.c: OMAP/StrongARM cp15 crn=0 cleanup
target-arm/helper.c: Implement MIDR aliases
target-arm/helper.c: Allow const opaques in arm CP
Peter Maydell (2):
target-arm: avoid undefined behaviour when writing TTBCR
target-arm: Avoid g_hash_table_get_keys()
target-arm/cpu.c | 7 ++-
target-arm/cpu.h | 1 +
target-arm/helper.c | 51 ++++++++++++-------
target-arm/translate.c | 133 ++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 161 insertions(+), 31 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 0/8] target-arm queue
@ 2014-06-30 12:47 Peter Maydell
2014-06-30 14:42 ` Peter Maydell
0 siblings, 1 reply; 18+ messages in thread
From: Peter Maydell @ 2014-06-30 12:47 UTC (permalink / raw)
To: qemu-devel
Last target-arm pull before hardfreeze; nothing much
exciting here.
thanks
-- PMM
The following changes since commit 9328cfd2fe4a7ff86a41b2c26ea33974241d7d4e:
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2014-06-29 18:09:51 +0100)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20140630
for you to fetch changes up to ffebe8997523fd922da58a8e19ddffee6b035429:
disas/libvixl: Fix wrong format strings (2014-06-29 22:04:28 +0100)
----------------------------------------------------------------
target-arm:
* provide PL031 RTC in virt board
* fix missing pxa2xx and strongarm vmstate
* convert cadence_ttc to instance_init
* fix libvixl format strings and README
----------------------------------------------------------------
Alistair Francis (1):
timer: cadence_ttc: Convert to instance_init
Peter Maydell (5):
hw/arm/virt: Provide PL031 RTC
hw/arm/strongarm: Fix handling of GPSR/GPCR reads
hw/arm/strongarm: Wire up missing GPIO and PPC vmstate
hw/arm/pxa2xx_gpio: Fix handling of GPSR/GPCR reads
hw/arm/pxa2xx_gpio: Correct and register vmstate
Richard Henderson (1):
disas/libvixl: Update README for version base
Stefan Weil (1):
disas/libvixl: Fix wrong format strings
disas/libvixl/README | 2 +-
disas/libvixl/a64/disasm-a64.cc | 20 ++++++++++----------
hw/arm/pxa2xx_gpio.c | 17 ++++++++---------
hw/arm/strongarm.c | 18 ++++++++++--------
hw/arm/virt.c | 30 ++++++++++++++++++++++++++++++
hw/timer/cadence_ttc.c | 15 ++++++---------
6 files changed, 65 insertions(+), 37 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] target-arm queue
2014-06-30 12:47 Peter Maydell
@ 2014-06-30 14:42 ` Peter Maydell
0 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2014-06-30 14:42 UTC (permalink / raw)
To: QEMU Developers
On 30 June 2014 13:47, Peter Maydell <peter.maydell@linaro.org> wrote:
> Last target-arm pull before hardfreeze; nothing much
> exciting here.
>
> thanks
> -- PMM
>
>
> The following changes since commit 9328cfd2fe4a7ff86a41b2c26ea33974241d7d4e:
>
> Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2014-06-29 18:09:51 +0100)
>
> are available in the git repository at:
>
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20140630
>
> for you to fetch changes up to ffebe8997523fd922da58a8e19ddffee6b035429:
>
> disas/libvixl: Fix wrong format strings (2014-06-29 22:04:28 +0100)
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 0/8] target-arm queue
@ 2015-04-01 17:08 Peter Maydell
2015-04-01 18:05 ` Peter Maydell
0 siblings, 1 reply; 18+ messages in thread
From: Peter Maydell @ 2015-04-01 17:08 UTC (permalink / raw)
To: qemu-devel
Pull request with what I hope are the last ARM fixes for 2.3...
The following changes since commit b8a86c4ac4d04c106ba38fbd707041cba334a155:
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2015-04-01 11:31:31 +0100)
are available in the git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20150401
for you to fetch changes up to 25b9fb107bc1f6735fdb3fce537792f5db95f78d:
target-arm: kvm64 fix save/restore of SPSR regs (2015-04-01 17:57:30 +0100)
----------------------------------------------------------------
target-arm:
* Fix broken migration on AArch64 KVM
* Fix minor memory leaks in virt, vexpress, highbank
* Honour requested filename when loading highbank rom image
----------------------------------------------------------------
Alex Bennée (4):
target-arm: kvm: save/restore mp state
hw/intc: arm_gic_kvm.c restore config first
target-arm: kvm64 sync FP register state
target-arm: kvm64 fix save/restore of SPSR regs
Peter Maydell (1):
target-arm: Store SPSR_EL1 state in banked_spsr[1] (SPSR_svc)
Stefan Weil (3):
hw/arm/highbank: Fix resource leak and wrong image loading
hw/arm/vexpress: Fix memory leak reported by Coverity
hw/arm/virt: Fix memory leak reported by Coverity
hw/arm/highbank.c | 3 +-
hw/arm/vexpress.c | 11 ++++-
hw/arm/virt.c | 9 +++-
hw/intc/arm_gic_kvm.c | 7 ++-
target-arm/helper-a64.c | 2 +-
target-arm/helper.c | 2 +-
target-arm/internals.h | 5 +-
target-arm/kvm.c | 44 ++++++++++++++++++
target-arm/kvm32.c | 4 ++
target-arm/kvm64.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++--
target-arm/kvm_arm.h | 17 +++++++
11 files changed, 207 insertions(+), 15 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] target-arm queue
2015-04-01 17:08 Peter Maydell
@ 2015-04-01 18:05 ` Peter Maydell
0 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2015-04-01 18:05 UTC (permalink / raw)
To: QEMU Developers
On 1 April 2015 at 18:08, Peter Maydell <peter.maydell@linaro.org> wrote:
> Pull request with what I hope are the last ARM fixes for 2.3...
>
>
> The following changes since commit b8a86c4ac4d04c106ba38fbd707041cba334a155:
>
> Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2015-04-01 11:31:31 +0100)
>
> are available in the git repository at:
>
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20150401
>
> for you to fetch changes up to 25b9fb107bc1f6735fdb3fce537792f5db95f78d:
>
> target-arm: kvm64 fix save/restore of SPSR regs (2015-04-01 17:57:30 +0100)
>
> ----------------------------------------------------------------
> target-arm:
> * Fix broken migration on AArch64 KVM
> * Fix minor memory leaks in virt, vexpress, highbank
> * Honour requested filename when loading highbank rom image
>
> ----------------------------------------------------------------
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PULL 0/8] target-arm queue
@ 2018-07-16 16:42 Peter Maydell
2018-07-17 8:57 ` Peter Maydell
0 siblings, 1 reply; 18+ messages in thread
From: Peter Maydell @ 2018-07-16 16:42 UTC (permalink / raw)
To: qemu-devel
target-arm queue: a smallish set of patches for rc1 tomorrow.
I've included the tcg patches because RTH has no others that
would merit a pullreq.
I haven't included Thomas Huth's 17-patch set to deal with
the introspection crashes, to give that a little more time
on-list for review.
thanks
-- PMM
The following changes since commit 102ad0a80f5110483efd06877c29c4236be267f9:
Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2018-07-16' into staging (2018-07-16 15:34:38 +0100)
are available in the Git repository at:
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180716
for you to fetch changes up to 3474c98a2a2afcefa7c665f02ad2bed2a43ab0f7:
accel/tcg: Assert that tlb fill gave us a valid TLB entry (2018-07-16 17:26:01 +0100)
----------------------------------------------------------------
target-arm queue:
* accel/tcg: Use correct test when looking in victim TLB for code
* bcm2835_aux: Swap RX and TX interrupt assignments
* hw/arm/bcm2836: Mark the bcm2836 / bcm2837 devices with user_creatable = false
* hw/intc/arm_gic: Fix handling of GICD_ITARGETSR
* hw/intc/arm_gic: Check interrupt number in gic_deactivate_irq()
* aspeed: Implement write-1-{set, clear} for AST2500 strapping
* target/arm: Fix LD1W and LDFF1W (scalar plus vector)
----------------------------------------------------------------
Andrew Jeffery (1):
aspeed: Implement write-1-{set, clear} for AST2500 strapping
Guenter Roeck (1):
bcm2835_aux: Swap RX and TX interrupt assignments
Peter Maydell (4):
hw/intc/arm_gic: Check interrupt number in gic_deactivate_irq()
hw/intc/arm_gic: Fix handling of GICD_ITARGETSR
accel/tcg: Use correct test when looking in victim TLB for code
accel/tcg: Assert that tlb fill gave us a valid TLB entry
Richard Henderson (1):
target/arm: Fix LD1W and LDFF1W (scalar plus vector)
Thomas Huth (1):
hw/arm/bcm2836: Mark the bcm2836 / bcm2837 devices with user_creatable = false
include/hw/misc/aspeed_scu.h | 2 ++
accel/tcg/cputlb.c | 6 +++---
hw/arm/bcm2836.c | 2 ++
hw/char/bcm2835_aux.c | 4 ++--
hw/intc/arm_gic.c | 22 +++++++++++++++++++---
hw/misc/aspeed_scu.c | 19 +++++++++++++++++--
target/arm/sve_helper.c | 4 ++--
7 files changed, 47 insertions(+), 12 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PULL 0/8] target-arm queue
2018-07-16 16:42 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
@ 2018-07-17 8:57 ` Peter Maydell
0 siblings, 0 replies; 18+ messages in thread
From: Peter Maydell @ 2018-07-17 8:57 UTC (permalink / raw)
To: QEMU Developers
On 16 July 2018 at 17:42, Peter Maydell <peter.maydell@linaro.org> wrote:
> target-arm queue: a smallish set of patches for rc1 tomorrow.
> I've included the tcg patches because RTH has no others that
> would merit a pullreq.
>
> I haven't included Thomas Huth's 17-patch set to deal with
> the introspection crashes, to give that a little more time
> on-list for review.
>
> thanks
> -- PMM
>
> The following changes since commit 102ad0a80f5110483efd06877c29c4236be267f9:
>
> Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2018-07-16' into staging (2018-07-16 15:34:38 +0100)
>
> are available in the Git repository at:
>
> git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180716
>
> for you to fetch changes up to 3474c98a2a2afcefa7c665f02ad2bed2a43ab0f7:
>
> accel/tcg: Assert that tlb fill gave us a valid TLB entry (2018-07-16 17:26:01 +0100)
>
> ----------------------------------------------------------------
> target-arm queue:
> * accel/tcg: Use correct test when looking in victim TLB for code
> * bcm2835_aux: Swap RX and TX interrupt assignments
> * hw/arm/bcm2836: Mark the bcm2836 / bcm2837 devices with user_creatable = false
> * hw/intc/arm_gic: Fix handling of GICD_ITARGETSR
> * hw/intc/arm_gic: Check interrupt number in gic_deactivate_irq()
> * aspeed: Implement write-1-{set, clear} for AST2500 strapping
> * target/arm: Fix LD1W and LDFF1W (scalar plus vector)
>
> ----------------------------------------------------------------
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2018-07-17 8:57 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-25 17:33 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 1/8] target-arm: Allow special cpregs to have flags set Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 2/8] target-arm: Add raw_readfn and raw_writefn to ARMCPRegInfo Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 3/8] target-arm: mark up cpregs for no-migrate or raw access Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 4/8] target-arm: Convert TCG to using (index, value) list for cp migration Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 5/8] target-arm: Initialize cpreg list from KVM when using KVM Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 6/8] target-arm: Reinitialize all KVM VCPU registers on reset Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 7/8] target-arm: Use tuple list to sync cp regs with KVM Peter Maydell
2013-06-25 17:33 ` [Qemu-devel] [PULL 8/8] target-arm: Make LPAE feature imply V7MP Peter Maydell
-- strict thread matches above, loose matches on Subject: below --
2018-07-16 16:42 [Qemu-devel] [PULL 0/8] target-arm queue Peter Maydell
2018-07-17 8:57 ` Peter Maydell
2015-04-01 17:08 Peter Maydell
2015-04-01 18:05 ` Peter Maydell
2014-06-30 12:47 Peter Maydell
2014-06-30 14:42 ` Peter Maydell
2013-07-15 16:16 Peter Maydell
2012-10-05 14:35 Peter Maydell
2012-10-06 18:35 ` 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).