mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
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 <clg@kaod.org> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
parent
13ce3297c5
commit
5ca8064748
3 changed files with 91 additions and 0 deletions
|
@ -17,6 +17,11 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
|
||||||
|
|
||||||
1. KVM_DEV_XIVE_GRP_CTRL
|
1. KVM_DEV_XIVE_GRP_CTRL
|
||||||
Provides global controls on the device
|
Provides global controls on the device
|
||||||
|
Attributes:
|
||||||
|
1.1 KVM_DEV_XIVE_RESET (write only)
|
||||||
|
Resets the interrupt controller configuration for sources and event
|
||||||
|
queues. To be used by kexec and kdump.
|
||||||
|
Errors: none
|
||||||
|
|
||||||
2. KVM_DEV_XIVE_GRP_SOURCE (write only)
|
2. KVM_DEV_XIVE_GRP_SOURCE (write only)
|
||||||
Initializes a new source in the XIVE device and mask it.
|
Initializes a new source in the XIVE device and mask it.
|
||||||
|
|
|
@ -679,6 +679,7 @@ struct kvm_ppc_cpu_char {
|
||||||
|
|
||||||
/* POWER9 XIVE Native Interrupt Controller */
|
/* POWER9 XIVE Native Interrupt Controller */
|
||||||
#define KVM_DEV_XIVE_GRP_CTRL 1
|
#define KVM_DEV_XIVE_GRP_CTRL 1
|
||||||
|
#define KVM_DEV_XIVE_RESET 1
|
||||||
#define KVM_DEV_XIVE_GRP_SOURCE 2 /* 64-bit source identifier */
|
#define KVM_DEV_XIVE_GRP_SOURCE 2 /* 64-bit source identifier */
|
||||||
#define KVM_DEV_XIVE_GRP_SOURCE_CONFIG 3 /* 64-bit source identifier */
|
#define KVM_DEV_XIVE_GRP_SOURCE_CONFIG 3 /* 64-bit source identifier */
|
||||||
#define KVM_DEV_XIVE_GRP_EQ_CONFIG 4 /* 64-bit EQ identifier */
|
#define KVM_DEV_XIVE_GRP_EQ_CONFIG 4 /* 64-bit EQ identifier */
|
||||||
|
|
|
@ -572,6 +572,83 @@ static int kvmppc_xive_native_get_queue_config(struct kvmppc_xive *xive,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void kvmppc_xive_reset_sources(struct kvmppc_xive_src_block *sb)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < KVMPPC_XICS_IRQ_PER_ICS; i++) {
|
||||||
|
struct kvmppc_xive_irq_state *state = &sb->irq_state[i];
|
||||||
|
|
||||||
|
if (!state->valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (state->act_priority == MASKED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
state->eisn = 0;
|
||||||
|
state->act_server = 0;
|
||||||
|
state->act_priority = MASKED;
|
||||||
|
xive_vm_esb_load(&state->ipi_data, XIVE_ESB_SET_PQ_01);
|
||||||
|
xive_native_configure_irq(state->ipi_number, 0, MASKED, 0);
|
||||||
|
if (state->pt_number) {
|
||||||
|
xive_vm_esb_load(state->pt_data, XIVE_ESB_SET_PQ_01);
|
||||||
|
xive_native_configure_irq(state->pt_number,
|
||||||
|
0, MASKED, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int kvmppc_xive_reset(struct kvmppc_xive *xive)
|
||||||
|
{
|
||||||
|
struct kvm *kvm = xive->kvm;
|
||||||
|
struct kvm_vcpu *vcpu;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
pr_devel("%s\n", __func__);
|
||||||
|
|
||||||
|
mutex_lock(&kvm->lock);
|
||||||
|
|
||||||
|
kvm_for_each_vcpu(i, vcpu, kvm) {
|
||||||
|
struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
|
||||||
|
unsigned int prio;
|
||||||
|
|
||||||
|
if (!xc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
kvmppc_xive_disable_vcpu_interrupts(vcpu);
|
||||||
|
|
||||||
|
for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) {
|
||||||
|
|
||||||
|
/* Single escalation, no queue 7 */
|
||||||
|
if (prio == 7 && xive->single_escalation)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (xc->esc_virq[prio]) {
|
||||||
|
free_irq(xc->esc_virq[prio], vcpu);
|
||||||
|
irq_dispose_mapping(xc->esc_virq[prio]);
|
||||||
|
kfree(xc->esc_virq_names[prio]);
|
||||||
|
xc->esc_virq[prio] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kvmppc_xive_native_cleanup_queue(vcpu, prio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <= xive->max_sbid; i++) {
|
||||||
|
struct kvmppc_xive_src_block *sb = xive->src_blocks[i];
|
||||||
|
|
||||||
|
if (sb) {
|
||||||
|
arch_spin_lock(&sb->lock);
|
||||||
|
kvmppc_xive_reset_sources(sb);
|
||||||
|
arch_spin_unlock(&sb->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&kvm->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int kvmppc_xive_native_set_attr(struct kvm_device *dev,
|
static int kvmppc_xive_native_set_attr(struct kvm_device *dev,
|
||||||
struct kvm_device_attr *attr)
|
struct kvm_device_attr *attr)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +656,10 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev,
|
||||||
|
|
||||||
switch (attr->group) {
|
switch (attr->group) {
|
||||||
case KVM_DEV_XIVE_GRP_CTRL:
|
case KVM_DEV_XIVE_GRP_CTRL:
|
||||||
|
switch (attr->attr) {
|
||||||
|
case KVM_DEV_XIVE_RESET:
|
||||||
|
return kvmppc_xive_reset(xive);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KVM_DEV_XIVE_GRP_SOURCE:
|
case KVM_DEV_XIVE_GRP_SOURCE:
|
||||||
return kvmppc_xive_native_set_source(xive, attr->attr,
|
return kvmppc_xive_native_set_source(xive, attr->attr,
|
||||||
|
@ -611,6 +692,10 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev,
|
||||||
{
|
{
|
||||||
switch (attr->group) {
|
switch (attr->group) {
|
||||||
case KVM_DEV_XIVE_GRP_CTRL:
|
case KVM_DEV_XIVE_GRP_CTRL:
|
||||||
|
switch (attr->attr) {
|
||||||
|
case KVM_DEV_XIVE_RESET:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KVM_DEV_XIVE_GRP_SOURCE:
|
case KVM_DEV_XIVE_GRP_SOURCE:
|
||||||
case KVM_DEV_XIVE_GRP_SOURCE_CONFIG:
|
case KVM_DEV_XIVE_GRP_SOURCE_CONFIG:
|
||||||
|
|
Loading…
Reference in a new issue