summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2015-02-04 19:53:25 -0500
committerAlexander Graf <agraf@suse.de>2015-04-21 09:21:28 -0400
commit99342cf8044420eebdf9297ca03a14cb6a7085a1 (patch)
treea69b2a8188c37bf8eb5b2e004d1f2ff3b278c493 /arch/powerpc
parentae75116efdc29bb42f1d99f8c51b5c52965b2413 (diff)
kvmppc: Implement H_LOGICAL_CI_{LOAD,STORE} in KVM
On POWER, storage caching is usually configured via the MMU - attributes such as cache-inhibited are stored in the TLB and the hashed page table. This makes correctly performing cache inhibited IO accesses awkward when the MMU is turned off (real mode). Some CPU models provide special registers to control the cache attributes of real mode load and stores but this is not at all consistent. This is a problem in particular for SLOF, the firmware used on KVM guests, which runs entirely in real mode, but which needs to do IO to load the kernel. To simplify this qemu implements two special hypercalls, H_LOGICAL_CI_LOAD and H_LOGICAL_CI_STORE which simulate a cache-inhibited load or store to a logical address (aka guest physical address). SLOF uses these for IO. However, because these are implemented within qemu, not the host kernel, these bypass any IO devices emulated within KVM itself. The simplest way to see this problem is to attempt to boot a KVM guest from a virtio-blk device with iothread / dataplane enabled. The iothread code relies on an in kernel implementation of the virtio queue notification, which is not triggered by the IO hcalls, and so the guest will stall in SLOF unable to load the guest OS. This patch addresses this by providing in-kernel implementations of the 2 hypercalls, which correctly scan the KVM IO bus. Any access to an address not handled by the KVM IO bus will cause a VM exit, hitting the qemu implementation as before. Note that a userspace change is also required, in order to enable these new hcall implementations with KVM_CAP_PPC_ENABLE_HCALL. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> [agraf: fix compilation] Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h3
-rw-r--r--arch/powerpc/kvm/book3s.c76
-rw-r--r--arch/powerpc/kvm/book3s_hv.c12
-rw-r--r--arch/powerpc/kvm/book3s_pr_papr.c28
4 files changed, 119 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 942c7b1678e3..578e550f937b 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -292,6 +292,9 @@ static inline bool kvmppc_supports_magic_page(struct kvm_vcpu *vcpu)
292 return !is_kvmppc_hv_enabled(vcpu->kvm); 292 return !is_kvmppc_hv_enabled(vcpu->kvm);
293} 293}
294 294
295extern int kvmppc_h_logical_ci_load(struct kvm_vcpu *vcpu);
296extern int kvmppc_h_logical_ci_store(struct kvm_vcpu *vcpu);
297
295/* Magic register values loaded into r3 and r4 before the 'sc' assembly 298/* Magic register values loaded into r3 and r4 before the 'sc' assembly
296 * instruction for the OSI hypercalls */ 299 * instruction for the OSI hypercalls */
297#define OSI_SC_MAGIC_R3 0x113724FA 300#define OSI_SC_MAGIC_R3 0x113724FA
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index cfbcdc654201..453a8a47a467 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -821,6 +821,82 @@ void kvmppc_core_destroy_vm(struct kvm *kvm)
821#endif 821#endif
822} 822}
823 823
824int kvmppc_h_logical_ci_load(struct kvm_vcpu *vcpu)
825{
826 unsigned long size = kvmppc_get_gpr(vcpu, 4);
827 unsigned long addr = kvmppc_get_gpr(vcpu, 5);
828 u64 buf;
829 int ret;
830
831 if (!is_power_of_2(size) || (size > sizeof(buf)))
832 return H_TOO_HARD;
833
834 ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, size, &buf);
835 if (ret != 0)
836 return H_TOO_HARD;
837
838 switch (size) {
839 case 1:
840 kvmppc_set_gpr(vcpu, 4, *(u8 *)&buf);
841 break;
842
843 case 2:
844 kvmppc_set_gpr(vcpu, 4, be16_to_cpu(*(__be16 *)&buf));
845 break;
846
847 case 4:
848 kvmppc_set_gpr(vcpu, 4, be32_to_cpu(*(__be32 *)&buf));
849 break;
850
851 case 8:
852 kvmppc_set_gpr(vcpu, 4, be64_to_cpu(*(__be64 *)&buf));
853 break;
854
855 default:
856 BUG();
857 }
858
859 return H_SUCCESS;
860}
861EXPORT_SYMBOL_GPL(kvmppc_h_logical_ci_load);
862
863int kvmppc_h_logical_ci_store(struct kvm_vcpu *vcpu)
864{
865 unsigned long size = kvmppc_get_gpr(vcpu, 4);
866 unsigned long addr = kvmppc_get_gpr(vcpu, 5);
867 unsigned long val = kvmppc_get_gpr(vcpu, 6);
868 u64 buf;
869 int ret;
870
871 switch (size) {
872 case 1:
873 *(u8 *)&buf = val;
874 break;
875
876 case 2:
877 *(__be16 *)&buf = cpu_to_be16(val);
878 break;
879
880 case 4:
881 *(__be32 *)&buf = cpu_to_be32(val);
882 break;
883
884 case 8:
885 *(__be64 *)&buf = cpu_to_be64(val);
886 break;
887
888 default:
889 return H_TOO_HARD;
890 }
891
892 ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, addr, size, &buf);
893 if (ret != 0)
894 return H_TOO_HARD;
895
896 return H_SUCCESS;
897}
898EXPORT_SYMBOL_GPL(kvmppc_h_logical_ci_store);
899
824int kvmppc_core_check_processor_compat(void) 900int kvmppc_core_check_processor_compat(void)
825{ 901{
826 /* 902 /*
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index de747563d29d..b9c11a3abcb2 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -706,6 +706,16 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
706 706
707 /* Send the error out to userspace via KVM_RUN */ 707 /* Send the error out to userspace via KVM_RUN */
708 return rc; 708 return rc;
709 case H_LOGICAL_CI_LOAD:
710 ret = kvmppc_h_logical_ci_load(vcpu);
711 if (ret == H_TOO_HARD)
712 return RESUME_HOST;
713 break;
714 case H_LOGICAL_CI_STORE:
715 ret = kvmppc_h_logical_ci_store(vcpu);
716 if (ret == H_TOO_HARD)
717 return RESUME_HOST;
718 break;
709 case H_SET_MODE: 719 case H_SET_MODE:
710 ret = kvmppc_h_set_mode(vcpu, kvmppc_get_gpr(vcpu, 4), 720 ret = kvmppc_h_set_mode(vcpu, kvmppc_get_gpr(vcpu, 4),
711 kvmppc_get_gpr(vcpu, 5), 721 kvmppc_get_gpr(vcpu, 5),
@@ -740,6 +750,8 @@ static int kvmppc_hcall_impl_hv(unsigned long cmd)
740 case H_CONFER: 750 case H_CONFER:
741 case H_REGISTER_VPA: 751 case H_REGISTER_VPA:
742 case H_SET_MODE: 752 case H_SET_MODE:
753 case H_LOGICAL_CI_LOAD:
754 case H_LOGICAL_CI_STORE:
743#ifdef CONFIG_KVM_XICS 755#ifdef CONFIG_KVM_XICS
744 case H_XIRR: 756 case H_XIRR:
745 case H_CPPR: 757 case H_CPPR:
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c
index ce3c893d509b..f2c75a1e0536 100644
--- a/arch/powerpc/kvm/book3s_pr_papr.c
+++ b/arch/powerpc/kvm/book3s_pr_papr.c
@@ -258,6 +258,28 @@ static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
258 return EMULATE_DONE; 258 return EMULATE_DONE;
259} 259}
260 260
261static int kvmppc_h_pr_logical_ci_load(struct kvm_vcpu *vcpu)
262{
263 long rc;
264
265 rc = kvmppc_h_logical_ci_load(vcpu);
266 if (rc == H_TOO_HARD)
267 return EMULATE_FAIL;
268 kvmppc_set_gpr(vcpu, 3, rc);
269 return EMULATE_DONE;
270}
271
272static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu *vcpu)
273{
274 long rc;
275
276 rc = kvmppc_h_logical_ci_store(vcpu);
277 if (rc == H_TOO_HARD)
278 return EMULATE_FAIL;
279 kvmppc_set_gpr(vcpu, 3, rc);
280 return EMULATE_DONE;
281}
282
261static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) 283static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
262{ 284{
263 long rc = kvmppc_xics_hcall(vcpu, cmd); 285 long rc = kvmppc_xics_hcall(vcpu, cmd);
@@ -290,6 +312,10 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
290 clear_bit(KVM_REQ_UNHALT, &vcpu->requests); 312 clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
291 vcpu->stat.halt_wakeup++; 313 vcpu->stat.halt_wakeup++;
292 return EMULATE_DONE; 314 return EMULATE_DONE;
315 case H_LOGICAL_CI_LOAD:
316 return kvmppc_h_pr_logical_ci_load(vcpu);
317 case H_LOGICAL_CI_STORE:
318 return kvmppc_h_pr_logical_ci_store(vcpu);
293 case H_XIRR: 319 case H_XIRR:
294 case H_CPPR: 320 case H_CPPR:
295 case H_EOI: 321 case H_EOI:
@@ -323,6 +349,8 @@ int kvmppc_hcall_impl_pr(unsigned long cmd)
323 case H_BULK_REMOVE: 349 case H_BULK_REMOVE:
324 case H_PUT_TCE: 350 case H_PUT_TCE:
325 case H_CEDE: 351 case H_CEDE:
352 case H_LOGICAL_CI_LOAD:
353 case H_LOGICAL_CI_STORE:
326#ifdef CONFIG_KVM_XICS 354#ifdef CONFIG_KVM_XICS
327 case H_XIRR: 355 case H_XIRR:
328 case H_CPPR: 356 case H_CPPR: