From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54345) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ykdci-0000Jb-WB for qemu-devel@nongnu.org; Tue, 21 Apr 2015 15:14:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ykdcf-000418-OU for qemu-devel@nongnu.org; Tue, 21 Apr 2015 15:14:20 -0400 Received: from cantor2.suse.de ([195.135.220.15]:58079 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ykdcf-00040y-D5 for qemu-devel@nongnu.org; Tue, 21 Apr 2015 15:14:17 -0400 Message-ID: <5536A11E.5020609@suse.de> Date: Tue, 21 Apr 2015 21:12:30 +0200 From: Alexander Graf MIME-Version: 1.0 References: <1428569498-27393-1-git-send-email-cornelia.huck@de.ibm.com> <1428569498-27393-10-git-send-email-cornelia.huck@de.ibm.com> <55351366.9000600@de.ibm.com> In-Reply-To: <55351366.9000600@de.ibm.com> Content-Type: text/plain; charset=iso-8859-15; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 09/10] s390x/mmu: Use ioctl for reading and writing from/to guest memory List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Christian Borntraeger , Cornelia Huck , qemu-devel@nongnu.org Cc: jfrei@linux.vnet.ibm.com, Thomas Huth On 04/20/2015 04:55 PM, Christian Borntraeger wrote: > Am 09.04.2015 um 10:51 schrieb Cornelia Huck: >> From: Thomas Huth >> >> 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. >> >> Signed-off-by: Thomas Huth >> Signed-off-by: Cornelia Huck > Acked-by: Christian Borntraeger > >> --- >> target-s390x/cpu.h | 7 +++++++ >> target-s390x/kvm.c | 35 +++++++++++++++++++++++++++++++++++ >> target-s390x/mmu_helper.c | 9 +++++++++ >> 3 files changed, 51 insertions(+) >> >> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h >> index 79bc80b..9c42743 100644 >> --- a/target-s390x/cpu.h >> +++ b/target-s390x/cpu.h >> @@ -401,6 +401,8 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq); >> void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq); >> int kvm_s390_inject_flic(struct kvm_s390_irq *irq); >> void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code); >> +int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, void *hostbuf, int len, >> + bool is_write); >> int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock); >> int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_clock); >> #else >> @@ -418,6 +420,11 @@ static inline int kvm_s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) >> { >> return -ENOSYS; >> } >> +static inline int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, void *hostbuf, >> + int len, bool is_write) >> +{ >> + return -ENOSYS; >> +} >> static inline void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, >> uint64_t te_code) >> { >> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c >> index 619684b..e2ae2b3 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,39 @@ 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, >> + }; >> + >> + if (!cap_mem_op) { >> + return -ENOSYS; >> + } >> + if (!hostbuf) { >> + mem_op.flags |= KVM_S390_MEMOP_F_CHECK_ONLY; >> + } >> + >> + return kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op); >> +} >> + >> /* >> * Legacy layout for s390: >> * Older S390 KVM requires the topmost vma of the RAM to be >> diff --git a/target-s390x/mmu_helper.c b/target-s390x/mmu_helper.c >> index 9b88498..1e7412c 100644 >> --- a/target-s390x/mmu_helper.c >> +++ b/target-s390x/mmu_helper.c >> @@ -450,6 +450,15 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, void *hostbuf, >> target_ulong *pages; >> int ret; >> >> + if (kvm_enabled()) { >> + ret = kvm_s390_mem_op(cpu, laddr, hostbuf, len, is_write); >> + if (ret >= 0) { >> + return ret; >> + } else if (ret != -ENOSYS) { >> + error_printf("kvm_s390_mem_op() failed: %s\n", strerror(-ret)); Won't this spill the logs like crazy when running new qemu on old kernels? Alex >> + } >> + } >> + >> nr_pages = (((laddr & ~TARGET_PAGE_MASK) + len - 1) >> TARGET_PAGE_BITS) >> + 1; >> pages = g_malloc(nr_pages * sizeof(*pages)); >>