Skip to content

Commit 5af5099

Browse files
ozbenhmpe
authored andcommitted
KVM: PPC: Book3S HV: Native usage of the XIVE interrupt controller
This patch makes KVM capable of using the XIVE interrupt controller to provide the standard PAPR "XICS" style hypercalls. It is necessary for proper operations when the host uses XIVE natively. This has been lightly tested on an actual system, including PCI pass-through with a TG3 device. Signed-off-by: Benjamin Herrenschmidt <[email protected]> [mpe: Cleanup pr_xxx(), unsplit pr_xxx() strings, etc., fix build failures by adding KVM_XIVE which depends on KVM_XICS and XIVE, and adding empty stubs for the kvm_xive_xxx() routines, fixup subject, integrate fixes from Paul for building PR=y HV=n] Signed-off-by: Michael Ellerman <[email protected]>
1 parent 8bf8f2e commit 5af5099

26 files changed

+3358
-89
lines changed

arch/powerpc/include/asm/kvm_book3s_asm.h

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ struct kvmppc_host_state {
111111
struct kvm_vcpu *kvm_vcpu;
112112
struct kvmppc_vcore *kvm_vcore;
113113
void __iomem *xics_phys;
114+
void __iomem *xive_tima_phys;
115+
void __iomem *xive_tima_virt;
114116
u32 saved_xirr;
115117
u64 dabr;
116118
u64 host_mmcr[7]; /* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */

arch/powerpc/include/asm/kvm_host.h

+27-1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ struct kvmppc_spapr_tce_table {
205205
/* XICS components, defined in book3s_xics.c */
206206
struct kvmppc_xics;
207207
struct kvmppc_icp;
208+
extern struct kvm_device_ops kvm_xics_ops;
209+
210+
/* XIVE components, defined in book3s_xive.c */
211+
struct kvmppc_xive;
212+
struct kvmppc_xive_vcpu;
213+
extern struct kvm_device_ops kvm_xive_ops;
208214

209215
struct kvmppc_passthru_irqmap;
210216

@@ -293,6 +299,7 @@ struct kvm_arch {
293299
#endif
294300
#ifdef CONFIG_KVM_XICS
295301
struct kvmppc_xics *xics;
302+
struct kvmppc_xive *xive;
296303
struct kvmppc_passthru_irqmap *pimap;
297304
#endif
298305
struct kvmppc_ops *kvm_ops;
@@ -421,7 +428,7 @@ struct kvmppc_passthru_irqmap {
421428

422429
#define KVMPPC_IRQ_DEFAULT 0
423430
#define KVMPPC_IRQ_MPIC 1
424-
#define KVMPPC_IRQ_XICS 2
431+
#define KVMPPC_IRQ_XICS 2 /* Includes a XIVE option */
425432

426433
#define MMIO_HPTE_CACHE_SIZE 4
427434

@@ -443,6 +450,21 @@ struct mmio_hpte_cache {
443450

444451
struct openpic;
445452

453+
/* W0 and W1 of a XIVE thread management context */
454+
union xive_tma_w01 {
455+
struct {
456+
u8 nsr;
457+
u8 cppr;
458+
u8 ipb;
459+
u8 lsmfb;
460+
u8 ack;
461+
u8 inc;
462+
u8 age;
463+
u8 pipr;
464+
};
465+
__be64 w01;
466+
};
467+
446468
struct kvm_vcpu_arch {
447469
ulong host_stack;
448470
u32 host_pid;
@@ -688,6 +710,10 @@ struct kvm_vcpu_arch {
688710
struct openpic *mpic; /* KVM_IRQ_MPIC */
689711
#ifdef CONFIG_KVM_XICS
690712
struct kvmppc_icp *icp; /* XICS presentation controller */
713+
struct kvmppc_xive_vcpu *xive_vcpu; /* XIVE virtual CPU data */
714+
__be32 xive_cam_word; /* Cooked W2 in proper endian with valid bit */
715+
u32 xive_pushed; /* Is the VP pushed on the physical CPU ? */
716+
union xive_tma_w01 xive_saved_state; /* W0..1 of XIVE thread state */
691717
#endif
692718

693719
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE

arch/powerpc/include/asm/kvm_ppc.h

+74
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq);
225225
extern int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp);
226226
extern int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu);
227227
extern void kvmppc_rtas_tokens_free(struct kvm *kvm);
228+
228229
extern int kvmppc_xics_set_xive(struct kvm *kvm, u32 irq, u32 server,
229230
u32 priority);
230231
extern int kvmppc_xics_get_xive(struct kvm *kvm, u32 irq, u32 *server,
@@ -412,6 +413,14 @@ static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
412413
paca[cpu].kvm_hstate.xics_phys = (void __iomem *)addr;
413414
}
414415

416+
static inline void kvmppc_set_xive_tima(int cpu,
417+
unsigned long phys_addr,
418+
void __iomem *virt_addr)
419+
{
420+
paca[cpu].kvm_hstate.xive_tima_phys = (void __iomem *)phys_addr;
421+
paca[cpu].kvm_hstate.xive_tima_virt = virt_addr;
422+
}
423+
415424
static inline u32 kvmppc_get_xics_latch(void)
416425
{
417426
u32 xirr;
@@ -442,6 +451,11 @@ static inline void __init kvm_cma_reserve(void)
442451
static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
443452
{}
444453

454+
static inline void kvmppc_set_xive_tima(int cpu,
455+
unsigned long phys_addr,
456+
void __iomem *virt_addr)
457+
{}
458+
445459
static inline u32 kvmppc_get_xics_latch(void)
446460
{
447461
return 0;
@@ -492,6 +506,10 @@ extern long kvmppc_deliver_irq_passthru(struct kvm_vcpu *vcpu, __be32 xirr,
492506
struct kvmppc_irq_map *irq_map,
493507
struct kvmppc_passthru_irqmap *pimap,
494508
bool *again);
509+
510+
extern int kvmppc_xics_set_irq(struct kvm *kvm, int irq_source_id, u32 irq,
511+
int level, bool line_status);
512+
495513
extern int h_ipi_redirect;
496514
#else
497515
static inline struct kvmppc_passthru_irqmap *kvmppc_get_passthru_irqmap(
@@ -509,6 +527,60 @@ static inline int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
509527
{ return 0; }
510528
#endif
511529

530+
#ifdef CONFIG_KVM_XIVE
531+
/*
532+
* Below the first "xive" is the "eXternal Interrupt Virtualization Engine"
533+
* ie. P9 new interrupt controller, while the second "xive" is the legacy
534+
* "eXternal Interrupt Vector Entry" which is the configuration of an
535+
* interrupt on the "xics" interrupt controller on P8 and earlier. Those
536+
* two function consume or produce a legacy "XIVE" state from the
537+
* new "XIVE" interrupt controller.
538+
*/
539+
extern int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server,
540+
u32 priority);
541+
extern int kvmppc_xive_get_xive(struct kvm *kvm, u32 irq, u32 *server,
542+
u32 *priority);
543+
extern int kvmppc_xive_int_on(struct kvm *kvm, u32 irq);
544+
extern int kvmppc_xive_int_off(struct kvm *kvm, u32 irq);
545+
extern void kvmppc_xive_init_module(void);
546+
extern void kvmppc_xive_exit_module(void);
547+
548+
extern int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
549+
struct kvm_vcpu *vcpu, u32 cpu);
550+
extern void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu);
551+
extern int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq,
552+
struct irq_desc *host_desc);
553+
extern int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq,
554+
struct irq_desc *host_desc);
555+
extern u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu);
556+
extern int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
557+
558+
extern int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq,
559+
int level, bool line_status);
560+
#else
561+
static inline int kvmppc_xive_set_xive(struct kvm *kvm, u32 irq, u32 server,
562+
u32 priority) { return -1; }
563+
static inline int kvmppc_xive_get_xive(struct kvm *kvm, u32 irq, u32 *server,
564+
u32 *priority) { return -1; }
565+
static inline int kvmppc_xive_int_on(struct kvm *kvm, u32 irq) { return -1; }
566+
static inline int kvmppc_xive_int_off(struct kvm *kvm, u32 irq) { return -1; }
567+
static inline void kvmppc_xive_init_module(void) { }
568+
static inline void kvmppc_xive_exit_module(void) { }
569+
570+
static inline int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
571+
struct kvm_vcpu *vcpu, u32 cpu) { return -EBUSY; }
572+
static inline void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu) { }
573+
static inline int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq,
574+
struct irq_desc *host_desc) { return -ENODEV; }
575+
static inline int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq,
576+
struct irq_desc *host_desc) { return -ENODEV; }
577+
static inline u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu) { return 0; }
578+
static inline int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) { return -ENOENT; }
579+
580+
static inline int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq,
581+
int level, bool line_status) { return -ENODEV; }
582+
#endif /* CONFIG_KVM_XIVE */
583+
512584
/*
513585
* Prototypes for functions called only from assembler code.
514586
* Having prototypes reduces sparse errors.
@@ -546,6 +618,8 @@ long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
546618
long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr,
547619
unsigned long slb_v, unsigned int status, bool data);
548620
unsigned long kvmppc_rm_h_xirr(struct kvm_vcpu *vcpu);
621+
unsigned long kvmppc_rm_h_xirr_x(struct kvm_vcpu *vcpu);
622+
unsigned long kvmppc_rm_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server);
549623
int kvmppc_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
550624
unsigned long mfrr);
551625
int kvmppc_rm_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr);

arch/powerpc/include/asm/xive.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ struct xive_q {
9999
#define XIVE_ESB_SET_PQ_01 0xd00
100100
#define XIVE_ESB_SET_PQ_10 0xe00
101101
#define XIVE_ESB_SET_PQ_11 0xf00
102-
#define XIVE_ESB_MASK XIVE_ESB_SET_PQ_01
103102

104103
#define XIVE_ESB_VAL_P 0x2
105104
#define XIVE_ESB_VAL_Q 0x1
@@ -136,11 +135,11 @@ extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
136135
__be32 *qpage, u32 order, bool can_escalate);
137136
extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
138137

139-
extern bool __xive_irq_trigger(struct xive_irq_data *xd);
140-
extern bool __xive_irq_retrigger(struct xive_irq_data *xd);
141-
extern void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd);
142-
138+
extern void xive_native_sync_source(u32 hw_irq);
143139
extern bool is_xive_irq(struct irq_chip *chip);
140+
extern int xive_native_enable_vp(u32 vp_id);
141+
extern int xive_native_disable_vp(u32 vp_id);
142+
extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
144143

145144
#else
146145

arch/powerpc/kernel/asm-offsets.c

+10
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ int main(void)
630630
HSTATE_FIELD(HSTATE_KVM_VCPU, kvm_vcpu);
631631
HSTATE_FIELD(HSTATE_KVM_VCORE, kvm_vcore);
632632
HSTATE_FIELD(HSTATE_XICS_PHYS, xics_phys);
633+
HSTATE_FIELD(HSTATE_XIVE_TIMA_PHYS, xive_tima_phys);
634+
HSTATE_FIELD(HSTATE_XIVE_TIMA_VIRT, xive_tima_virt);
633635
HSTATE_FIELD(HSTATE_SAVED_XIRR, saved_xirr);
634636
HSTATE_FIELD(HSTATE_HOST_IPI, host_ipi);
635637
HSTATE_FIELD(HSTATE_PTID, ptid);
@@ -715,6 +717,14 @@ int main(void)
715717
OFFSET(VCPU_HOST_MAS6, kvm_vcpu, arch.host_mas6);
716718
#endif
717719

720+
#ifdef CONFIG_KVM_XICS
721+
DEFINE(VCPU_XIVE_SAVED_STATE, offsetof(struct kvm_vcpu,
722+
arch.xive_saved_state));
723+
DEFINE(VCPU_XIVE_CAM_WORD, offsetof(struct kvm_vcpu,
724+
arch.xive_cam_word));
725+
DEFINE(VCPU_XIVE_PUSHED, offsetof(struct kvm_vcpu, arch.xive_pushed));
726+
#endif
727+
718728
#ifdef CONFIG_KVM_EXIT_TIMING
719729
OFFSET(VCPU_TIMING_EXIT_TBU, kvm_vcpu, arch.timing_exit.tv32.tbu);
720730
OFFSET(VCPU_TIMING_EXIT_TBL, kvm_vcpu, arch.timing_exit.tv32.tbl);

arch/powerpc/kvm/Kconfig

+5
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ config KVM_XICS
196196
Specification) interrupt controller architecture used on
197197
IBM POWER (pSeries) servers.
198198

199+
config KVM_XIVE
200+
bool
201+
default y
202+
depends on KVM_XICS && PPC_XIVE_NATIVE && KVM_BOOK3S_HV_POSSIBLE
203+
199204
source drivers/vhost/Kconfig
200205

201206
endif # VIRTUALIZATION

arch/powerpc/kvm/Makefile

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ kvm-hv-y += \
7474
book3s_64_mmu_radix.o
7575

7676
kvm-book3s_64-builtin-xics-objs-$(CONFIG_KVM_XICS) := \
77-
book3s_hv_rm_xics.o
77+
book3s_hv_rm_xics.o book3s_hv_rm_xive.o
7878

7979
ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
8080
kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \
@@ -89,6 +89,8 @@ endif
8989
kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \
9090
book3s_xics.o
9191

92+
kvm-book3s_64-objs-$(CONFIG_KVM_XIVE) += book3s_xive.o
93+
9294
kvm-book3s_64-module-objs := \
9395
$(common-objs-y) \
9496
book3s.o \

arch/powerpc/kvm/book3s.c

+69-6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <asm/kvm_book3s.h>
3636
#include <asm/mmu_context.h>
3737
#include <asm/page.h>
38+
#include <asm/xive.h>
3839

3940
#include "book3s.h"
4041
#include "trace.h"
@@ -578,11 +579,14 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
578579
break;
579580
#ifdef CONFIG_KVM_XICS
580581
case KVM_REG_PPC_ICP_STATE:
581-
if (!vcpu->arch.icp) {
582+
if (!vcpu->arch.icp && !vcpu->arch.xive_vcpu) {
582583
r = -ENXIO;
583584
break;
584585
}
585-
*val = get_reg_val(id, kvmppc_xics_get_icp(vcpu));
586+
if (xive_enabled())
587+
*val = get_reg_val(id, kvmppc_xive_get_icp(vcpu));
588+
else
589+
*val = get_reg_val(id, kvmppc_xics_get_icp(vcpu));
586590
break;
587591
#endif /* CONFIG_KVM_XICS */
588592
case KVM_REG_PPC_FSCR:
@@ -648,12 +652,14 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
648652
#endif /* CONFIG_VSX */
649653
#ifdef CONFIG_KVM_XICS
650654
case KVM_REG_PPC_ICP_STATE:
651-
if (!vcpu->arch.icp) {
655+
if (!vcpu->arch.icp && !vcpu->arch.xive_vcpu) {
652656
r = -ENXIO;
653657
break;
654658
}
655-
r = kvmppc_xics_set_icp(vcpu,
656-
set_reg_val(id, *val));
659+
if (xive_enabled())
660+
r = kvmppc_xive_set_icp(vcpu, set_reg_val(id, *val));
661+
else
662+
r = kvmppc_xics_set_icp(vcpu, set_reg_val(id, *val));
657663
break;
658664
#endif /* CONFIG_KVM_XICS */
659665
case KVM_REG_PPC_FSCR:
@@ -924,6 +930,50 @@ int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hcall)
924930
return kvm->arch.kvm_ops->hcall_implemented(hcall);
925931
}
926932

933+
#ifdef CONFIG_KVM_XICS
934+
int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
935+
bool line_status)
936+
{
937+
if (xive_enabled())
938+
return kvmppc_xive_set_irq(kvm, irq_source_id, irq, level,
939+
line_status);
940+
else
941+
return kvmppc_xics_set_irq(kvm, irq_source_id, irq, level,
942+
line_status);
943+
}
944+
945+
int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *irq_entry,
946+
struct kvm *kvm, int irq_source_id,
947+
int level, bool line_status)
948+
{
949+
return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
950+
level, line_status);
951+
}
952+
static int kvmppc_book3s_set_irq(struct kvm_kernel_irq_routing_entry *e,
953+
struct kvm *kvm, int irq_source_id, int level,
954+
bool line_status)
955+
{
956+
return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status);
957+
}
958+
959+
int kvm_irq_map_gsi(struct kvm *kvm,
960+
struct kvm_kernel_irq_routing_entry *entries, int gsi)
961+
{
962+
entries->gsi = gsi;
963+
entries->type = KVM_IRQ_ROUTING_IRQCHIP;
964+
entries->set = kvmppc_book3s_set_irq;
965+
entries->irqchip.irqchip = 0;
966+
entries->irqchip.pin = gsi;
967+
return 1;
968+
}
969+
970+
int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
971+
{
972+
return pin;
973+
}
974+
975+
#endif /* CONFIG_KVM_XICS */
976+
927977
static int kvmppc_book3s_init(void)
928978
{
929979
int r;
@@ -934,12 +984,25 @@ static int kvmppc_book3s_init(void)
934984
#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
935985
r = kvmppc_book3s_init_pr();
936986
#endif
937-
return r;
938987

988+
#ifdef CONFIG_KVM_XICS
989+
#ifdef CONFIG_KVM_XIVE
990+
if (xive_enabled()) {
991+
kvmppc_xive_init_module();
992+
kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS);
993+
} else
994+
#endif
995+
kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS);
996+
#endif
997+
return r;
939998
}
940999

9411000
static void kvmppc_book3s_exit(void)
9421001
{
1002+
#ifdef CONFIG_KVM_XICS
1003+
if (xive_enabled())
1004+
kvmppc_xive_exit_module();
1005+
#endif
9431006
#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
9441007
kvmppc_book3s_exit_pr();
9451008
#endif

0 commit comments

Comments
 (0)