diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2015-02-06 15:54:58 +0100 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2015-04-30 13:21:42 +0200 |
commit | a9bcd1b8719dea2e91512238d810e2a0037e174d (patch) | |
tree | 9f4520bf1f7267b405dbf8e4b18074af306a56cd /target-s390x/kvm.c | |
parent | f07177a5599fb204e42a007db4820ceda1bc85ba (diff) |
s390x/mmu: Use ioctl for reading and writing from/to guest memory
Add code to make use of the new ioctl for reading from / writing to
virtual guest memory. By using the ioctl, the memory accesses are now
protected with the so-called ipte-lock in the kernel.
[CH: moved error message into kvm_s390_mem_op()]
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'target-s390x/kvm.c')
-rw-r--r-- | target-s390x/kvm.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 619684b9ee..1c0e78c64b 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -123,6 +123,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { static int cap_sync_regs; static int cap_async_pf; +static int cap_mem_op; static void *legacy_s390_alloc(size_t size, uint64_t *align); @@ -247,6 +248,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) { cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS); cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF); + cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP); kvm_s390_enable_cmma(s); @@ -550,6 +552,44 @@ int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); } +/** + * kvm_s390_mem_op: + * @addr: the logical start address in guest memory + * @hostbuf: buffer in host memory. NULL = do only checks w/o copying + * @len: length that should be transfered + * @is_write: true = write, false = read + * Returns: 0 on success, non-zero if an exception or error occured + * + * Use KVM ioctl to read/write from/to guest memory. An access exception + * is injected into the vCPU in case of translation errors. + */ +int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, void *hostbuf, int len, + bool is_write) +{ + struct kvm_s390_mem_op mem_op = { + .gaddr = addr, + .flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION, + .size = len, + .op = is_write ? KVM_S390_MEMOP_LOGICAL_WRITE + : KVM_S390_MEMOP_LOGICAL_READ, + .buf = (uint64_t)hostbuf, + }; + int ret; + + if (!cap_mem_op) { + return -ENOSYS; + } + if (!hostbuf) { + mem_op.flags |= KVM_S390_MEMOP_F_CHECK_ONLY; + } + + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op); + if (ret < 0) { + error_printf("KVM_S390_MEM_OP failed: %s\n", strerror(-ret)); + } + return ret; +} + /* * Legacy layout for s390: * Older S390 KVM requires the topmost vma of the RAM to be |