aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2013-04-17 16:30:00 -0400
committerAlexander Graf <agraf@suse.de>2013-04-26 14:27:29 -0400
commit8e591cb7204739efa8e15967ea334eb367039dde (patch)
tree3fa76d3875c8133eeafc2e36372aaf83232fc54f
parent91194919a6b07d70081fe185a79b129efee84fff (diff)
KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls
For pseries machine emulation, in order to move the interrupt controller code to the kernel, we need to intercept some RTAS calls in the kernel itself. This adds an infrastructure to allow in-kernel handlers to be registered for RTAS services by name. A new ioctl, KVM_PPC_RTAS_DEFINE_TOKEN, then allows userspace to associate token values with those service names. Then, when the guest requests an RTAS service with one of those token values, it will be handled by the relevant in-kernel handler rather than being passed up to userspace as at present. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org> [agraf: fix warning] Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--Documentation/virtual/kvm/api.txt19
-rw-r--r--arch/powerpc/include/asm/hvcall.h3
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h4
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h6
-rw-r--r--arch/powerpc/kvm/Makefile1
-rw-r--r--arch/powerpc/kvm/book3s_hv.c18
-rw-r--r--arch/powerpc/kvm/book3s_pr.c1
-rw-r--r--arch/powerpc/kvm/book3s_pr_papr.c7
-rw-r--r--arch/powerpc/kvm/book3s_rtas.c182
-rw-r--r--arch/powerpc/kvm/powerpc.c8
-rw-r--r--include/uapi/linux/kvm.h3
12 files changed, 252 insertions, 1 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 149558b1e81e..fb308be8521b 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2341,6 +2341,25 @@ and distributor interface, the ioctl must be called after calling
2341KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling 2341KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling
2342this ioctl twice for any of the base addresses will return -EEXIST. 2342this ioctl twice for any of the base addresses will return -EEXIST.
2343 2343
23444.82 KVM_PPC_RTAS_DEFINE_TOKEN
2345
2346Capability: KVM_CAP_PPC_RTAS
2347Architectures: ppc
2348Type: vm ioctl
2349Parameters: struct kvm_rtas_token_args
2350Returns: 0 on success, -1 on error
2351
2352Defines a token value for a RTAS (Run Time Abstraction Services)
2353service in order to allow it to be handled in the kernel. The
2354argument struct gives the name of the service, which must be the name
2355of a service that has a kernel-side implementation. If the token
2356value is non-zero, it will be associated with that service, and
2357subsequent RTAS calls by the guest specifying that token will be
2358handled by the kernel. If the token value is 0, then any token
2359associated with the service will be forgotten, and subsequent RTAS
2360calls by the guest for that service will be passed to userspace to be
2361handled.
2362
2344 2363
23455. The kvm_run structure 23645. The kvm_run structure
2346------------------------ 2365------------------------
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 4bc2c3dad6ad..cf4df8e2139a 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -270,6 +270,9 @@
270#define H_SET_MODE 0x31C 270#define H_SET_MODE 0x31C
271#define MAX_HCALL_OPCODE H_SET_MODE 271#define MAX_HCALL_OPCODE H_SET_MODE
272 272
273/* Platform specific hcalls, used by KVM */
274#define H_RTAS 0xf000
275
273#ifndef __ASSEMBLY__ 276#ifndef __ASSEMBLY__
274 277
275/** 278/**
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 13740a645a6d..311f7e6f09e9 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -259,6 +259,7 @@ struct kvm_arch {
259#endif /* CONFIG_KVM_BOOK3S_64_HV */ 259#endif /* CONFIG_KVM_BOOK3S_64_HV */
260#ifdef CONFIG_PPC_BOOK3S_64 260#ifdef CONFIG_PPC_BOOK3S_64
261 struct list_head spapr_tce_tables; 261 struct list_head spapr_tce_tables;
262 struct list_head rtas_tokens;
262#endif 263#endif
263#ifdef CONFIG_KVM_MPIC 264#ifdef CONFIG_KVM_MPIC
264 struct openpic *mpic; 265 struct openpic *mpic;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index df9c80b37905..8a30eb7f2bec 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -166,6 +166,10 @@ extern int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *);
166 166
167int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq); 167int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq);
168 168
169extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp);
170extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu);
171extern void kvmppc_rtas_tokens_free(struct kvm *kvm);
172
169/* 173/*
170 * Cuts out inst bits with ordering according to spec. 174 * Cuts out inst bits with ordering according to spec.
171 * That means the leftmost bit is zero. All given bits are included. 175 * That means the leftmost bit is zero. All given bits are included.
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 03c7819a44a3..eb9e25c194ad 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -324,6 +324,12 @@ struct kvm_allocate_rma {
324 __u64 rma_size; 324 __u64 rma_size;
325}; 325};
326 326
327/* for KVM_CAP_PPC_RTAS */
328struct kvm_rtas_token_args {
329 char name[120];
330 __u64 token; /* Use a token of 0 to undefine a mapping */
331};
332
327struct kvm_book3e_206_tlb_entry { 333struct kvm_book3e_206_tlb_entry {
328 __u32 mas8; 334 __u32 mas8;
329 __u32 mas1; 335 __u32 mas1;
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 4eada0c01082..3faf5c07329c 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -86,6 +86,7 @@ kvm-book3s_64-module-objs := \
86 emulate.o \ 86 emulate.o \
87 book3s.o \ 87 book3s.o \
88 book3s_64_vio.o \ 88 book3s_64_vio.o \
89 book3s_rtas.o \
89 $(kvm-book3s_64-objs-y) 90 $(kvm-book3s_64-objs-y)
90 91
91kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-module-objs) 92kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-module-objs)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 5af0f2979833..f3d7af7981c7 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -483,7 +483,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
483 unsigned long req = kvmppc_get_gpr(vcpu, 3); 483 unsigned long req = kvmppc_get_gpr(vcpu, 3);
484 unsigned long target, ret = H_SUCCESS; 484 unsigned long target, ret = H_SUCCESS;
485 struct kvm_vcpu *tvcpu; 485 struct kvm_vcpu *tvcpu;
486 int idx; 486 int idx, rc;
487 487
488 switch (req) { 488 switch (req) {
489 case H_ENTER: 489 case H_ENTER:
@@ -519,6 +519,19 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
519 kvmppc_get_gpr(vcpu, 5), 519 kvmppc_get_gpr(vcpu, 5),
520 kvmppc_get_gpr(vcpu, 6)); 520 kvmppc_get_gpr(vcpu, 6));
521 break; 521 break;
522 case H_RTAS:
523 if (list_empty(&vcpu->kvm->arch.rtas_tokens))
524 return RESUME_HOST;
525
526 rc = kvmppc_rtas_hcall(vcpu);
527
528 if (rc == -ENOENT)
529 return RESUME_HOST;
530 else if (rc == 0)
531 break;
532
533 /* Send the error out to userspace via KVM_RUN */
534 return rc;
522 default: 535 default:
523 return RESUME_HOST; 536 return RESUME_HOST;
524 } 537 }
@@ -1829,6 +1842,7 @@ int kvmppc_core_init_vm(struct kvm *kvm)
1829 cpumask_setall(&kvm->arch.need_tlb_flush); 1842 cpumask_setall(&kvm->arch.need_tlb_flush);
1830 1843
1831 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); 1844 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables);
1845 INIT_LIST_HEAD(&kvm->arch.rtas_tokens);
1832 1846
1833 kvm->arch.rma = NULL; 1847 kvm->arch.rma = NULL;
1834 1848
@@ -1874,6 +1888,8 @@ void kvmppc_core_destroy_vm(struct kvm *kvm)
1874 kvm->arch.rma = NULL; 1888 kvm->arch.rma = NULL;
1875 } 1889 }
1876 1890
1891 kvmppc_rtas_tokens_free(kvm);
1892
1877 kvmppc_free_hpt(kvm); 1893 kvmppc_free_hpt(kvm);
1878 WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); 1894 WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables));
1879} 1895}
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index c1cffa882a69..d09baf143500 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1296,6 +1296,7 @@ int kvmppc_core_init_vm(struct kvm *kvm)
1296{ 1296{
1297#ifdef CONFIG_PPC64 1297#ifdef CONFIG_PPC64
1298 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); 1298 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables);
1299 INIT_LIST_HEAD(&kvm->arch.rtas_tokens);
1299#endif 1300#endif
1300 1301