Skip to content

Commit 5ca8064

Browse files
legoaterpaulusmack
authored andcommitted
KVM: PPC: Book3S HV: XIVE: Add a global reset control
This control is to be used by the H_INT_RESET hcall from QEMU. Its purpose is to clear all configuration of the sources and EQs. This is necessary in case of a kexec (for a kdump kernel for instance) to make sure that no remaining configuration is left from the previous boot setup so that the new kernel can start safely from a clean state. The queue 7 is ignored when the XIVE device is configured to run in single escalation mode. Prio 7 is used by escalations. The XIVE VP is kept enabled as the vCPU is still active and connected to the XIVE device. Signed-off-by: Cédric Le Goater <[email protected]> Reviewed-by: David Gibson <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent 13ce329 commit 5ca8064

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

Documentation/virtual/kvm/devices/xive.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
1717

1818
1. KVM_DEV_XIVE_GRP_CTRL
1919
Provides global controls on the device
20+
Attributes:
21+
1.1 KVM_DEV_XIVE_RESET (write only)
22+
Resets the interrupt controller configuration for sources and event
23+
queues. To be used by kexec and kdump.
24+
Errors: none
2025

2126
2. KVM_DEV_XIVE_GRP_SOURCE (write only)
2227
Initializes a new source in the XIVE device and mask it.

arch/powerpc/include/uapi/asm/kvm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ struct kvm_ppc_cpu_char {
679679

680680
/* POWER9 XIVE Native Interrupt Controller */
681681
#define KVM_DEV_XIVE_GRP_CTRL 1
682+
#define KVM_DEV_XIVE_RESET 1
682683
#define KVM_DEV_XIVE_GRP_SOURCE 2 /* 64-bit source identifier */
683684
#define KVM_DEV_XIVE_GRP_SOURCE_CONFIG 3 /* 64-bit source identifier */
684685
#define KVM_DEV_XIVE_GRP_EQ_CONFIG 4 /* 64-bit EQ identifier */

arch/powerpc/kvm/book3s_xive_native.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,13 +572,94 @@ static int kvmppc_xive_native_get_queue_config(struct kvmppc_xive *xive,
572572
return 0;
573573
}
574574

575+
static void kvmppc_xive_reset_sources(struct kvmppc_xive_src_block *sb)
576+
{
577+
int i;
578+
579+
for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) {
580+
struct kvmppc_xive_irq_state *state = &sb->irq_state[i];
581+
582+
if (!state->valid)
583+
continue;
584+
585+
if (state->act_priority == MASKED)
586+
continue;
587+
588+
state->eisn = 0;
589+
state->act_server = 0;
590+
state->act_priority = MASKED;
591+
xive_vm_esb_load(&state->ipi_data, XIVE_ESB_SET_PQ_01);
592+
xive_native_configure_irq(state->ipi_number, 0, MASKED, 0);
593+
if (state->pt_number) {
594+
xive_vm_esb_load(state->pt_data, XIVE_ESB_SET_PQ_01);
595+
xive_native_configure_irq(state->pt_number,
596+
0, MASKED, 0);
597+
}
598+
}
599+
}
600+
601+
static int kvmppc_xive_reset(struct kvmppc_xive *xive)
602+
{
603+
struct kvm *kvm = xive->kvm;
604+
struct kvm_vcpu *vcpu;
605+
unsigned int i;
606+
607+
pr_devel("%s\n", __func__);
608+
609+
mutex_lock(&kvm->lock);
610+
611+
kvm_for_each_vcpu(i, vcpu, kvm) {
612+
struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
613+
unsigned int prio;
614+
615+
if (!xc)
616+
continue;
617+
618+
kvmppc_xive_disable_vcpu_interrupts(vcpu);
619+
620+
for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) {
621+
622+
/* Single escalation, no queue 7 */
623+
if (prio == 7 && xive->single_escalation)
624+
break;
625+
626+
if (xc->esc_virq[prio]) {
627+
free_irq(xc->esc_virq[prio], vcpu);
628+
irq_dispose_mapping(xc->esc_virq[prio]);
629+
kfree(xc->esc_virq_names[prio]);
630+
xc->esc_virq[prio] = 0;
631+
}
632+
633+
kvmppc_xive_native_cleanup_queue(vcpu, prio);
634+
}
635+
}
636+
637+
for (i = 0; i <= xive->max_sbid; i++) {
638+
struct kvmppc_xive_src_block *sb = xive->src_blocks[i];
639+
640+
if (sb) {
641+
arch_spin_lock(&sb->lock);
642+
kvmppc_xive_reset_sources(sb);
643+
arch_spin_unlock(&sb->lock);
644+
}
645+
}
646+
647+
mutex_unlock(&kvm->lock);
648+
649+
return 0;
650+
}
651+
575652
static int kvmppc_xive_native_set_attr(struct kvm_device *dev,
576653
struct kvm_device_attr *attr)
577654
{
578655
struct kvmppc_xive *xive = dev->private;
579656

580657
switch (attr->group) {
581658
case KVM_DEV_XIVE_GRP_CTRL:
659+
switch (attr->attr) {
660+
case KVM_DEV_XIVE_RESET:
661+
return kvmppc_xive_reset(xive);
662+
}
582663
break;
583664
case KVM_DEV_XIVE_GRP_SOURCE:
584665
return kvmppc_xive_native_set_source(xive, attr->attr,
@@ -611,6 +692,10 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev,
611692
{
612693
switch (attr->group) {
613694
case KVM_DEV_XIVE_GRP_CTRL:
695+
switch (attr->attr) {
696+
case KVM_DEV_XIVE_RESET:
697+
return 0;
698+
}
614699
break;
615700
case KVM_DEV_XIVE_GRP_SOURCE:
616701
case KVM_DEV_XIVE_GRP_SOURCE_CONFIG:

0 commit comments

Comments
 (0)