From: Paul Mackerras <paulus@samba.org>
To: Alexander Graf <agraf@suse.de>
Cc: kvm@vger.kernel.org, kvm-ppc@vger.kernel.org
Subject: [PATCH 4/9] KVM: PPC: Book3S: Generalize interfaces to interrupt controller emulation
Date: Fri, 15 Feb 2013 00:01:42 +0000 [thread overview]
Message-ID: <20130215000142.GE17099@iris.ozlabs.ibm.com> (raw)
In-Reply-To: <20130214235907.GA17099@iris.ozlabs.ibm.com>
This makes the XICS interrupt controller emulation code export a struct
containing function pointers for the various calls into the XICS code.
The generic book3s code then uses these function pointers instead of
calling directly into the XICS code (except for the XICS instantiation
function).
This should make it possible for other interrupt controller emulations
to coexist with the XICS emulation.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
arch/powerpc/include/asm/kvm_host.h | 11 ++++-
arch/powerpc/include/asm/kvm_ppc.h | 14 ------
arch/powerpc/kvm/book3s_hv.c | 18 +++----
arch/powerpc/kvm/book3s_pr.c | 14 +++---
arch/powerpc/kvm/book3s_pr_papr.c | 10 ++--
arch/powerpc/kvm/book3s_xics.c | 93 +++++++++++++++++++----------------
arch/powerpc/kvm/powerpc.c | 4 +-
7 files changed, 85 insertions(+), 79 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index b05e7cd..8af4c0b 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -230,8 +230,18 @@ struct kvm_arch_memory_slot {
#endif /* CONFIG_KVM_BOOK3S_64_HV */
};
+struct kvm_irq_ctrler {
+ int (*setup_vcpu)(struct kvm_vcpu *vcpu);
+ void (*teardown_vcpu)(struct kvm_vcpu *vcpu);
+ void (*free_ctrler)(struct kvm *kvm);
+ int (*hcall)(struct kvm_vcpu *vcpu, unsigned long req);
+ int (*ioctl)(struct kvm *kvm, unsigned int ioctl, unsigned long arg);
+};
+
struct kvm_arch {
unsigned int lpid;
+ struct kvm_irq_ctrler *irq_ctrler;
+ void *irq_ctrler_private;
#ifdef CONFIG_KVM_BOOK3S_64_HV
unsigned long hpt_virt;
struct revmap_entry *revmap;
@@ -260,7 +270,6 @@ struct kvm_arch {
#ifdef CONFIG_PPC_BOOK3S_64
struct list_head spapr_tce_tables;
struct list_head rtas_tokens;
- struct kvmppc_xics *xics;
#endif
};
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index f0fd22b..2308fff 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -130,12 +130,7 @@ extern long kvmppc_prepare_vrma(struct kvm *kvm,
extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
struct kvm_memory_slot *memslot, unsigned long porder);
extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
-extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd);
-extern int kvmppc_xics_ioctl(struct kvm *kvm, unsigned ioctl, unsigned long arg);
extern int kvmppc_xics_create(struct kvm *kvm, struct kvm_irqchip_args *args);
-extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
-extern int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu);
-extern void kvmppc_xics_free(struct kvm *kvm);
extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
struct kvm_create_spapr_tce *args);
@@ -275,15 +270,6 @@ static inline void kvm_linear_init(void)
#endif
-#ifdef CONFIG_PPC_BOOK3S_64
-static inline int kvmppc_xics_enabled(struct kvm *kvm)
-{
- return kvm->arch.xics != NULL;
-}
-#else
-static inline int kvmppc_xics_enabled(struct kvm *kvm) { return 0; }
-#endif
-
static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr)
{
#ifdef CONFIG_KVM_BOOKE_HV
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index aa3a0db..8f09c36 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -532,8 +532,8 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
case H_CPPR:
case H_EOI:
case H_IPI:
- if (kvmppc_xics_enabled(vcpu->kvm)) {
- ret = kvmppc_xics_hcall(vcpu, req);
+ if (vcpu->kvm->arch.irq_ctrler) {
+ ret = vcpu->kvm->arch.irq_ctrler->hcall(vcpu, req);
break;
} /* fallthrough */
default:
@@ -894,9 +894,9 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
spin_lock_init(&vcpu->arch.tbacct_lock);
vcpu->arch.busy_preempt = TB_NIL;
- /* Create the XICS */
- if (kvmppc_xics_enabled(kvm)) {
- err = kvmppc_xics_create_icp(vcpu);
+ /* Create the interrupt-controller-specific state */
+ if (kvm->arch.irq_ctrler) {
+ err = kvm->arch.irq_ctrler->setup_vcpu(vcpu);
if (err < 0)
goto free_vcpu;
}
@@ -952,8 +952,8 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.vpa.pinned_addr);
spin_unlock(&vcpu->arch.vpa_update_lock);
kvm_vcpu_uninit(vcpu);
- if (kvmppc_xics_enabled(vcpu->kvm))
- kvmppc_xics_free_icp(vcpu);
+ if (vcpu->kvm->arch.irq_ctrler)
+ vcpu->kvm->arch.irq_ctrler->teardown_vcpu(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu);
}
@@ -1899,8 +1899,8 @@ void kvmppc_core_destroy_vm(struct kvm *kvm)
kvmppc_rtas_tokens_free(kvm);
- if (kvmppc_xics_enabled(kvm))
- kvmppc_xics_free(kvm);
+ if (kvm->arch.irq_ctrler)
+ kvm->arch.irq_ctrler->free_ctrler(kvm);
kvmppc_free_hpt(kvm);
WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables));
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 9b2237f..0c84242 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1069,9 +1069,9 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
if (err < 0)
goto uninit_vcpu;
- /* Create the XICS */
- if (kvmppc_xics_enabled(kvm)) {
- err = kvmppc_xics_create_icp(vcpu);
+ /* Create the interrupt-controller-specific vcpu state */
+ if (kvm->arch.irq_ctrler) {
+ err = kvm->arch.irq_ctrler->setup_vcpu(vcpu);
if (err < 0)
goto free_vcpu;
}
@@ -1092,8 +1092,8 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
- if (kvmppc_xics_enabled(vcpu->kvm))
- kvmppc_xics_free_icp(vcpu);
+ if (vcpu->kvm->arch.irq_ctrler)
+ vcpu->kvm->arch.irq_ctrler->teardown_vcpu(vcpu);
free_page((unsigned long)vcpu->arch.shared & PAGE_MASK);
kvm_vcpu_uninit(vcpu);
kfree(vcpu_book3s->shadow_vcpu);
@@ -1313,8 +1313,8 @@ void kvmppc_core_destroy_vm(struct kvm *kvm)
#ifdef CONFIG_PPC64
WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables));
#endif
- if (kvmppc_xics_enabled(kvm))
- kvmppc_xics_free(kvm);
+ if (kvm->arch.irq_ctrler)
+ kvm->arch.irq_ctrler->free_ctrler(kvm);
}
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c
index 94cec5b..c423b51 100644
--- a/arch/powerpc/kvm/book3s_pr_papr.c
+++ b/arch/powerpc/kvm/book3s_pr_papr.c
@@ -229,7 +229,11 @@ static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
{
- long rc = kvmppc_xics_hcall(vcpu, cmd);
+ long rc;
+
+ if (!vcpu->kvm->arch.irq_ctrler)
+ return EMULATE_FAIL;
+ rc = vcpu->kvm->arch.irq_ctrler->hcall(vcpu, cmd);
if (rc = H_TOO_HARD)
return EMULATE_FAIL;
kvmppc_set_gpr(vcpu, 3, rc);
@@ -259,9 +263,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
case H_CPPR:
case H_EOI:
case H_IPI:
- if (kvmppc_xics_enabled(vcpu->kvm))
- return kvmppc_h_pr_xics_hcall(vcpu, cmd);
- break;
+ return kvmppc_h_pr_xics_hcall(vcpu, cmd);
case H_RTAS:
if (list_empty(&vcpu->kvm->arch.rtas_tokens))
return RESUME_HOST;
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index 7749060..2312b56 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -115,7 +115,7 @@ static void ics_check_resend(struct kvmppc_xics *xics, struct kvmppc_ics *ics,
int kvmppc_xics_set_xive(struct kvm *kvm, u32 irq, u32 server, u32 priority)
{
- struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_xics *xics = kvm->arch.irq_ctrler_private;
struct kvmppc_icp *icp;
struct kvmppc_ics *ics;
struct ics_irq_state *state;
@@ -158,7 +158,7 @@ int kvmppc_xics_set_xive(struct kvm *kvm, u32 irq, u32 server, u32 priority)
int kvmppc_xics_get_xive(struct kvm *kvm, u32 irq, u32 *server, u32 *priority)
{
- struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_xics *xics = kvm->arch.irq_ctrler_private;
struct kvmppc_ics *ics;
struct ics_irq_state *state;
u16 src;
@@ -514,7 +514,7 @@ static noinline int h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
unsigned long mfrr)
{
union kvmppc_icp_state old_state, new_state;
- struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
+ struct kvmppc_xics *xics = vcpu->kvm->arch.irq_ctrler_private;
struct kvmppc_icp *icp;
u32 reject;
bool resend;
@@ -582,7 +582,7 @@ static noinline int h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
static noinline void h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
{
union kvmppc_icp_state old_state, new_state;
- struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
+ struct kvmppc_xics *xics = vcpu->kvm->arch.irq_ctrler_private;
struct kvmppc_icp *icp = vcpu->arch.icp;
u32 reject;
@@ -638,7 +638,7 @@ static noinline void h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
static noinline int h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
{
- struct kvmppc_xics *xics = vcpu->kvm->arch.xics;
+ struct kvmppc_xics *xics = vcpu->kvm->arch.irq_ctrler_private;
struct kvmppc_icp *icp = vcpu->arch.icp;
struct kvmppc_ics *ics;
struct ics_irq_state *state;
@@ -686,13 +686,13 @@ static noinline int h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
return H_SUCCESS;
}
-int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 req)
+static int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, unsigned long req)
{
unsigned long res;
int rc = H_SUCCESS;
/* Check if we have an ICP */
- if (!vcpu->arch.icp || !vcpu->kvm->arch.xics)
+ if (!vcpu->arch.icp || !vcpu->kvm->arch.irq_ctrler_private)
return H_HARDWARE;
switch (req) {
@@ -838,7 +838,7 @@ static struct kvmppc_ics *kvmppc_xics_create_ics(struct kvmppc_xics *xics,
return xics->ics[icsid];
}
-int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu)
+static int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu)
{
struct kvmppc_icp *icp;
@@ -856,7 +856,7 @@ int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu)
return 0;
}
-void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
+static void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
{
if (!vcpu->arch.icp)
return;
@@ -864,9 +864,9 @@ void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
vcpu->arch.icp = NULL;
}
-void kvmppc_xics_free(struct kvm *kvm)
+static void kvmppc_xics_free(struct kvm *kvm)
{
- struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_xics *xics = kvm->arch.irq_ctrler_private;
int i;
if (!xics)
@@ -877,7 +877,7 @@ void kvmppc_xics_free(struct kvm *kvm)
debugfs_remove(xics->dentry);
if (xics->kvm) {
- xics->kvm->arch.xics = NULL;
+ xics->kvm->arch.irq_ctrler_private = NULL;
xics->kvm = NULL;
}
@@ -891,7 +891,7 @@ void kvmppc_xics_free(struct kvm *kvm)
static int kvm_xics_get_sources(struct kvm *kvm, struct kvm_irq_sources *srcs)
{
int ret = 0;
- struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_xics *xics = kvm->arch.irq_ctrler_private;
struct kvmppc_ics *ics;
struct ics_irq_state *irqp;
u64 __user *ubufp;
@@ -941,7 +941,7 @@ static int kvm_xics_get_sources(struct kvm *kvm, struct kvm_irq_sources *srcs)
static int kvm_xics_set_sources(struct kvm *kvm, struct kvm_irq_sources *srcs)
{
int ret = 0;
- struct kvmppc_xics *xics = kvm->arch.xics;
+ struct kvmppc_xics *xics = kvm->arch.irq_ctrler_private;
struct kvmppc_ics *ics;
struct ics_irq_state *irqp;
u64 __user *ubufp;
@@ -999,39 +999,13 @@ static int kvm_xics_set_sources(struct kvm *kvm, struct kvm_irq_sources *srcs)
/* -- ioctls -- */
-int kvmppc_xics_create(struct kvm *kvm, struct kvm_irqchip_args *args)
-{
- struct kvmppc_xics *xics;
- int rc = 0;
-
- mutex_lock(&kvm->lock);
-
- /* Already there ? */
- if (kvm->arch.xics)
- return -EEXIST;
-
- xics = kzalloc(sizeof(*xics), GFP_KERNEL);
- if (!xics) {
- rc = -ENOMEM;
- goto out;
- }
-
- xics->kvm = kvm;
- kvm->arch.xics = xics;
- xics_debugfs_init(xics);
-
-out:
- mutex_unlock(&kvm->lock);
- return rc;
-}
-
static int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args)
{
struct kvmppc_xics *xics;
/* locking against multiple callers? */
- xics = kvm->arch.xics;
+ xics = kvm->arch.irq_ctrler_private;
if (!xics)
return -ENODEV;
@@ -1048,7 +1022,7 @@ static int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args)
return 0;
}
-int kvmppc_xics_ioctl(struct kvm *kvm, unsigned ioctl, unsigned long arg)
+static int kvmppc_xics_ioctl(struct kvm *kvm, unsigned ioctl, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int rc;
@@ -1099,3 +1073,38 @@ int kvmppc_xics_ioctl(struct kvm *kvm, unsigned ioctl, unsigned long arg)
return rc;
}
+
+static struct kvm_irq_ctrler xics_ctrler = {
+ .setup_vcpu = kvmppc_xics_create_icp,
+ .teardown_vcpu = kvmppc_xics_free_icp,
+ .free_ctrler = kvmppc_xics_free,
+ .hcall = kvmppc_xics_hcall,
+ .ioctl = kvmppc_xics_ioctl,
+};
+
+int kvmppc_xics_create(struct kvm *kvm, struct kvm_irqchip_args *args)
+{
+ struct kvmppc_xics *xics;
+ int rc = 0;
+
+ mutex_lock(&kvm->lock);
+
+ /* Already there ? */
+ if (kvm->arch.irq_ctrler)
+ return -EEXIST;
+
+ xics = kzalloc(sizeof(*xics), GFP_KERNEL);
+ if (!xics) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ xics->kvm = kvm;
+ kvm->arch.irq_ctrler = &xics_ctrler;
+ kvm->arch.irq_ctrler_private = xics;
+ xics_debugfs_init(xics);
+
+out:
+ mutex_unlock(&kvm->lock);
+ return rc;
+}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 3bcc030..e429839 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -1009,8 +1009,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
struct kvm *kvm = filp->private_data;
r = -ENOTTY;
- if (kvmppc_xics_enabled(kvm))
- r = kvmppc_xics_ioctl(kvm, ioctl, arg);
+ if (kvm->arch.irq_ctrler)
+ r = kvm->arch.irq_ctrler->ioctl(kvm, ioctl, arg);
break;
}
case KVM_CREATE_IRQCHIP_ARGS: {
--
1.7.10.rc3.219.g53414
next prev parent reply other threads:[~2013-02-15 0:01 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-14 23:59 [PATCH 0/9] In-kernel XICS interrupt controller emulation Paul Mackerras
2013-02-14 23:59 ` [PATCH 1/9] KVM: PPC: Book3S: Add infrastructure to implement kernel-side RTAS calls Paul Mackerras
2013-03-21 8:52 ` Alexander Graf
2013-04-04 5:37 ` Paul Mackerras
2013-04-04 9:49 ` Alexander Graf
2013-04-04 22:38 ` Paul Mackerras
2013-04-19 15:16 ` Alexander Graf
2013-02-15 0:00 ` [PATCH 2/9] KVM: PPC: Remove unused argument to kvmppc_core_dequeue_external Paul Mackerras
2013-03-21 8:58 ` Alexander Graf
2013-02-15 0:01 ` [PATCH 3/9] KVM: PPC: Book3S: Add kernel emulation for the XICS interrupt controller Paul Mackerras
2013-02-15 20:05 ` Scott Wood
2013-02-15 23:18 ` Paul Mackerras
2013-02-15 23:59 ` Scott Wood
2013-02-16 2:56 ` Paul Mackerras
2013-02-16 3:57 ` Scott Wood
2013-02-16 4:51 ` Paul Mackerras
2013-02-18 22:43 ` Scott Wood
2013-02-20 0:41 ` Paul Mackerras
2013-02-20 1:01 ` Scott Wood
2013-02-20 19:58 ` Marcelo Tosatti
2013-02-21 0:20 ` Scott Wood
2013-02-21 1:09 ` Marcelo Tosatti
2013-02-21 1:45 ` Scott Wood
2013-02-24 14:08 ` Gleb Natapov
2013-02-25 0:59 ` Paul Mackerras
2013-03-21 9:20 ` Alexander Graf
2013-02-15 0:01 ` Paul Mackerras [this message]
2013-02-15 0:02 ` [PATCH 5/9] KVM: PPC: Book3S: Facilities to save/restore XICS presentation ctrler state Paul Mackerras
2013-02-15 0:02 ` [PATCH 6/9] KVM: PPC: Book3S HV: Speed up wakeups of CPUs on HV KVM Paul Mackerras
2013-02-15 0:03 ` [PATCH 7/9] KVM: PPC: Book3S HV: Add support for real mode ICP in XICS emulation Paul Mackerras
2013-02-15 0:03 ` [PATCH 8/9] KVM: PPC: Book3S HV: Improve real-mode handling of external interrupts Paul Mackerras
2013-02-15 0:04 ` [PATCH 9/9] KVM: PPC: Book3S: Add support for ibm,int-on/off RTAS calls Paul Mackerras
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130215000142.GE17099@iris.ozlabs.ibm.com \
--to=paulus@samba.org \
--cc=agraf@suse.de \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox