mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
target-arm queue:
* don't sync CNTVCT with kernel all the time (fixes VM time weirdnesses) * fix a warning compiling disas/arm-a64 with -Wextra -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJVrinVAAoJEDwlJe0UNgzexIYP/R1/0+gf5176j9c6JV0UV/ly zTfkupOWoigI5htZeGTyJmG8sGVIElpPjiewXwyGWXND0k+q8v/6KXuUJ38WrqZ7 T/vYIyyqHYR87g3dQKLq8kvtwlI74Zn2cXxENgF0XinHfs49dwyAkQsbR3VexvQm VQiIS8ANLMK70SPjJcs8QwPRphfB7uljS7YktKRxsU993NXpN1YoTeFpfadTKbx8 nspB7e/XyMoj2rEO64gq9oOyGsKn+Ls9M6/UwjeTOFe4ceRZ2g4WVCYy8hM+kWe/ Xrb310CzbL8zInlfWCiL8ywBd9cUZ7Jpz2N/A95jhkXc1ZFqAz/WfrjXXzsWn4r3 +fYZEZ6i8DgIMA9rakAPxtdErWmeAFrYGMTGsQ3oa1GbG1AqFFOzRAdSz/t8GVEp FbuqnUZVignzqYbcmhEuP2Q3IOlLiLMOR7u8C+cT2rr8SSEjj4vgURpKVLr//nLJ tvJJF/ZbKuJaHPVUNDMk893TEkj5UnHhmM0dzy8bEtzIPLf3zhwD4ev0wBFB+zvj YbCAifu3PI1oroIfvwZ/wBT+dSWqyodWU3x55PVJS8OegEJPsyQjiRjSJBO78Dx0 EOQhQR4QWIhNw+tymO1T+Xy614SI/3yj/9CWEgdlGC5SHmvq8XWnm7oM0Etcgpb1 8UKnl7If+Dgg4svok+EE =oVzg -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20150721' into staging target-arm queue: * don't sync CNTVCT with kernel all the time (fixes VM time weirdnesses) * fix a warning compiling disas/arm-a64 with -Wextra # gpg: Signature made Tue Jul 21 12:15:33 2015 BST using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-target-arm-20150721: disas/arm-a64: Add missing compiler attribute GCC_FMT_ATTR target-arm: kvm: Differentiate registers based on write-back levels Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
774ee4772b
|
@ -42,7 +42,7 @@ public:
|
||||||
stream_ = stream;
|
stream_ = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPrintf(int (*printf_fn)(FILE *, const char *, ...)) {
|
void SetPrintf(fprintf_function printf_fn) {
|
||||||
printf_ = printf_fn;
|
printf_ = printf_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int (*printf_)(FILE *, const char *, ...);
|
fprintf_function printf_;
|
||||||
FILE *stream_;
|
FILE *stream_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_list_to_kvmstate(ARMCPU *cpu)
|
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
|
||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,7 +409,7 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_list_to_kvmstate(ARMCPU *cpu)
|
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
|
||||||
{
|
{
|
||||||
CPUState *cs = CPU(cpu);
|
CPUState *cs = CPU(cpu);
|
||||||
int i;
|
int i;
|
||||||
|
@ -421,6 +421,10 @@ bool write_list_to_kvmstate(ARMCPU *cpu)
|
||||||
uint32_t v32;
|
uint32_t v32;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (kvm_arm_cpreg_level(regidx) > level) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
r.id = regidx;
|
r.id = regidx;
|
||||||
switch (regidx & KVM_REG_SIZE_MASK) {
|
switch (regidx & KVM_REG_SIZE_MASK) {
|
||||||
case KVM_REG_SIZE_U32:
|
case KVM_REG_SIZE_U32:
|
||||||
|
|
|
@ -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_MPIDR_HWID_BITMASK 0xFFFFFF
|
||||||
#define ARM_CPU_ID_MPIDR 0, 0, 0, 5
|
#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
|
* managed to update the CPUARMState with, and only allowing those
|
||||||
* to be written back up into the kernel).
|
* to be written back up into the kernel).
|
||||||
*/
|
*/
|
||||||
if (!write_list_to_kvmstate(cpu)) {
|
if (!write_list_to_kvmstate(cpu, level)) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,34 @@ bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct CPRegStateLevel {
|
||||||
|
uint64_t regidx;
|
||||||
|
int level;
|
||||||
|
} CPRegStateLevel;
|
||||||
|
|
||||||
|
/* All system 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 AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
|
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
|
||||||
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
|
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
|
||||||
|
|
||||||
|
@ -280,7 +308,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!write_list_to_kvmstate(cpu)) {
|
if (!write_list_to_kvmstate(cpu, level)) {
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,19 @@ int kvm_arm_init_cpreg_list(ARMCPU *cpu);
|
||||||
*/
|
*/
|
||||||
bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
|
bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kvm_arm_cpreg_level
|
||||||
|
* regidx: KVM register index
|
||||||
|
*
|
||||||
|
* Return the level of this coprocessor/system register. Return value is
|
||||||
|
* either KVM_PUT_RUNTIME_STATE, KVM_PUT_RESET_STATE, or KVM_PUT_FULL_STATE.
|
||||||
|
*/
|
||||||
|
int kvm_arm_cpreg_level(uint64_t regidx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* write_list_to_kvmstate:
|
* write_list_to_kvmstate:
|
||||||
* @cpu: ARMCPU
|
* @cpu: ARMCPU
|
||||||
|
* @level: the state level to sync
|
||||||
*
|
*
|
||||||
* For each register listed in the ARMCPU cpreg_indexes list, write
|
* For each register listed in the ARMCPU cpreg_indexes list, write
|
||||||
* its value from the cpreg_values list into the kernel (via ioctl).
|
* its value from the cpreg_values list into the kernel (via ioctl).
|
||||||
|
@ -83,7 +93,7 @@ bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx);
|
||||||
* Note that we do not stop early on failure -- we will attempt
|
* Note that we do not stop early on failure -- we will attempt
|
||||||
* writing all registers in the list.
|
* writing all registers in the list.
|
||||||
*/
|
*/
|
||||||
bool write_list_to_kvmstate(ARMCPU *cpu);
|
bool write_list_to_kvmstate(ARMCPU *cpu, int level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* write_kvmstate_to_list:
|
* write_kvmstate_to_list:
|
||||||
|
|
|
@ -251,7 +251,7 @@ static int cpu_post_load(void *opaque, int version_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
if (!write_list_to_kvmstate(cpu)) {
|
if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Note that it's OK for the TCG side not to know about
|
/* Note that it's OK for the TCG side not to know about
|
||||||
|
|
Loading…
Reference in a new issue