get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/744355/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 744355,
    "url": "http://patchwork.ozlabs.org/api/patches/744355/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1490714052-18902-8-git-send-email-clombard@linux.vnet.ibm.com/",
    "project": {
        "id": 2,
        "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api",
        "name": "Linux PPC development",
        "link_name": "linuxppc-dev",
        "list_id": "linuxppc-dev.lists.ozlabs.org",
        "list_email": "linuxppc-dev@lists.ozlabs.org",
        "web_url": "https://github.com/linuxppc/wiki/wiki",
        "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git",
        "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/",
        "list_archive_url": "https://lore.kernel.org/linuxppc-dev/",
        "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/",
        "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"
    },
    "msgid": "<1490714052-18902-8-git-send-email-clombard@linux.vnet.ibm.com>",
    "list_archive_url": "https://lore.kernel.org/linuxppc-dev/1490714052-18902-8-git-send-email-clombard@linux.vnet.ibm.com/",
    "date": "2017-03-28T15:14:12",
    "name": "[V3,7/7] cxl: Add psl9 specific code",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "d499b4d9725491aeabe2cf2388630cf0297e91d9",
    "submitter": {
        "id": 67351,
        "url": "http://patchwork.ozlabs.org/api/people/67351/?format=api",
        "name": "Christophe Lombard",
        "email": "clombard@linux.vnet.ibm.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1490714052-18902-8-git-send-email-clombard@linux.vnet.ibm.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/744355/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/744355/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@lists.ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3vsvpw45Tkz9s2Q\n\tfor <patchwork-incoming@ozlabs.org>;\n\tWed, 29 Mar 2017 02:25:28 +1100 (AEDT)",
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3vsvpw3LzVzDqpX\n\tfor <patchwork-incoming@ozlabs.org>;\n\tWed, 29 Mar 2017 02:25:28 +1100 (AEDT)",
            "from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com\n\t[148.163.158.5])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3vsvbX4QbyzDqZQ\n\tfor <linuxppc-dev@lists.ozlabs.org>;\n\tWed, 29 Mar 2017 02:15:09 +1100 (AEDT)",
            "from pps.filterd (m0098419.ppops.net [127.0.0.1])\n\tby mx0b-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id\n\tv2SFE8Zs030984\n\tfor <linuxppc-dev@lists.ozlabs.org>; Tue, 28 Mar 2017 11:14:57 -0400",
            "from e06smtp10.uk.ibm.com (e06smtp10.uk.ibm.com [195.75.94.106])\n\tby mx0b-001b2d01.pphosted.com with ESMTP id 29fsrdtmww-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <linuxppc-dev@lists.ozlabs.org>; Tue, 28 Mar 2017 11:14:56 -0400",
            "from localhost\n\tby e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <linuxppc-dev@lists.ozlabs.org> from\n\t<clombard@linux.vnet.ibm.com>; Tue, 28 Mar 2017 16:14:55 +0100",
            "from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195)\n\tby e06smtp10.uk.ibm.com (192.168.101.140) with IBM ESMTP SMTP\n\tGateway: Authorized Use Only! Violators will be prosecuted; \n\tTue, 28 Mar 2017 16:14:52 +0100",
            "from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com\n\t[9.149.105.232])\n\tby b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with\n\tESMTP id v2SFEQ757602654; Tue, 28 Mar 2017 15:14:26 GMT",
            "from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id DF29D5204D;\n\tTue, 28 Mar 2017 15:12:40 +0100 (BST)",
            "from lombard-w520.ibm.com (unknown [9.167.235.7])\n\tby d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id F34C65204E; \n\tTue, 28 Mar 2017 15:12:39 +0100 (BST)"
        ],
        "From": "Christophe Lombard <clombard@linux.vnet.ibm.com>",
        "To": "linuxppc-dev@lists.ozlabs.org, fbarrat@linux.vnet.ibm.com,\n\timunsie@au1.ibm.com, andrew.donnellan@au1.ibm.com",
        "Subject": "[PATCH V3 7/7] cxl: Add psl9 specific code",
        "Date": "Tue, 28 Mar 2017 17:14:12 +0200",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1490714052-18902-1-git-send-email-clombard@linux.vnet.ibm.com>",
        "References": "<1490714052-18902-1-git-send-email-clombard@linux.vnet.ibm.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "X-TM-AS-GCONF": "00",
        "x-cbid": "17032815-0040-0000-0000-000003551171",
        "X-IBM-AV-DETECTION": "SAVI=unused REMOTE=unused XFE=unused",
        "x-cbparentid": "17032815-0041-0000-0000-000024B70383",
        "Message-Id": "<1490714052-18902-8-git-send-email-clombard@linux.vnet.ibm.com>",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-03-28_12:, , signatures=0",
        "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=2\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1702020001\n\tdefinitions=main-1703280131",
        "X-BeenThere": "linuxppc-dev@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "Linux on PowerPC Developers Mail List\n\t<linuxppc-dev.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/linuxppc-dev/>",
        "List-Post": "<mailto:linuxppc-dev@lists.ozlabs.org>",
        "List-Help": "<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>",
        "Errors-To": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org",
        "Sender": "\"Linuxppc-dev\"\n\t<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>"
    },
    "content": "The new Coherent Accelerator Interface Architecture, level 2, for the\nIBM POWER9 brings new content and features:\n- POWER9 Service Layer\n- Registers\n- Radix mode\n- Process element entry\n- Dedicated-Shared Process Programming Model\n- Translation Fault Handling\n- CAPP\n- Memory Context ID\n    If a valid mm_struct is found the memory context id is used for each\n    transaction associated with the process handle. The PSL uses the\n    context ID to find the corresponding process element.\n\nSigned-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>\n---\n drivers/misc/cxl/context.c |  16 ++-\n drivers/misc/cxl/cxl.h     | 137 +++++++++++++++++++++----\n drivers/misc/cxl/debugfs.c |  19 ++++\n drivers/misc/cxl/fault.c   |  78 ++++++++------\n drivers/misc/cxl/guest.c   |   8 +-\n drivers/misc/cxl/irq.c     |  53 ++++++++++\n drivers/misc/cxl/native.c  | 247 ++++++++++++++++++++++++++++++++++++++++-----\n drivers/misc/cxl/pci.c     | 246 +++++++++++++++++++++++++++++++++++++++++---\n drivers/misc/cxl/trace.h   |  43 ++++++++\n 9 files changed, 752 insertions(+), 95 deletions(-)",
    "diff": "diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c\nindex ac2531e..45363be 100644\n--- a/drivers/misc/cxl/context.c\n+++ b/drivers/misc/cxl/context.c\n@@ -188,12 +188,24 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)\n \tif (ctx->afu->current_mode == CXL_MODE_DEDICATED) {\n \t\tif (start + len > ctx->afu->adapter->ps_size)\n \t\t\treturn -EINVAL;\n+\n+\t\tif (cxl_is_psl9(ctx->afu)) {\n+\t\t\t/* make sure there is a valid problem state\n+\t\t\t * area space for this AFU\n+\t\t\t */\n+\t\t\tif (ctx->master && !ctx->afu->psa) {\n+\t\t\t\tpr_devel(\"AFU doesn't support mmio space\\n\");\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\n+\t\t\t/* Can't mmap until the AFU is enabled */\n+\t\t\tif (!ctx->afu->enabled)\n+\t\t\t\treturn -EBUSY;\n+\t\t}\n \t} else {\n \t\tif (start + len > ctx->psn_size)\n \t\t\treturn -EINVAL;\n-\t}\n \n-\tif (ctx->afu->current_mode != CXL_MODE_DEDICATED) {\n \t\t/* make sure there is a valid per process space for this AFU */\n \t\tif ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) {\n \t\t\tpr_devel(\"AFU doesn't support mmio space\\n\");\ndiff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h\nindex 2f2d9e4..aac0504 100644\n--- a/drivers/misc/cxl/cxl.h\n+++ b/drivers/misc/cxl/cxl.h\n@@ -63,7 +63,7 @@ typedef struct {\n /* Memory maps. Ref CXL Appendix A */\n \n /* PSL Privilege 1 Memory Map */\n-/* Configuration and Control area */\n+/* Configuration and Control area - CAIA 1&2 */\n static const cxl_p1_reg_t CXL_PSL_CtxTime = {0x0000};\n static const cxl_p1_reg_t CXL_PSL_ErrIVTE = {0x0008};\n static const cxl_p1_reg_t CXL_PSL_KEY1    = {0x0010};\n@@ -98,11 +98,29 @@ static const cxl_p1_reg_t CXL_XSL_Timebase  = {0x0100};\n static const cxl_p1_reg_t CXL_XSL_TB_CTLSTAT = {0x0108};\n static const cxl_p1_reg_t CXL_XSL_FEC       = {0x0158};\n static const cxl_p1_reg_t CXL_XSL_DSNCTL    = {0x0168};\n+/* PSL registers - CAIA 2 */\n+static const cxl_p1_reg_t CXL_PSL9_CONTROL  = {0x0020};\n+static const cxl_p1_reg_t CXL_XSL9_DSNCTL   = {0x0168};\n+static const cxl_p1_reg_t CXL_PSL9_FIR1     = {0x0300};\n+static const cxl_p1_reg_t CXL_PSL9_FIR2     = {0x0308};\n+static const cxl_p1_reg_t CXL_PSL9_Timebase = {0x0310};\n+static const cxl_p1_reg_t CXL_PSL9_DEBUG    = {0x0320};\n+static const cxl_p1_reg_t CXL_PSL9_FIR_CNTL = {0x0348};\n+static const cxl_p1_reg_t CXL_PSL9_DSNDCTL  = {0x0350};\n+static const cxl_p1_reg_t CXL_PSL9_TB_CTLSTAT = {0x0340};\n+static const cxl_p1_reg_t CXL_PSL9_TRACECFG = {0x0368};\n+static const cxl_p1_reg_t CXL_PSL9_APCDEDALLOC = {0x0378};\n+static const cxl_p1_reg_t CXL_PSL9_APCDEDTYPE = {0x0380};\n+static const cxl_p1_reg_t CXL_PSL9_TNR_ADDR = {0x0388};\n+static const cxl_p1_reg_t CXL_PSL9_GP_CT = {0x0398};\n+static const cxl_p1_reg_t CXL_XSL9_IERAT = {0x0588};\n+static const cxl_p1_reg_t CXL_XSL9_ILPP  = {0x0590};\n+\n /* 0x7F00:7FFF Reserved PCIe MSI-X Pending Bit Array area */\n /* 0x8000:FFFF Reserved PCIe MSI-X Table Area */\n \n /* PSL Slice Privilege 1 Memory Map */\n-/* Configuration Area */\n+/* Configuration Area - CAIA 1&2 */\n static const cxl_p1n_reg_t CXL_PSL_SR_An          = {0x00};\n static const cxl_p1n_reg_t CXL_PSL_LPID_An        = {0x08};\n static const cxl_p1n_reg_t CXL_PSL_AMBAR_An       = {0x10};\n@@ -111,17 +129,18 @@ static const cxl_p1n_reg_t CXL_PSL_ID_An          = {0x20};\n static const cxl_p1n_reg_t CXL_PSL_SERR_An        = {0x28};\n /* Memory Management and Lookaside Buffer Management - CAIA 1*/\n static const cxl_p1n_reg_t CXL_PSL_SDR_An         = {0x30};\n+/* Memory Management and Lookaside Buffer Management - CAIA 1&2 */\n static const cxl_p1n_reg_t CXL_PSL_AMOR_An        = {0x38};\n-/* Pointer Area */\n+/* Pointer Area - CAIA 1&2 */\n static const cxl_p1n_reg_t CXL_HAURP_An           = {0x80};\n static const cxl_p1n_reg_t CXL_PSL_SPAP_An        = {0x88};\n static const cxl_p1n_reg_t CXL_PSL_LLCMD_An       = {0x90};\n-/* Control Area */\n+/* Control Area - CAIA 1&2 */\n static const cxl_p1n_reg_t CXL_PSL_SCNTL_An       = {0xA0};\n static const cxl_p1n_reg_t CXL_PSL_CtxTime_An     = {0xA8};\n static const cxl_p1n_reg_t CXL_PSL_IVTE_Offset_An = {0xB0};\n static const cxl_p1n_reg_t CXL_PSL_IVTE_Limit_An  = {0xB8};\n-/* 0xC0:FF Implementation Dependent Area */\n+/* 0xC0:FF Implementation Dependent Area - CAIA 1&2 */\n static const cxl_p1n_reg_t CXL_PSL_FIR_SLICE_An   = {0xC0};\n static const cxl_p1n_reg_t CXL_AFU_DEBUG_An       = {0xC8};\n /* 0xC0:FF Implementation Dependent Area - CAIA 1 */\n@@ -131,7 +150,7 @@ static const cxl_p1n_reg_t CXL_PSL_RXCTL_A        = {0xE0};\n static const cxl_p1n_reg_t CXL_PSL_SLICE_TRACE    = {0xE8};\n \n /* PSL Slice Privilege 2 Memory Map */\n-/* Configuration and Control Area */\n+/* Configuration and Control Area - CAIA 1&2 */\n static const cxl_p2n_reg_t CXL_PSL_PID_TID_An = {0x000};\n static const cxl_p2n_reg_t CXL_CSRP_An        = {0x008};\n /* Configuration and Control Area - CAIA 1 */\n@@ -145,17 +164,17 @@ static const cxl_p2n_reg_t CXL_PSL_AMR_An     = {0x030};\n static const cxl_p2n_reg_t CXL_SLBIE_An       = {0x040};\n static const cxl_p2n_reg_t CXL_SLBIA_An       = {0x048};\n static const cxl_p2n_reg_t CXL_SLBI_Select_An = {0x050};\n-/* Interrupt Registers */\n+/* Interrupt Registers - CAIA 1&2 */\n static const cxl_p2n_reg_t CXL_PSL_DSISR_An   = {0x060};\n static const cxl_p2n_reg_t CXL_PSL_DAR_An     = {0x068};\n static const cxl_p2n_reg_t CXL_PSL_DSR_An     = {0x070};\n static const cxl_p2n_reg_t CXL_PSL_TFC_An     = {0x078};\n static const cxl_p2n_reg_t CXL_PSL_PEHandle_An = {0x080};\n static const cxl_p2n_reg_t CXL_PSL_ErrStat_An = {0x088};\n-/* AFU Registers */\n+/* AFU Registers - CAIA 1&2 */\n static const cxl_p2n_reg_t CXL_AFU_Cntl_An    = {0x090};\n static const cxl_p2n_reg_t CXL_AFU_ERR_An     = {0x098};\n-/* Work Element Descriptor */\n+/* Work Element Descriptor - CAIA 1&2 */\n static const cxl_p2n_reg_t CXL_PSL_WED_An     = {0x0A0};\n /* 0x0C0:FFF Implementation Dependent Area */\n \n@@ -182,6 +201,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An     = {0x0A0};\n #define CXL_PSL_SR_An_SF  MSR_SF            /* 64bit */\n #define CXL_PSL_SR_An_TA  (1ull << (63-1))  /* Tags active,   GA1: 0 */\n #define CXL_PSL_SR_An_HV  MSR_HV            /* Hypervisor,    GA1: 0 */\n+#define CXL_PSL_SR_An_XLAT_hpt (0ull << (63-6))/* Hashed page table (HPT) mode */\n+#define CXL_PSL_SR_An_XLAT_roh (2ull << (63-6))/* Radix on HPT mode */\n+#define CXL_PSL_SR_An_XLAT_ror (3ull << (63-6))/* Radix on Radix mode */\n+#define CXL_PSL_SR_An_BOT (1ull << (63-10)) /* Use the in-memory segment table */\n #define CXL_PSL_SR_An_PR  MSR_PR            /* Problem state, GA1: 1 */\n #define CXL_PSL_SR_An_ISL (1ull << (63-53)) /* Ignore Segment Large Page */\n #define CXL_PSL_SR_An_TC  (1ull << (63-54)) /* Page Table secondary hash */\n@@ -298,12 +321,38 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An     = {0x0A0};\n #define CXL_PSL_DSISR_An_S  DSISR_ISSTORE     /* Access was afu_wr or afu_zero */\n #define CXL_PSL_DSISR_An_K  DSISR_KEYFAULT    /* Access not permitted by virtual page class key protection */\n \n+/****** CXL_PSL_DSISR_An - CAIA 2 ****************************************************/\n+#define CXL_PSL9_DSISR_An_TF (1ull << (63-3))  /* Translation fault */\n+#define CXL_PSL9_DSISR_An_PE (1ull << (63-4))  /* PSL Error (implementation specific) */\n+#define CXL_PSL9_DSISR_An_AE (1ull << (63-5))  /* AFU Error */\n+#define CXL_PSL9_DSISR_An_OC (1ull << (63-6))  /* OS Context Warning */\n+#define CXL_PSL9_DSISR_An_S (1ull << (63-38))  /* TF for a write operation */\n+#define CXL_PSL9_DSISR_PENDING (CXL_PSL9_DSISR_An_TF | CXL_PSL9_DSISR_An_PE | CXL_PSL9_DSISR_An_AE | CXL_PSL9_DSISR_An_OC)\n+/* NOTE: Bits 56:63 (Checkout Response Status) are valid when DSISR_An[TF] = 1\n+ * Status (0:7) Encoding\n+ */\n+#define CXL_PSL9_DSISR_An_CO_MASK 0x00000000000000ffULL\n+#define CXL_PSL9_DSISR_An_SF      0x0000000000000080ULL  /* Segment Fault                        0b10000000 */\n+#define CXL_PSL9_DSISR_An_PF_SLR  0x0000000000000088ULL  /* PTE not found (Single Level Radix)   0b10001000 */\n+#define CXL_PSL9_DSISR_An_PF_RGC  0x000000000000008CULL  /* PTE not found (Radix Guest (child))  0b10001100 */\n+#define CXL_PSL9_DSISR_An_PF_RGP  0x0000000000000090ULL  /* PTE not found (Radix Guest (parent)) 0b10010000 */\n+#define CXL_PSL9_DSISR_An_PF_HRH  0x0000000000000094ULL  /* PTE not found (HPT/Radix Host)       0b10010100 */\n+#define CXL_PSL9_DSISR_An_PF_STEG 0x000000000000009CULL  /* PTE not found (STEG VA)              0b10011100 */\n+\n /****** CXL_PSL_TFC_An ******************************************************/\n #define CXL_PSL_TFC_An_A  (1ull << (63-28)) /* Acknowledge non-translation fault */\n #define CXL_PSL_TFC_An_C  (1ull << (63-29)) /* Continue (abort transaction) */\n #define CXL_PSL_TFC_An_AE (1ull << (63-30)) /* Restart PSL with address error */\n #define CXL_PSL_TFC_An_R  (1ull << (63-31)) /* Restart PSL transaction */\n \n+/****** CXL_XSL9_IERAT_ERAT - CAIA 2 **********************************/\n+#define CXL_XSL9_IERAT_MLPID    (1ull << (63-0))  /* Match LPID */\n+#define CXL_XSL9_IERAT_MPID     (1ull << (63-1))  /* Match PID */\n+#define CXL_XSL9_IERAT_PRS      (1ull << (63-4))  /* PRS bit for Radix invalidations */\n+#define CXL_XSL9_IERAT_INVR     (1ull << (63-3))  /* Invalidate Radix */\n+#define CXL_XSL9_IERAT_IALL     (1ull << (63-8))  /* Invalidate All */\n+#define CXL_XSL9_IERAT_IINPROG  (1ull << (63-63)) /* Invalidate in progress */\n+\n /* cxl_process_element->software_status */\n #define CXL_PE_SOFTWARE_STATE_V (1ul << (31 -  0)) /* Valid */\n #define CXL_PE_SOFTWARE_STATE_C (1ul << (31 - 29)) /* Complete */\n@@ -654,25 +703,38 @@ int cxl_pci_reset(struct cxl *adapter);\n void cxl_pci_release_afu(struct device *dev);\n ssize_t cxl_pci_read_adapter_vpd(struct cxl *adapter, void *buf, size_t len);\n \n-/* common == phyp + powernv */\n+/* common == phyp + powernv - CAIA 1&2 */\n struct cxl_process_element_common {\n \t__be32 tid;\n \t__be32 pid;\n \t__be64 csrp;\n-\t__be64 aurp0;\n-\t__be64 aurp1;\n-\t__be64 sstp0;\n-\t__be64 sstp1;\n+\tunion {\n+\t\tstruct {\n+\t\t\t__be64 aurp0;\n+\t\t\t__be64 aurp1;\n+\t\t\t__be64 sstp0;\n+\t\t\t__be64 sstp1;\n+\t\t} psl8;  /* CAIA 1 */\n+\t\tstruct {\n+\t\t\tu8     reserved2[8];\n+\t\t\tu8     reserved3[8];\n+\t\t\tu8     reserved4[8];\n+\t\t\tu8     reserved5[8];\n+\t\t} psl9;  /* CAIA 2 */\n+\t} u;\n \t__be64 amr;\n-\tu8     reserved3[4];\n+\tu8     reserved6[4];\n \t__be64 wed;\n } __packed;\n \n-/* just powernv */\n+/* just powernv - CAIA 1&2 */\n struct cxl_process_element {\n \t__be64 sr;\n \t__be64 SPOffset;\n-\t__be64 sdr;\n+\tunion {\n+\t\t__be64 sdr;          /* CAIA 1 */\n+\t\tu8     reserved1[8]; /* CAIA 2 */\n+\t} u;\n \t__be64 haurp;\n \t__be32 ctxtime;\n \t__be16 ivte_offsets[4];\n@@ -761,6 +823,16 @@ static inline bool cxl_is_power8(void)\n \treturn false;\n }\n \n+static inline bool cxl_is_power9(void)\n+{\n+\t/* intermediate solution */\n+\tif (!cxl_is_power8() &&\n+\t   (cpu_has_feature(CPU_FTRS_POWER9) ||\n+\t    cpu_has_feature(CPU_FTR_POWER9_DD1)))\n+\t\treturn true;\n+\treturn false;\n+}\n+\n static inline bool cxl_is_psl8(struct cxl_afu *afu)\n {\n \tif (afu->adapter->caia_major == 1)\n@@ -768,6 +840,13 @@ static inline bool cxl_is_psl8(struct cxl_afu *afu)\n \treturn false;\n }\n \n+static inline bool cxl_is_psl9(struct cxl_afu *afu)\n+{\n+\tif (afu->adapter->caia_major == 2)\n+\t\treturn true;\n+\treturn false;\n+}\n+\n ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,\n \t\t\t\tloff_t off, size_t count);\n \n@@ -794,7 +873,6 @@ int cxl_update_properties(struct device_node *dn, struct property *new_prop);\n \n void cxl_remove_adapter_nr(struct cxl *adapter);\n \n-int cxl_alloc_spa(struct cxl_afu *afu);\n void cxl_release_spa(struct cxl_afu *afu);\n \n dev_t cxl_get_dev(void);\n@@ -832,9 +910,13 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count);\n void afu_release_irqs(struct cxl_context *ctx, void *cookie);\n void afu_irq_name_free(struct cxl_context *ctx);\n \n+int cxl_attach_afu_directed_psl9(struct cxl_context *ctx, u64 wed, u64 amr);\n int cxl_attach_afu_directed_psl8(struct cxl_context *ctx, u64 wed, u64 amr);\n+int cxl_activate_dedicated_process_psl9(struct cxl_afu *afu);\n int cxl_activate_dedicated_process_psl8(struct cxl_afu *afu);\n+int cxl_attach_dedicated_process_psl9(struct cxl_context *ctx, u64 wed, u64 amr);\n int cxl_attach_dedicated_process_psl8(struct cxl_context *ctx, u64 wed, u64 amr);\n+void cxl_update_dedicated_ivtes_psl9(struct cxl_context *ctx);\n void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx);\n \n #ifdef CONFIG_DEBUG_FS\n@@ -845,9 +927,12 @@ int cxl_debugfs_adapter_add(struct cxl *adapter);\n void cxl_debugfs_adapter_remove(struct cxl *adapter);\n int cxl_debugfs_afu_add(struct cxl_afu *afu);\n void cxl_debugfs_afu_remove(struct cxl_afu *afu);\n+void cxl_stop_trace_psl9(struct cxl *cxl);\n void cxl_stop_trace_psl8(struct cxl *cxl);\n+void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir);\n void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir);\n void cxl_debugfs_add_adapter_regs_xsl(struct cxl *adapter, struct dentry *dir);\n+void cxl_debugfs_add_afu_regs_psl9(struct cxl_afu *afu, struct dentry *dir);\n void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir);\n \n #else /* CONFIG_DEBUG_FS */\n@@ -879,10 +964,19 @@ static inline void cxl_debugfs_afu_remove(struct cxl_afu *afu)\n {\n }\n \n+static inline void cxl_stop_trace_psl9(struct cxl *cxl)\n+{\n+}\n+\n static inline void cxl_stop_trace_psl8(struct cxl *cxl)\n {\n }\n \n+static inline void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter,\n+\t\t\t\t\t\t    struct dentry *dir)\n+{\n+}\n+\n static inline void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter,\n \t\t\t\t\t\t    struct dentry *dir)\n {\n@@ -893,6 +987,10 @@ static inline void cxl_debugfs_add_adapter_regs_xsl(struct cxl *adapter,\n {\n }\n \n+static inline void cxl_debugfs_add_afu_regs_psl9(struct cxl_afu *afu, struct dentry *dir)\n+{\n+}\n+\n static inline void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir)\n {\n }\n@@ -951,7 +1049,9 @@ struct cxl_irq_info {\n };\n \n void cxl_assign_psn_space(struct cxl_context *ctx);\n+int cxl_invalidate_all_psl9(struct cxl *adapter);\n int cxl_invalidate_all_psl8(struct cxl *adapter);\n+irqreturn_t cxl_irq_psl9(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);\n irqreturn_t cxl_irq_psl8(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info);\n irqreturn_t cxl_fail_irq_psl(struct cxl_afu *afu, struct cxl_irq_info *irq_info);\n int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,\n@@ -964,6 +1064,7 @@ int cxl_data_cache_flush(struct cxl *adapter);\n int cxl_afu_disable(struct cxl_afu *afu);\n int cxl_psl_purge(struct cxl_afu *afu);\n \n+void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx);\n void cxl_native_irq_dump_regs_psl8(struct cxl_context *ctx);\n void cxl_native_err_irq_dump_regs(struct cxl *adapter);\n int cxl_pci_vphb_add(struct cxl_afu *afu);\ndiff --git a/drivers/misc/cxl/debugfs.c b/drivers/misc/cxl/debugfs.c\nindex 43a1a27..eae9d74 100644\n--- a/drivers/misc/cxl/debugfs.c\n+++ b/drivers/misc/cxl/debugfs.c\n@@ -15,6 +15,12 @@\n \n static struct dentry *cxl_debugfs;\n \n+void cxl_stop_trace_psl9(struct cxl *adapter)\n+{\n+\t/* Stop the trace */\n+\tcxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x4480000000000000ULL);\n+}\n+\n void cxl_stop_trace_psl8(struct cxl *adapter)\n {\n \tint slice;\n@@ -53,6 +59,14 @@ static struct dentry *debugfs_create_io_x64(const char *name, umode_t mode,\n \t\t\t\t\t  (void __force *)value, &fops_io_x64);\n }\n \n+void cxl_debugfs_add_adapter_regs_psl9(struct cxl *adapter, struct dentry *dir)\n+{\n+\tdebugfs_create_io_x64(\"fir1\", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR1));\n+\tdebugfs_create_io_x64(\"fir2\", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR2));\n+\tdebugfs_create_io_x64(\"fir_cntl\", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_FIR_CNTL));\n+\tdebugfs_create_io_x64(\"trace\", S_IRUSR | S_IWUSR, dir, _cxl_p1_addr(adapter, CXL_PSL9_TRACECFG));\n+}\n+\n void cxl_debugfs_add_adapter_regs_psl8(struct cxl *adapter, struct dentry *dir)\n {\n \tdebugfs_create_io_x64(\"fir1\", S_IRUSR, dir, _cxl_p1_addr(adapter, CXL_PSL_FIR1));\n@@ -92,6 +106,11 @@ void cxl_debugfs_adapter_remove(struct cxl *adapter)\n \tdebugfs_remove_recursive(adapter->debugfs);\n }\n \n+void cxl_debugfs_add_afu_regs_psl9(struct cxl_afu *afu, struct dentry *dir)\n+{\n+\tdebugfs_create_io_x64(\"serr\", S_IRUSR, dir, _cxl_p1n_addr(afu, CXL_PSL_SERR_An));\n+}\n+\n void cxl_debugfs_add_afu_regs_psl8(struct cxl_afu *afu, struct dentry *dir)\n {\n \tdebugfs_create_io_x64(\"sstp0\", S_IRUSR, dir, _cxl_p2n_addr(afu, CXL_SSTP0_An));\ndiff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c\nindex f24c15c..381ae70 100644\n--- a/drivers/misc/cxl/fault.c\n+++ b/drivers/misc/cxl/fault.c\n@@ -146,25 +146,26 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,\n \t\treturn cxl_ack_ae(ctx);\n \t}\n \n-\t/*\n-\t * update_mmu_cache() will not have loaded the hash since current->trap\n-\t * is not a 0x400 or 0x300, so just call hash_page_mm() here.\n-\t */\n-\taccess = _PAGE_PRESENT | _PAGE_READ;\n-\tif (dsisr & CXL_PSL_DSISR_An_S)\n-\t\taccess |= _PAGE_WRITE;\n-\n-\taccess |= _PAGE_PRIVILEGED;\n-\tif ((!ctx->kernel) || (REGION_ID(dar) == USER_REGION_ID))\n-\t\taccess &= ~_PAGE_PRIVILEGED;\n-\n-\tif (dsisr & DSISR_NOHPTE)\n-\t\tinv_flags |= HPTE_NOHPTE_UPDATE;\n-\n-\tlocal_irq_save(flags);\n-\thash_page_mm(mm, dar, access, 0x300, inv_flags);\n-\tlocal_irq_restore(flags);\n-\n+\tif (!radix_enabled()) {\n+\t\t/*\n+\t\t * update_mmu_cache() will not have loaded the hash since current->trap\n+\t\t * is not a 0x400 or 0x300, so just call hash_page_mm() here.\n+\t\t */\n+\t\taccess = _PAGE_PRESENT | _PAGE_READ;\n+\t\tif (dsisr & CXL_PSL_DSISR_An_S)\n+\t\t\taccess |= _PAGE_WRITE;\n+\n+\t\taccess |= _PAGE_PRIVILEGED;\n+\t\tif ((!ctx->kernel) || (REGION_ID(dar) == USER_REGION_ID))\n+\t\t\taccess &= ~_PAGE_PRIVILEGED;\n+\n+\t\tif (dsisr & DSISR_NOHPTE)\n+\t\t\tinv_flags |= HPTE_NOHPTE_UPDATE;\n+\n+\t\tlocal_irq_save(flags);\n+\t\thash_page_mm(mm, dar, access, 0x300, inv_flags);\n+\t\tlocal_irq_restore(flags);\n+\t}\n \tpr_devel(\"Page fault successfully handled for pe: %i!\\n\", ctx->pe);\n \tcxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);\n }\n@@ -179,12 +180,33 @@ static struct mm_struct *get_mem_context(struct cxl_context *ctx)\n \t\treturn NULL;\n \n \tif (!atomic_inc_not_zero(&ctx->mm->mm_users))\n-\t\treturn ctx->mm;\n+\t\treturn NULL;\n \n-\treturn NULL;\n+\treturn ctx->mm;\n }\n \n+static bool cxl_is_segment_miss(struct cxl_context *ctx, u64 dsisr)\n+{\n+\tif ((cxl_is_psl8(ctx->afu)) && (dsisr & CXL_PSL_DSISR_An_DS))\n+\t\treturn true;\n \n+\treturn false;\n+}\n+\n+static bool cxl_is_page_fault(struct cxl_context *ctx, u64 dsisr)\n+{\n+\tif ((cxl_is_psl8(ctx->afu)) && (dsisr & CXL_PSL_DSISR_An_DM))\n+\t\treturn true;\n+\n+\tif ((cxl_is_psl9(ctx->afu)) &&\n+\t    ((dsisr & CXL_PSL9_DSISR_An_CO_MASK) &\n+\t\t(CXL_PSL9_DSISR_An_PF_SLR | CXL_PSL9_DSISR_An_PF_RGC |\n+\t\t CXL_PSL9_DSISR_An_PF_RGP | CXL_PSL9_DSISR_An_PF_HRH |\n+\t\t CXL_PSL9_DSISR_An_PF_STEG)))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n \n void cxl_handle_fault(struct work_struct *fault_work)\n {\n@@ -230,14 +252,12 @@ void cxl_handle_fault(struct work_struct *fault_work)\n \t\t}\n \t}\n \n-\tif (cxl_is_psl8(ctx->afu)) {\n-\t\tif (dsisr & CXL_PSL_DSISR_An_DS)\n-\t\t\tcxl_handle_segment_miss(ctx, mm, dar);\n-\t\telse if (dsisr & CXL_PSL_DSISR_An_DM)\n-\t\t\tcxl_handle_page_fault(ctx, mm, dsisr, dar);\n-\t\telse\n-\t\t\tWARN(1, \"cxl_handle_fault has nothing to handle\\n\");\n-\t}\n+\tif (cxl_is_segment_miss(ctx, dsisr))\n+\t\tcxl_handle_segment_miss(ctx, mm, dar);\n+\telse if (cxl_is_page_fault(ctx, dsisr))\n+\t\tcxl_handle_page_fault(ctx, mm, dsisr, dar);\n+\telse\n+\t\tWARN(1, \"cxl_handle_fault has nothing to handle\\n\");\n \n \tif (mm)\n \t\tmmput(mm);\ndiff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c\nindex 3ad7381..f58b4b6c 100644\n--- a/drivers/misc/cxl/guest.c\n+++ b/drivers/misc/cxl/guest.c\n@@ -551,13 +551,13 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)\n \telem->common.tid    = cpu_to_be32(0); /* Unused */\n \telem->common.pid    = cpu_to_be32(pid);\n \telem->common.csrp   = cpu_to_be64(0); /* disable */\n-\telem->common.aurp0  = cpu_to_be64(0); /* disable */\n-\telem->common.aurp1  = cpu_to_be64(0); /* disable */\n+\telem->common.u.psl8.aurp0  = cpu_to_be64(0); /* disable */\n+\telem->common.u.psl8.aurp1  = cpu_to_be64(0); /* disable */\n \n \tcxl_prefault(ctx, wed);\n \n-\telem->common.sstp0  = cpu_to_be64(ctx->sstp0);\n-\telem->common.sstp1  = cpu_to_be64(ctx->sstp1);\n+\telem->common.u.psl8.sstp0  = cpu_to_be64(ctx->sstp0);\n+\telem->common.u.psl8.sstp1  = cpu_to_be64(ctx->sstp1);\n \n \t/*\n \t * Ensure we have at least one interrupt allocated to take faults for\ndiff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c\nindex fa9f8a2..1eb5168 100644\n--- a/drivers/misc/cxl/irq.c\n+++ b/drivers/misc/cxl/irq.c\n@@ -34,6 +34,59 @@ static irqreturn_t schedule_cxl_fault(struct cxl_context *ctx, u64 dsisr, u64 da\n \treturn IRQ_HANDLED;\n }\n \n+irqreturn_t cxl_irq_psl9(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info)\n+{\n+\tu64 dsisr, dar;\n+\n+\tdsisr = irq_info->dsisr;\n+\tdar = irq_info->dar;\n+\n+\ttrace_cxl_psl9_irq(ctx, irq, dsisr, dar);\n+\n+\tpr_devel(\"CXL interrupt %i for afu pe: %i DSISR: %#llx DAR: %#llx\\n\", irq, ctx->pe, dsisr, dar);\n+\n+\tif (dsisr & CXL_PSL9_DSISR_An_TF) {\n+\t\tpr_devel(\"CXL interrupt: Scheduling translation fault\"\n+\t\t\t \" handling for later (pe: %i)\\n\", ctx->pe);\n+\t\treturn schedule_cxl_fault(ctx, dsisr, dar);\n+\t}\n+\n+\tif (dsisr & CXL_PSL9_DSISR_An_PE)\n+\t\treturn cxl_ops->handle_psl_slice_error(ctx, dsisr,\n+\t\t\t\t\t\tirq_info->errstat);\n+\tif (dsisr & CXL_PSL9_DSISR_An_AE) {\n+\t\tpr_devel(\"CXL interrupt: AFU Error 0x%016llx\\n\", irq_info->afu_err);\n+\n+\t\tif (ctx->pending_afu_err) {\n+\t\t\t/*\n+\t\t\t * This shouldn't happen - the PSL treats these errors\n+\t\t\t * as fatal and will have reset the AFU, so there's not\n+\t\t\t * much point buffering multiple AFU errors.\n+\t\t\t * OTOH if we DO ever see a storm of these come in it's\n+\t\t\t * probably best that we log them somewhere:\n+\t\t\t */\n+\t\t\tdev_err_ratelimited(&ctx->afu->dev, \"CXL AFU Error \"\n+\t\t\t\t\t    \"undelivered to pe %i: 0x%016llx\\n\",\n+\t\t\t\t\t    ctx->pe, irq_info->afu_err);\n+\t\t} else {\n+\t\t\tspin_lock(&ctx->lock);\n+\t\t\tctx->afu_err = irq_info->afu_err;\n+\t\t\tctx->pending_afu_err = 1;\n+\t\t\tspin_unlock(&ctx->lock);\n+\n+\t\t\twake_up_all(&ctx->wq);\n+\t\t}\n+\n+\t\tcxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);\n+\t\treturn IRQ_HANDLED;\n+\t}\n+\tif (dsisr & CXL_PSL9_DSISR_An_OC)\n+\t\tpr_devel(\"CXL interrupt: OS Context Warning\\n\");\n+\n+\tWARN(1, \"Unhandled CXL PSL IRQ\\n\");\n+\treturn IRQ_HANDLED;\n+}\n+\n irqreturn_t cxl_irq_psl8(int irq, struct cxl_context *ctx, struct cxl_irq_info *irq_info)\n {\n \tu64 dsisr, dar;\ndiff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c\nindex 7b86ffa..67c9bc6 100644\n--- a/drivers/misc/cxl/native.c\n+++ b/drivers/misc/cxl/native.c\n@@ -120,6 +120,7 @@ int cxl_psl_purge(struct cxl_afu *afu)\n \tu64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);\n \tu64 dsisr, dar;\n \tu64 start, end;\n+\tu64 trans_fault = 0x0ULL;\n \tunsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);\n \tint rc = 0;\n \n@@ -127,6 +128,11 @@ int cxl_psl_purge(struct cxl_afu *afu)\n \n \tpr_devel(\"PSL purge request\\n\");\n \n+\tif (cxl_is_psl8(afu))\n+\t\ttrans_fault = CXL_PSL_DSISR_TRANS;\n+\tif (cxl_is_psl9(afu))\n+\t\ttrans_fault = CXL_PSL9_DSISR_An_TF;\n+\n \tif (!cxl_ops->link_ok(afu->adapter, afu)) {\n \t\tdev_warn(&afu->dev, \"PSL Purge called with link down, ignoring\\n\");\n \t\trc = -EIO;\n@@ -158,22 +164,21 @@ int cxl_psl_purge(struct cxl_afu *afu)\n \t\tpr_devel_ratelimited(\"PSL purging... PSL_CNTL: 0x%016llx\"\n \t\t\t\t     \"  PSL_DSISR: 0x%016llx\\n\",\n \t\t\t\t     PSL_CNTL, dsisr);\n-\t\tif (cxl_is_psl8(afu)) {\n-\t\t\tif (dsisr & CXL_PSL_DSISR_TRANS) {\n-\t\t\t\tdar = cxl_p2n_read(afu, CXL_PSL_DAR_An);\n-\t\t\t\tdev_notice(&afu->dev, \"PSL purge terminating \"\n-\t\t\t\t\t\t      \"pending translation, \"\n-\t\t\t\t\t\t      \"DSISR: 0x%016llx, DAR: 0x%016llx\\n\",\n-\t\t\t\t\t\t       dsisr, dar);\n-\t\t\t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);\n-\t\t\t} else if (dsisr) {\n-\t\t\t\tdev_notice(&afu->dev, \"PSL purge acknowledging \"\n-\t\t\t\t\t\t      \"pending non-translation fault, \"\n-\t\t\t\t\t\t      \"DSISR: 0x%016llx\\n\", dsisr);\n-\t\t\t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);\n-\t\t\t} else {\n-\t\t\t\tcpu_relax();\n-\t\t\t}\n+\n+\t\tif (dsisr & trans_fault) {\n+\t\t\tdar = cxl_p2n_read(afu, CXL_PSL_DAR_An);\n+\t\t\tdev_notice(&afu->dev, \"PSL purge terminating \"\n+\t\t\t\t\t      \"pending translation, \"\n+\t\t\t\t\t      \"DSISR: 0x%016llx, DAR: 0x%016llx\\n\",\n+\t\t\t\t\t       dsisr, dar);\n+\t\t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);\n+\t\t} else if (dsisr) {\n+\t\t\tdev_notice(&afu->dev, \"PSL purge acknowledging \"\n+\t\t\t\t\t      \"pending non-translation fault, \"\n+\t\t\t\t\t      \"DSISR: 0x%016llx\\n\", dsisr);\n+\t\t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);\n+\t\t} else {\n+\t\t\tcpu_relax();\n \t\t}\n \t\tPSL_CNTL = cxl_p1n_read(afu, CXL_PSL_SCNTL_An);\n \t}\n@@ -205,7 +210,7 @@ static int spa_max_procs(int spa_size)\n \treturn ((spa_size / 8) - 96) / 17;\n }\n \n-int cxl_alloc_spa(struct cxl_afu *afu)\n+static int cxl_alloc_spa(struct cxl_afu *afu, int mode)\n {\n \tunsigned spa_size;\n \n@@ -218,7 +223,8 @@ int cxl_alloc_spa(struct cxl_afu *afu)\n \t\tif (spa_size > 0x100000) {\n \t\t\tdev_warn(&afu->dev, \"num_of_processes too large for the SPA, limiting to %i (0x%x)\\n\",\n \t\t\t\t\tafu->native->spa_max_procs, afu->native->spa_size);\n-\t\t\tafu->num_procs = afu->native->spa_max_procs;\n+\t\t\tif (mode != CXL_MODE_DEDICATED)\n+\t\t\t\tafu->num_procs = afu->native->spa_max_procs;\n \t\t\tbreak;\n \t\t}\n \n@@ -267,6 +273,35 @@ void cxl_release_spa(struct cxl_afu *afu)\n \t}\n }\n \n+/* Invalidation of all ERAT entries is no longer required by CAIA2. Use\n+ * only for debug\n+ */\n+int cxl_invalidate_all_psl9(struct cxl *adapter)\n+{\n+\tunsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);\n+\tu64 ierat;\n+\n+\tpr_devel(\"CXL adapter - invalidation of all ERAT entries\\n\");\n+\n+\t/* Invalidates all ERAT entries for Radix or HPT */\n+\tierat = CXL_XSL9_IERAT_IALL;\n+\tif (radix_enabled())\n+\t\tierat |= CXL_XSL9_IERAT_INVR;\n+\tcxl_p1_write(adapter, CXL_XSL9_IERAT, ierat);\n+\n+\twhile (cxl_p1_read(adapter, CXL_XSL9_IERAT) & CXL_XSL9_IERAT_IINPROG) {\n+\t\tif (time_after_eq(jiffies, timeout)) {\n+\t\t\tdev_warn(&adapter->dev,\n+\t\t\t\"WARNING: CXL adapter invalidation of all ERAT entries timed out!\\n\");\n+\t\t\treturn -EBUSY;\n+\t\t}\n+\t\tif (!cxl_ops->link_ok(adapter, NULL))\n+\t\t\treturn -EIO;\n+\t\tcpu_relax();\n+\t}\n+\treturn 0;\n+}\n+\n int cxl_invalidate_all_psl8(struct cxl *adapter)\n {\n \tunsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);\n@@ -503,7 +538,7 @@ static int activate_afu_directed(struct cxl_afu *afu)\n \n \tafu->num_procs = afu->max_procs_virtualised;\n \tif (afu->native->spa == NULL) {\n-\t\tif (cxl_alloc_spa(afu))\n+\t\tif (cxl_alloc_spa(afu, CXL_MODE_DIRECTED))\n \t\t\treturn -ENOMEM;\n \t}\n \tattach_spa(afu);\n@@ -553,10 +588,19 @@ static u64 calculate_sr(struct cxl_context *ctx)\n \t\tsr |= (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV;\n \t} else {\n \t\tsr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;\n-\t\tsr &= ~(CXL_PSL_SR_An_HV);\n+\t\tif (radix_enabled())\n+\t\t\tsr |= CXL_PSL_SR_An_HV;\n+\t\telse\n+\t\t\tsr &= ~(CXL_PSL_SR_An_HV);\n \t\tif (!test_tsk_thread_flag(current, TIF_32BIT))\n \t\t\tsr |= CXL_PSL_SR_An_SF;\n \t}\n+\tif (cxl_is_psl9(ctx->afu)) {\n+\t\tif (radix_enabled())\n+\t\t\tsr |= CXL_PSL_SR_An_XLAT_ror;\n+\t\telse\n+\t\t\tsr |= CXL_PSL_SR_An_XLAT_hpt;\n+\t}\n \treturn sr;\n }\n \n@@ -589,6 +633,70 @@ static void update_ivtes_directed(struct cxl_context *ctx)\n \t\tWARN_ON(add_process_element(ctx));\n }\n \n+static int process_element_entry(struct cxl_context *ctx, u64 wed, u64 amr)\n+{\n+\tu32 pid;\n+\n+\tcxl_assign_psn_space(ctx);\n+\n+\tctx->elem->ctxtime = 0; /* disable */\n+\tctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));\n+\tctx->elem->haurp = 0; /* disable */\n+\n+\tif (ctx->kernel)\n+\t\tpid = 0;\n+\telse {\n+\t\tif (ctx->mm == NULL) {\n+\t\t\tpr_devel(\"%s: unable to get mm for pe=%d pid=%i\\n\",\n+\t\t\t\t__func__, ctx->pe, pid_nr(ctx->pid));\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tpid = ctx->mm->context.id;\n+\t}\n+\n+\tctx->elem->common.tid = 0;\n+\tctx->elem->common.pid = cpu_to_be32(pid);\n+\n+\tctx->elem->sr = cpu_to_be64(calculate_sr(ctx));\n+\n+\tctx->elem->common.csrp = 0; /* disable */\n+\n+\tcxl_prefault(ctx, wed);\n+\n+\t/*\n+\t * Ensure we have the multiplexed PSL interrupt set up to take faults\n+\t * for kernel contexts that may not have allocated any AFU IRQs at all:\n+\t */\n+\tif (ctx->irqs.range[0] == 0) {\n+\t\tctx->irqs.offset[0] = ctx->afu->native->psl_hwirq;\n+\t\tctx->irqs.range[0] = 1;\n+\t}\n+\n+\tctx->elem->common.amr = cpu_to_be64(amr);\n+\tctx->elem->common.wed = cpu_to_be64(wed);\n+\n+\treturn 0;\n+}\n+\n+int cxl_attach_afu_directed_psl9(struct cxl_context *ctx, u64 wed, u64 amr)\n+{\n+\tint result;\n+\n+\t/* fill the process element entry */\n+\tresult = process_element_entry(ctx, wed, amr);\n+\tif (result)\n+\t\treturn result;\n+\n+\tupdate_ivtes_directed(ctx);\n+\n+\t/* first guy needs to enable */\n+\tresult = cxl_ops->afu_check_and_enable(ctx->afu);\n+\tif (result)\n+\t\treturn result;\n+\n+\treturn add_process_element(ctx);\n+}\n+\n int cxl_attach_afu_directed_psl8(struct cxl_context *ctx, u64 wed, u64 amr)\n {\n \tu32 pid;\n@@ -599,7 +707,7 @@ int cxl_attach_afu_directed_psl8(struct cxl_context *ctx, u64 wed, u64 amr)\n \tctx->elem->ctxtime = 0; /* disable */\n \tctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));\n \tctx->elem->haurp = 0; /* disable */\n-\tctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1));\n+\tctx->elem->u.sdr = cpu_to_be64(mfspr(SPRN_SDR1));\n \n \tpid = current->pid;\n \tif (ctx->kernel)\n@@ -610,13 +718,13 @@ int cxl_attach_afu_directed_psl8(struct cxl_context *ctx, u64 wed, u64 amr)\n \tctx->elem->sr = cpu_to_be64(calculate_sr(ctx));\n \n \tctx->elem->common.csrp = 0; /* disable */\n-\tctx->elem->common.aurp0 = 0; /* disable */\n-\tctx->elem->common.aurp1 = 0; /* disable */\n+\tctx->elem->common.u.psl8.aurp0 = 0; /* disable */\n+\tctx->elem->common.u.psl8.aurp1 = 0; /* disable */\n \n \tcxl_prefault(ctx, wed);\n \n-\tctx->elem->common.sstp0 = cpu_to_be64(ctx->sstp0);\n-\tctx->elem->common.sstp1 = cpu_to_be64(ctx->sstp1);\n+\tctx->elem->common.u.psl8.sstp0 = cpu_to_be64(ctx->sstp0);\n+\tctx->elem->common.u.psl8.sstp1 = cpu_to_be64(ctx->sstp1);\n \n \t/*\n \t * Ensure we have the multiplexed PSL interrupt set up to take faults\n@@ -682,6 +790,31 @@ static int deactivate_afu_directed(struct cxl_afu *afu)\n \treturn 0;\n }\n \n+int cxl_activate_dedicated_process_psl9(struct cxl_afu *afu)\n+{\n+\tdev_info(&afu->dev, \"Activating dedicated process mode\\n\");\n+\n+\t/* If XSL is set to dedicated mode (Set in PSL_SCNTL reg), the\n+\t * XSL and AFU are programmed to work with a single context.\n+\t * The context information should be configured in the SPA area\n+\t * index 0 (so PSL_SPAP must be configured before enabling the\n+\t * AFU).\n+\t */\n+\tafu->num_procs = 1;\n+\tif (afu->native->spa == NULL) {\n+\t\tif (cxl_alloc_spa(afu, CXL_MODE_DEDICATED))\n+\t\t\treturn -ENOMEM;\n+\t}\n+\tattach_spa(afu);\n+\n+\tcxl_p1n_write(afu, CXL_PSL_SCNTL_An, CXL_PSL_SCNTL_An_PM_Process);\n+\tcxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);\n+\n+\tafu->current_mode = CXL_MODE_DEDICATED;\n+\n+\treturn cxl_chardev_d_afu_add(afu);\n+}\n+\n int cxl_activate_dedicated_process_psl8(struct cxl_afu *afu)\n {\n \tdev_info(&afu->dev, \"Activating dedicated process mode\\n\");\n@@ -705,6 +838,16 @@ int cxl_activate_dedicated_process_psl8(struct cxl_afu *afu)\n \treturn cxl_chardev_d_afu_add(afu);\n }\n \n+void cxl_update_dedicated_ivtes_psl9(struct cxl_context *ctx)\n+{\n+\tint r;\n+\n+\tfor (r = 0; r < CXL_IRQ_RANGES; r++) {\n+\t\tctx->elem->ivte_offsets[r] = cpu_to_be16(ctx->irqs.offset[r]);\n+\t\tctx->elem->ivte_ranges[r] = cpu_to_be16(ctx->irqs.range[r]);\n+\t}\n+}\n+\n void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx)\n {\n \tstruct cxl_afu *afu = ctx->afu;\n@@ -721,6 +864,26 @@ void cxl_update_dedicated_ivtes_psl8(struct cxl_context *ctx)\n \t\t\t((u64)ctx->irqs.range[3] & 0xffff));\n }\n \n+int cxl_attach_dedicated_process_psl9(struct cxl_context *ctx, u64 wed, u64 amr)\n+{\n+\tstruct cxl_afu *afu = ctx->afu;\n+\tint result;\n+\n+\t/* fill the process element entry */\n+\tresult = process_element_entry(ctx, wed, amr);\n+\tif (result)\n+\t\treturn result;\n+\n+\tif (ctx->afu->adapter->native->sl_ops->update_dedicated_ivtes)\n+\t\tafu->adapter->native->sl_ops->update_dedicated_ivtes(ctx);\n+\n+\tresult = cxl_ops->afu_reset(afu);\n+\tif (result)\n+\t\treturn result;\n+\n+\treturn afu_enable(afu);\n+}\n+\n int cxl_attach_dedicated_process_psl8(struct cxl_context *ctx, u64 wed, u64 amr)\n {\n \tstruct cxl_afu *afu = ctx->afu;\n@@ -892,6 +1055,21 @@ static int native_get_irq_info(struct cxl_afu *afu, struct cxl_irq_info *info)\n \treturn 0;\n }\n \n+void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx)\n+{\n+\tu64 fir1, fir2, serr;\n+\n+\tfir1 = cxl_p1_read(ctx->afu->adapter, CXL_PSL9_FIR1);\n+\tfir2 = cxl_p1_read(ctx->afu->adapter, CXL_PSL9_FIR2);\n+\n+\tdev_crit(&ctx->afu->dev, \"PSL_FIR1: 0x%016llx\\n\", fir1);\n+\tdev_crit(&ctx->afu->dev, \"PSL_FIR2: 0x%016llx\\n\", fir2);\n+\tif (ctx->afu->adapter->native->sl_ops->register_serr_irq) {\n+\t\tserr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An);\n+\t\tcxl_afu_decode_psl_serr(ctx->afu, serr);\n+\t}\n+}\n+\n void cxl_native_irq_dump_regs_psl8(struct cxl_context *ctx)\n {\n \tu64 fir1, fir2, fir_slice, serr, afu_debug;\n@@ -928,9 +1106,20 @@ static irqreturn_t native_handle_psl_slice_error(struct cxl_context *ctx,\n \treturn cxl_ops->ack_irq(ctx, 0, errstat);\n }\n \n+static bool cxl_is_translation_fault(struct cxl_afu *afu, u64 dsisr)\n+{\n+\tif ((cxl_is_psl8(afu)) && (dsisr & CXL_PSL_DSISR_TRANS))\n+\t\treturn true;\n+\n+\tif ((cxl_is_psl9(afu)) && (dsisr & CXL_PSL9_DSISR_An_TF))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n irqreturn_t cxl_fail_irq_psl(struct cxl_afu *afu, struct cxl_irq_info *irq_info)\n {\n-\tif (irq_info->dsisr & CXL_PSL_DSISR_TRANS)\n+\tif (cxl_is_translation_fault(afu, irq_info->dsisr))\n \t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);\n \telse\n \t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);\n@@ -1001,6 +1190,9 @@ static void native_irq_wait(struct cxl_context *ctx)\n \t\tif (cxl_is_psl8(ctx->afu) &&\n \t\t   ((dsisr & CXL_PSL_DSISR_PENDING) == 0))\n \t\t\treturn;\n+\t\tif (cxl_is_psl9(ctx->afu) &&\n+\t\t   ((dsisr & CXL_PSL9_DSISR_PENDING) == 0))\n+\t\t\treturn;\n \t\t/*\n \t\t * We are waiting for the workqueue to process our\n \t\t * irq, so need to let that run here.\n@@ -1127,8 +1319,7 @@ int cxl_native_register_serr_irq(struct cxl_afu *afu)\n \t}\n \n \tserr = cxl_p1n_read(afu, CXL_PSL_SERR_An);\n-\tif (cxl_is_power8())\n-\t\tserr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);\n+\tserr = (serr & 0x00ffffffffff0000ULL) | (afu->serr_hwirq & 0xffff);\n \tcxl_p1n_write(afu, CXL_PSL_SERR_An, serr);\n \n \treturn 0;\ndiff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c\nindex 360c231..428c80b 100644\n--- a/drivers/misc/cxl/pci.c\n+++ b/drivers/misc/cxl/pci.c\n@@ -60,7 +60,7 @@\n #define CXL_VSEC_PROTOCOL_MASK   0xe0\n #define CXL_VSEC_PROTOCOL_1024TB 0x80\n #define CXL_VSEC_PROTOCOL_512TB  0x40\n-#define CXL_VSEC_PROTOCOL_256TB  0x20 /* Power 8 uses this */\n+#define CXL_VSEC_PROTOCOL_256TB  0x20 /* Power 8/9 uses this */\n #define CXL_VSEC_PROTOCOL_ENABLE 0x01\n \n #define CXL_READ_VSEC_PSL_REVISION(dev, vsec, dest) \\\n@@ -326,14 +326,20 @@ static void dump_afu_descriptor(struct cxl_afu *afu)\n \n #define P8_CAPP_UNIT0_ID 0xBA\n #define P8_CAPP_UNIT1_ID 0XBE\n+#define P9_CAPP_UNIT0_ID 0xC0\n+#define P9_CAPP_UNIT1_ID 0xE0\n \n-static u64 get_capp_unit_id(struct device_node *np)\n+static u32 get_phb_index(struct device_node *np)\n {\n \tu32 phb_index;\n \n \tif (of_property_read_u32(np, \"ibm,phb-index\", &phb_index))\n-\t\treturn 0;\n+\t\treturn -ENODEV;\n+\treturn phb_index;\n+}\n \n+static u64 get_capp_unit_id(struct device_node *np, u32 phb_index)\n+{\n \t/*\n \t * POWER 8:\n \t *  - For chips other than POWER8NVL, we only have CAPP 0,\n@@ -352,10 +358,25 @@ static u64 get_capp_unit_id(struct device_node *np)\n \t\t\treturn P8_CAPP_UNIT1_ID;\n \t}\n \n+\t/*\n+\t * POWER 9:\n+\t *   PEC0 (PHB0). Capp ID = CAPP0 (0b1100_0000)\n+\t *   PEC1 (PHB1 - PHB2). No capi mode\n+\t *   PEC2 (PHB3 - PHB4 - PHB5): Capi mode on PHB3 only. Capp ID = CAPP1 (0b1110_0000)\n+\t */\n+\tif (cxl_is_power9()) {\n+\t\tif (phb_index == 0)\n+\t\t\treturn P9_CAPP_UNIT0_ID;\n+\n+\t\tif (phb_index == 3)\n+\t\t\treturn P9_CAPP_UNIT1_ID;\n+\t}\n+\n \treturn 0;\n }\n \n-static int calc_capp_routing(struct pci_dev *dev, u64 *chipid, u64 *capp_unit_id)\n+static int calc_capp_routing(struct pci_dev *dev, u64 *chipid,\n+\t\t\t     u32 *phb_index, u64 *capp_unit_id)\n {\n \tstruct device_node *np;\n \tconst __be32 *prop;\n@@ -367,8 +388,16 @@ static int calc_capp_routing(struct pci_dev *dev, u64 *chipid, u64 *capp_unit_id\n \t\tnp = of_get_next_parent(np);\n \tif (!np)\n \t\treturn -ENODEV;\n+\n \t*chipid = be32_to_cpup(prop);\n-\t*capp_unit_id = get_capp_unit_id(np);\n+\n+\t*phb_index = get_phb_index(np);\n+\tif (*phb_index == -ENODEV) {\n+\t\tpr_err(\"cxl: invalid phb index\\n\");\n+\t\treturn -ENODEV;\n+\t}\n+\n+\t*capp_unit_id = get_capp_unit_id(np, *phb_index);\n \tof_node_put(np);\n \tif (!*capp_unit_id) {\n \t\tpr_err(\"cxl: invalid capp unit id\\n\");\n@@ -378,14 +407,97 @@ static int calc_capp_routing(struct pci_dev *dev, u64 *chipid, u64 *capp_unit_id\n \treturn 0;\n }\n \n+static int init_implementation_adapter_regs_psl9(struct cxl *adapter, struct pci_dev *dev)\n+{\n+\tu64 xsl_dsnctl, psl_fircntl;\n+\tu64 chipid;\n+\tu32 phb_index;\n+\tu64 capp_unit_id;\n+\tint rc;\n+\n+\trc = calc_capp_routing(dev, &chipid, &phb_index, &capp_unit_id);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* CAPI Identifier bits [0:7]\n+\t * bit 61:60 MSI bits --> 0\n+\t * bit 59 TVT selector --> 0\n+\t */\n+\t/* Tell XSL where to route data to.\n+\t * The field chipid should match the PHB CAPI_CMPM register\n+\t */\n+\txsl_dsnctl = ((u64)0x2 << (63-7)); /* Bit 57 */\n+\txsl_dsnctl |= (capp_unit_id << (63-15));\n+\n+\t/* nMMU_ID Defaults to: b’000001001’*/\n+\txsl_dsnctl |= ((u64)0x09 << (63-28));\n+\n+\tif (cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1)) {\n+\t\t/* Used to identify CAPI packets which should be sorted into\n+\t\t * the Non-Blocking queues by the PHB. This field should match\n+\t\t * the PHB PBL_NBW_CMPM register\n+\t\t * nbwind=0x03, bits [57:58], must include capi indicator.\n+\t\t * Not supported on P9 DD1.\n+\t\t */\n+\t\txsl_dsnctl |= ((u64)0x03 << (63-47));\n+\n+\t\t/* Upper 16b address bits of ASB_Notify messages sent to the\n+\t\t * system. Need to match the PHB’s ASN Compare/Mask Register.\n+\t\t * Not supported on P9 DD1.\n+\t\t */\n+\t\txsl_dsnctl |= ((u64)0x04 << (63-55));\n+\t}\n+\n+\tcxl_p1_write(adapter, CXL_XSL9_DSNCTL, xsl_dsnctl);\n+\n+\t/* Set fir_cntl to recommended value for production env */\n+\tpsl_fircntl = (0x2ULL << (63-3)); /* ce_report */\n+\tpsl_fircntl |= (0x1ULL << (63-6)); /* FIR_report */\n+\tpsl_fircntl |= 0x1ULL; /* ce_thresh */\n+\tcxl_p1_write(adapter, CXL_PSL9_FIR_CNTL, psl_fircntl);\n+\n+\t/* vccredits=0x1  pcklat=0x4 */\n+\tcxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0000000000001810ULL);\n+\n+\t/* For debugging with trace arrays.\n+\t * Configure RX trace 0 segmented mode.\n+\t * Configure CT trace 0 segmented mode.\n+\t * Configure LA0 trace 0 segmented mode.\n+\t * Configure LA1 trace 0 segmented mode.\n+\t */\n+\tcxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000000ULL);\n+\tcxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000003ULL);\n+\tcxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000005ULL);\n+\tcxl_p1_write(adapter, CXL_PSL9_TRACECFG, 0x8040800080000006ULL);\n+\n+\t/* A response to an ASB_Notify request is returned by the\n+\t * system as an MMIO write to the address defined in\n+\t * the PSL_TNR_ADDR register\n+\t */\n+\t/* PSL_TNR_ADDR */\n+\n+\t/* NORST */\n+\tcxl_p1_write(adapter, CXL_PSL9_DEBUG, 0x8000000000000000ULL);\n+\n+\t/* allocate the apc machines */\n+\tcxl_p1_write(adapter, CXL_PSL9_APCDEDTYPE, 0x40000003FFFF0000ULL);\n+\n+\t/* Disable vc dd1 fix */\n+\tif ((cxl_is_power9() && cpu_has_feature(CPU_FTR_POWER9_DD1)))\n+\t\tcxl_p1_write(adapter, CXL_PSL9_GP_CT, 0x0400000000000001ULL);\n+\n+\treturn 0;\n+}\n+\n static int init_implementation_adapter_regs_psl8(struct cxl *adapter, struct pci_dev *dev)\n {\n \tu64 psl_dsnctl, psl_fircntl;\n \tu64 chipid;\n+\tu32 phb_index;\n \tu64 capp_unit_id;\n \tint rc;\n \n-\trc = calc_capp_routing(dev, &chipid, &capp_unit_id);\n+\trc = calc_capp_routing(dev, &chipid, &phb_index, &capp_unit_id);\n \tif (rc)\n \t\treturn rc;\n \n@@ -414,10 +526,11 @@ static int init_implementation_adapter_regs_xsl(struct cxl *adapter, struct pci_\n {\n \tu64 xsl_dsnctl;\n \tu64 chipid;\n+\tu32 phb_index;\n \tu64 capp_unit_id;\n \tint rc;\n \n-\trc = calc_capp_routing(dev, &chipid, &capp_unit_id);\n+\trc = calc_capp_routing(dev, &chipid, &phb_index, &capp_unit_id);\n \tif (rc)\n \t\treturn rc;\n \n@@ -435,6 +548,12 @@ static int init_implementation_adapter_regs_xsl(struct cxl *adapter, struct pci_\n /* For the PSL this is a multiple for 0 < n <= 7: */\n #define PSL_2048_250MHZ_CYCLES 1\n \n+static void write_timebase_ctrl_psl9(struct cxl *adapter)\n+{\n+\tcxl_p1_write(adapter, CXL_PSL9_TB_CTLSTAT,\n+\t\t     TBSYNC_CNT(2 * PSL_2048_250MHZ_CYCLES));\n+}\n+\n static void write_timebase_ctrl_psl8(struct cxl *adapter)\n {\n \tcxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT,\n@@ -456,6 +575,11 @@ static void write_timebase_ctrl_xsl(struct cxl *adapter)\n \t\t     TBSYNC_CNT(XSL_4000_CLOCKS));\n }\n \n+static u64 timebase_read_psl9(struct cxl *adapter)\n+{\n+\treturn cxl_p1_read(adapter, CXL_PSL9_Timebase);\n+}\n+\n static u64 timebase_read_psl8(struct cxl *adapter)\n {\n \treturn cxl_p1_read(adapter, CXL_PSL_Timebase);\n@@ -514,6 +638,11 @@ static void cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)\n \treturn;\n }\n \n+static int init_implementation_afu_regs_psl9(struct cxl_afu *afu)\n+{\n+\treturn 0;\n+}\n+\n static int init_implementation_afu_regs_psl8(struct cxl_afu *afu)\n {\n \t/* read/write masks for this slice */\n@@ -612,7 +741,7 @@ static int setup_cxl_bars(struct pci_dev *dev)\n \t/*\n \t * BAR 4/5 has a special meaning for CXL and must be programmed with a\n \t * special value corresponding to the CXL protocol address range.\n-\t * For POWER 8 that means bits 48:49 must be set to 10\n+\t * For POWER 8/9 that means bits 48:49 must be set to 10\n \t */\n \tpci_write_config_dword(dev, PCI_BASE_ADDRESS_4, 0x00000000);\n \tpci_write_config_dword(dev, PCI_BASE_ADDRESS_5, 0x00020000);\n@@ -997,6 +1126,52 @@ static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)\n \treturn 0;\n }\n \n+static int sanitise_afu_regs_psl9(struct cxl_afu *afu)\n+{\n+\tu64 reg;\n+\n+\t/*\n+\t * Clear out any regs that contain either an IVTE or address or may be\n+\t * waiting on an acknowledgment to try to be a bit safer as we bring\n+\t * it online\n+\t */\n+\treg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);\n+\tif ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {\n+\t\tdev_warn(&afu->dev, \"WARNING: AFU was not disabled: %#016llx\\n\", reg);\n+\t\tif (cxl_ops->afu_reset(afu))\n+\t\t\treturn -EIO;\n+\t\tif (cxl_afu_disable(afu))\n+\t\t\treturn -EIO;\n+\t\tif (cxl_psl_purge(afu))\n+\t\t\treturn -EIO;\n+\t}\n+\tcxl_p1n_write(afu, CXL_PSL_SPAP_An, 0x0000000000000000);\n+\tcxl_p1n_write(afu, CXL_PSL_AMBAR_An, 0x0000000000000000);\n+\treg = cxl_p2n_read(afu, CXL_PSL_DSISR_An);\n+\tif (reg) {\n+\t\tdev_warn(&afu->dev, \"AFU had pending DSISR: %#016llx\\n\", reg);\n+\t\tif (reg & CXL_PSL9_DSISR_An_TF)\n+\t\t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_AE);\n+\t\telse\n+\t\t\tcxl_p2n_write(afu, CXL_PSL_TFC_An, CXL_PSL_TFC_An_A);\n+\t}\n+\tif (afu->adapter->native->sl_ops->register_serr_irq) {\n+\t\treg = cxl_p1n_read(afu, CXL_PSL_SERR_An);\n+\t\tif (reg) {\n+\t\t\tif (reg & ~0x000000007fffffff)\n+\t\t\t\tdev_warn(&afu->dev, \"AFU had pending SERR: %#016llx\\n\", reg);\n+\t\t\tcxl_p1n_write(afu, CXL_PSL_SERR_An, reg & ~0xffff);\n+\t\t}\n+\t}\n+\treg = cxl_p2n_read(afu, CXL_PSL_ErrStat_An);\n+\tif (reg) {\n+\t\tdev_warn(&afu->dev, \"AFU had pending error status: %#016llx\\n\", reg);\n+\t\tcxl_p2n_write(afu, CXL_PSL_ErrStat_An, reg);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int sanitise_afu_regs_psl8(struct cxl_afu *afu)\n {\n \tu64 reg;\n@@ -1254,10 +1429,10 @@ int cxl_pci_reset(struct cxl *adapter)\n \n \t/*\n \t * The adapter is about to be reset, so ignore errors.\n-\t * Not supported on P9 DD1 but don't forget to enable it\n-\t * on P9 DD2\n+\t * Not supported on P9 DD1\n \t */\n-\tif (cxl_is_power8())\n+\tif ((cxl_is_power8()) ||\n+\t    ((cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1))))\n \t\tcxl_data_cache_flush(adapter);\n \n \t/* pcie_warm_reset requests a fundamental pci reset which includes a\n@@ -1393,6 +1568,9 @@ static bool cxl_compatible_caia_version(struct cxl *adapter)\n \tif (cxl_is_power8() && (adapter->caia_major == 1))\n \t\treturn true;\n \n+\tif (cxl_is_power9() && (adapter->caia_major == 2))\n+\t\treturn true;\n+\n \treturn false;\n }\n \n@@ -1460,8 +1638,12 @@ static int sanitise_adapter_regs(struct cxl *adapter)\n \t/* Clear PSL tberror bit by writing 1 to it */\n \tcxl_p1_write(adapter, CXL_PSL_ErrIVTE, CXL_PSL_ErrIVTE_tberror);\n \n-\tif (adapter->native->sl_ops->invalidate_all)\n+\tif (adapter->native->sl_ops->invalidate_all) {\n+\t\t/* do not invalidate ERAT entries when not reloading on PERST */\n+\t\tif (cxl_is_power9() && (adapter->perst_loads_image))\n+\t\t\treturn 0;\n \t\trc = adapter->native->sl_ops->invalidate_all(adapter);\n+\t}\n \n \treturn rc;\n }\n@@ -1546,6 +1728,30 @@ static void cxl_deconfigure_adapter(struct cxl *adapter)\n \tpci_disable_device(pdev);\n }\n \n+static const struct cxl_service_layer_ops psl9_ops = {\n+\t.adapter_regs_init = init_implementation_adapter_regs_psl9,\n+\t.invalidate_all = cxl_invalidate_all_psl9,\n+\t.afu_regs_init = init_implementation_afu_regs_psl9,\n+\t.sanitise_afu_regs = sanitise_afu_regs_psl9,\n+\t.register_serr_irq = cxl_native_register_serr_irq,\n+\t.release_serr_irq = cxl_native_release_serr_irq,\n+\t.handle_interrupt = cxl_irq_psl9,\n+\t.fail_irq = cxl_fail_irq_psl,\n+\t.activate_dedicated_process = cxl_activate_dedicated_process_psl9,\n+\t.attach_afu_directed = cxl_attach_afu_directed_psl9,\n+\t.attach_dedicated_process = cxl_attach_dedicated_process_psl9,\n+\t.update_dedicated_ivtes = cxl_update_dedicated_ivtes_psl9,\n+\t.debugfs_add_adapter_regs = cxl_debugfs_add_adapter_regs_psl9,\n+\t.debugfs_add_afu_regs = cxl_debugfs_add_afu_regs_psl9,\n+\t.psl_irq_dump_registers = cxl_native_irq_dump_regs_psl9,\n+\t.err_irq_dump_registers = cxl_native_err_irq_dump_regs,\n+\t.debugfs_stop_trace = cxl_stop_trace_psl9,\n+\t.write_timebase_ctrl = write_timebase_ctrl_psl9,\n+\t.timebase_read = timebase_read_psl9,\n+\t.capi_mode = OPAL_PHB_CAPI_MODE_CAPI,\n+\t.needs_reset_before_disable = true,\n+};\n+\n static const struct cxl_service_layer_ops psl8_ops = {\n \t.adapter_regs_init = init_implementation_adapter_regs_psl8,\n \t.invalidate_all = cxl_invalidate_all_psl8,\n@@ -1589,6 +1795,9 @@ static void set_sl_ops(struct cxl *adapter, struct pci_dev *dev)\n \t\tif (cxl_is_power8()) {\n \t\t\tdev_info(&dev->dev, \"Device uses a PSL8\\n\");\n \t\t\tadapter->native->sl_ops = &psl8_ops;\n+\t\t} else {\n+\t\t\tdev_info(&dev->dev, \"Device uses a PSL9\\n\");\n+\t\t\tadapter->native->sl_ops = &psl9_ops;\n \t\t}\n \t}\n }\n@@ -1659,8 +1868,12 @@ static void cxl_pci_remove_adapter(struct cxl *adapter)\n \tcxl_sysfs_adapter_remove(adapter);\n \tcxl_debugfs_adapter_remove(adapter);\n \n-\t/* Flush adapter datacache as its about to be removed */\n-\tcxl_data_cache_flush(adapter);\n+\t/* Flush adapter datacache as its about to be removed.\n+\t * Not supported on P9 DD1\n+\t */\n+\tif ((cxl_is_power8()) ||\n+\t    ((cxl_is_power9() && !cpu_has_feature(CPU_FTR_POWER9_DD1))))\n+\t\tcxl_data_cache_flush(adapter);\n \n \tcxl_deconfigure_adapter(adapter);\n \n@@ -1744,6 +1957,11 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)\n \t\treturn -ENODEV;\n \t}\n \n+\tif (cxl_is_power9() && !radix_enabled()) {\n+\t\tdev_info(&dev->dev, \"Only Radix mode supported\\n\");\n+\t\treturn -ENODEV;\n+\t}\n+\n \tif (cxl_verbose)\n \t\tdump_cxl_config_space(dev);\n \ndiff --git a/drivers/misc/cxl/trace.h b/drivers/misc/cxl/trace.h\nindex 751d611..b8e300a 100644\n--- a/drivers/misc/cxl/trace.h\n+++ b/drivers/misc/cxl/trace.h\n@@ -17,6 +17,15 @@\n \n #include \"cxl.h\"\n \n+#define dsisr_psl9_flags(flags) \\\n+\t__print_flags(flags, \"|\", \\\n+\t\t{ CXL_PSL9_DSISR_An_CO_MASK,\t\"FR\" }, \\\n+\t\t{ CXL_PSL9_DSISR_An_TF,\t\t\"TF\" }, \\\n+\t\t{ CXL_PSL9_DSISR_An_PE,\t\t\"PE\" }, \\\n+\t\t{ CXL_PSL9_DSISR_An_AE,\t\t\"AE\" }, \\\n+\t\t{ CXL_PSL9_DSISR_An_OC,\t\t\"OC\" }, \\\n+\t\t{ CXL_PSL9_DSISR_An_S,\t\t\"S\" })\n+\n #define DSISR_FLAGS \\\n \t{ CXL_PSL_DSISR_An_DS,\t\"DS\" }, \\\n \t{ CXL_PSL_DSISR_An_DM,\t\"DM\" }, \\\n@@ -154,6 +163,40 @@ TRACE_EVENT(cxl_afu_irq,\n \t)\n );\n \n+TRACE_EVENT(cxl_psl9_irq,\n+\tTP_PROTO(struct cxl_context *ctx, int irq, u64 dsisr, u64 dar),\n+\n+\tTP_ARGS(ctx, irq, dsisr, dar),\n+\n+\tTP_STRUCT__entry(\n+\t\t__field(u8, card)\n+\t\t__field(u8, afu)\n+\t\t__field(u16, pe)\n+\t\t__field(int, irq)\n+\t\t__field(u64, dsisr)\n+\t\t__field(u64, dar)\n+\t),\n+\n+\tTP_fast_assign(\n+\t\t__entry->card = ctx->afu->adapter->adapter_num;\n+\t\t__entry->afu = ctx->afu->slice;\n+\t\t__entry->pe = ctx->pe;\n+\t\t__entry->irq = irq;\n+\t\t__entry->dsisr = dsisr;\n+\t\t__entry->dar = dar;\n+\t),\n+\n+\tTP_printk(\"afu%i.%i pe=%i irq=%i dsisr=0x%016llx dsisr=%s dar=0x%016llx\",\n+\t\t__entry->card,\n+\t\t__entry->afu,\n+\t\t__entry->pe,\n+\t\t__entry->irq,\n+\t\t__entry->dsisr,\n+\t\tdsisr_psl9_flags(__entry->dsisr),\n+\t\t__entry->dar\n+\t)\n+);\n+\n TRACE_EVENT(cxl_psl_irq,\n \tTP_PROTO(struct cxl_context *ctx, int irq, u64 dsisr, u64 dar),\n \n",
    "prefixes": [
        "V3",
        "7/7"
    ]
}