Blame SOURCES/kvm-pseries-Enable-in-kernel-H_LOGICAL_CI_-LOAD-STORE-im.patch

8be556
From 9c94ac69a0301cf41267fded8c2e812c4f975426 Mon Sep 17 00:00:00 2001
8be556
From: David Gibson <dgibson@redhat.com>
8be556
Date: Fri, 3 Jul 2015 04:56:16 +0200
8be556
Subject: [PATCH 105/217] pseries: Enable in-kernel H_LOGICAL_CI_{LOAD, STORE}
8be556
 implementations
8be556
8be556
Message-id: <1435899376-15918-1-git-send-email-dgibson@redhat.com>
8be556
Patchwork-id: 66618
8be556
O-Subject: [RHEL-7.2 qemu-kvm-rhev PATCH] pseries: Enable in-kernel H_LOGICAL_CI_{LOAD, STORE} implementations
8be556
Bugzilla: 1217277
8be556
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
8be556
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
8be556
RH-Acked-by: Thomas Huth <thuth@redhat.com>
8be556
8be556
qemu currently implements the hypercalls H_LOGICAL_CI_LOAD and
8be556
H_LOGICAL_CI_STORE as PAPR extensions.  These are used by the SLOF firmware
8be556
for IO, because performing cache inhibited MMIO accesses with the MMU off
8be556
(real mode) is very awkward on POWER.
8be556
8be556
This approach breaks when SLOF needs to access IO devices implemented
8be556
within KVM instead of in qemu.  The simplest example would be virtio-blk
8be556
using an iothread, because the iothread / dataplane mechanism relies on
8be556
an in-kernel implementation of the virtio queue notification MMIO.
8be556
8be556
To fix this, an in-kernel implementation of these hypercalls has been made,
8be556
(kernel commit 99342cf "kvmppc: Implement H_LOGICAL_CI_{LOAD,STORE} in KVM"
8be556
however, the hypercalls still need to be enabled from qemu.  This performs
8be556
the necessary calls to do so.
8be556
8be556
It would be nice to provide some warning if we encounter a problematic
8be556
device with a kernel which doesn't support the new calls.  Unfortunately,
8be556
I can't see a way to detect this case which won't either warn in far too
8be556
many cases that will probably work, or which is horribly invasive.
8be556
8be556
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
8be556
Reviewed-by: Thomas Huth <thuth@redhat.com>
8be556
Signed-off-by: Alexander Graf <agraf@suse.de>
8be556
(cherry picked from commit 026bfd89cb896c8a3460cc551cc4836219bd7ff9)
8be556
8be556
Signed-off-by: David Gibson <dgibson@redhat.com>
8be556
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
8be556
---
8be556
 hw/ppc/spapr.c       |  5 +++++
8be556
 target-ppc/kvm.c     | 17 +++++++++++++++++
8be556
 target-ppc/kvm_ppc.h |  5 +++++
8be556
 3 files changed, 27 insertions(+)
8be556
8be556
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
8be556
index 41930d8..21bb6da 100644
8be556
--- a/hw/ppc/spapr.c
8be556
+++ b/hw/ppc/spapr.c
8be556
@@ -1506,6 +1506,11 @@ static void ppc_spapr_init(MachineState *machine)
8be556
         qemu_register_reset(spapr_cpu_reset, cpu);
8be556
     }
8be556
 
8be556
+    if (kvm_enabled()) {
8be556
+        /* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */
8be556
+        kvmppc_enable_logical_ci_hcalls();
8be556
+    }
8be556
+
8be556
     /* allocate RAM */
8be556
     spapr->ram_limit = ram_size;
8be556
     memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",
8be556
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
8be556
index 12328a4..16f62b5 100644
8be556
--- a/target-ppc/kvm.c
8be556
+++ b/target-ppc/kvm.c
8be556
@@ -1882,6 +1882,23 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
8be556
     return 0;
8be556
 }
8be556
 
8be556
+static inline int kvmppc_enable_hcall(KVMState *s, target_ulong hcall)
8be556
+{
8be556
+    return kvm_vm_enable_cap(s, KVM_CAP_PPC_ENABLE_HCALL, 0, hcall, 1);
8be556
+}
8be556
+
8be556
+void kvmppc_enable_logical_ci_hcalls(void)
8be556
+{
8be556
+    /*
8be556
+     * FIXME: it would be nice if we could detect the cases where
8be556
+     * we're using a device which requires the in kernel
8be556
+     * implementation of these hcalls, but the kernel lacks them and
8be556
+     * produce a warning.
8be556
+     */
8be556
+    kvmppc_enable_hcall(kvm_state, H_LOGICAL_CI_LOAD);
8be556
+    kvmppc_enable_hcall(kvm_state, H_LOGICAL_CI_STORE);
8be556
+}
8be556
+
8be556
 void kvmppc_set_papr(PowerPCCPU *cpu)
8be556
 {
8be556
     CPUState *cs = CPU(cpu);
8be556
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
8be556
index 2e0224c..4d30e27 100644
8be556
--- a/target-ppc/kvm_ppc.h
8be556
+++ b/target-ppc/kvm_ppc.h
8be556
@@ -24,6 +24,7 @@ bool kvmppc_get_host_serial(char **buf);
8be556
 int kvmppc_get_hasidle(CPUPPCState *env);
8be556
 int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
8be556
 int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
8be556
+void kvmppc_enable_logical_ci_hcalls(void);
8be556
 void kvmppc_set_papr(PowerPCCPU *cpu);
8be556
 int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version);
8be556
 void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
8be556
@@ -107,6 +108,10 @@ static inline int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level)
8be556
     return -1;
8be556
 }
8be556
 
8be556
+static inline void kvmppc_enable_logical_ci_hcalls(void)
8be556
+{
8be556
+}
8be556
+
8be556
 static inline void kvmppc_set_papr(PowerPCCPU *cpu)
8be556
 {
8be556
 }
8be556
-- 
8be556
1.8.3.1
8be556