aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-04-17 16:30:26 -0400
committerAlexander Graf <agraf@suse.de>2013-04-26 14:27:30 -0400
commitbc5ad3f3701116e7db57268e6f89010ec714697e (patch)
tree21a00d1213598eab4dc0ae3fb03bb7ba3344185a /arch/powerpc/include
parent8e591cb7204739efa8e15967ea334eb367039dde (diff)
KVM: PPC: Book3S: Add kernel emulation for the XICS interrupt controller
This adds in-kernel emulation of the XICS (eXternal Interrupt Controller Specification) interrupt controller specified by PAPR, for both HV and PR KVM guests. The XICS emulation supports up to 1048560 interrupt sources. Interrupt source numbers below 16 are reserved; 0 is used to mean no interrupt and 2 is used for IPIs. Internally these are represented in blocks of 1024, called ICS (interrupt controller source) entities, but that is not visible to userspace. Each vcpu gets one ICP (interrupt controller presentation) entity, used to store the per-vcpu state such as vcpu priority, pending interrupt state, IPI request, etc. This does not include any API or any way to connect vcpus to their ICP state; that will be added in later patches. This is based on an initial implementation by Michael Ellerman <michael@ellerman.id.au> reworked by Benjamin Herrenschmidt and Paul Mackerras. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org> [agraf: fix typo, add dependency on !KVM_MPIC] Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h2
-rw-r--r--arch/powerpc/include/asm/kvm_host.h11
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h29
3 files changed, 42 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index c55f7e6affaa..349ed85c7d61 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -142,6 +142,8 @@ extern int kvmppc_mmu_hv_init(void);
142extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); 142extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data);
143extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); 143extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data);
144extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); 144extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
145extern void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
146 unsigned int vec);
145extern void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags); 147extern void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags);
146extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, 148extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
147 bool upper, u32 val); 149 bool upper, u32 val);
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 311f7e6f09e9..af326cde7cb6 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -192,6 +192,10 @@ struct kvmppc_linear_info {
192 int type; 192 int type;
193}; 193};
194 194
195/* XICS components, defined in book3s_xics.c */
196struct kvmppc_xics;
197struct kvmppc_icp;
198
195/* 199/*
196 * The reverse mapping array has one entry for each HPTE, 200 * The reverse mapping array has one entry for each HPTE,
197 * which stores the guest's view of the second word of the HPTE 201 * which stores the guest's view of the second word of the HPTE
@@ -264,6 +268,9 @@ struct kvm_arch {
264#ifdef CONFIG_KVM_MPIC 268#ifdef CONFIG_KVM_MPIC
265 struct openpic *mpic; 269 struct openpic *mpic;
266#endif 270#endif
271#ifdef CONFIG_KVM_XICS
272 struct kvmppc_xics *xics;
273#endif
267}; 274};
268 275
269/* 276/*
@@ -387,6 +394,7 @@ struct kvmppc_booke_debug_reg {
387 394
388#define KVMPPC_IRQ_DEFAULT 0 395#define KVMPPC_IRQ_DEFAULT 0
389#define KVMPPC_IRQ_MPIC 1 396#define KVMPPC_IRQ_MPIC 1
397#define KVMPPC_IRQ_XICS 2
390 398
391struct openpic; 399struct openpic;
392 400
@@ -574,6 +582,9 @@ struct kvm_vcpu_arch {
574 int irq_type; /* one of KVM_IRQ_* */ 582 int irq_type; /* one of KVM_IRQ_* */
575 int irq_cpu_id; 583 int irq_cpu_id;
576 struct openpic *mpic; /* KVM_IRQ_MPIC */ 584 struct openpic *mpic; /* KVM_IRQ_MPIC */
585#ifdef CONFIG_KVM_XICS
586 struct kvmppc_icp *icp; /* XICS presentation controller */
587#endif
577 588
578#ifdef CONFIG_KVM_BOOK3S_64_HV 589#ifdef CONFIG_KVM_BOOK3S_64_HV
579 struct kvm_vcpu_arch_shared shregs; 590 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 8a30eb7f2bec..6582eed321ba 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -130,6 +130,7 @@ extern long kvmppc_prepare_vrma(struct kvm *kvm,
130extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu, 130extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
131 struct kvm_memory_slot *memslot, unsigned long porder); 131 struct kvm_memory_slot *memslot, unsigned long porder);
132extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu); 132extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
133
133extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 134extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
134 struct kvm_create_spapr_tce *args); 135 struct kvm_create_spapr_tce *args);
135extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 136extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
@@ -169,6 +170,10 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq);
169extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp); 170extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp);
170extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu); 171extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu);
171extern void kvmppc_rtas_tokens_free(struct kvm *kvm); 172extern void kvmppc_rtas_tokens_free(struct kvm *kvm);
173extern int kvmppc_xics_set_xive(struct kvm *kvm, u32 irq, u32 server,
174 u32 priority);
175extern int kvmppc_xics_get_xive(struct kvm *kvm, u32 irq, u32 *server,
176 u32 *priority);
172 177
173/* 178/*
174 * Cuts out inst bits with ordering according to spec. 179 * Cuts out inst bits with ordering according to spec.
@@ -267,6 +272,30 @@ static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
267 272
268static inline void kvm_linear_init(void) 273static inline void kvm_linear_init(void)
269{} 274{}
275
276#endif
277
278#ifdef CONFIG_KVM_XICS
279static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
280{
281 return vcpu->arch.irq_type == KVMPPC_IRQ_XICS;
282}
283extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
284extern int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server);
285extern int kvm_vm_ioctl_xics_irq(struct kvm *kvm, struct kvm_irq_level *args);
286extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd);
287#else
288static inline int kvmppc_xics_enabled(struct kvm_vcpu *vcpu)
289 { return 0; }
290static inline void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu) { }
291static inline int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu,
292 unsigned long server)
293 { return -EINVAL; }
294static inline int kvm_vm_ioctl_xics_irq(struct kvm *kvm,
295 struct kvm_irq_level *args)
296 { return -ENOTTY; }
297static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
298 { return 0; }
270#endif 299#endif
271 300
272static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr) 301static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr)