KVM: selftests: Add a test for the KVM_S390_MEM_OP ioctl
PATCH v2 1/1 KVM: selftests: Add a test for the KVM_S390_MEM_OP ioctl
Check that we can write and read the guest memory with this s390x ioctl, and that some error cases are handled correctly.
---
v2: Check the ioctl also with "size" set to 0
tools/testing/selftests/kvm/Makefile | 1 + tools/testing/selftests/kvm/s390x/memop.c | 165 ++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 tools/testing/selftests/kvm/s390x/memop.c
tools/testing/selftests/kvm/Makefile +1 -0
@@ -32,6 +32,7 @@ TEST_GEN_PROGS_aarch64 += clear_dirty_log_test TEST_GEN_PROGS_aarch64 += dirty_log_test TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus +TEST_GEN_PROGS_s390x = s390x/memop TEST_GEN_PROGS_s390x += s390x/sync_regs_test TEST_GEN_PROGS_s390x += dirty_log_test TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
tools/testing/selftests/kvm/s390x/memop.c new file +165 -0
165 lines not on this page · raw message
Signature · 1 line
2.18.1
Quoted 7 lines · Thomas Huth
Check that we can write and read the guest memory with this s390x ioctl, and that some error cases are handled correctly.
Signed-off-by Thomas Huth <[email protected]>---
v2: Check the ioctl also with "size" set to 0
[...]
tools/testing/selftests/kvm/s390x/memop.c line 104
Quoted 10 lines
tools/testing/selftests/kvm/s390x/memop.c new file +10
-0+ +/* Zero size: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size =0 ; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 ,"ioctl allows 0 as size" );
Test for errno == -EINVAL?
Quoted 10 lines
tools/testing/selftests/kvm/s390x/memop.c new file +10
-0+ +/* Bad flags: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =-1 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows all flags?" );
tools/testing/selftests/kvm/s390x/memop.c line 124
Quoted 10 lines
tools/testing/selftests/kvm/s390x/memop.c new file +10
-0+ +/* Bad operation: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size = maxsize; + ksmo.op =-1 ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows all flags?" );
Wrong report string
Quoted 9 lines · Janosch Frank
Quoted 7 lines · Thomas Huth
Check that we can write and read the guest memory with this s390x ioctl, and that some error cases are handled correctly.
Signed-off-by Thomas Huth <[email protected]>---
v2: Check the ioctl also with "size" set to 0[...]
Quoted 12 lines
tools/testing/selftests/kvm/s390x/memop.c line 104
Quoted 10 lines
tools/testing/selftests/kvm/s390x/memop.c new file +10
-0+ +/* Zero size: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size =0 ; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 ,"ioctl allows 0 as size" );Test for errno ==
-EINVAL?
Assuming that my "Test for bad access register and size at the start
of S390_MEM_OP" goes in first, yes, I can add that check.
Otherwise, the current kernel still returns ENOMEM.
Quoted 14 lines
Quoted 14 lines
tools/testing/selftests/kvm/s390x/memop.c new file +14
-0+ +/* Bad flags: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =-1 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows all flags?" ); + +/* Bad operation: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ;
Quoted 8 lines
tools/testing/selftests/kvm/s390x/memop.c line 124
Quoted 6 lines
tools/testing/selftests/kvm/s390x/memop.c new file +6
-0+ ksmo.size = maxsize; + ksmo.op =-1 ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows all flags?" );Wrong report string
Oops, stupid copy-n-paste bug ... I'll fix it in v3...
Thanks,
Thomas
Quoted 186 lines · Thomas Huth
Check that we can write and read the guest memory with this s390x ioctl, and that some error cases are handled correctly.
Signed-off-by Thomas Huth <[email protected]>---
v2: Check the ioctl also with "size" set to 0tools/testing/selftests/kvm/Makefile | 1 + tools/testing/selftests/kvm/s390x/memop.c | 165 ++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 tools/testing/selftests/kvm/s390x/memop.ctools/testing/selftests/kvm/Makefile +1
-0@@ -32,6 +32,7 @@ TEST_GEN_PROGS_aarch64 += clear_dirty_log_test TEST_GEN_PROGS_aarch64 += dirty_log_test TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus +TEST_GEN_PROGS_s390x = s390x/memop TEST_GEN_PROGS_s390x += s390x/sync_regs_test TEST_GEN_PROGS_s390x += dirty_log_test TEST_GEN_PROGS_s390x += kvm_create_max_vcpustools/testing/selftests/kvm/s390x/memop.c new file +155
-0@@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* Test for s390x KVM_S390_MEM_OP +* +* Copyright (C) 2019, Red Hat, Inc. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "test_util.h" +#include "kvm_util.h" + +#define VCPU_ID 1 + +static uint8_t mem1[65536 ]; +static uint8_t mem2[65536 ]; + +static void guest_code (void ) +{ +int i; + +for (;;) { +for (i =0 ; i <sizeof (mem2); i++) + mem2[i] = mem1[i]; +GUEST_SYNC (0 ); + } +} + +int main (int argc,char *argv[]) +{ +struct kvm_vm *vm; +struct kvm_run *run; +struct kvm_s390_mem_op ksmo; +int rv, i, maxsize; + +setbuf (stdout,NULL );/* Tell stdout not to buffer its content */ + + maxsize =kvm_check_cap (KVM_CAP_S390_MEM_OP ); +if (!maxsize) { +fprintf (stderr,"CAP_S390_MEM_OP not supported -> skip test\n" ); +exit (KSFT_SKIP ); + } +if (maxsize >sizeof (mem1)) + maxsize =sizeof (mem1); + +/* Create VM */ + vm =vm_create_default (VCPU_ID ,0 , guest_code); + run =vcpu_state (vm,VCPU_ID ); + +for (i =0 ; i <sizeof (mem1); i++) + mem1[i] = i * i + i; + +/* Set the first array */ + ksmo.gaddr =addr_gva2gpa (vm, (uintptr_t )mem1); + ksmo.flags =0 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; +vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); + +/* Let the guest code copy the first array to the second */ +vcpu_run (vm,VCPU_ID ); +TEST_ASSERT (run->exit_reason ==KVM_EXIT_S390_SIEIC , +"Unexpected exit reason: %u (%s)\n" , + run->exit_reason, +exit_reason_str (run->exit_reason)); + +memset (mem2,0xaa ,sizeof (mem2)); + +/* Get the second array */ + ksmo.gaddr = (uintptr_t )mem2; + ksmo.flags =0 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_READ ; + ksmo.buf = (uintptr_t )mem2; + ksmo.ar =0 ; +vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); + +TEST_ASSERT (!memcmp (mem1, mem2, maxsize), +"Memory contents do not match!" ); + +/* Check error conditions - first bad size: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size =-1 ; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==E2BIG ,"ioctl allows insane sizes" ); + +/* Zero size: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size =0 ; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 ,"ioctl allows 0 as size" ); + +/* Bad flags: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =-1 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows all flags?" ); + +/* Bad operation: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size = maxsize; + ksmo.op =-1 ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows all flags?" ); + +/* Bad guest address: */ + ksmo.gaddr = ~0xfffUL ; + ksmo.flags =KVM_S390_MEMOP_F_CHECK_ONLY ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv >0 ,"ioctl does not report bad guest memory access" ); + +/* Bad host address: */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf =0 ; + ksmo.ar =0 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EFAULT , +"ioctl does not report bad host memory address" ); + +/* Bad access register: */ + run->psw_mask &= ~(3UL << (63 -17 )); + run->psw_mask |=1UL << (63 -17 );/* Enable AR mode */ +vcpu_run (vm,VCPU_ID );/* To sync new state to SIE block */ + ksmo.gaddr = (uintptr_t )mem1; + ksmo.flags =0 ; + ksmo.size = maxsize; + ksmo.op =KVM_S390_MEMOP_LOGICAL_WRITE ; + ksmo.buf = (uintptr_t )mem1;
tools/testing/selftests/kvm/s390x/memop.c line 165
Quoted 10 lines
tools/testing/selftests/kvm/s390x/memop.c new file +10
-0+ ksmo.ar =17 ; + rv =_vcpu_ioctl (vm,VCPU_ID ,KVM_S390_MEM_OP , &ksmo); +TEST_ASSERT (rv ==-1 && errno ==EINVAL ,"ioctl allows ARs > 15" ); + run->psw_mask &= ~(3UL << (63 -17 ));/* Disable AR mode */ +vcpu_run (vm,VCPU_ID );/* Run to sync new state */ + +kvm_vm_free (vm); + +return 0 ; +}
Had a quick glimpse and besides the two things Janosch mentioned, nothing jumped at me.
Signature · 3 lines
Thanks, David / dhildenb