brintos

brintos / linux-shallow public Read only

0
0
Text · 1.9 KiB · 2c432fa Raw
81 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Test handler for the s390x DIAGNOSE 0x0318 instruction.4 *5 * Copyright (C) 2020, IBM6 */7 8#include "test_util.h"9#include "kvm_util.h"10 11#define ICPT_INSTRUCTION	0x0412#define IPA0_DIAG		0x830013 14static void guest_code(void)15{16	uint64_t diag318_info = 0x12345678;17 18	asm volatile ("diag %0,0,0x318\n" : : "d" (diag318_info));19}20 21/*22 * The DIAGNOSE 0x0318 instruction call must be handled via userspace. As such,23 * we create an ad-hoc VM here to handle the instruction then extract the24 * necessary data. It is up to the caller to decide what to do with that data.25 */26static uint64_t diag318_handler(void)27{28	struct kvm_vcpu *vcpu;29	struct kvm_vm *vm;30	struct kvm_run *run;31	uint64_t reg;32	uint64_t diag318_info;33 34	vm = vm_create_with_one_vcpu(&vcpu, guest_code);35	vcpu_run(vcpu);36	run = vcpu->run;37 38	TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);39	TEST_ASSERT(run->s390_sieic.icptcode == ICPT_INSTRUCTION,40		    "Unexpected intercept code: 0x%x", run->s390_sieic.icptcode);41	TEST_ASSERT((run->s390_sieic.ipa & 0xff00) == IPA0_DIAG,42		    "Unexpected IPA0 code: 0x%x", (run->s390_sieic.ipa & 0xff00));43 44	reg = (run->s390_sieic.ipa & 0x00f0) >> 4;45	diag318_info = run->s.regs.gprs[reg];46 47	TEST_ASSERT(diag318_info != 0, "DIAGNOSE 0x0318 info not set");48 49	kvm_vm_free(vm);50 51	return diag318_info;52}53 54uint64_t get_diag318_info(void)55{56	static uint64_t diag318_info;57	static bool printed_skip;58 59	/*60	 * If KVM does not support diag318, then return 0 to61	 * ensure tests do not break.62	 */63	if (!kvm_has_cap(KVM_CAP_S390_DIAG318)) {64		if (!printed_skip) {65			fprintf(stdout, "KVM_CAP_S390_DIAG318 not supported. "66				"Skipping diag318 test.\n");67			printed_skip = true;68		}69		return 0;70	}71 72	/*73	 * If a test has previously requested the diag318 info,74	 * then don't bother spinning up a temporary VM again.75	 */76	if (!diag318_info)77		diag318_info = diag318_handler();78 79	return diag318_info;80}81