From patchwork Thu Jun 13 07:02:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 250994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DFBD52C0079 for ; Thu, 13 Jun 2013 17:07:21 +1000 (EST) Received: from localhost ([::1]:45936 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Un1ct-0000bX-LS for incoming@patchwork.ozlabs.org; Thu, 13 Jun 2013 03:07:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52487) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Un1YB-0002yC-IV for qemu-devel@nongnu.org; Thu, 13 Jun 2013 03:02:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Un1Y8-00033D-GI for qemu-devel@nongnu.org; Thu, 13 Jun 2013 03:02:27 -0400 Received: from oxygen.pond.sub.org ([2a01:4f8:121:10e4::3]:39476) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Un1Y8-00032a-61 for qemu-devel@nongnu.org; Thu, 13 Jun 2013 03:02:24 -0400 Received: from blackfin.pond.sub.org (p5B32AA2B.dip0.t-ipconnect.de [91.50.170.43]) by oxygen.pond.sub.org (Postfix) with ESMTPA id 045FAA0179; Thu, 13 Jun 2013 09:02:22 +0200 (CEST) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 96142200B8; Thu, 13 Jun 2013 09:02:19 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Jun 2013 09:02:16 +0200 Message-Id: <1371106939-6968-6-git-send-email-armbru@redhat.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1371106939-6968-1-git-send-email-armbru@redhat.com> References: <1371106939-6968-1-git-send-email-armbru@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a01:4f8:121:10e4::3 Cc: mtosatti@redhat.com, borntraeger@de.ibm.com, pbonzini@redhat.com, agraf@suse.de, stefano.stabellini@eu.citrix.com Subject: [Qemu-devel] [PATCH RFC 5/8] s390: Make qemu_ram_remap() consistent with allocation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Old S390 KVM wants guest RAM mapped in a peculiar way. Commit fdec991 changed qemu_ram_alloc_from_ptr() to do this only when necessary, but forgot to update qemu_ram_remap(). If qemu_ram_alloc_from_ptr() maps RAM the normal way, but qemu_ram_remap() remaps it the peculiar way, remapping changes protection and flags, which it shouldn't. Fortunately, this can't happen right now, as we never remap on S390. Fix it anyway. Thanks to Christian Borntraeger for help with assessing the bug's (non-)impact. Signed-off-by: Markus Armbruster --- exec.c | 19 +++++++------------ include/sysemu/kvm.h | 1 + kvm-all.c | 1 + target-s390x/kvm.c | 15 ++++++++++----- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/exec.c b/exec.c index 7552e3c..8810d33 100644 --- a/exec.c +++ b/exec.c @@ -1209,27 +1209,22 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) } else if (xen_enabled()) { abort(); } else { - flags = MAP_FIXED; munmap(vaddr, length); if (block->fd >= 0) { #ifdef MAP_POPULATE - flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED : + flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE; #else - flags |= MAP_PRIVATE; + flags = MAP_PRIVATE; #endif area = mmap(vaddr, length, PROT_READ | PROT_WRITE, - flags, block->fd, offset); + MAP_FIXED | flags, block->fd, offset); + } else if (kvm_enabled() && kvm_arch_ram_remap) { + area = kvm_arch_ram_remap(vaddr, length); } else { -#if defined(TARGET_S390X) && defined(CONFIG_KVM) - flags |= MAP_SHARED | MAP_ANONYMOUS; - area = mmap(vaddr, length, PROT_EXEC|PROT_READ|PROT_WRITE, - flags, -1, 0); -#else - flags |= MAP_PRIVATE | MAP_ANONYMOUS; area = mmap(vaddr, length, PROT_READ | PROT_WRITE, - flags, -1, 0); -#endif + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); } if (area != vaddr) { fprintf(stderr, "Could not remap addr: " diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index dd79914..fdfa7ba 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -153,6 +153,7 @@ int kvm_cpu_exec(CPUArchState *env); #if !defined(CONFIG_USER_ONLY) extern void *(*kvm_arch_ram_alloc)(ram_addr_t size); +extern void *(*kvm_arch_ram_remap)(void *vaddr, ram_addr_t size); #endif void kvm_setup_guest_memory(void *start, size_t size); diff --git a/kvm-all.c b/kvm-all.c index 5e0cc9b..daa4d40 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -120,6 +120,7 @@ static const KVMCapabilityInfo kvm_required_capabilites[] = { }; void *(*kvm_arch_ram_alloc)(ram_addr_t size); +void *(*kvm_arch_ram_remap)(void *vaddr, ram_addr_t size); static KVMSlot *kvm_alloc_slot(KVMState *s) { diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index be802ab..aa45e06 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -93,6 +93,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { static int cap_sync_regs; static void *legacy_s390_alloc(ram_addr_t size); +static void *legacy_s390_mmap(void *vaddr, ram_addr_t length); int kvm_arch_init(KVMState *s) { @@ -100,6 +101,7 @@ int kvm_arch_init(KVMState *s) if (!kvm_check_extension(s, KVM_CAP_S390_GMAP) || !kvm_check_extension(s, KVM_CAP_S390_COW)) { kvm_arch_ram_alloc = legacy_s390_alloc; + kvm_arch_ram_remap = legacy_s390_mmap; } return 0; } @@ -324,13 +326,16 @@ int kvm_s390_get_registers_partial(CPUState *cs) * to grow. We also have to use MAP parameters that avoid * read-only mapping of guest pages. */ -static void *legacy_s390_alloc(ram_addr_t size) + +static void *legacy_s390_mmap(void *vaddr, ram_addr_t size) { - void *mem; + return mmap(vaddr, size, PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS, -1, 0); +} - mem = mmap((void *) 0x800000000ULL, size, - PROT_EXEC|PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0); +static void *legacy_s390_alloc(ram_addr_t size) +{ + void *mem = legacy_s390_mmap((void *) 0x800000000ULL, size); if (mem == MAP_FAILED) { fprintf(stderr, "Allocating RAM failed\n"); abort();