From patchwork Thu Oct 4 13:56:45 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 189158 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9FC152C03A2 for ; Thu, 4 Oct 2012 23:59:58 +1000 (EST) Received: from localhost ([::1]:42132 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJly0-0006g2-Hh for incoming@patchwork.ozlabs.org; Thu, 04 Oct 2012 09:59:56 -0400 Received: from eggs.gnu.org ([208.118.235.92]:34661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJlvd-0002MB-8s for qemu-devel@nongnu.org; Thu, 04 Oct 2012 09:57:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TJlvS-00068M-HX for qemu-devel@nongnu.org; Thu, 04 Oct 2012 09:57:29 -0400 Received: from cantor2.suse.de ([195.135.220.15]:38297 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJlvS-000689-0X; Thu, 04 Oct 2012 09:57:18 -0400 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 7206DA39D0; Thu, 4 Oct 2012 15:57:17 +0200 (CEST) From: Alexander Graf To: qemu-devel qemu-devel Date: Thu, 4 Oct 2012 15:56:45 +0200 Message-Id: <1349359016-13107-24-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1349359016-13107-1-git-send-email-agraf@suse.de> References: <1349359016-13107-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 X-Received-From: 195.135.220.15 Cc: Blue Swirl , "qemu-ppc@nongnu.org List" , Aurelien Jarno , David Gibson Subject: [Qemu-devel] [PATCH 23/34] target-ppc: KVM: Fix some kernel version edge cases for kvmppc_reset_htab() 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 From: David Gibson The kvmppc_reset_htab() function invokes the KVM_PPC_ALLOCATE_HTAB vm ioctl to request KVM to allocate and reset a hash page table for the guest - it returns the size of hash table allocated, or 0 to indicate that qemu needs to allocate the hash table itself. In practice qemu needs to allocate the htab for full emulation and with Book3sPR KVM, but the kernel has to allocate it for Book3sHV KVM (the hash table needs to be physically contiguous in that case). Unfortunately, the logic in this function is incorrect for some existing kernels. Specifically: * at least some PR KVM versions advertise the relevant capability but don't actually implement the ioctl(), returning ENOTTY. * For old kernels which don't have the capability, we currently return 0. This is correct for PV KVM, where we need to allocate the htab, but not for HV KVM - kernels of this era always allocate a 16MB hash table per guest. This patch corrects both of these edge cases. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- target-ppc/kvm.c | 30 +++++++++++++++++++++++++----- 1 files changed, 25 insertions(+), 5 deletions(-) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 546c116..1975323 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1127,18 +1127,38 @@ int kvmppc_reset_htab(int shift_hint) { uint32_t shift = shift_hint; - if (kvm_enabled() && - kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) { + if (!kvm_enabled()) { + /* Full emulation, tell caller to allocate htab itself */ + return 0; + } + if (kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) { int ret; ret = kvm_vm_ioctl(kvm_state, KVM_PPC_ALLOCATE_HTAB, &shift); - if (ret < 0) { + if (ret == -ENOTTY) { + /* At least some versions of PR KVM advertise the + * capability, but don't implement the ioctl(). Oops. + * Return 0 so that we allocate the htab in qemu, as is + * correct for PR. */ + return 0; + } else if (ret < 0) { return ret; } return shift; } - /* For now.. */ - return 0; + /* We have a kernel that predates the htab reset calls. For PR + * KVM, we need to allocate the htab ourselves, for an HV KVM of + * this era, it has allocated a 16MB fixed size hash table + * already. Kernels of this era have the GET_PVINFO capability + * only on PR, so we use this hack to determine the right + * answer */ + if (kvm_check_extension(kvm_state, KVM_CAP_PPC_GET_PVINFO)) { + /* PR - tell caller to allocate htab */ + return 0; + } else { + /* HV - assume 16MB kernel allocated htab */ + return 24; + } } static inline uint32_t mfpvr(void)