From patchwork Thu Nov 13 14:56:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 40773 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f70.google.com (mail-wg0-f70.google.com [74.125.82.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 35C9024493 for ; Thu, 13 Nov 2014 14:56:13 +0000 (UTC) Received: by mail-wg0-f70.google.com with SMTP id x13sf7993899wgg.9 for ; Thu, 13 Nov 2014 06:56:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=ySbWOj+zKXewM/sVbfyeNDPRl2vtskr8evPx4jegIgc=; b=XYmza0u5Z6Aqri866gcaLI1al8lokVZiXGNLA5KbfeBHQ90bQF2J276gyazd+LyPEX O2VjI6R4lfyVs5fEpucPMeNo3vyTta2d6GGDG7qqbAuymYTJGH+BzXGxXofCHRC3WoDl Umv5LmK0qfsBWw5YKDh7pSm1Bh5VrVvSBhAEkHIr0/OD46njFfK4msMzos1JrqtjfB/v H9afq9YcLP6KKRDZMG8YSzdG7bahakpPJAGnjqFYk6Zl7hI2zww3cR9G9ZMZD19a/TXi AMXIvCWB8qEp/cjJ2i4C5b3vtBj3xlnDB2z37oW0oaBS1omNLlX9AQ4Anw0HQuvtG8ea 0MpQ== X-Gm-Message-State: ALoCoQmYGjPCgd+Qs8D9oHmzef7zbJiddzBaoiiKopO92mgMGJ8/xVGXzHdcEOAWB7Z1XrCiqvm9 X-Received: by 10.112.32.163 with SMTP id k3mr38697lbi.17.1415890572286; Thu, 13 Nov 2014 06:56:12 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.19.227 with SMTP id i3ls655515lae.28.gmail; Thu, 13 Nov 2014 06:56:12 -0800 (PST) X-Received: by 10.152.30.33 with SMTP id p1mr2860635lah.78.1415890572083; Thu, 13 Nov 2014 06:56:12 -0800 (PST) Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com. [209.85.217.182]) by mx.google.com with ESMTPS id u4si14850160lae.31.2014.11.13.06.56.11 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 13 Nov 2014 06:56:11 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.182 as permitted sender) client-ip=209.85.217.182; Received: by mail-lb0-f182.google.com with SMTP id f15so12418785lbj.27 for ; Thu, 13 Nov 2014 06:56:11 -0800 (PST) X-Received: by 10.112.189.10 with SMTP id ge10mr2854121lbc.23.1415890571627; Thu, 13 Nov 2014 06:56:11 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.184.201 with SMTP id ew9csp600774lbc; Thu, 13 Nov 2014 06:56:11 -0800 (PST) X-Received: by 10.194.78.3 with SMTP id x3mr4509865wjw.127.1415890570889; Thu, 13 Nov 2014 06:56:10 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id d4si44918272wje.123.2014.11.13.06.56.10 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 13 Nov 2014 06:56:10 -0800 (PST) Received-SPF: none (google.com: pm215@archaic.org.uk does not designate permitted sender hosts) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Xovof-0001wh-5N; Thu, 13 Nov 2014 14:56:09 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Paolo Bonzini Subject: [PATCH] target-arm: handle address translations that start at level 3 Date: Thu, 13 Nov 2014 14:56:09 +0000 Message-Id: <1415890569-7454-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.182 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The ARMv8 address translation system defines that a page table walk starts at a level which depends on the translation granule size and the number of bits of virtual address that need to be resolved. Where the translation granule is 64KB and the guest sets the TCR.TxSZ field to between 35 and 39, it's actually possible to start at level 3 (the final level). QEMU's implementation failed to handle this case, and so we would set level to 2 and behave incorrectly (including invoking the C undefined behaviour of shifting left by a negative number). Correct the code that determines the starting level to deal with the start-at-3 case, by replacing the if-else ladder with an expression derived from the ARM ARM pseudocode version. This error was detected by the Coverity scan, which spotted the potential shift by a negative number. Signed-off-by: Peter Maydell --- target-arm/helper.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/target-arm/helper.c b/target-arm/helper.c index c47487a..b74d348 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4545,16 +4545,18 @@ static int get_phys_addr_lpae(CPUARMState *env, target_ulong address, goto do_fault; } - /* The starting level depends on the virtual address size which can be - * up to 48-bits and the translation granule size. + /* The starting level depends on the virtual address size (which can be + * up to 48 bits) and the translation granule size. It indicates the number + * of strides (granule_sz bits at a time) needed to consume the bits + * of the input address. In the pseudocode this is: + * level = 4 - RoundUp((inputsize - grainsize) / stride) + * where their 'inputsize' is our 'va_size - tsz', 'grainsize' is + * our 'granule_sz + 3' and 'stride' is our 'granule_sz'. + * Applying the usual "rounded up m/n is (m+n-1)/n" and simplifying: + * = 4 - (va_size - tsz - granule_sz - 3 + granule_sz - 1) / granule_sz + * = 4 - (va_size - tsz - 4) / granule_sz; */ - if ((va_size - tsz) > (granule_sz * 4 + 3)) { - level = 0; - } else if ((va_size - tsz) > (granule_sz * 3 + 3)) { - level = 1; - } else { - level = 2; - } + level = 4 - (va_size - tsz - 4) / granule_sz; /* Clear the vaddr bits which aren't part of the within-region address, * so that we don't have to special case things when calculating the