1d87f36a0SRajneesh Bhardwaj // SPDX-License-Identifier: GPL-2.0 OR MIT
219f6d2a6SOded Gabbay /*
3d87f36a0SRajneesh Bhardwaj  * Copyright 2014-2022 Advanced Micro Devices, Inc.
419f6d2a6SOded Gabbay  *
519f6d2a6SOded Gabbay  * Permission is hereby granted, free of charge, to any person obtaining a
619f6d2a6SOded Gabbay  * copy of this software and associated documentation files (the "Software"),
719f6d2a6SOded Gabbay  * to deal in the Software without restriction, including without limitation
819f6d2a6SOded Gabbay  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
919f6d2a6SOded Gabbay  * and/or sell copies of the Software, and to permit persons to whom the
1019f6d2a6SOded Gabbay  * Software is furnished to do so, subject to the following conditions:
1119f6d2a6SOded Gabbay  *
1219f6d2a6SOded Gabbay  * The above copyright notice and this permission notice shall be included in
1319f6d2a6SOded Gabbay  * all copies or substantial portions of the Software.
1419f6d2a6SOded Gabbay  *
1519f6d2a6SOded Gabbay  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1619f6d2a6SOded Gabbay  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1719f6d2a6SOded Gabbay  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1819f6d2a6SOded Gabbay  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1919f6d2a6SOded Gabbay  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2019f6d2a6SOded Gabbay  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2119f6d2a6SOded Gabbay  * OTHER DEALINGS IN THE SOFTWARE.
2219f6d2a6SOded Gabbay  *
2319f6d2a6SOded Gabbay  */
2419f6d2a6SOded Gabbay 
2519f6d2a6SOded Gabbay #include <linux/device.h>
2619f6d2a6SOded Gabbay #include <linux/export.h>
2719f6d2a6SOded Gabbay #include <linux/err.h>
2819f6d2a6SOded Gabbay #include <linux/fs.h>
2919f6d2a6SOded Gabbay #include <linux/sched.h>
3019f6d2a6SOded Gabbay #include <linux/slab.h>
3119f6d2a6SOded Gabbay #include <linux/uaccess.h>
3219f6d2a6SOded Gabbay #include <linux/compat.h>
3319f6d2a6SOded Gabbay #include <uapi/linux/kfd_ioctl.h>
3419f6d2a6SOded Gabbay #include <linux/time.h>
3519f6d2a6SOded Gabbay #include "kfd_priv.h"
3619f6d2a6SOded Gabbay #include <linux/mm.h>
372497ee72SChristoph Hellwig #include <linux/mman.h>
382243f493SRajneesh Bhardwaj #include <linux/processor.h>
3919f6d2a6SOded Gabbay 
4019f6d2a6SOded Gabbay /*
4119f6d2a6SOded Gabbay  * The primary memory I/O features being added for revisions of gfxip
4219f6d2a6SOded Gabbay  * beyond 7.0 (Kaveri) are:
4319f6d2a6SOded Gabbay  *
4419f6d2a6SOded Gabbay  * Access to ATC/IOMMU mapped memory w/ associated extension of VA to 48b
4519f6d2a6SOded Gabbay  *
4619f6d2a6SOded Gabbay  * “Flat” shader memory access – These are new shader vector memory
4719f6d2a6SOded Gabbay  * operations that do not reference a T#/V# so a “pointer” is what is
4819f6d2a6SOded Gabbay  * sourced from the vector gprs for direct access to memory.
4919f6d2a6SOded Gabbay  * This pointer space has the Shared(LDS) and Private(Scratch) memory
5019f6d2a6SOded Gabbay  * mapped into this pointer space as apertures.
5119f6d2a6SOded Gabbay  * The hardware then determines how to direct the memory request
5219f6d2a6SOded Gabbay  * based on what apertures the request falls in.
5319f6d2a6SOded Gabbay  *
5419f6d2a6SOded Gabbay  * Unaligned support and alignment check
5519f6d2a6SOded Gabbay  *
5619f6d2a6SOded Gabbay  *
5719f6d2a6SOded Gabbay  * System Unified Address - SUA
5819f6d2a6SOded Gabbay  *
5919f6d2a6SOded Gabbay  * The standard usage for GPU virtual addresses are that they are mapped by
6019f6d2a6SOded Gabbay  * a set of page tables we call GPUVM and these page tables are managed by
6119f6d2a6SOded Gabbay  * a combination of vidMM/driver software components.  The current virtual
6219f6d2a6SOded Gabbay  * address (VA) range for GPUVM is 40b.
6319f6d2a6SOded Gabbay  *
6419f6d2a6SOded Gabbay  * As of gfxip7.1 and beyond we’re adding the ability for compute memory
6519f6d2a6SOded Gabbay  * clients (CP/RLC, DMA, SHADER(ifetch, scalar, and vector ops)) to access
6619f6d2a6SOded Gabbay  * the same page tables used by host x86 processors and that are managed by
6719f6d2a6SOded Gabbay  * the operating system. This is via a technique and hardware called ATC/IOMMU.
6819f6d2a6SOded Gabbay  * The GPU has the capability of accessing both the GPUVM and ATC address
6919f6d2a6SOded Gabbay  * spaces for a given VMID (process) simultaneously and we call this feature
7019f6d2a6SOded Gabbay  * system unified address (SUA).
7119f6d2a6SOded Gabbay  *
7219f6d2a6SOded Gabbay  * There are three fundamental address modes of operation for a given VMID
7319f6d2a6SOded Gabbay  * (process) on the GPU:
7419f6d2a6SOded Gabbay  *
7519f6d2a6SOded Gabbay  *	HSA64 – 64b pointers and the default address space is ATC
7619f6d2a6SOded Gabbay  *	HSA32 – 32b pointers and the default address space is ATC
7719f6d2a6SOded Gabbay  *	GPUVM – 64b pointers and the default address space is GPUVM (driver
7819f6d2a6SOded Gabbay  *		model mode)
7919f6d2a6SOded Gabbay  *
8019f6d2a6SOded Gabbay  *
8119f6d2a6SOded Gabbay  * HSA64 - ATC/IOMMU 64b
8219f6d2a6SOded Gabbay  *
8319f6d2a6SOded Gabbay  * A 64b pointer in the AMD64/IA64 CPU architecture is not fully utilized
8419f6d2a6SOded Gabbay  * by the CPU so an AMD CPU can only access the high area
8519f6d2a6SOded Gabbay  * (VA[63:47] == 0x1FFFF) and low area (VA[63:47 == 0) of the address space
8619f6d2a6SOded Gabbay  * so the actual VA carried to translation is 48b.  There is a “hole” in
8719f6d2a6SOded Gabbay  * the middle of the 64b VA space.
8819f6d2a6SOded Gabbay  *
8919f6d2a6SOded Gabbay  * The GPU not only has access to all of the CPU accessible address space via
9019f6d2a6SOded Gabbay  * ATC/IOMMU, but it also has access to the GPUVM address space.  The “system
9119f6d2a6SOded Gabbay  * unified address” feature (SUA) is the mapping of GPUVM and ATC address
9219f6d2a6SOded Gabbay  * spaces into a unified pointer space.  The method we take for 64b mode is
9319f6d2a6SOded Gabbay  * to map the full 40b GPUVM address space into the hole of the 64b address
9419f6d2a6SOded Gabbay  * space.
9519f6d2a6SOded Gabbay 
9619f6d2a6SOded Gabbay  * The GPUVM_Base/GPUVM_Limit defines the aperture in the 64b space where we
9719f6d2a6SOded Gabbay  * direct requests to be translated via GPUVM page tables instead of the
9819f6d2a6SOded Gabbay  * IOMMU path.
9919f6d2a6SOded Gabbay  *
10019f6d2a6SOded Gabbay  *
10119f6d2a6SOded Gabbay  * 64b to 49b Address conversion
10219f6d2a6SOded Gabbay  *
10319f6d2a6SOded Gabbay  * Note that there are still significant portions of unused regions (holes)
10419f6d2a6SOded Gabbay  * in the 64b address space even for the GPU.  There are several places in
10519f6d2a6SOded Gabbay  * the pipeline (sw and hw), we wish to compress the 64b virtual address
10619f6d2a6SOded Gabbay  * to a 49b address.  This 49b address is constituted of an “ATC” bit
10719f6d2a6SOded Gabbay  * plus a 48b virtual address.  This 49b address is what is passed to the
10819f6d2a6SOded Gabbay  * translation hardware.  ATC==0 means the 48b address is a GPUVM address
10919f6d2a6SOded Gabbay  * (max of 2^40 – 1) intended to be translated via GPUVM page tables.
11019f6d2a6SOded Gabbay  * ATC==1 means the 48b address is intended to be translated via IOMMU
11119f6d2a6SOded Gabbay  * page tables.
11219f6d2a6SOded Gabbay  *
11319f6d2a6SOded Gabbay  * A 64b pointer is compared to the apertures that are defined (Base/Limit), in
11419f6d2a6SOded Gabbay  * this case the GPUVM aperture (red) is defined and if a pointer falls in this
11519f6d2a6SOded Gabbay  * aperture, we subtract the GPUVM_Base address and set the ATC bit to zero
11619f6d2a6SOded Gabbay  * as part of the 64b to 49b conversion.
11719f6d2a6SOded Gabbay  *
11819f6d2a6SOded Gabbay  * Where this 64b to 49b conversion is done is a function of the usage.
11919f6d2a6SOded Gabbay  * Most GPU memory access is via memory objects where the driver builds
12019f6d2a6SOded Gabbay  * a descriptor which consists of a base address and a memory access by
12119f6d2a6SOded Gabbay  * the GPU usually consists of some kind of an offset or Cartesian coordinate
12219f6d2a6SOded Gabbay  * that references this memory descriptor.  This is the case for shader
12319f6d2a6SOded Gabbay  * instructions that reference the T# or V# constants, or for specified
12419f6d2a6SOded Gabbay  * locations of assets (ex. the shader program location).  In these cases
12519f6d2a6SOded Gabbay  * the driver is what handles the 64b to 49b conversion and the base
12619f6d2a6SOded Gabbay  * address in the descriptor (ex. V# or T# or shader program location)
12719f6d2a6SOded Gabbay  * is defined as a 48b address w/ an ATC bit.  For this usage a given
12819f6d2a6SOded Gabbay  * memory object cannot straddle multiple apertures in the 64b address
12919f6d2a6SOded Gabbay  * space. For example a shader program cannot jump in/out between ATC
13019f6d2a6SOded Gabbay  * and GPUVM space.
13119f6d2a6SOded Gabbay  *
13219f6d2a6SOded Gabbay  * In some cases we wish to pass a 64b pointer to the GPU hardware and
13319f6d2a6SOded Gabbay  * the GPU hw does the 64b to 49b conversion before passing memory
13419f6d2a6SOded Gabbay  * requests to the cache/memory system.  This is the case for the
13519f6d2a6SOded Gabbay  * S_LOAD and FLAT_* shader memory instructions where we have 64b pointers
13619f6d2a6SOded Gabbay  * in scalar and vector GPRs respectively.
13719f6d2a6SOded Gabbay  *
13819f6d2a6SOded Gabbay  * In all cases (no matter where the 64b -> 49b conversion is done), the gfxip
13919f6d2a6SOded Gabbay  * hardware sends a 48b address along w/ an ATC bit, to the memory controller
14019f6d2a6SOded Gabbay  * on the memory request interfaces.
14119f6d2a6SOded Gabbay  *
14219f6d2a6SOded Gabbay  *	<client>_MC_rdreq_atc   // read request ATC bit
14319f6d2a6SOded Gabbay  *
14419f6d2a6SOded Gabbay  *		0 : <client>_MC_rdreq_addr is a GPUVM VA
14519f6d2a6SOded Gabbay  *
14619f6d2a6SOded Gabbay  *		1 : <client>_MC_rdreq_addr is a ATC VA
14719f6d2a6SOded Gabbay  *
14819f6d2a6SOded Gabbay  *
14919f6d2a6SOded Gabbay  * “Spare” aperture (APE1)
15019f6d2a6SOded Gabbay  *
15119f6d2a6SOded Gabbay  * We use the GPUVM aperture to differentiate ATC vs. GPUVM, but we also use
15219f6d2a6SOded Gabbay  * apertures to set the Mtype field for S_LOAD/FLAT_* ops which is input to the
15319f6d2a6SOded Gabbay  * config tables for setting cache policies. The “spare” (APE1) aperture is
15419f6d2a6SOded Gabbay  * motivated by getting a different Mtype from the default.
15519f6d2a6SOded Gabbay  * The default aperture isn’t an actual base/limit aperture; it is just the
15619f6d2a6SOded Gabbay  * address space that doesn’t hit any defined base/limit apertures.
15719f6d2a6SOded Gabbay  * The following diagram is a complete picture of the gfxip7.x SUA apertures.
15819f6d2a6SOded Gabbay  * The APE1 can be placed either below or above
15919f6d2a6SOded Gabbay  * the hole (cannot be in the hole).
16019f6d2a6SOded Gabbay  *
16119f6d2a6SOded Gabbay  *
16219f6d2a6SOded Gabbay  * General Aperture definitions and rules
16319f6d2a6SOded Gabbay  *
16419f6d2a6SOded Gabbay  * An aperture register definition consists of a Base, Limit, Mtype, and
16519f6d2a6SOded Gabbay  * usually an ATC bit indicating which translation tables that aperture uses.
16619f6d2a6SOded Gabbay  * In all cases (for SUA and DUA apertures discussed later), aperture base
16719f6d2a6SOded Gabbay  * and limit definitions are 64KB aligned.
16819f6d2a6SOded Gabbay  *
16919f6d2a6SOded Gabbay  *	<ape>_Base[63:0] = { <ape>_Base_register[63:16], 0x0000 }
17019f6d2a6SOded Gabbay  *
17119f6d2a6SOded Gabbay  *	<ape>_Limit[63:0] = { <ape>_Limit_register[63:16], 0xFFFF }
17219f6d2a6SOded Gabbay  *
17319f6d2a6SOded Gabbay  * The base and limit are considered inclusive to an aperture so being
17419f6d2a6SOded Gabbay  * inside an aperture means (address >= Base) AND (address <= Limit).
17519f6d2a6SOded Gabbay  *
17619f6d2a6SOded Gabbay  * In no case is a payload that straddles multiple apertures expected to work.
17719f6d2a6SOded Gabbay  * For example a load_dword_x4 that starts in one aperture and ends in another,
17819f6d2a6SOded Gabbay  * does not work.  For the vector FLAT_* ops we have detection capability in
17919f6d2a6SOded Gabbay  * the shader for reporting a “memory violation” back to the
18019f6d2a6SOded Gabbay  * SQ block for use in traps.
18119f6d2a6SOded Gabbay  * A memory violation results when an op falls into the hole,
18219f6d2a6SOded Gabbay  * or a payload straddles multiple apertures.  The S_LOAD instruction
18319f6d2a6SOded Gabbay  * does not have this detection.
18419f6d2a6SOded Gabbay  *
18519f6d2a6SOded Gabbay  * Apertures cannot overlap.
18619f6d2a6SOded Gabbay  *
18719f6d2a6SOded Gabbay  *
18819f6d2a6SOded Gabbay  *
18919f6d2a6SOded Gabbay  * HSA32 - ATC/IOMMU 32b
19019f6d2a6SOded Gabbay  *
19119f6d2a6SOded Gabbay  * For HSA32 mode, the pointers are interpreted as 32 bits and use a single GPR
19219f6d2a6SOded Gabbay  * instead of two for the S_LOAD and FLAT_* ops. The entire GPUVM space of 40b
19319f6d2a6SOded Gabbay  * will not fit so there is only partial visibility to the GPUVM
19419f6d2a6SOded Gabbay  * space (defined by the aperture) for S_LOAD and FLAT_* ops.
19519f6d2a6SOded Gabbay  * There is no spare (APE1) aperture for HSA32 mode.
19619f6d2a6SOded Gabbay  *
19719f6d2a6SOded Gabbay  *
19819f6d2a6SOded Gabbay  * GPUVM 64b mode (driver model)
19919f6d2a6SOded Gabbay  *
20019f6d2a6SOded Gabbay  * This mode is related to HSA64 in that the difference really is that
20119f6d2a6SOded Gabbay  * the default aperture is GPUVM (ATC==0) and not ATC space.
20219f6d2a6SOded Gabbay  * We have gfxip7.x hardware that has FLAT_* and S_LOAD support for
20319f6d2a6SOded Gabbay  * SUA GPUVM mode, but does not support HSA32/HSA64.
20419f6d2a6SOded Gabbay  *
20519f6d2a6SOded Gabbay  *
20619f6d2a6SOded Gabbay  * Device Unified Address - DUA
20719f6d2a6SOded Gabbay  *
20819f6d2a6SOded Gabbay  * Device unified address (DUA) is the name of the feature that maps the
20919f6d2a6SOded Gabbay  * Shared(LDS) memory and Private(Scratch) memory into the overall address
21019f6d2a6SOded Gabbay  * space for use by the new FLAT_* vector memory ops.  The Shared and
21119f6d2a6SOded Gabbay  * Private memories are mapped as apertures into the address space,
21219f6d2a6SOded Gabbay  * and the hardware detects when a FLAT_* memory request is to be redirected
21319f6d2a6SOded Gabbay  * to the LDS or Scratch memory when it falls into one of these apertures.
21419f6d2a6SOded Gabbay  * Like the SUA apertures, the Shared/Private apertures are 64KB aligned and
21519f6d2a6SOded Gabbay  * the base/limit is “in” the aperture. For both HSA64 and GPUVM SUA modes,
21619f6d2a6SOded Gabbay  * the Shared/Private apertures are always placed in a limited selection of
21719f6d2a6SOded Gabbay  * options in the hole of the 64b address space. For HSA32 mode, the
21819f6d2a6SOded Gabbay  * Shared/Private apertures can be placed anywhere in the 32b space
21919f6d2a6SOded Gabbay  * except at 0.
22019f6d2a6SOded Gabbay  *
22119f6d2a6SOded Gabbay  *
22219f6d2a6SOded Gabbay  * HSA64 Apertures for FLAT_* vector ops
22319f6d2a6SOded Gabbay  *
22419f6d2a6SOded Gabbay  * For HSA64 SUA mode, the Shared and Private apertures are always placed
22519f6d2a6SOded Gabbay  * in the hole w/ a limited selection of possible locations. The requests
22619f6d2a6SOded Gabbay  * that fall in the private aperture are expanded as a function of the
22719f6d2a6SOded Gabbay  * work-item id (tid) and redirected to the location of the
22819f6d2a6SOded Gabbay  * “hidden private memory”. The hidden private can be placed in either GPUVM
22919f6d2a6SOded Gabbay  * or ATC space. The addresses that fall in the shared aperture are
23019f6d2a6SOded Gabbay  * re-directed to the on-chip LDS memory hardware.
23119f6d2a6SOded Gabbay  *
23219f6d2a6SOded Gabbay  *
23319f6d2a6SOded Gabbay  * HSA32 Apertures for FLAT_* vector ops
23419f6d2a6SOded Gabbay  *
23519f6d2a6SOded Gabbay  * In HSA32 mode, the Private and Shared apertures can be placed anywhere
23619f6d2a6SOded Gabbay  * in the 32b space except at 0 (Private or Shared Base at zero disables
23719f6d2a6SOded Gabbay  * the apertures). If the base address of the apertures are non-zero
23819f6d2a6SOded Gabbay  * (ie apertures exists), the size is always 64KB.
23919f6d2a6SOded Gabbay  *
24019f6d2a6SOded Gabbay  *
24119f6d2a6SOded Gabbay  * GPUVM Apertures for FLAT_* vector ops
24219f6d2a6SOded Gabbay  *
24319f6d2a6SOded Gabbay  * In GPUVM mode, the Shared/Private apertures are specified identically
24419f6d2a6SOded Gabbay  * to HSA64 mode where they are always in the hole at a limited selection
24519f6d2a6SOded Gabbay  * of locations.
24619f6d2a6SOded Gabbay  *
24719f6d2a6SOded Gabbay  *
24819f6d2a6SOded Gabbay  * Aperture Definitions for SUA and DUA
24919f6d2a6SOded Gabbay  *
25019f6d2a6SOded Gabbay  * The interpretation of the aperture register definitions for a given
25119f6d2a6SOded Gabbay  * VMID is a function of the “SUA Mode” which is one of HSA64, HSA32, or
25219f6d2a6SOded Gabbay  * GPUVM64 discussed in previous sections. The mode is first decoded, and
25319f6d2a6SOded Gabbay  * then the remaining register decode is a function of the mode.
25419f6d2a6SOded Gabbay  *
25519f6d2a6SOded Gabbay  *
25619f6d2a6SOded Gabbay  * SUA Mode Decode
25719f6d2a6SOded Gabbay  *
25819f6d2a6SOded Gabbay  * For the S_LOAD and FLAT_* shader operations, the SUA mode is decoded from
25919f6d2a6SOded Gabbay  * the COMPUTE_DISPATCH_INITIATOR:DATA_ATC bit and
26019f6d2a6SOded Gabbay  * the SH_MEM_CONFIG:PTR32 bits.
26119f6d2a6SOded Gabbay  *
26219f6d2a6SOded Gabbay  * COMPUTE_DISPATCH_INITIATOR:DATA_ATC    SH_MEM_CONFIG:PTR32        Mode
26319f6d2a6SOded Gabbay  *
26419f6d2a6SOded Gabbay  * 1                                              0                  HSA64
26519f6d2a6SOded Gabbay  *
26619f6d2a6SOded Gabbay  * 1                                              1                  HSA32
26719f6d2a6SOded Gabbay  *
26819f6d2a6SOded Gabbay  * 0                                              X                 GPUVM64
26919f6d2a6SOded Gabbay  *
27019f6d2a6SOded Gabbay  * In general the hardware will ignore the PTR32 bit and treat
27119f6d2a6SOded Gabbay  * as “0” whenever DATA_ATC = “0”, but sw should set PTR32=0
27219f6d2a6SOded Gabbay  * when DATA_ATC=0.
27319f6d2a6SOded Gabbay  *
27419f6d2a6SOded Gabbay  * The DATA_ATC bit is only set for compute dispatches.
27519f6d2a6SOded Gabbay  * All “Draw” dispatches are hardcoded to GPUVM64 mode
27619f6d2a6SOded Gabbay  * for FLAT_* / S_LOAD operations.
27719f6d2a6SOded Gabbay  */
27819f6d2a6SOded Gabbay 
27970a31d16SFelix Kuehling #define MAKE_GPUVM_APP_BASE_VI(gpu_num) \
280585dbf38SOded Gabbay 	(((uint64_t)(gpu_num) << 61) + 0x1000000000000L)
28119f6d2a6SOded Gabbay 
282d01994c2SFelix Kuehling #define MAKE_GPUVM_APP_LIMIT(base, size) \
283d01994c2SFelix Kuehling 	(((uint64_t)(base) & 0xFFFFFF0000000000UL) + (size) - 1)
28419f6d2a6SOded Gabbay 
28570a31d16SFelix Kuehling #define MAKE_SCRATCH_APP_BASE_VI() \
286c7bcbfa4SFelix Kuehling 	(((uint64_t)(0x1UL) << 61) + 0x100000000L)
28719f6d2a6SOded Gabbay 
28819f6d2a6SOded Gabbay #define MAKE_SCRATCH_APP_LIMIT(base) \
289585dbf38SOded Gabbay 	(((uint64_t)base & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)
29019f6d2a6SOded Gabbay 
29170a31d16SFelix Kuehling #define MAKE_LDS_APP_BASE_VI() \
292c7bcbfa4SFelix Kuehling 	(((uint64_t)(0x1UL) << 61) + 0x0)
29319f6d2a6SOded Gabbay #define MAKE_LDS_APP_LIMIT(base) \
294585dbf38SOded Gabbay 	(((uint64_t)(base) & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)
29519f6d2a6SOded Gabbay 
29670a31d16SFelix Kuehling /* On GFXv9 the LDS and scratch apertures are programmed independently
29770a31d16SFelix Kuehling  * using the high 16 bits of the 64-bit virtual address. They must be
29870a31d16SFelix Kuehling  * in the hole, which will be the case as long as the high 16 bits are
29970a31d16SFelix Kuehling  * not 0.
30070a31d16SFelix Kuehling  *
30170a31d16SFelix Kuehling  * The aperture sizes are still 4GB implicitly.
30270a31d16SFelix Kuehling  *
30370a31d16SFelix Kuehling  * A GPUVM aperture is not applicable on GFXv9.
30470a31d16SFelix Kuehling  */
30570a31d16SFelix Kuehling #define MAKE_LDS_APP_BASE_V9() ((uint64_t)(0x1UL) << 48)
30670a31d16SFelix Kuehling #define MAKE_SCRATCH_APP_BASE_V9() ((uint64_t)(0x2UL) << 48)
30770a31d16SFelix Kuehling 
308d01994c2SFelix Kuehling /* User mode manages most of the SVM aperture address space. The low
309d01994c2SFelix Kuehling  * 16MB are reserved for kernel use (CWSR trap handler and kernel IB
310d01994c2SFelix Kuehling  * for now).
311d01994c2SFelix Kuehling  */
3123aac6aa6SAlex Sierra #define SVM_USER_BASE (u64)(KFD_CWSR_TBA_TMA_SIZE + 2*PAGE_SIZE)
313d01994c2SFelix Kuehling #define SVM_CWSR_BASE (SVM_USER_BASE - KFD_CWSR_TBA_TMA_SIZE)
314d01994c2SFelix Kuehling #define SVM_IB_BASE   (SVM_CWSR_BASE - PAGE_SIZE)
315d01994c2SFelix Kuehling 
kfd_init_apertures_vi(struct kfd_process_device * pdd,uint8_t id)31670a31d16SFelix Kuehling static void kfd_init_apertures_vi(struct kfd_process_device *pdd, uint8_t id)
31770a31d16SFelix Kuehling {
31870a31d16SFelix Kuehling 	/*
31970a31d16SFelix Kuehling 	 * node id couldn't be 0 - the three MSB bits of
3208cd29608SColin Ian King 	 * aperture shouldn't be 0
32170a31d16SFelix Kuehling 	 */
32270a31d16SFelix Kuehling 	pdd->lds_base = MAKE_LDS_APP_BASE_VI();
32370a31d16SFelix Kuehling 	pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
32470a31d16SFelix Kuehling 
32570a31d16SFelix Kuehling 	/* dGPUs: SVM aperture starting at 0
32670a31d16SFelix Kuehling 	 * with small reserved space for kernel.
32770a31d16SFelix Kuehling 	 * Set them to CANONICAL addresses.
32870a31d16SFelix Kuehling 	 */
32970a31d16SFelix Kuehling 	pdd->gpuvm_base = SVM_USER_BASE;
33070a31d16SFelix Kuehling 	pdd->gpuvm_limit =
3318dc1db31SMukul Joshi 		pdd->dev->kfd->shared_resources.gpuvm_size - 1;
33296c211f1SJay Cornwall 
33370a31d16SFelix Kuehling 	pdd->scratch_base = MAKE_SCRATCH_APP_BASE_VI();
33470a31d16SFelix Kuehling 	pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
33570a31d16SFelix Kuehling }
33670a31d16SFelix Kuehling 
kfd_init_apertures_v9(struct kfd_process_device * pdd,uint8_t id)33770a31d16SFelix Kuehling static void kfd_init_apertures_v9(struct kfd_process_device *pdd, uint8_t id)
33870a31d16SFelix Kuehling {
33970a31d16SFelix Kuehling 	pdd->lds_base = MAKE_LDS_APP_BASE_V9();
34070a31d16SFelix Kuehling 	pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
34170a31d16SFelix Kuehling 
342*3a99f15cSKaibo Ma         /* Raven needs SVM to support graphic handle, etc. Leave the small
343*3a99f15cSKaibo Ma          * reserved space before SVM on Raven as well, even though we don't
344*3a99f15cSKaibo Ma          * have to.
345*3a99f15cSKaibo Ma          * Set gpuvm_base and gpuvm_limit to CANONICAL addresses so that they
346*3a99f15cSKaibo Ma          * are used in Thunk to reserve SVM.
347*3a99f15cSKaibo Ma          */
348*3a99f15cSKaibo Ma         pdd->gpuvm_base = SVM_USER_BASE;
34970a31d16SFelix Kuehling 	pdd->gpuvm_limit =
3508dc1db31SMukul Joshi 		pdd->dev->kfd->shared_resources.gpuvm_size - 1;
35170a31d16SFelix Kuehling 
35270a31d16SFelix Kuehling 	pdd->scratch_base = MAKE_SCRATCH_APP_BASE_V9();
35370a31d16SFelix Kuehling 	pdd->scratch_limit = MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
35496c211f1SJay Cornwall }
35570a31d16SFelix Kuehling 
kfd_init_apertures(struct kfd_process * process)35619f6d2a6SOded Gabbay int kfd_init_apertures(struct kfd_process *process)
35719f6d2a6SOded Gabbay {
35819f6d2a6SOded Gabbay 	uint8_t id  = 0;
3598dc1db31SMukul Joshi 	struct kfd_node *dev;
36019f6d2a6SOded Gabbay 	struct kfd_process_device *pdd;
36119f6d2a6SOded Gabbay 
36219f6d2a6SOded Gabbay 	/*Iterating over all devices*/
3636aac0a48SFelix Kuehling 	while (kfd_topology_enum_kfd_devices(id, &dev) == 0) {
3646b855f7bSHarish Kasiviswanathan 		if (!dev || kfd_devcgroup_check_permission(dev)) {
3656b855f7bSHarish Kasiviswanathan 			/* Skip non GPU devices and devices to which the
3666b855f7bSHarish Kasiviswanathan 			 * current process have no access to. Access can be
3676b855f7bSHarish Kasiviswanathan 			 * limited by placing the process in a specific
3686b855f7bSHarish Kasiviswanathan 			 * cgroup hierarchy
3696b855f7bSHarish Kasiviswanathan 			 */
3706b855f7bSHarish Kasiviswanathan 			id++;
3716d82eb0eSHarish Kasiviswanathan 			continue;
3726d82eb0eSHarish Kasiviswanathan 		}
3736d82eb0eSHarish Kasiviswanathan 
374093c7d8cSAlexey Skidanov 		pdd = kfd_create_process_device_data(dev, process);
3754eacc26bSKent Russell 		if (!pdd) {
376093c7d8cSAlexey Skidanov 			pr_err("Failed to create process device data\n");
37770a31d16SFelix Kuehling 			return -ENOMEM;
378093c7d8cSAlexey Skidanov 		}
37919f6d2a6SOded Gabbay 		/*
380c7bcbfa4SFelix Kuehling 		 * For 64 bit process apertures will be statically reserved in
38119f6d2a6SOded Gabbay 		 * the x86_64 non canonical process address space
38219f6d2a6SOded Gabbay 		 * amdkfd doesn't currently support apertures for 32 bit process
38319f6d2a6SOded Gabbay 		 */
38419f6d2a6SOded Gabbay 		if (process->is_32bit_user_mode) {
38519f6d2a6SOded Gabbay 			pdd->lds_base = pdd->lds_limit = 0;
38619f6d2a6SOded Gabbay 			pdd->gpuvm_base = pdd->gpuvm_limit = 0;
38719f6d2a6SOded Gabbay 			pdd->scratch_base = pdd->scratch_limit = 0;
38819f6d2a6SOded Gabbay 		} else {
3897eb0502aSGraham Sider 			switch (dev->adev->asic_type) {
39070a31d16SFelix Kuehling 			case CHIP_KAVERI:
39170a31d16SFelix Kuehling 			case CHIP_HAWAII:
39270a31d16SFelix Kuehling 			case CHIP_CARRIZO:
39370a31d16SFelix Kuehling 			case CHIP_TONGA:
39470a31d16SFelix Kuehling 			case CHIP_FIJI:
39570a31d16SFelix Kuehling 			case CHIP_POLARIS10:
39670a31d16SFelix Kuehling 			case CHIP_POLARIS11:
397846a44d7SGang Ba 			case CHIP_POLARIS12:
398ed81cd6eSKent Russell 			case CHIP_VEGAM:
39970a31d16SFelix Kuehling 				kfd_init_apertures_vi(pdd, id);
40070a31d16SFelix Kuehling 				break;
40170a31d16SFelix Kuehling 			default:
402e4804a39SGraham Sider 				if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1))
403e4804a39SGraham Sider 					kfd_init_apertures_v9(pdd, id);
404e4804a39SGraham Sider 				else {
40570a31d16SFelix Kuehling 					WARN(1, "Unexpected ASIC family %u",
4067eb0502aSGraham Sider 					     dev->adev->asic_type);
40770a31d16SFelix Kuehling 					return -EINVAL;
40870a31d16SFelix Kuehling 				}
409e4804a39SGraham Sider 			}
410*3a99f15cSKaibo Ma 
411*3a99f15cSKaibo Ma                         /* dGPUs: the reserved space for kernel
412*3a99f15cSKaibo Ma                          * before SVM
413*3a99f15cSKaibo Ma                          */
414*3a99f15cSKaibo Ma                         pdd->qpd.cwsr_base = SVM_CWSR_BASE;
415*3a99f15cSKaibo Ma                         pdd->qpd.ib_base = SVM_IB_BASE;
41619f6d2a6SOded Gabbay 		}
41719f6d2a6SOded Gabbay 
41819f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "node id %u\n", id);
41919f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "gpu id %u\n", pdd->dev->id);
42019f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "lds_base %llX\n", pdd->lds_base);
42119f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "lds_limit %llX\n", pdd->lds_limit);
42219f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "gpuvm_base %llX\n", pdd->gpuvm_base);
42319f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "gpuvm_limit %llX\n", pdd->gpuvm_limit);
42419f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "scratch_base %llX\n", pdd->scratch_base);
42519f6d2a6SOded Gabbay 		dev_dbg(kfd_device, "scratch_limit %llX\n", pdd->scratch_limit);
42619f6d2a6SOded Gabbay 
42719f6d2a6SOded Gabbay 		id++;
42819f6d2a6SOded Gabbay 	}
42919f6d2a6SOded Gabbay 
43019f6d2a6SOded Gabbay 	return 0;
43119f6d2a6SOded Gabbay }
432