aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_hv.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2014-06-01 21:02:59 -0400
committerAlexander Graf <agraf@suse.de>2014-07-28 09:22:17 -0400
commit699a0ea0823d32030b0666b28ff8633960f7ffa7 (patch)
treefdfa3e767593f47b66a08313e97cd0fe35b12300 /arch/powerpc/kvm/book3s_hv.c
parent1f0eeb7e1a88f46afa0f435cf7c34b0c84cf2394 (diff)
KVM: PPC: Book3S: Controls for in-kernel sPAPR hypercall handling
This provides a way for userspace controls which sPAPR hcalls get handled in the kernel. Each hcall can be individually enabled or disabled for in-kernel handling, except for H_RTAS. The exception for H_RTAS is because userspace can already control whether individual RTAS functions are handled in-kernel or not via the KVM_PPC_RTAS_DEFINE_TOKEN ioctl, and because the numeric value for H_RTAS is out of the normal sequence of hcall numbers. Hcalls are enabled or disabled using the KVM_ENABLE_CAP ioctl for the KVM_CAP_PPC_ENABLE_HCALL capability on the file descriptor for the VM. The args field of the struct kvm_enable_cap specifies the hcall number in args[0] and the enable/disable flag in args[1]; 0 means disable in-kernel handling (so that the hcall will always cause an exit to userspace) and 1 means enable. Enabling or disabling in-kernel handling of an hcall is effective across the whole VM. The ability for KVM_ENABLE_CAP to be used on a VM file descriptor on PowerPC is new, added by this commit. The KVM_CAP_ENABLE_CAP_VM capability advertises that this ability exists. When a VM is created, an initial set of hcalls are enabled for in-kernel handling. The set that is enabled is the set that have an in-kernel implementation at this point. Any new hcall implementations from this point onwards should not be added to the default set without a good reason. No distinction is made between real-mode and virtual-mode hcall implementations; the one setting controls them both. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/book3s_hv.c')
-rw-r--r--arch/powerpc/kvm/book3s_hv.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 1562acfa05bf..cf445d22570f 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -67,6 +67,8 @@
67/* Used as a "null" value for timebase values */ 67/* Used as a "null" value for timebase values */
68#define TB_NIL (~(u64)0) 68#define TB_NIL (~(u64)0)
69 69
70static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);
71
70static void kvmppc_end_cede(struct kvm_vcpu *vcpu); 72static void kvmppc_end_cede(struct kvm_vcpu *vcpu);
71static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); 73static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu);
72 74
@@ -562,6 +564,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
562 struct kvm_vcpu *tvcpu; 564 struct kvm_vcpu *tvcpu;
563 int idx, rc; 565 int idx, rc;
564 566
567 if (req <= MAX_HCALL_OPCODE &&
568 !test_bit(req/4, vcpu->kvm->arch.enabled_hcalls))
569 return RESUME_HOST;
570
565 switch (req) { 571 switch (req) {
566 case H_ENTER: 572 case H_ENTER:
567 idx = srcu_read_lock(&vcpu->kvm->srcu); 573 idx = srcu_read_lock(&vcpu->kvm->srcu);
@@ -2269,6 +2275,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
2269 */ 2275 */
2270 cpumask_setall(&kvm->arch.need_tlb_flush); 2276 cpumask_setall(&kvm->arch.need_tlb_flush);
2271 2277
2278 /* Start out with the default set of hcalls enabled */
2279 memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls,
2280 sizeof(kvm->arch.enabled_hcalls));
2281
2272 kvm->arch.rma = NULL; 2282 kvm->arch.rma = NULL;
2273 2283
2274 kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); 2284 kvm->arch.host_sdr1 = mfspr(SPRN_SDR1);
@@ -2407,6 +2417,45 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp,
2407 return r; 2417 return r;
2408} 2418}
2409 2419
2420/*
2421 * List of hcall numbers to enable by default.
2422 * For compatibility with old userspace, we enable by default
2423 * all hcalls that were implemented before the hcall-enabling
2424 * facility was added. Note this list should not include H_RTAS.
2425 */
2426static unsigned int default_hcall_list[] = {
2427 H_REMOVE,
2428 H_ENTER,
2429 H_READ,
2430 H_PROTECT,
2431 H_BULK_REMOVE,
2432 H_GET_TCE,
2433 H_PUT_TCE,
2434 H_SET_DABR,
2435 H_SET_XDABR,
2436 H_CEDE,
2437 H_PROD,
2438 H_CONFER,
2439 H_REGISTER_VPA,
2440#ifdef CONFIG_KVM_XICS
2441 H_EOI,
2442 H_CPPR,
2443 H_IPI,
2444 H_IPOLL,
2445 H_XIRR,
2446 H_XIRR_X,
2447#endif
2448 0
2449};
2450
2451static void init_default_hcalls(void)
2452{
2453 int i;
2454
2455 for (i = 0; default_hcall_list[i]; ++i)
2456 __set_bit(default_hcall_list[i] / 4, default_enabled_hcalls);
2457}
2458
2410static struct kvmppc_ops kvm_ops_hv = { 2459static struct kvmppc_ops kvm_ops_hv = {
2411 .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, 2460 .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv,
2412 .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, 2461 .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv,
@@ -2454,6 +2503,8 @@ static int kvmppc_book3s_init_hv(void)
2454 kvm_ops_hv.owner = THIS_MODULE; 2503 kvm_ops_hv.owner = THIS_MODULE;
2455 kvmppc_hv_ops = &kvm_ops_hv; 2504 kvmppc_hv_ops = &kvm_ops_hv;
2456 2505
2506 init_default_hcalls();
2507
2457 r = kvmppc_mmu_hv_init(); 2508 r = kvmppc_mmu_hv_init();
2458 return r; 2509 return r;
2459} 2510}