Received: by 2002:a05:6a10:eb17:0:0:0:0 with SMTP id hx23csp318516pxb; Fri, 3 Sep 2021 02:52:47 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzcao7DDYISW8nu8upqXlWZYoaQmCVc/cguCn+snMv8H3uWR0GMTSLqvm9kNf9bcLXge1rf X-Received: by 2002:a6b:5911:: with SMTP id n17mr2309225iob.180.1630662767699; Fri, 03 Sep 2021 02:52:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1630662767; cv=none; d=google.com; s=arc-20160816; b=widdzDIua3KmTU8mHtut+REopGcO0IJqDjLRzX4jMKCP7j0/CfZVEwiIAueyxZRCLK qEWK5Yy2JYl18LDM59nNu1hZ0hKo4ld9bkk4L8sLrhkQ0Z4P77FlYOjtNGmsWZ2/b8ft gnVu9fXzbKWripVN3Eua9cbdLTBEyGmf3hFhyBsQZWFyhmaOJsXSNwcLizXGZknHPM1Y /AA6hwfITT2qv5X4EO9qhqbdlTN79xIb3nIhDpvnHYuu4Z8TW3L3ts1r47UQUPOyQNf3 EhoC19ux0m3Q+672TeeX+RTcGLCF+D6AA+3CKfLxeT8BuuK0mB79DRMmJhzfNEz8eUaY mFYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=WkYc1/YjJY1ynZLsgBiWr/OqwU0IENPxsEZomUtlG48=; b=wISY2kNBFuAtg7YI4YdLRK8Ho6BV9eUGP4iKeQS1QMuYRtN+rb1Jy0IK6z1VfRuFnd LakoNBtWidkT7em+T4i5BxeAif3K4NBNPBp3k+J1Vdc8PRjoo3/MGIl5MC6OfMHr+3kV Fo1OpBP5/TUWyigt43Qh4soIxhWZFYqGrBw5UEHvvKLtCehOa9DHTWQ0Ds11Xw7wPtmV kcTB6TpotEeINrWUXntdJov5RjKk4wW83ZC/zC/zM7GOpOqKuptBOKkB/dljNhiWXDEp RKM6mJLlG3qhUrCqJeUI/+p8PSB2vtU0Sxeo0jweJRz+kmcrbI12oEV9qOLnsNnBTDZ/ BXHw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h15si76743ili.36.2021.09.03.02.52.32; Fri, 03 Sep 2021 02:52:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348822AbhICJvU (ORCPT + 99 others); Fri, 3 Sep 2021 05:51:20 -0400 Received: from foss.arm.com ([217.140.110.172]:39970 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234932AbhICJvR (ORCPT ); Fri, 3 Sep 2021 05:51:17 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 467E41FB; Fri, 3 Sep 2021 02:50:16 -0700 (PDT) Received: from e122027.lan (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E97293F694; Fri, 3 Sep 2021 02:50:14 -0700 (PDT) From: Steven Price To: Rob Herring , Tomeu Vizoso , Alyssa Rosenzweig , Boris Brezillon Cc: Steven Price , Daniel Vetter , David Airlie , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] drm/panfrost: Calculate lock region size correctly Date: Fri, 3 Sep 2021 10:49:57 +0100 Message-Id: <20210903094957.74560-1-steven.price@arm.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It turns out that when locking a region, the region must be a naturally aligned power of 2. The upshot of this is that if the desired region crosses a 'large boundary' the region size must be increased significantly to ensure that the locked region completely covers the desired region. Previous calculations (including in kbase for the proprietary driver) failed to take this into account. Since it's known that the lock region must be naturally aligned we can compute the required size by looking at the highest bit position which changes between the start/end of the lock region (subtracting 1 from the end because the end address is exclusive). The start address is then aligned based on the size (this is technically unnecessary as the hardware will ignore these bits, but the spec advises to do this "to avoid confusion"). Reviewed-by: Boris Brezillon Signed-off-by: Steven Price --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 30 +++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index dfe5f1d29763..e2629b8d6a02 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -58,17 +58,33 @@ static int write_cmd(struct panfrost_device *pfdev, u32 as_nr, u32 cmd) } static void lock_region(struct panfrost_device *pfdev, u32 as_nr, - u64 iova, u64 size) + u64 region_start, u64 size) { u8 region_width; - u64 region = iova & PAGE_MASK; + u64 region; + u64 region_end = region_start + size; - /* The size is encoded as ceil(log2) minus(1), which may be calculated - * with fls. The size must be clamped to hardware bounds. + if (!size) + return; + + /* + * The locked region is a naturally aligned power of 2 block encoded as + * log2 minus(1). + * Calculate the desired start/end and look for the highest bit which + * differs. The smallest naturally aligned block must include this bit + * change, the desired region starts with this bit (and subsequent bits) + * zeroed and ends with the bit (and subsequent bits) set to one. */ - size = max_t(u64, size, AS_LOCK_REGION_MIN_SIZE); - region_width = fls64(size - 1) - 1; - region |= region_width; + region_width = max(fls64(region_start ^ (region_end - 1)), + const_ilog2(AS_LOCK_REGION_MIN_SIZE)) - 1; + + /* + * Mask off the low bits of region_start (which would be ignored by + * the hardware anyway) + */ + region_start &= GENMASK_ULL(63, region_width); + + region = region_width | region_start; /* Lock the region that needs to be updated */ mmu_write(pfdev, AS_LOCKADDR_LO(as_nr), region & 0xFFFFFFFFUL); -- 2.30.2