Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-2…
Browse files Browse the repository at this point in the history
…0150721' 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>
  • Loading branch information
pm215 committed Jul 21, 2015
2 parents a1bc040 + 57b7309 commit 774ee47
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 8 deletions.
4 changes: 2 additions & 2 deletions disas/arm-a64.cc
Expand Up @@ -42,7 +42,7 @@ class QEMUDisassembler : public Disassembler {
stream_ = stream;
}

void SetPrintf(int (*printf_fn)(FILE *, const char *, ...)) {
void SetPrintf(fprintf_function printf_fn) {
printf_ = printf_fn;
}

Expand All @@ -53,7 +53,7 @@ class QEMUDisassembler : public Disassembler {
}

private:
int (*printf_)(FILE *, const char *, ...);
fprintf_function printf_;
FILE *stream_;
};

Expand Down
2 changes: 1 addition & 1 deletion target-arm/kvm-stub.c
Expand Up @@ -17,7 +17,7 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
abort();
}

bool write_list_to_kvmstate(ARMCPU *cpu)
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
{
abort();
}
6 changes: 5 additions & 1 deletion target-arm/kvm.c
Expand Up @@ -409,7 +409,7 @@ bool write_kvmstate_to_list(ARMCPU *cpu)
return ok;
}

bool write_list_to_kvmstate(ARMCPU *cpu)
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
{
CPUState *cs = CPU(cpu);
int i;
Expand All @@ -421,6 +421,10 @@ bool write_list_to_kvmstate(ARMCPU *cpu)
uint32_t v32;
int ret;

if (kvm_arm_cpreg_level(regidx) > level) {
continue;
}

r.id = regidx;
switch (regidx & KVM_REG_SIZE_MASK) {
case KVM_REG_SIZE_U32:
Expand Down
30 changes: 29 additions & 1 deletion target-arm/kvm32.c
Expand Up @@ -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

Expand Down Expand Up @@ -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;
}

Expand Down
30 changes: 29 additions & 1 deletion target-arm/kvm64.c
Expand Up @@ -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 | \
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))

Expand Down Expand Up @@ -280,7 +308,7 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}

if (!write_list_to_kvmstate(cpu)) {
if (!write_list_to_kvmstate(cpu, level)) {
return EINVAL;
}

Expand Down
12 changes: 11 additions & 1 deletion target-arm/kvm_arm.h
Expand Up @@ -68,9 +68,19 @@ int kvm_arm_init_cpreg_list(ARMCPU *cpu);
*/
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:
* @cpu: ARMCPU
* @level: the state level to sync
*
* For each register listed in the ARMCPU cpreg_indexes list, write
* its value from the cpreg_values list into the kernel (via ioctl).
Expand All @@ -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
* 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:
Expand Down
2 changes: 1 addition & 1 deletion target-arm/machine.c
Expand Up @@ -251,7 +251,7 @@ static int cpu_post_load(void *opaque, int version_id)
}

if (kvm_enabled()) {
if (!write_list_to_kvmstate(cpu)) {
if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) {
return -1;
}
/* Note that it's OK for the TCG side not to know about
Expand Down

0 comments on commit 774ee47

Please sign in to comment.