summaryrefslogtreecommitdiff
path: root/target-arm/kvm32.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/kvm32.c')
-rw-r--r--target-arm/kvm32.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c
index d7e7d6877f..421ce0ea0d 100644
--- a/target-arm/kvm32.c
+++ b/target-arm/kvm32.c
@@ -153,6 +153,34 @@ bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
}
}
+typedef struct CPRegStateLevel {
+ uint64_t regidx;
+ int level;
+} CPRegStateLevel;
+
+/* All coprocessor registers not listed in the following table are assumed to
+ * be of the level KVM_PUT_RUNTIME_STATE. If a register should be written less
+ * often, you must add it to this table with a state of either
+ * KVM_PUT_RESET_STATE or KVM_PUT_FULL_STATE.
+ */
+static const CPRegStateLevel non_runtime_cpregs[] = {
+ { KVM_REG_ARM_TIMER_CNT, KVM_PUT_FULL_STATE },
+};
+
+int kvm_arm_cpreg_level(uint64_t regidx)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(non_runtime_cpregs); i++) {
+ const CPRegStateLevel *l = &non_runtime_cpregs[i];
+ if (l->regidx == regidx) {
+ return l->level;
+ }
+ }
+
+ return KVM_PUT_RUNTIME_STATE;
+}
+
#define ARM_MPIDR_HWID_BITMASK 0xFFFFFF
#define ARM_CPU_ID_MPIDR 0, 0, 0, 5
@@ -367,7 +395,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
* managed to update the CPUARMState with, and only allowing those
* to be written back up into the kernel).
*/
- if (!write_list_to_kvmstate(cpu)) {
+ if (!write_list_to_kvmstate(cpu, level)) {
return EINVAL;
}