Skip to content

Commit b2ff728

Browse files
Pierre Morelborntraeger
authored andcommitted
selftests: KVM: testing the local IRQs resets
Local IRQs are reset by a normal cpu reset. The initial cpu reset and the clear cpu reset, as superset of the normal reset, both clear the IRQs too. Let's inject an interrupt to a vCPU before calling a reset and see if it is gone after the reset. We choose to inject only an emergency interrupt at this point and can extend the test to other types of IRQs later. Signed-off-by: Pierre Morel <[email protected]> Signed-off-by: Janosch Frank <[email protected]> [minor fixups] Reviewed-by: Cornelia Huck <[email protected]> Reviewed-by: Thomas Huth <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Borntraeger <[email protected]>
1 parent b25d4cb commit b2ff728

File tree

1 file changed

+42
-0
lines changed
  • tools/testing/selftests/kvm/s390x

1 file changed

+42
-0
lines changed

tools/testing/selftests/kvm/s390x/resets.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#include "kvm_util.h"
1515

1616
#define VCPU_ID 3
17+
#define LOCAL_IRQS 32
18+
19+
struct kvm_s390_irq buf[VCPU_ID + LOCAL_IRQS];
1720

1821
struct kvm_vm *vm;
1922
struct kvm_run *run;
@@ -53,6 +56,23 @@ static void test_one_reg(uint64_t id, uint64_t value)
5356
TEST_ASSERT(eval_reg == value, "value == %s", value);
5457
}
5558

59+
static void assert_noirq(void)
60+
{
61+
struct kvm_s390_irq_state irq_state;
62+
int irqs;
63+
64+
irq_state.len = sizeof(buf);
65+
irq_state.buf = (unsigned long)buf;
66+
irqs = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_GET_IRQ_STATE, &irq_state);
67+
/*
68+
* irqs contains the number of retrieved interrupts. Any interrupt
69+
* (notably, the emergency call interrupt we have injected) should
70+
* be cleared by the resets, so this should be 0.
71+
*/
72+
TEST_ASSERT(irqs >= 0, "Could not fetch IRQs: errno %d\n", errno);
73+
TEST_ASSERT(!irqs, "IRQ pending");
74+
}
75+
5676
static void assert_clear(void)
5777
{
5878
struct kvm_sregs sregs;
@@ -94,6 +114,22 @@ static void assert_initial(void)
94114
static void assert_normal(void)
95115
{
96116
test_one_reg(KVM_REG_S390_PFTOKEN, KVM_S390_PFAULT_TOKEN_INVALID);
117+
assert_noirq();
118+
}
119+
120+
static void inject_irq(int cpu_id)
121+
{
122+
struct kvm_s390_irq_state irq_state;
123+
struct kvm_s390_irq *irq = &buf[0];
124+
int irqs;
125+
126+
/* Inject IRQ */
127+
irq_state.len = sizeof(struct kvm_s390_irq);
128+
irq_state.buf = (unsigned long)buf;
129+
irq->type = KVM_S390_INT_EMERGENCY;
130+
irq->u.emerg.code = cpu_id;
131+
irqs = _vcpu_ioctl(vm, cpu_id, KVM_S390_SET_IRQ_STATE, &irq_state);
132+
TEST_ASSERT(irqs >= 0, "Error injecting EMERGENCY IRQ errno %d\n", errno);
97133
}
98134

99135
static void test_normal(void)
@@ -106,6 +142,8 @@ static void test_normal(void)
106142

107143
vcpu_run(vm, VCPU_ID);
108144

145+
inject_irq(VCPU_ID);
146+
109147
vcpu_ioctl(vm, VCPU_ID, KVM_S390_NORMAL_RESET, 0);
110148
assert_normal();
111149
kvm_vm_free(vm);
@@ -120,6 +158,8 @@ static void test_initial(void)
120158

121159
vcpu_run(vm, VCPU_ID);
122160

161+
inject_irq(VCPU_ID);
162+
123163
vcpu_ioctl(vm, VCPU_ID, KVM_S390_INITIAL_RESET, 0);
124164
assert_normal();
125165
assert_initial();
@@ -135,6 +175,8 @@ static void test_clear(void)
135175

136176
vcpu_run(vm, VCPU_ID);
137177

178+
inject_irq(VCPU_ID);
179+
138180
vcpu_ioctl(vm, VCPU_ID, KVM_S390_CLEAR_RESET, 0);
139181
assert_normal();
140182
assert_initial();

0 commit comments

Comments
 (0)