Discussion:
[PATCH 0/3] KVM: PPC: Book3S: Some miscellanous fixes
Paul Mackerras
2014-09-02 06:14:41 UTC
Permalink
This series of patches is based on Alex Graf's kvm-ppc-queue branch.
It contains 3 small patches from the tree that we are shipping on
POWER8 machines: a fix for an error that we see very occasionally,
and two minor improvements. Please apply for 3.18.

Paul.
---
arch/powerpc/include/asm/kvm_host.h | 2 ++
arch/powerpc/kvm/book3s_hv.c | 6 ++++--
arch/powerpc/kvm/book3s_pr.c | 39 +++++++++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 2 deletions(-)
Paul Mackerras
2014-09-02 06:14:42 UTC
Permalink
From: Paul Mackerras <***@au1.ibm.com>

Occasional failures have been seen with split-core mode and migration
where the message "KVM: couldn't grab cpu" appears. This increases
the length of time that we wait from 1ms to 10ms, which seems to
work around the issue.

Signed-off-by: Paul Mackerras <***@samba.org>
---
arch/powerpc/kvm/book3s_hv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 27cced9..4526bef 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1489,7 +1489,7 @@ static void kvmppc_remove_runnable(struct kvmppc_vcore *vc,
static int kvmppc_grab_hwthread(int cpu)
{
struct paca_struct *tpaca;
- long timeout = 1000;
+ long timeout = 10000;

tpaca = &paca[cpu];
--
2.1.0.rc1
Paul Mackerras
2014-09-02 06:14:43 UTC
Permalink
Since the guest can read the machine's PVR (Processor Version Register)
directly and see the real value, we should disallow userspace from
setting any value for the guest's PVR other than the real host value.
Therefore this makes kvm_arch_vcpu_set_sregs_hv() check the supplied
PVR value and return an error if it is different from the host value,
which has been put into vcpu->arch.pvr at vcpu creation time.

Signed-off-by: Paul Mackerras <***@samba.org>
---
arch/powerpc/kvm/book3s_hv.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 4526bef..529d10a 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -856,7 +856,9 @@ static int kvm_arch_vcpu_ioctl_set_sregs_hv(struct kvm_vcpu *vcpu,
{
int i, j;

- kvmppc_set_pvr_hv(vcpu, sregs->pvr);
+ /* Only accept the same PVR as the host's, since we can't spoof it */
+ if (sregs->pvr != vcpu->arch.pvr)
+ return -EINVAL;

j = 0;
for (i = 0; i < vcpu->arch.slb_nr; i++) {
--
2.1.0.rc1
Paul Mackerras
2014-09-02 06:14:44 UTC
Permalink
This provides basic support for the KVM_REG_PPC_ARCH_COMPAT register
in PR KVM. At present the value is sanity-checked when set, but
doesn't actually affect anything yet.

Implementing this makes it possible to use a qemu command-line
argument such as "-cpu host,compat=power7" on a POWER8 machine,
just as we would with HV KVM. In turn this means that we can use the
same libvirt XML for nested virtualization with PR KVM as we do with
HV KVM.

Signed-off-by: Paul Mackerras <***@samba.org>
---
arch/powerpc/include/asm/kvm_host.h | 2 ++
arch/powerpc/kvm/book3s_pr.c | 39 +++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 3502649..f435a889 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -515,6 +515,8 @@ struct kvm_vcpu_arch {
u32 ivor[64];
ulong ivpr;
u32 pvr;
+ u32 pvr_arch;
+ u32 compat_arch;

u32 shadow_pid;
u32 shadow_pid1;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index faffb27..7183bdc 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -398,6 +398,28 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)
kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
}

+/*
+ * Evaluate the architecture level of a PVR value.
+ * The result is in terms of PVR_ARCH_* values.
+ */
+static u32 pvr_to_arch(u32 pvr)
+{
+ switch (PVR_VER(pvr)) {
+ case PVR_POWER5p:
+ return PVR_ARCH_204;
+ case PVR_POWER6:
+ return PVR_ARCH_205;
+ case PVR_POWER7:
+ case PVR_POWER7p:
+ return PVR_ARCH_206;
+ case PVR_POWER8:
+ case PVR_POWER8E:
+ return PVR_ARCH_207;
+ default:
+ return 0;
+ }
+}
+
void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr)
{
u32 host_pvr;
@@ -473,6 +495,18 @@ void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr)
/* Enable HID2.PSE - in case we need it later */
mtspr(SPRN_HID2_GEKKO, mfspr(SPRN_HID2_GEKKO) | (1 << 29));
}
+
+ vcpu->arch.pvr_arch = pvr_to_arch(pvr);
+ if (vcpu->arch.pvr_arch < vcpu->arch.compat_arch)
+ vcpu->arch.compat_arch = 0;
+}
+
+static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 compat_arch)
+{
+ if (compat_arch > vcpu->arch.pvr_arch)
+ return -EINVAL;
+ vcpu->arch.compat_arch = vcpu->arch.pvr_arch;
+ return 0;
}

/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To
@@ -1332,6 +1366,9 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id,
else
*val = get_reg_val(id, 0);
break;
+ case KVM_REG_PPC_ARCH_COMPAT:
+ *val = get_reg_val(id, vcpu->arch.compat_arch);
+ break;
default:
r = -EINVAL;
break;
@@ -1361,6 +1398,8 @@ static int kvmppc_set_one_reg_pr(struct kvm_vcpu *vcpu, u64 id,
case KVM_REG_PPC_LPCR:
case KVM_REG_PPC_LPCR_64:
kvmppc_set_lpcr_pr(vcpu, set_reg_val(id, *val));
+ case KVM_REG_PPC_ARCH_COMPAT:
+ r = kvmppc_set_arch_compat(vcpu, set_reg_val(id, *val));
break;
default:
r = -EINVAL;
--
2.1.0.rc1
Loading...