Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

David Gibson and committed by
Alexander Graf
99342cf8 ae75116e

+119
+3
arch/powerpc/include/asm/kvm_book3s.h
··· 292 292 return !is_kvmppc_hv_enabled(vcpu->kvm); 293 293 } 294 294 295 + extern int kvmppc_h_logical_ci_load(struct kvm_vcpu *vcpu); 296 + extern int kvmppc_h_logical_ci_store(struct kvm_vcpu *vcpu); 297 + 295 298 /* Magic register values loaded into r3 and r4 before the 'sc' assembly 296 299 * instruction for the OSI hypercalls */ 297 300 #define OSI_SC_MAGIC_R3 0x113724FA
+76
arch/powerpc/kvm/book3s.c
··· 821 821 #endif 822 822 } 823 823 824 + int 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 + } 861 + EXPORT_SYMBOL_GPL(kvmppc_h_logical_ci_load); 862 + 863 + int 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 + } 898 + EXPORT_SYMBOL_GPL(kvmppc_h_logical_ci_store); 899 + 824 900 int kvmppc_core_check_processor_compat(void) 825 901 { 826 902 /*
+12
arch/powerpc/kvm/book3s_hv.c
··· 706 706 707 707 /* Send the error out to userspace via KVM_RUN */ 708 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 719 case H_SET_MODE: 710 720 ret = kvmppc_h_set_mode(vcpu, kvmppc_get_gpr(vcpu, 4), 711 721 kvmppc_get_gpr(vcpu, 5), ··· 750 740 case H_CONFER: 751 741 case H_REGISTER_VPA: 752 742 case H_SET_MODE: 743 + case H_LOGICAL_CI_LOAD: 744 + case H_LOGICAL_CI_STORE: 753 745 #ifdef CONFIG_KVM_XICS 754 746 case H_XIRR: 755 747 case H_CPPR:
+28
arch/powerpc/kvm/book3s_pr_papr.c
··· 258 258 return EMULATE_DONE; 259 259 } 260 260 261 + static 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 + 272 + static 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 + 261 283 static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) 262 284 { 263 285 long rc = kvmppc_xics_hcall(vcpu, cmd); ··· 312 290 clear_bit(KVM_REQ_UNHALT, &vcpu->requests); 313 291 vcpu->stat.halt_wakeup++; 314 292 return EMULATE_DONE; 293 + case H_LOGICAL_CI_LOAD: 294 + return kvmppc_h_pr_logical_ci_load(vcpu); 295 + case H_LOGICAL_CI_STORE: 296 + return kvmppc_h_pr_logical_ci_store(vcpu); 315 297 case H_XIRR: 316 298 case H_CPPR: 317 299 case H_EOI: ··· 349 323 case H_BULK_REMOVE: 350 324 case H_PUT_TCE: 351 325 case H_CEDE: 326 + case H_LOGICAL_CI_LOAD: 327 + case H_LOGICAL_CI_STORE: 352 328 #ifdef CONFIG_KVM_XICS 353 329 case H_XIRR: 354 330 case H_CPPR: