Path: blob/master/tools/testing/selftests/kvm/s390/user_operexec.c
38237 views
// SPDX-License-Identifier: GPL-2.0-only1/* Test operation exception forwarding.2*3* Copyright IBM Corp. 20254*5* Authors:6* Janosch Frank <[email protected]>7*/8#include "kselftest.h"9#include "kvm_util.h"10#include "test_util.h"11#include "sie.h"1213#include <linux/kvm.h>1415static void guest_code_instr0(void)16{17asm(".word 0x0000");18}1920static void test_user_instr0(void)21{22struct kvm_vcpu *vcpu;23struct kvm_vm *vm;24int rc;2526vm = vm_create_with_one_vcpu(&vcpu, guest_code_instr0);27rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_INSTR0, 0);28TEST_ASSERT_EQ(0, rc);2930vcpu_run(vcpu);31TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);32TEST_ASSERT_EQ(vcpu->run->s390_sieic.icptcode, ICPT_OPEREXC);33TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipa, 0);3435kvm_vm_free(vm);36}3738static void guest_code_user_operexec(void)39{40asm(".word 0x0807");41}4243static void test_user_operexec(void)44{45struct kvm_vcpu *vcpu;46struct kvm_vm *vm;47int rc;4849vm = vm_create_with_one_vcpu(&vcpu, guest_code_user_operexec);50rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_OPEREXEC, 0);51TEST_ASSERT_EQ(0, rc);5253vcpu_run(vcpu);54TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);55TEST_ASSERT_EQ(vcpu->run->s390_sieic.icptcode, ICPT_OPEREXC);56TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipa, 0x0807);5758kvm_vm_free(vm);5960/*61* Since user_operexec is the superset it can be used for the62* 0 instruction.63*/64vm = vm_create_with_one_vcpu(&vcpu, guest_code_instr0);65rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_OPEREXEC, 0);66TEST_ASSERT_EQ(0, rc);6768vcpu_run(vcpu);69TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);70TEST_ASSERT_EQ(vcpu->run->s390_sieic.icptcode, ICPT_OPEREXC);71TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipa, 0);7273kvm_vm_free(vm);74}7576/* combine user_instr0 and user_operexec */77static void test_user_operexec_combined(void)78{79struct kvm_vcpu *vcpu;80struct kvm_vm *vm;81int rc;8283vm = vm_create_with_one_vcpu(&vcpu, guest_code_user_operexec);84rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_INSTR0, 0);85TEST_ASSERT_EQ(0, rc);86rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_OPEREXEC, 0);87TEST_ASSERT_EQ(0, rc);8889vcpu_run(vcpu);90TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);91TEST_ASSERT_EQ(vcpu->run->s390_sieic.icptcode, ICPT_OPEREXC);92TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipa, 0x0807);9394kvm_vm_free(vm);9596/* Reverse enablement order */97vm = vm_create_with_one_vcpu(&vcpu, guest_code_user_operexec);98rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_OPEREXEC, 0);99TEST_ASSERT_EQ(0, rc);100rc = __vm_enable_cap(vm, KVM_CAP_S390_USER_INSTR0, 0);101TEST_ASSERT_EQ(0, rc);102103vcpu_run(vcpu);104TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_S390_SIEIC);105TEST_ASSERT_EQ(vcpu->run->s390_sieic.icptcode, ICPT_OPEREXC);106TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipa, 0x0807);107108kvm_vm_free(vm);109}110111/*112* Run all tests above.113*114* Enablement after VCPU has been added is automatically tested since115* we enable the capability after VCPU creation.116*/117static struct testdef {118const char *name;119void (*test)(void);120} testlist[] = {121{ "instr0", test_user_instr0 },122{ "operexec", test_user_operexec },123{ "operexec_combined", test_user_operexec_combined},124};125126int main(int argc, char *argv[])127{128int idx;129130TEST_REQUIRE(kvm_has_cap(KVM_CAP_S390_USER_INSTR0));131132ksft_print_header();133ksft_set_plan(ARRAY_SIZE(testlist));134for (idx = 0; idx < ARRAY_SIZE(testlist); idx++) {135testlist[idx].test();136ksft_test_result_pass("%s\n", testlist[idx].name);137}138ksft_finished();139}140141142