提交 1a61a9ae 编写于 作者: S Stuart Yoder 提交者: Alexander Graf

PPC: KVM: set has-idle in guest device tree

On e500mc, the platform doesn't provide a way for the CPU to go idle.

To still not uselessly burn CPU time, expose an idle hypercall to the guest
if kvm supports it.
Signed-off-by: NStuart Yoder <stuart.yoder@freescale.com>
[agraf: adjust for current code base, add patch description, fix non-kvm case]
Signed-off-by: NAlexander Graf <agraf@suse.de>
上级 d4834ff9
......@@ -225,6 +225,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,
kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
hypercall, sizeof(hypercall));
/* if KVM supports the idle hcall, set property indicating this */
if (kvmppc_get_hasidle(env)) {
qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
}
}
/* Create CPU nodes */
......
......@@ -989,18 +989,38 @@ uint32_t kvmppc_get_dfp(void)
return kvmppc_read_int_cpu_dt("ibm,dfp");
}
static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
CPUState *cs = CPU(cpu);
if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
!kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) {
return 0;
}
return 1;
}
int kvmppc_get_hasidle(CPUPPCState *env)
{
struct kvm_ppc_pvinfo pvinfo;
if (!kvmppc_get_pvinfo(env, &pvinfo) &&
(pvinfo.flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)) {
return 1;
}
return 0;
}
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
CPUState *cs = CPU(cpu);
uint32_t *hc = (uint32_t*)buf;
struct kvm_ppc_pvinfo pvinfo;
if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
!kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) {
if (!kvmppc_get_pvinfo(env, &pvinfo)) {
memcpy(buf, pvinfo.hcall, buf_len);
return 0;
}
......
......@@ -19,6 +19,7 @@ uint32_t kvmppc_get_tbfreq(void);
uint64_t kvmppc_get_clockfreq(void);
uint32_t kvmppc_get_vmx(void);
uint32_t kvmppc_get_dfp(void);
int kvmppc_get_hasidle(CPUPPCState *env);
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
void kvmppc_set_papr(PowerPCCPU *cpu);
......@@ -55,6 +56,11 @@ static inline uint32_t kvmppc_get_dfp(void)
return 0;
}
static inline int kvmppc_get_hasidle(CPUPPCState *env)
{
return 0;
}
static inline int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
{
return -1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册