|
|
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 |
|