1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Test handler for the s390x DIAGNOSE 0x0318 instruction.
5 * Copyright (C) 2020, IBM
13 #define ICPT_INSTRUCTION 0x04
14 #define IPA0_DIAG 0x8300
16 static void guest_code(void)
18 uint64_t diag318_info
= 0x12345678;
20 asm volatile ("diag %0,0,0x318\n" : : "d" (diag318_info
));
24 * The DIAGNOSE 0x0318 instruction call must be handled via userspace. As such,
25 * we create an ad-hoc VM here to handle the instruction then extract the
26 * necessary data. It is up to the caller to decide what to do with that data.
28 static uint64_t diag318_handler(void)
33 uint64_t diag318_info
;
35 vm
= vm_create_default(VCPU_ID
, 0, guest_code
);
36 vcpu_run(vm
, VCPU_ID
);
37 run
= vcpu_state(vm
, VCPU_ID
);
39 TEST_ASSERT(run
->exit_reason
== KVM_EXIT_S390_SIEIC
,
40 "DIAGNOSE 0x0318 instruction was not intercepted");
41 TEST_ASSERT(run
->s390_sieic
.icptcode
== ICPT_INSTRUCTION
,
42 "Unexpected intercept code: 0x%x", run
->s390_sieic
.icptcode
);
43 TEST_ASSERT((run
->s390_sieic
.ipa
& 0xff00) == IPA0_DIAG
,
44 "Unexpected IPA0 code: 0x%x", (run
->s390_sieic
.ipa
& 0xff00));
46 reg
= (run
->s390_sieic
.ipa
& 0x00f0) >> 4;
47 diag318_info
= run
->s
.regs
.gprs
[reg
];
49 TEST_ASSERT(diag318_info
!= 0, "DIAGNOSE 0x0318 info not set");
56 uint64_t get_diag318_info(void)
58 static uint64_t diag318_info
;
59 static bool printed_skip
;
62 * If KVM does not support diag318, then return 0 to
63 * ensure tests do not break.
65 if (!kvm_check_cap(KVM_CAP_S390_DIAG318
)) {
67 fprintf(stdout
, "KVM_CAP_S390_DIAG318 not supported. "
68 "Skipping diag318 test.\n");
75 * If a test has previously requested the diag318 info,
76 * then don't bother spinning up a temporary VM again.
79 diag318_info
= diag318_handler();