[PATCH 14/20] kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC

2013-04-26 Thread Alexander Graf
From: Scott Wood 

Enabling this capability connects the vcpu to the designated in-kernel
MPIC.  Using explicit connections between vcpus and irqchips allows
for flexibility, but the main benefit at the moment is that it
simplifies the code -- KVM doesn't need vm-global state to remember
which MPIC object is associated with this vm, and it doesn't need to
care about ordering between irqchip creation and vcpu creation.

Signed-off-by: Scott Wood 
[agraf: add stub functions for kvmppc_mpic_{dis,}connect_vcpu]
Signed-off-by: Alexander Graf 
---
 Documentation/virtual/kvm/api.txt   |8 +++
 arch/powerpc/include/asm/kvm_host.h |9 
 arch/powerpc/include/asm/kvm_ppc.h  |   15 ++-
 arch/powerpc/kvm/booke.c|4 ++
 arch/powerpc/kvm/mpic.c |   82 ---
 arch/powerpc/kvm/powerpc.c  |   30 +
 include/uapi/linux/kvm.h|1 +
 7 files changed, 141 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index d52f3f9..4c326ae 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2728,3 +2728,11 @@ to receive the topmost interrupt vector.
 When disabled (args[0] == 0), behavior is as if this facility is unsupported.
 
 When this capability is enabled, KVM_EXIT_EPR can occur.
+
+6.6 KVM_CAP_IRQ_MPIC
+
+Architectures: ppc
+Parameters: args[0] is the MPIC device fd
+args[1] is the MPIC CPU number for this vcpu
+
+This capability connects the vcpu to an in-kernel MPIC device.
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 7e7aef9..36368c9 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -375,6 +375,11 @@ struct kvmppc_booke_debug_reg {
u64 dac[KVMPPC_BOOKE_MAX_DAC];
 };
 
+#define KVMPPC_IRQ_DEFAULT 0
+#define KVMPPC_IRQ_MPIC1
+
+struct openpic;
+
 struct kvm_vcpu_arch {
ulong host_stack;
u32 host_pid;
@@ -554,6 +559,10 @@ struct kvm_vcpu_arch {
unsigned long magic_page_pa; /* phys addr to map the magic page to */
unsigned long magic_page_ea; /* effect. addr to map the magic page to */
 
+   int irq_type;   /* one of KVM_IRQ_* */
+   int irq_cpu_id;
+   struct openpic *mpic;   /* KVM_IRQ_MPIC */
+
 #ifdef CONFIG_KVM_BOOK3S_64_HV
struct kvm_vcpu_arch_shared shregs;
 
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index da43e5f..fa85d56 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -248,7 +248,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union 
kvmppc_one_reg *);
 void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
 
 struct openpic;
-void kvmppc_mpic_put(struct openpic *opp);
 
 #ifdef CONFIG_KVM_BOOK3S_64_HV
 static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
@@ -278,6 +277,9 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, 
u32 epr)
 #ifdef CONFIG_KVM_MPIC
 
 void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu);
+int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu,
+u32 cpu);
+void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu);
 
 #else
 
@@ -285,6 +287,17 @@ static inline void kvmppc_mpic_set_epr(struct kvm_vcpu 
*vcpu)
 {
 }
 
+static inline int kvmppc_mpic_connect_vcpu(struct kvm_device *dev,
+   struct kvm_vcpu *vcpu, u32 cpu)
+{
+   return -EINVAL;
+}
+
+static inline void kvmppc_mpic_disconnect_vcpu(struct openpic *opp,
+   struct kvm_vcpu *vcpu)
+{
+}
+
 #endif /* CONFIG_KVM_MPIC */
 
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index cff53d4..0097912 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -430,6 +430,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu 
*vcpu,
if (update_epr == true) {
if (vcpu->arch.epr_flags & KVMPPC_EPR_USER)
kvm_make_request(KVM_REQ_EPR_EXIT, vcpu);
+   else if (vcpu->arch.epr_flags & KVMPPC_EPR_KERNEL) {
+   BUG_ON(vcpu->arch.irq_type != KVMPPC_IRQ_MPIC);
+   kvmppc_mpic_set_epr(vcpu);
+   }
}
 
new_msr &= msr_mask;
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index cb451b9..10bc08a 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -115,7 +115,7 @@ static int get_current_cpu(void)
 {
 #if defined(CONFIG_KVM) && defined(CONFIG_BOOKE)
struct kvm_vcpu *vcpu = current->thread.kvm_vcpu;
-   return vcpu ? vcpu->vcpu_id : -1;
+   return vcpu ? vcpu->arch.irq_cpu_id : -1;
 #else
/* XXX */
return -1;
@@ -249,7 +249,7

[PATCH 14/20] kvm/ppc/mpic: add KVM_CAP_IRQ_MPIC

2013-04-26 Thread Alexander Graf
From: Scott Wood 

Enabling this capability connects the vcpu to the designated in-kernel
MPIC.  Using explicit connections between vcpus and irqchips allows
for flexibility, but the main benefit at the moment is that it
simplifies the code -- KVM doesn't need vm-global state to remember
which MPIC object is associated with this vm, and it doesn't need to
care about ordering between irqchip creation and vcpu creation.

Signed-off-by: Scott Wood 
[agraf: add stub functions for kvmppc_mpic_{dis,}connect_vcpu]
Signed-off-by: Alexander Graf 
---
 Documentation/virtual/kvm/api.txt   |8 +++
 arch/powerpc/include/asm/kvm_host.h |9 
 arch/powerpc/include/asm/kvm_ppc.h  |   15 ++-
 arch/powerpc/kvm/booke.c|4 ++
 arch/powerpc/kvm/mpic.c |   82 ---
 arch/powerpc/kvm/powerpc.c  |   30 +
 include/uapi/linux/kvm.h|1 +
 7 files changed, 141 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index d52f3f9..4c326ae 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2728,3 +2728,11 @@ to receive the topmost interrupt vector.
 When disabled (args[0] == 0), behavior is as if this facility is unsupported.
 
 When this capability is enabled, KVM_EXIT_EPR can occur.
+
+6.6 KVM_CAP_IRQ_MPIC
+
+Architectures: ppc
+Parameters: args[0] is the MPIC device fd
+args[1] is the MPIC CPU number for this vcpu
+
+This capability connects the vcpu to an in-kernel MPIC device.
diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 7e7aef9..36368c9 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -375,6 +375,11 @@ struct kvmppc_booke_debug_reg {
u64 dac[KVMPPC_BOOKE_MAX_DAC];
 };
 
+#define KVMPPC_IRQ_DEFAULT 0
+#define KVMPPC_IRQ_MPIC1
+
+struct openpic;
+
 struct kvm_vcpu_arch {
ulong host_stack;
u32 host_pid;
@@ -554,6 +559,10 @@ struct kvm_vcpu_arch {
unsigned long magic_page_pa; /* phys addr to map the magic page to */
unsigned long magic_page_ea; /* effect. addr to map the magic page to */
 
+   int irq_type;   /* one of KVM_IRQ_* */
+   int irq_cpu_id;
+   struct openpic *mpic;   /* KVM_IRQ_MPIC */
+
 #ifdef CONFIG_KVM_BOOK3S_64_HV
struct kvm_vcpu_arch_shared shregs;
 
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index da43e5f..fa85d56 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -248,7 +248,6 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union 
kvmppc_one_reg *);
 void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
 
 struct openpic;
-void kvmppc_mpic_put(struct openpic *opp);
 
 #ifdef CONFIG_KVM_BOOK3S_64_HV
 static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
@@ -278,6 +277,9 @@ static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, 
u32 epr)
 #ifdef CONFIG_KVM_MPIC
 
 void kvmppc_mpic_set_epr(struct kvm_vcpu *vcpu);
+int kvmppc_mpic_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu,
+u32 cpu);
+void kvmppc_mpic_disconnect_vcpu(struct openpic *opp, struct kvm_vcpu *vcpu);
 
 #else
 
@@ -285,6 +287,17 @@ static inline void kvmppc_mpic_set_epr(struct kvm_vcpu 
*vcpu)
 {
 }
 
+static inline int kvmppc_mpic_connect_vcpu(struct kvm_device *dev,
+   struct kvm_vcpu *vcpu, u32 cpu)
+{
+   return -EINVAL;
+}
+
+static inline void kvmppc_mpic_disconnect_vcpu(struct openpic *opp,
+   struct kvm_vcpu *vcpu)
+{
+}
+
 #endif /* CONFIG_KVM_MPIC */
 
 int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index cff53d4..0097912 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -430,6 +430,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu 
*vcpu,
if (update_epr == true) {
if (vcpu->arch.epr_flags & KVMPPC_EPR_USER)
kvm_make_request(KVM_REQ_EPR_EXIT, vcpu);
+   else if (vcpu->arch.epr_flags & KVMPPC_EPR_KERNEL) {
+   BUG_ON(vcpu->arch.irq_type != KVMPPC_IRQ_MPIC);
+   kvmppc_mpic_set_epr(vcpu);
+   }
}
 
new_msr &= msr_mask;
diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c
index cb451b9..10bc08a 100644
--- a/arch/powerpc/kvm/mpic.c
+++ b/arch/powerpc/kvm/mpic.c
@@ -115,7 +115,7 @@ static int get_current_cpu(void)
 {
 #if defined(CONFIG_KVM) && defined(CONFIG_BOOKE)
struct kvm_vcpu *vcpu = current->thread.kvm_vcpu;
-   return vcpu ? vcpu->vcpu_id : -1;
+   return vcpu ? vcpu->arch.irq_cpu_id : -1;
 #else
/* XXX */
return -1;
@@ -249,7 +249,7