* [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2
@ 2014-05-31 7:21 Paul Mackerras
2014-05-31 7:21 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Paul Mackerras @ 2014-05-31 7:21 UTC (permalink / raw)
To: Alexander Graf; +Cc: kvm-ppc, kvm
This patch series adds a way for userspace to control which PAPR
hypercalls get handled by kernel handlers vs. being sent up to
userspace, and then adds an implementation of a new hypercall,
H_SET_MODE.
This version makes the KVM_CAP_PPC_ENABLE_HCALL capability a VM
capability rather than a vcpu capability, and checks that the hcall
numbers in the default-enabled list have an in-kernel implementation.
The series is against the queue branch of the kvm tree. I would like
these patches to go into 3.16 if possible.
Paul.
Documentation/virtual/kvm/api.txt | 23 ++++++
arch/powerpc/include/asm/hvcall.h | 6 ++
arch/powerpc/include/asm/kvm_book3s.h | 4 +
arch/powerpc/include/asm/kvm_host.h | 2 +
arch/powerpc/include/asm/kvm_ppc.h | 2 +-
arch/powerpc/kernel/asm-offsets.c | 1 +
arch/powerpc/kvm/book3s.c | 5 ++
arch/powerpc/kvm/book3s_hv.c | 130 +++++++++++++++++++++++++++++++-
arch/powerpc/kvm/book3s_hv_builtin.c | 13 ++++
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 12 +++
arch/powerpc/kvm/book3s_pr.c | 8 ++
arch/powerpc/kvm/book3s_pr_papr.c | 62 +++++++++++++++
arch/powerpc/kvm/powerpc.c | 47 ++++++++++++
include/uapi/linux/kvm.h | 1 +
14 files changed, 314 insertions(+), 2 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling 2014-05-31 7:21 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Paul Mackerras @ 2014-05-31 7:21 ` Paul Mackerras 2014-06-01 9:55 ` Alexander Graf 2014-05-31 7:21 ` [PATCH 2/3] KVM: PPC: Book3S: Allow only implemented hcalls to be enabled or disabled Paul Mackerras ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Paul Mackerras @ 2014-05-31 7:21 UTC (permalink / raw) To: Alexander Graf; +Cc: kvm-ppc, kvm, Paul Mackerras This provides a way for userspace controls which PAPR 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> --- Documentation/virtual/kvm/api.txt | 19 ++++++++++++ arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/include/asm/kvm_host.h | 2 ++ arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kvm/book3s_hv.c | 51 +++++++++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 11 +++++++ arch/powerpc/kvm/book3s_pr.c | 5 ++++ arch/powerpc/kvm/book3s_pr_papr.c | 37 ++++++++++++++++++++++++ arch/powerpc/kvm/powerpc.c | 45 +++++++++++++++++++++++++++++ include/uapi/linux/kvm.h | 1 + 10 files changed, 173 insertions(+) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 6ff3a77..73c614f 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -3002,3 +3002,22 @@ Parameters: args[0] is the XICS device fd args[1] is the XICS CPU number (server ID) for this vcpu This capability connects the vcpu to an in-kernel XICS device. + +6.8 KVM_CAP_PPC_ENABLE_HCALL + +Architectures: ppc (VM capability) +Parameters: args[0] is the PAPR hcall number + args[1] is 0 to disable, 1 to enable in-kernel handling + +This capability controls whether individual PAPR hypercalls (hcalls) +get handled by the kernel or not. Enabling or disabling in-kernel +handling of an hcall is effective across the VM. On creation, an +initial set of hcalls are enabled for in-kernel handling, which +consists of those hcalls for which in-kernel handlers were implemented +before this capability was implemented. If disabled, the kernel will +not to attempt to handle the hcall, but will always exit to userspace +to handle it. Note that it may not make sense to enable some and +disable others of a group of related hcalls, but KVM does not prevent +userspace from doing that. + +This capability is a VM-level capability, not a VCPU capability. diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index f52f656..772044b 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -189,6 +189,7 @@ extern void kvmppc_hv_entry_trampoline(void); extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); +extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm); extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, struct kvm_vcpu *vcpu); extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index bb66d8b..2889587 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -34,6 +34,7 @@ #include <asm/processor.h> #include <asm/page.h> #include <asm/cacheflush.h> +#include <asm/hvcall.h> #define KVM_MAX_VCPUS NR_CPUS #define KVM_MAX_VCORES NR_CPUS @@ -263,6 +264,7 @@ struct kvm_arch { #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; struct list_head rtas_tokens; + DECLARE_BITMAP(enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); #endif #ifdef CONFIG_KVM_MPIC struct openpic *mpic; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 93e1465..c427b51 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -492,6 +492,7 @@ int main(void) DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); + DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index aba05bb..84e695d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -67,6 +67,8 @@ /* Used as a "null" value for timebase values */ #define TB_NIL (~(u64)0) +static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); + static void kvmppc_end_cede(struct kvm_vcpu *vcpu); static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); @@ -562,6 +564,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) struct kvm_vcpu *tvcpu; int idx, rc; + if (req <= MAX_HCALL_OPCODE && + !test_bit(req/4, vcpu->kvm->arch.enabled_hcalls)) + return RESUME_HOST; + switch (req) { case H_ENTER: idx = srcu_read_lock(&vcpu->kvm->srcu); @@ -2275,6 +2281,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) */ cpumask_setall(&kvm->arch.need_tlb_flush); + /* Start out with the default set of hcalls enabled */ + memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, + sizeof(kvm->arch.enabled_hcalls)); + kvm->arch.rma = NULL; kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); @@ -2413,6 +2423,45 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, return r; } +/* + * List of hcall numbers to enable by default. + * For compatibility with old userspace, we enable by default + * all hcalls that were implemented before the hcall-enabling + * facility was added. Note this list should not include H_RTAS. + */ +static unsigned int default_hcall_list[] = { + H_REMOVE, + H_ENTER, + H_READ, + H_PROTECT, + H_BULK_REMOVE, + H_GET_TCE, + H_PUT_TCE, + H_SET_DABR, + H_SET_XDABR, + H_CEDE, + H_PROD, + H_CONFER, + H_REGISTER_VPA, +#ifdef CONFIG_KVM_XICS + H_EOI, + H_CPPR, + H_IPI, + H_IPOLL, + H_XIRR, + H_XIRR_X, +#endif + 0 +}; + +static void init_default_hcalls(void) +{ + int i; + + for (i = 0; default_hcall_list[i]; ++i) + __set_bit(default_hcall_list[i] / 4, default_enabled_hcalls); +} + static struct kvmppc_ops kvm_ops_hv = { .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, @@ -2460,6 +2509,8 @@ static int kvmppc_book3s_init_hv(void) kvm_ops_hv.owner = THIS_MODULE; kvmppc_hv_ops = &kvm_ops_hv; + init_default_hcalls(); + r = kvmppc_mmu_hv_init(); return r; } diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 220aefb..c26b0e2 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1795,6 +1795,17 @@ hcall_try_real_mode: clrrdi r3,r3,2 cmpldi r3,hcall_real_table_end - hcall_real_table bge guest_exit_cont + /* See if this hcall is enabled for in-kernel handling */ + ld r4, VCPU_KVM(r9) + srdi r0, r3, 8 /* r0 = (r3 / 4) >> 6 */ + sldi r0, r0, 3 /* index into kvm->arch.enabled_hcalls[] */ + add r4, r4, r0 + ld r0, KVM_ENABLED_HCALLS(r4) + rlwinm r4, r3, 32-2, 0x3f /* r4 = (r3 / 4) & 0x3f */ + srd r0, r0, r4 + andi. r0, r0, 1 + beq guest_exit_cont + /* Get pointer to handler, if any, and call it */ LOAD_REG_ADDR(r4, hcall_real_table) lwax r3,r3,r4 cmpwi r3,0 diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 23367a7..59dc94e 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1568,6 +1568,11 @@ static int kvmppc_core_init_vm_pr(struct kvm *kvm) { mutex_init(&kvm->arch.hpt_mutex); +#ifdef CONFIG_PPC_BOOK3S_64 + /* Start out with the default set of hcalls enabled */ + kvmppc_pr_init_default_hcalls(kvm); +#endif + if (firmware_has_feature(FW_FEATURE_SET_MODE)) { spin_lock(&kvm_global_user_count_lock); if (++kvm_global_user_count == 1) diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index 52a63bf..c5afde2 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -266,6 +266,10 @@ static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) { + if (cmd <= MAX_HCALL_OPCODE && + !test_bit(cmd/4, vcpu->kvm->arch.enabled_hcalls)) + return EMULATE_FAIL; + switch (cmd) { case H_ENTER: return kvmppc_h_pr_enter(vcpu); @@ -303,3 +307,36 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) return EMULATE_FAIL; } + + +/* + * List of hcall numbers to enable by default. + * For compatibility with old userspace, we enable by default + * all hcalls that were implemented before the hcall-enabling + * facility was added. Note this list should not include H_RTAS. + */ +static unsigned int default_hcall_list[] = { + H_ENTER, + H_REMOVE, + H_PROTECT, + H_BULK_REMOVE, + H_PUT_TCE, + H_CEDE, +#ifdef CONFIG_KVM_XICS + H_XIRR, + H_CPPR, + H_EOI, + H_IPI, + H_IPOLL, + H_XIRR_X, +#endif + 0 +}; + +void kvmppc_pr_init_default_hcalls(struct kvm *kvm) +{ + int i; + + for (i = 0; default_hcall_list[i]; ++i) + __set_bit(default_hcall_list[i] / 4, kvm->arch.enabled_hcalls); +} diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index bab20f4..636f930 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -387,6 +387,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PPC_UNSET_IRQ: case KVM_CAP_PPC_IRQ_LEVEL: case KVM_CAP_ENABLE_CAP: + case KVM_CAP_ENABLE_CAP_VM: case KVM_CAP_ONE_REG: case KVM_CAP_IOEVENTFD: case KVM_CAP_DEVICE_CTRL: @@ -417,6 +418,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_PPC_ALLOC_HTAB: case KVM_CAP_PPC_RTAS: case KVM_CAP_PPC_FIXUP_HCALL: + case KVM_CAP_PPC_ENABLE_HCALL: #ifdef CONFIG_KVM_XICS case KVM_CAP_IRQ_XICS: #endif @@ -1099,6 +1101,40 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, return 0; } + +static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, + struct kvm_enable_cap *cap) +{ + int r; + + if (cap->flags) + return -EINVAL; + + switch (cap->cap) { +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER + case KVM_CAP_PPC_ENABLE_HCALL: { + unsigned long hcall = cap->args[0]; + + r = -EINVAL; + if (hcall > MAX_HCALL_OPCODE || (hcall & 3) || + cap->args[1] > 1) + break; + if (cap->args[1]) + set_bit(hcall / 4, kvm->arch.enabled_hcalls); + else + clear_bit(hcall / 4, kvm->arch.enabled_hcalls); + r = 0; + break; + } +#endif + default: + r = -EINVAL; + break; + } + + return r; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -1118,6 +1154,15 @@ long kvm_arch_vm_ioctl(struct file *filp, break; } + case KVM_ENABLE_CAP: + { + struct kvm_enable_cap cap; + r = -EFAULT; + if (copy_from_user(&cap, argp, sizeof(cap))) + goto out; + r = kvm_vm_ioctl_enable_cap(kvm, &cap); + break; + } #ifdef CONFIG_PPC_BOOK3S_64 case KVM_CREATE_SPAPR_TCE: { struct kvm_create_spapr_tce create_tce; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index e11d8f1..0418b74 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -758,6 +758,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_VM_ATTRIBUTES 101 #define KVM_CAP_ARM_PSCI_0_2 102 #define KVM_CAP_PPC_FIXUP_HCALL 103 +#define KVM_CAP_PPC_ENABLE_HCALL 104 #ifdef KVM_CAP_IRQ_ROUTING -- 2.0.0.rc4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling 2014-05-31 7:21 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras @ 2014-06-01 9:55 ` Alexander Graf 0 siblings, 0 replies; 10+ messages in thread From: Alexander Graf @ 2014-06-01 9:55 UTC (permalink / raw) To: Paul Mackerras; +Cc: kvm-ppc, kvm, Cornelia Huck On 31.05.14 09:21, Paul Mackerras wrote: > This provides a way for userspace controls which PAPR 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> > --- > Documentation/virtual/kvm/api.txt | 19 ++++++++++++ > arch/powerpc/include/asm/kvm_book3s.h | 1 + > arch/powerpc/include/asm/kvm_host.h | 2 ++ > arch/powerpc/kernel/asm-offsets.c | 1 + > arch/powerpc/kvm/book3s_hv.c | 51 +++++++++++++++++++++++++++++++++ > arch/powerpc/kvm/book3s_hv_rmhandlers.S | 11 +++++++ > arch/powerpc/kvm/book3s_pr.c | 5 ++++ > arch/powerpc/kvm/book3s_pr_papr.c | 37 ++++++++++++++++++++++++ > arch/powerpc/kvm/powerpc.c | 45 +++++++++++++++++++++++++++++ > include/uapi/linux/kvm.h | 1 + > 10 files changed, 173 insertions(+) > > diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt > index 6ff3a77..73c614f 100644 > --- a/Documentation/virtual/kvm/api.txt > +++ b/Documentation/virtual/kvm/api.txt > @@ -3002,3 +3002,22 @@ Parameters: args[0] is the XICS device fd > args[1] is the XICS CPU number (server ID) for this vcpu > > This capability connects the vcpu to an in-kernel XICS device. > + > +6.8 KVM_CAP_PPC_ENABLE_HCALL > + > +Architectures: ppc (VM capability) Hrm. Just create a new section for VM scope ENABLE_CAP caps. Putting them into the same bucket as CPU ones will end up confusing :). > +Parameters: args[0] is the PAPR hcall number > + args[1] is 0 to disable, 1 to enable in-kernel handling > + > +This capability controls whether individual PAPR hypercalls (hcalls) Sorry for not seeing this earlier. We support both ePAPR and sPAPR compliant hypercalls on PPC. I think it makes sense to document which ones we're talking about here. Alex ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] KVM: PPC: Book3S: Allow only implemented hcalls to be enabled or disabled 2014-05-31 7:21 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Paul Mackerras 2014-05-31 7:21 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras @ 2014-05-31 7:21 ` Paul Mackerras 2014-05-31 7:21 ` [PATCH 3/3] KVM: PPC: Book3S HV: Add H_SET_MODE hcall handling Paul Mackerras 2014-06-01 10:01 ` [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Alexander Graf 3 siblings, 0 replies; 10+ messages in thread From: Paul Mackerras @ 2014-05-31 7:21 UTC (permalink / raw) To: Alexander Graf; +Cc: kvm-ppc, kvm, Paul Mackerras This adds code to check that when the KVM_CAP_PPC_ENABLE_HCALL capability is used to enable or disable in-kernel handling of an hcall, that the hcall is actually implemented by the kernel. If not an EINVAL error is returned. This also checks the default-enabled list of hcalls and prints a warning if any hcall there is not actually implemented. Signed-off-by: Paul Mackerras <paulus@samba.org> --- Documentation/virtual/kvm/api.txt | 4 ++++ arch/powerpc/include/asm/kvm_book3s.h | 3 +++ arch/powerpc/include/asm/kvm_ppc.h | 2 +- arch/powerpc/kvm/book3s.c | 5 +++++ arch/powerpc/kvm/book3s_hv.c | 31 +++++++++++++++++++++++++++++-- arch/powerpc/kvm/book3s_hv_builtin.c | 13 +++++++++++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 1 + arch/powerpc/kvm/book3s_pr.c | 3 +++ arch/powerpc/kvm/book3s_pr_papr.c | 29 +++++++++++++++++++++++++++-- arch/powerpc/kvm/powerpc.c | 2 ++ 10 files changed, 88 insertions(+), 5 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 73c614f..dbe78ff 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -3020,4 +3020,8 @@ to handle it. Note that it may not make sense to enable some and disable others of a group of related hcalls, but KVM does not prevent userspace from doing that. +If the hcall number specified is not one that has an in-kernel +implementation, the KVM_ENABLE_CAP ioctl will fail with an EINVAL +error. + This capability is a VM-level capability, not a VCPU capability. diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 772044b..a31e49c 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -148,6 +148,7 @@ extern void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache * extern int kvmppc_mmu_hpte_sysinit(void); extern void kvmppc_mmu_hpte_sysexit(void); extern int kvmppc_mmu_hv_init(void); +extern int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hc); extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); @@ -190,6 +191,8 @@ extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm); +extern int kvmppc_hcall_impl_pr(unsigned long cmd); +extern int kvmppc_hcall_impl_hv_realmode(unsigned long cmd); extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, struct kvm_vcpu *vcpu); extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 4a7cc45..0c5cad2 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -228,7 +228,7 @@ struct kvmppc_ops { void (*fast_vcpu_kick)(struct kvm_vcpu *vcpu); long (*arch_vm_ioctl)(struct file *filp, unsigned int ioctl, unsigned long arg); - + int (*hcall_implemented)(unsigned long hcall); }; extern struct kvmppc_ops *kvmppc_hv_ops; diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 52c654d..1e810f4 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -913,6 +913,11 @@ int kvmppc_core_check_processor_compat(void) return 0; } +int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hcall) +{ + return kvm->arch.kvm_ops->hcall_implemented(hcall); +} + static int kvmppc_book3s_init(void) { int r; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 84e695d..1445da5 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -645,6 +645,28 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) return RESUME_GUEST; } +static int kvmppc_hcall_impl_hv(unsigned long cmd) +{ + switch (cmd) { + case H_CEDE: + case H_PROD: + case H_CONFER: + case H_REGISTER_VPA: +#ifdef CONFIG_KVM_XICS + case H_XIRR: + case H_CPPR: + case H_EOI: + case H_IPI: + case H_IPOLL: + case H_XIRR_X: +#endif + return 1; + } + + /* See if it's in the real-mode table */ + return kvmppc_hcall_impl_hv_realmode(cmd); +} + static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, struct task_struct *tsk) { @@ -2457,9 +2479,13 @@ static unsigned int default_hcall_list[] = { static void init_default_hcalls(void) { int i; + unsigned int hcall; - for (i = 0; default_hcall_list[i]; ++i) - __set_bit(default_hcall_list[i] / 4, default_enabled_hcalls); + for (i = 0; default_hcall_list[i]; ++i) { + hcall = default_hcall_list[i]; + WARN_ON(!kvmppc_hcall_impl_hv(hcall)); + __set_bit(hcall / 4, default_enabled_hcalls); + } } static struct kvmppc_ops kvm_ops_hv = { @@ -2494,6 +2520,7 @@ static struct kvmppc_ops kvm_ops_hv = { .emulate_mfspr = kvmppc_core_emulate_mfspr_hv, .fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv, .arch_vm_ioctl = kvm_arch_vm_ioctl_hv, + .hcall_implemented = kvmppc_hcall_impl_hv, }; static int kvmppc_book3s_init_hv(void) diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 8cd0dae..f1b86b3 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -181,3 +181,16 @@ void __init kvm_cma_reserve(void) kvm_cma_declare_contiguous(selected_size, align_size); } } + +extern int hcall_real_table[], hcall_real_table_end[]; + +int kvmppc_hcall_impl_hv_realmode(unsigned long cmd) +{ + cmd /= 4; + if (cmd < hcall_real_table_end - hcall_real_table && + hcall_real_table[cmd]) + return 1; + + return 0; +} +EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode); diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index c26b0e2..6571fcc 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1928,6 +1928,7 @@ hcall_real_table: .long 0 /* 0x12c */ .long 0 /* 0x130 */ .long .kvmppc_h_set_xdabr - hcall_real_table + .globl hcall_real_table_end hcall_real_table_end: ignore_hdec: diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 59dc94e..8e4cba6 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1641,6 +1641,9 @@ static struct kvmppc_ops kvm_ops_pr = { .emulate_mfspr = kvmppc_core_emulate_mfspr_pr, .fast_vcpu_kick = kvm_vcpu_kick, .arch_vm_ioctl = kvm_arch_vm_ioctl_pr, +#ifdef CONFIG_PPC_BOOK3S_64 + .hcall_implemented = kvmppc_hcall_impl_pr, +#endif }; diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index c5afde2..b422f46 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -308,6 +308,27 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) return EMULATE_FAIL; } +int kvmppc_hcall_impl_pr(unsigned long cmd) +{ + switch (cmd) { + case H_ENTER: + case H_REMOVE: + case H_PROTECT: + case H_BULK_REMOVE: + case H_PUT_TCE: + case H_CEDE: +#ifdef CONFIG_KVM_XICS + case H_XIRR: + case H_CPPR: + case H_EOI: + case H_IPI: + case H_IPOLL: + case H_XIRR_X: +#endif + return 1; + } + return 0; +} /* * List of hcall numbers to enable by default. @@ -336,7 +357,11 @@ static unsigned int default_hcall_list[] = { void kvmppc_pr_init_default_hcalls(struct kvm *kvm) { int i; + unsigned int hcall; - for (i = 0; default_hcall_list[i]; ++i) - __set_bit(default_hcall_list[i] / 4, kvm->arch.enabled_hcalls); + for (i = 0; default_hcall_list[i]; ++i) { + hcall = default_hcall_list[i]; + WARN_ON(!kvmppc_hcall_impl_pr(hcall)); + __set_bit(hcall / 4, kvm->arch.enabled_hcalls); + } } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 636f930..b4b81ed 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -1119,6 +1119,8 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, if (hcall > MAX_HCALL_OPCODE || (hcall & 3) || cap->args[1] > 1) break; + if (!kvmppc_book3s_hcall_implemented(kvm, hcall)) + break; if (cap->args[1]) set_bit(hcall / 4, kvm->arch.enabled_hcalls); else -- 2.0.0.rc4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] KVM: PPC: Book3S HV: Add H_SET_MODE hcall handling 2014-05-31 7:21 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Paul Mackerras 2014-05-31 7:21 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras 2014-05-31 7:21 ` [PATCH 2/3] KVM: PPC: Book3S: Allow only implemented hcalls to be enabled or disabled Paul Mackerras @ 2014-05-31 7:21 ` Paul Mackerras 2014-06-01 10:01 ` [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Alexander Graf 3 siblings, 0 replies; 10+ messages in thread From: Paul Mackerras @ 2014-05-31 7:21 UTC (permalink / raw) To: Alexander Graf; +Cc: kvm-ppc, kvm, Michael Neuling, Paul Mackerras From: Michael Neuling <mikey@neuling.org> This adds support for the H_SET_MODE hcall. This hcall is a multiplexer that has several functions, some of which are called rarely, and some which are potentially called very frequently. Here we add support for the functions that set the debug registers CIABR (Completed Instruction Address Breakpoint Register) and DAWR/DAWRX (Data Address Watchpoint Register and eXtension), since they could be updated by the guest as often as every context switch. This also adds a kvmppc_power8_compatible() function to test to see if a guest is compatible with POWER8 or not. The CIABR and DAWR/X only exist on POWER8. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org> --- arch/powerpc/include/asm/hvcall.h | 6 +++++ arch/powerpc/kvm/book3s_hv.c | 52 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 5dbbb29..85bc8c0 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -279,6 +279,12 @@ #define H_GET_24X7_DATA 0xF07C #define H_GET_PERF_COUNTER_INFO 0xF080 +/* Values for 2nd argument to H_SET_MODE */ +#define H_SET_MODE_RESOURCE_SET_CIABR 1 +#define H_SET_MODE_RESOURCE_SET_DAWR 2 +#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 +#define H_SET_MODE_RESOURCE_LE 4 + #ifndef __ASSEMBLY__ /** diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 1445da5..06aaadc 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -557,6 +557,48 @@ static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu, vcpu->arch.dtl.dirty = true; } +static bool kvmppc_power8_compatible(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.vcore->arch_compat >= PVR_ARCH_207) + return true; + if ((!vcpu->arch.vcore->arch_compat) && + cpu_has_feature(CPU_FTR_ARCH_207S)) + return true; + return false; +} + +static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags, + unsigned long resource, unsigned long value1, + unsigned long value2) +{ + switch (resource) { + case H_SET_MODE_RESOURCE_SET_CIABR: + if (!kvmppc_power8_compatible(vcpu)) + return H_P2; + if (value2) + return H_P4; + if (mflags) + return H_UNSUPPORTED_FLAG_START; + /* Guests can't breakpoint the hypervisor */ + if ((value1 & CIABR_PRIV) == CIABR_PRIV_HYPER) + return H_P3; + vcpu->arch.ciabr = value1; + return H_SUCCESS; + case H_SET_MODE_RESOURCE_SET_DAWR: + if (!kvmppc_power8_compatible(vcpu)) + return H_P2; + if (mflags) + return H_UNSUPPORTED_FLAG_START; + if (value2 & DABRX_HYP) + return H_P4; + vcpu->arch.dawr = value1; + vcpu->arch.dawrx = value2; + return H_SUCCESS; + default: + return H_TOO_HARD; + } +} + int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) { unsigned long req = kvmppc_get_gpr(vcpu, 3); @@ -626,7 +668,14 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) /* Send the error out to userspace via KVM_RUN */ return rc; - + case H_SET_MODE: + ret = kvmppc_h_set_mode(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5), + kvmppc_get_gpr(vcpu, 6), + kvmppc_get_gpr(vcpu, 7)); + if (ret == H_TOO_HARD) + return RESUME_HOST; + break; case H_XIRR: case H_CPPR: case H_EOI: @@ -652,6 +701,7 @@ static int kvmppc_hcall_impl_hv(unsigned long cmd) case H_PROD: case H_CONFER: case H_REGISTER_VPA: + case H_SET_MODE: #ifdef CONFIG_KVM_XICS case H_XIRR: case H_CPPR: -- 2.0.0.rc4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 2014-05-31 7:21 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Paul Mackerras ` (2 preceding siblings ...) 2014-05-31 7:21 ` [PATCH 3/3] KVM: PPC: Book3S HV: Add H_SET_MODE hcall handling Paul Mackerras @ 2014-06-01 10:01 ` Alexander Graf 3 siblings, 0 replies; 10+ messages in thread From: Alexander Graf @ 2014-06-01 10:01 UTC (permalink / raw) To: Paul Mackerras; +Cc: kvm-ppc, kvm On 31.05.14 09:21, Paul Mackerras wrote: > This patch series adds a way for userspace to control which PAPR > hypercalls get handled by kernel handlers vs. being sent up to > userspace, and then adds an implementation of a new hypercall, > H_SET_MODE. > > This version makes the KVM_CAP_PPC_ENABLE_HCALL capability a VM > capability rather than a vcpu capability, and checks that the hcall > numbers in the default-enabled list have an in-kernel implementation. > > The series is against the queue branch of the kvm tree. I would like > these patches to go into 3.16 if possible. Thanks, I like all the patches and I think we can manage to get them into 3.16. Please just resend patch 1/3 with fixed documentation :). Alex ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 0/3] New PAPR hypercall plus individual hypercall enables @ 2014-05-26 12:17 Paul Mackerras 2014-05-26 12:17 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras 0 siblings, 1 reply; 10+ messages in thread From: Paul Mackerras @ 2014-05-26 12:17 UTC (permalink / raw) To: Alexander Graf; +Cc: kvm-ppc, kvm This patch series adds a way for userspace to control which PAPR hypercalls get handled by kernel handlers vs. being sent up to userspace, and then adds an implementation of a new hypercall, H_SET_MODE. The series is against Alex Graf's kvm-ppc-queue tree plus the series of 8 bug-fix patches that I posted recently. Please apply these patches for 3.16. Paul. Documentation/virtual/kvm/api.txt | 21 ++++++ arch/powerpc/include/asm/hvcall.h | 6 ++ arch/powerpc/include/asm/kvm_book3s.h | 4 + arch/powerpc/include/asm/kvm_host.h | 2 + arch/powerpc/include/asm/kvm_ppc.h | 2 +- arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kvm/book3s.c | 5 ++ arch/powerpc/kvm/book3s_hv.c | 125 +++++++++++++++++++++++++++++++- arch/powerpc/kvm/book3s_hv_builtin.c | 13 ++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 12 +++ arch/powerpc/kvm/book3s_pr.c | 8 ++ arch/powerpc/kvm/book3s_pr_papr.c | 58 +++++++++++++++ arch/powerpc/kvm/powerpc.c | 21 ++++++ include/uapi/linux/kvm.h | 1 + 14 files changed, 277 insertions(+), 2 deletions(-) ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling 2014-05-26 12:17 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables Paul Mackerras @ 2014-05-26 12:17 ` Paul Mackerras 2014-05-28 13:27 ` Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Paul Mackerras @ 2014-05-26 12:17 UTC (permalink / raw) To: Alexander Graf; +Cc: kvm-ppc, kvm This provides a way for userspace controls which PAPR 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. 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, even though the KVM_ENABLE_CAP ioctl is applied to a vcpu. 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. 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> --- Documentation/virtual/kvm/api.txt | 17 +++++++++++ arch/powerpc/include/asm/kvm_book3s.h | 1 + arch/powerpc/include/asm/kvm_host.h | 2 ++ arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kvm/book3s_hv.c | 51 +++++++++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 11 +++++++ arch/powerpc/kvm/book3s_pr.c | 5 ++++ arch/powerpc/kvm/book3s_pr_papr.c | 37 ++++++++++++++++++++++++ arch/powerpc/kvm/powerpc.c | 19 ++++++++++++ include/uapi/linux/kvm.h | 1 + 10 files changed, 145 insertions(+) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 6b0225d..dfd6e0c 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2983,3 +2983,20 @@ Parameters: args[0] is the XICS device fd args[1] is the XICS CPU number (server ID) for this vcpu This capability connects the vcpu to an in-kernel XICS device. + +6.8 KVM_CAP_PPC_ENABLE_HCALL + +Architectures: ppc +Parameters: args[0] is the PAPR hcall number + args[1] is 0 to disable, 1 to enable in-kernel handling + +This capability controls whether individual PAPR hypercalls (hcalls) +get handled by the kernel or not. Enabling or disabling in-kernel +handling of an hcall is effective across the VM. On creation, an +initial set of hcalls are enabled for in-kernel handling, which +consists of those hcalls for which in-kernel handlers were implemented +before this capability was implemented. If disabled, the kernel will +not to attempt to handle the hcall, but will always exit to userspace +to handle it. Note that it may not make sense to enable some and +disable others of a group of related hcalls, but KVM will not prevent +userspace from doing that. diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index f52f656..772044b 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -189,6 +189,7 @@ extern void kvmppc_hv_entry_trampoline(void); extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); +extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm); extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, struct kvm_vcpu *vcpu); extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index bb66d8b..2889587 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -34,6 +34,7 @@ #include <asm/processor.h> #include <asm/page.h> #include <asm/cacheflush.h> +#include <asm/hvcall.h> #define KVM_MAX_VCPUS NR_CPUS #define KVM_MAX_VCORES NR_CPUS @@ -263,6 +264,7 @@ struct kvm_arch { #ifdef CONFIG_PPC_BOOK3S_64 struct list_head spapr_tce_tables; struct list_head rtas_tokens; + DECLARE_BITMAP(enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); #endif #ifdef CONFIG_KVM_MPIC struct openpic *mpic; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 93e1465..c427b51 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -492,6 +492,7 @@ int main(void) DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); + DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index aba05bb..84e695d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -67,6 +67,8 @@ /* Used as a "null" value for timebase values */ #define TB_NIL (~(u64)0) +static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); + static void kvmppc_end_cede(struct kvm_vcpu *vcpu); static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); @@ -562,6 +564,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) struct kvm_vcpu *tvcpu; int idx, rc; + if (req <= MAX_HCALL_OPCODE && + !test_bit(req/4, vcpu->kvm->arch.enabled_hcalls)) + return RESUME_HOST; + switch (req) { case H_ENTER: idx = srcu_read_lock(&vcpu->kvm->srcu); @@ -2275,6 +2281,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) */ cpumask_setall(&kvm->arch.need_tlb_flush); + /* Start out with the default set of hcalls enabled */ + memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, + sizeof(kvm->arch.enabled_hcalls)); + kvm->arch.rma = NULL; kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); @@ -2413,6 +2423,45 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, return r; } +/* + * List of hcall numbers to enable by default. + * For compatibility with old userspace, we enable by default + * all hcalls that were implemented before the hcall-enabling + * facility was added. Note this list should not include H_RTAS. + */ +static unsigned int default_hcall_list[] = { + H_REMOVE, + H_ENTER, + H_READ, + H_PROTECT, + H_BULK_REMOVE, + H_GET_TCE, + H_PUT_TCE, + H_SET_DABR, + H_SET_XDABR, + H_CEDE, + H_PROD, + H_CONFER, + H_REGISTER_VPA, +#ifdef CONFIG_KVM_XICS + H_EOI, + H_CPPR, + H_IPI, + H_IPOLL, + H_XIRR, + H_XIRR_X, +#endif + 0 +}; + +static void init_default_hcalls(void) +{ + int i; + + for (i = 0; default_hcall_list[i]; ++i) + __set_bit(default_hcall_list[i] / 4, default_enabled_hcalls); +} + static struct kvmppc_ops kvm_ops_hv = { .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, @@ -2460,6 +2509,8 @@ static int kvmppc_book3s_init_hv(void) kvm_ops_hv.owner = THIS_MODULE; kvmppc_hv_ops = &kvm_ops_hv; + init_default_hcalls(); + r = kvmppc_mmu_hv_init(); return r; } diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 220aefb..c26b0e2 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1795,6 +1795,17 @@ hcall_try_real_mode: clrrdi r3,r3,2 cmpldi r3,hcall_real_table_end - hcall_real_table bge guest_exit_cont + /* See if this hcall is enabled for in-kernel handling */ + ld r4, VCPU_KVM(r9) + srdi r0, r3, 8 /* r0 = (r3 / 4) >> 6 */ + sldi r0, r0, 3 /* index into kvm->arch.enabled_hcalls[] */ + add r4, r4, r0 + ld r0, KVM_ENABLED_HCALLS(r4) + rlwinm r4, r3, 32-2, 0x3f /* r4 = (r3 / 4) & 0x3f */ + srd r0, r0, r4 + andi. r0, r0, 1 + beq guest_exit_cont + /* Get pointer to handler, if any, and call it */ LOAD_REG_ADDR(r4, hcall_real_table) lwax r3,r3,r4 cmpwi r3,0 diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 23367a7..59dc94e 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1568,6 +1568,11 @@ static int kvmppc_core_init_vm_pr(struct kvm *kvm) { mutex_init(&kvm->arch.hpt_mutex); +#ifdef CONFIG_PPC_BOOK3S_64 + /* Start out with the default set of hcalls enabled */ + kvmppc_pr_init_default_hcalls(kvm); +#endif + if (firmware_has_feature(FW_FEATURE_SET_MODE)) { spin_lock(&kvm_global_user_count_lock); if (++kvm_global_user_count == 1) diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index 52a63bf..c5afde2 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -266,6 +266,10 @@ static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) { + if (cmd <= MAX_HCALL_OPCODE && + !test_bit(cmd/4, vcpu->kvm->arch.enabled_hcalls)) + return EMULATE_FAIL; + switch (cmd) { case H_ENTER: return kvmppc_h_pr_enter(vcpu); @@ -303,3 +307,36 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) return EMULATE_FAIL; } + + +/* + * List of hcall numbers to enable by default. + * For compatibility with old userspace, we enable by default + * all hcalls that were implemented before the hcall-enabling + * facility was added. Note this list should not include H_RTAS. + */ +static unsigned int default_hcall_list[] = { + H_ENTER, + H_REMOVE, + H_PROTECT, + H_BULK_REMOVE, + H_PUT_TCE, + H_CEDE, +#ifdef CONFIG_KVM_XICS + H_XIRR, + H_CPPR, + H_EOI, + H_IPI, + H_IPOLL, + H_XIRR_X, +#endif + 0 +}; + +void kvmppc_pr_init_default_hcalls(struct kvm *kvm) +{ + int i; + + for (i = 0; default_hcall_list[i]; ++i) + __set_bit(default_hcall_list[i] / 4, kvm->arch.enabled_hcalls); +} diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 154f352..5690c74 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -416,6 +416,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_SPAPR_TCE: case KVM_CAP_PPC_ALLOC_HTAB: case KVM_CAP_PPC_RTAS: + case KVM_CAP_PPC_ENABLE_HCALL: #ifdef CONFIG_KVM_XICS case KVM_CAP_IRQ_XICS: #endif @@ -964,6 +965,24 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, break; } #endif /* CONFIG_KVM_XICS */ +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER + case KVM_CAP_PPC_ENABLE_HCALL: { + unsigned long hcall = cap->args[0]; + + r = -EINVAL; + if (!vcpu->arch.papr_enabled) + break; + if (hcall > MAX_HCALL_OPCODE || (hcall & 3) || + cap->args[1] > 1) + break; + if (cap->args[1]) + set_bit(hcall / 4, vcpu->kvm->arch.enabled_hcalls); + else + clear_bit(hcall / 4, vcpu->kvm->arch.enabled_hcalls); + r = 0; + break; + } +#endif default: r = -EINVAL; break; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 836e15b..79e4532 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -746,6 +746,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_S390_IRQCHIP 99 #define KVM_CAP_IOEVENTFD_NO_LENGTH 100 #define KVM_CAP_VM_ATTRIBUTES 101 +#define KVM_CAP_PPC_ENABLE_HCALL 102 #ifdef KVM_CAP_IRQ_ROUTING -- 2.0.0.rc2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling 2014-05-26 12:17 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras @ 2014-05-28 13:27 ` Alexander Graf 2014-05-29 5:27 ` Paul Mackerras 0 siblings, 1 reply; 10+ messages in thread From: Alexander Graf @ 2014-05-28 13:27 UTC (permalink / raw) To: Paul Mackerras; +Cc: kvm-ppc, kvm On 26.05.14 14:17, Paul Mackerras wrote: > This provides a way for userspace controls which PAPR 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. 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, even though the KVM_ENABLE_CAP ioctl is > applied to a vcpu. > > 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. > > 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> > --- > Documentation/virtual/kvm/api.txt | 17 +++++++++++ > arch/powerpc/include/asm/kvm_book3s.h | 1 + > arch/powerpc/include/asm/kvm_host.h | 2 ++ > arch/powerpc/kernel/asm-offsets.c | 1 + > arch/powerpc/kvm/book3s_hv.c | 51 +++++++++++++++++++++++++++++++++ > arch/powerpc/kvm/book3s_hv_rmhandlers.S | 11 +++++++ > arch/powerpc/kvm/book3s_pr.c | 5 ++++ > arch/powerpc/kvm/book3s_pr_papr.c | 37 ++++++++++++++++++++++++ > arch/powerpc/kvm/powerpc.c | 19 ++++++++++++ > include/uapi/linux/kvm.h | 1 + > 10 files changed, 145 insertions(+) > > diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt > index 6b0225d..dfd6e0c 100644 > --- a/Documentation/virtual/kvm/api.txt > +++ b/Documentation/virtual/kvm/api.txt > @@ -2983,3 +2983,20 @@ Parameters: args[0] is the XICS device fd > args[1] is the XICS CPU number (server ID) for this vcpu > > This capability connects the vcpu to an in-kernel XICS device. > + > +6.8 KVM_CAP_PPC_ENABLE_HCALL > + > +Architectures: ppc > +Parameters: args[0] is the PAPR hcall number > + args[1] is 0 to disable, 1 to enable in-kernel handling > + > +This capability controls whether individual PAPR hypercalls (hcalls) > +get handled by the kernel or not. Enabling or disabling in-kernel > +handling of an hcall is effective across the VM. On creation, an Hrm. Could we move the CAP to vm level then? > +initial set of hcalls are enabled for in-kernel handling, which > +consists of those hcalls for which in-kernel handlers were implemented > +before this capability was implemented. If disabled, the kernel will > +not to attempt to handle the hcall, but will always exit to userspace > +to handle it. Note that it may not make sense to enable some and > +disable others of a group of related hcalls, but KVM will not prevent > +userspace from doing that. > diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h > index f52f656..772044b 100644 > --- a/arch/powerpc/include/asm/kvm_book3s.h > +++ b/arch/powerpc/include/asm/kvm_book3s.h > @@ -189,6 +189,7 @@ extern void kvmppc_hv_entry_trampoline(void); > extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); > extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); > extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd); > +extern void kvmppc_pr_init_default_hcalls(struct kvm *kvm); > extern void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, > struct kvm_vcpu *vcpu); > extern void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, > diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h > index bb66d8b..2889587 100644 > --- a/arch/powerpc/include/asm/kvm_host.h > +++ b/arch/powerpc/include/asm/kvm_host.h > @@ -34,6 +34,7 @@ > #include <asm/processor.h> > #include <asm/page.h> > #include <asm/cacheflush.h> > +#include <asm/hvcall.h> > > #define KVM_MAX_VCPUS NR_CPUS > #define KVM_MAX_VCORES NR_CPUS > @@ -263,6 +264,7 @@ struct kvm_arch { > #ifdef CONFIG_PPC_BOOK3S_64 > struct list_head spapr_tce_tables; > struct list_head rtas_tokens; > + DECLARE_BITMAP(enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); > #endif > #ifdef CONFIG_KVM_MPIC > struct openpic *mpic; > diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c > index 93e1465..c427b51 100644 > --- a/arch/powerpc/kernel/asm-offsets.c > +++ b/arch/powerpc/kernel/asm-offsets.c > @@ -492,6 +492,7 @@ int main(void) > DEFINE(KVM_HOST_SDR1, offsetof(struct kvm, arch.host_sdr1)); > DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); > DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); > + DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); > DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); > DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); > DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index aba05bb..84e695d 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -67,6 +67,8 @@ > /* Used as a "null" value for timebase values */ > #define TB_NIL (~(u64)0) > > +static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1); > + > static void kvmppc_end_cede(struct kvm_vcpu *vcpu); > static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); > > @@ -562,6 +564,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) > struct kvm_vcpu *tvcpu; > int idx, rc; > > + if (req <= MAX_HCALL_OPCODE && > + !test_bit(req/4, vcpu->kvm->arch.enabled_hcalls)) > + return RESUME_HOST; > + > switch (req) { > case H_ENTER: > idx = srcu_read_lock(&vcpu->kvm->srcu); > @@ -2275,6 +2281,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) > */ > cpumask_setall(&kvm->arch.need_tlb_flush); > > + /* Start out with the default set of hcalls enabled */ > + memcpy(kvm->arch.enabled_hcalls, default_enabled_hcalls, > + sizeof(kvm->arch.enabled_hcalls)); > + > kvm->arch.rma = NULL; > > kvm->arch.host_sdr1 = mfspr(SPRN_SDR1); > @@ -2413,6 +2423,45 @@ static long kvm_arch_vm_ioctl_hv(struct file *filp, > return r; > } > > +/* > + * List of hcall numbers to enable by default. > + * For compatibility with old userspace, we enable by default > + * all hcalls that were implemented before the hcall-enabling > + * facility was added. Note this list should not include H_RTAS. > + */ > +static unsigned int default_hcall_list[] = { > + H_REMOVE, > + H_ENTER, > + H_READ, > + H_PROTECT, > + H_BULK_REMOVE, > + H_GET_TCE, > + H_PUT_TCE, > + H_SET_DABR, > + H_SET_XDABR, > + H_CEDE, > + H_PROD, > + H_CONFER, > + H_REGISTER_VPA, > +#ifdef CONFIG_KVM_XICS > + H_EOI, > + H_CPPR, > + H_IPI, > + H_IPOLL, > + H_XIRR, > + H_XIRR_X, > +#endif > + 0 > +}; > + > +static void init_default_hcalls(void) > +{ > + int i; > + > + for (i = 0; default_hcall_list[i]; ++i) BUG_ON(default_hcall_list[i] > MAX_HCALL_OPCODE); Alex > + __set_bit(default_hcall_list[i] / 4, default_enabled_hcalls); > +} > + > static struct kvmppc_ops kvm_ops_hv = { > .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, > .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, > @@ -2460,6 +2509,8 @@ static int kvmppc_book3s_init_hv(void) > kvm_ops_hv.owner = THIS_MODULE; > kvmppc_hv_ops = &kvm_ops_hv; > > + init_default_hcalls(); > + > r = kvmppc_mmu_hv_init(); > return r; > } > diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S > index 220aefb..c26b0e2 100644 > --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S > +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S > @@ -1795,6 +1795,17 @@ hcall_try_real_mode: > clrrdi r3,r3,2 > cmpldi r3,hcall_real_table_end - hcall_real_table > bge guest_exit_cont > + /* See if this hcall is enabled for in-kernel handling */ > + ld r4, VCPU_KVM(r9) > + srdi r0, r3, 8 /* r0 = (r3 / 4) >> 6 */ > + sldi r0, r0, 3 /* index into kvm->arch.enabled_hcalls[] */ > + add r4, r4, r0 > + ld r0, KVM_ENABLED_HCALLS(r4) > + rlwinm r4, r3, 32-2, 0x3f /* r4 = (r3 / 4) & 0x3f */ > + srd r0, r0, r4 > + andi. r0, r0, 1 > + beq guest_exit_cont > + /* Get pointer to handler, if any, and call it */ > LOAD_REG_ADDR(r4, hcall_real_table) > lwax r3,r3,r4 > cmpwi r3,0 > diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c > index 23367a7..59dc94e 100644 > --- a/arch/powerpc/kvm/book3s_pr.c > +++ b/arch/powerpc/kvm/book3s_pr.c > @@ -1568,6 +1568,11 @@ static int kvmppc_core_init_vm_pr(struct kvm *kvm) > { > mutex_init(&kvm->arch.hpt_mutex); > > +#ifdef CONFIG_PPC_BOOK3S_64 > + /* Start out with the default set of hcalls enabled */ > + kvmppc_pr_init_default_hcalls(kvm); > +#endif > + > if (firmware_has_feature(FW_FEATURE_SET_MODE)) { > spin_lock(&kvm_global_user_count_lock); > if (++kvm_global_user_count == 1) > diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c > index 52a63bf..c5afde2 100644 > --- a/arch/powerpc/kvm/book3s_pr_papr.c > +++ b/arch/powerpc/kvm/book3s_pr_papr.c > @@ -266,6 +266,10 @@ static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd) > > int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) > { > + if (cmd <= MAX_HCALL_OPCODE && > + !test_bit(cmd/4, vcpu->kvm->arch.enabled_hcalls)) > + return EMULATE_FAIL; > + > switch (cmd) { > case H_ENTER: > return kvmppc_h_pr_enter(vcpu); > @@ -303,3 +307,36 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) > > return EMULATE_FAIL; > } > + > + > +/* > + * List of hcall numbers to enable by default. > + * For compatibility with old userspace, we enable by default > + * all hcalls that were implemented before the hcall-enabling > + * facility was added. Note this list should not include H_RTAS. > + */ > +static unsigned int default_hcall_list[] = { > + H_ENTER, > + H_REMOVE, > + H_PROTECT, > + H_BULK_REMOVE, > + H_PUT_TCE, > + H_CEDE, > +#ifdef CONFIG_KVM_XICS > + H_XIRR, > + H_CPPR, > + H_EOI, > + H_IPI, > + H_IPOLL, > + H_XIRR_X, > +#endif > + 0 > +}; > + > +void kvmppc_pr_init_default_hcalls(struct kvm *kvm) > +{ > + int i; > + > + for (i = 0; default_hcall_list[i]; ++i) > + __set_bit(default_hcall_list[i] / 4, kvm->arch.enabled_hcalls); > +} > diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c > index 154f352..5690c74 100644 > --- a/arch/powerpc/kvm/powerpc.c > +++ b/arch/powerpc/kvm/powerpc.c > @@ -416,6 +416,7 @@ int kvm_dev_ioctl_check_extension(long ext) > case KVM_CAP_SPAPR_TCE: > case KVM_CAP_PPC_ALLOC_HTAB: > case KVM_CAP_PPC_RTAS: > + case KVM_CAP_PPC_ENABLE_HCALL: > #ifdef CONFIG_KVM_XICS > case KVM_CAP_IRQ_XICS: > #endif > @@ -964,6 +965,24 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, > break; > } > #endif /* CONFIG_KVM_XICS */ > +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER > + case KVM_CAP_PPC_ENABLE_HCALL: { > + unsigned long hcall = cap->args[0]; > + > + r = -EINVAL; > + if (!vcpu->arch.papr_enabled) > + break; > + if (hcall > MAX_HCALL_OPCODE || (hcall & 3) || > + cap->args[1] > 1) > + break; > + if (cap->args[1]) > + set_bit(hcall / 4, vcpu->kvm->arch.enabled_hcalls); > + else > + clear_bit(hcall / 4, vcpu->kvm->arch.enabled_hcalls); > + r = 0; > + break; > + } > +#endif > default: > r = -EINVAL; > break; > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index 836e15b..79e4532 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -746,6 +746,7 @@ struct kvm_ppc_smmu_info { > #define KVM_CAP_S390_IRQCHIP 99 > #define KVM_CAP_IOEVENTFD_NO_LENGTH 100 > #define KVM_CAP_VM_ATTRIBUTES 101 > +#define KVM_CAP_PPC_ENABLE_HCALL 102 > > #ifdef KVM_CAP_IRQ_ROUTING > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling 2014-05-28 13:27 ` Alexander Graf @ 2014-05-29 5:27 ` Paul Mackerras 2014-05-29 6:35 ` Alexander Graf 0 siblings, 1 reply; 10+ messages in thread From: Paul Mackerras @ 2014-05-29 5:27 UTC (permalink / raw) To: Alexander Graf; +Cc: kvm-ppc, kvm On Wed, May 28, 2014 at 03:27:32PM +0200, Alexander Graf wrote: > > On 26.05.14 14:17, Paul Mackerras wrote: > >+6.8 KVM_CAP_PPC_ENABLE_HCALL > >+ > >+Architectures: ppc > >+Parameters: args[0] is the PAPR hcall number > >+ args[1] is 0 to disable, 1 to enable in-kernel handling > >+ > >+This capability controls whether individual PAPR hypercalls (hcalls) > >+get handled by the kernel or not. Enabling or disabling in-kernel > >+handling of an hcall is effective across the VM. On creation, an > > Hrm. Could we move the CAP to vm level then? You mean, define a VM ioctl instead of using a capability? Or are you suggesting something else? Paul. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling 2014-05-29 5:27 ` Paul Mackerras @ 2014-05-29 6:35 ` Alexander Graf 0 siblings, 0 replies; 10+ messages in thread From: Alexander Graf @ 2014-05-29 6:35 UTC (permalink / raw) To: Paul Mackerras; +Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org > Am 29.05.2014 um 07:27 schrieb Paul Mackerras <paulus@samba.org>: > >> On Wed, May 28, 2014 at 03:27:32PM +0200, Alexander Graf wrote: >> >>> On 26.05.14 14:17, Paul Mackerras wrote: >>> +6.8 KVM_CAP_PPC_ENABLE_HCALL >>> + >>> +Architectures: ppc >>> +Parameters: args[0] is the PAPR hcall number >>> + args[1] is 0 to disable, 1 to enable in-kernel handling >>> + >>> +This capability controls whether individual PAPR hypercalls (hcalls) >>> +get handled by the kernel or not. Enabling or disabling in-kernel >>> +handling of an hcall is effective across the VM. On creation, an >> >> Hrm. Could we move the CAP to vm level then? > > You mean, define a VM ioctl instead of using a capability? Or are you > suggesting something else? I'm suggesting ENABLE_CAP on the vm fd :) Alex > > Paul. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-06-01 10:01 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-05-31 7:21 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Paul Mackerras 2014-05-31 7:21 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras 2014-06-01 9:55 ` Alexander Graf 2014-05-31 7:21 ` [PATCH 2/3] KVM: PPC: Book3S: Allow only implemented hcalls to be enabled or disabled Paul Mackerras 2014-05-31 7:21 ` [PATCH 3/3] KVM: PPC: Book3S HV: Add H_SET_MODE hcall handling Paul Mackerras 2014-06-01 10:01 ` [PATCH 0/3] New PAPR hypercall plus individual hypercall enables, v2 Alexander Graf -- strict thread matches above, loose matches on Subject: below -- 2014-05-26 12:17 [PATCH 0/3] New PAPR hypercall plus individual hypercall enables Paul Mackerras 2014-05-26 12:17 ` [PATCH 1/3] KVM: PPC: Book3S: Controls for in-kernel PAPR hypercall handling Paul Mackerras 2014-05-28 13:27 ` Alexander Graf 2014-05-29 5:27 ` Paul Mackerras 2014-05-29 6:35 ` Alexander Graf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox