From patchwork Mon Jun 13 22:06:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Suthikulpanit, Suravee" X-Patchwork-Id: 69948 Delivered-To: patch@linaro.org Received: by 10.140.106.246 with SMTP id e109csp1759169qgf; Mon, 13 Jun 2016 15:22:42 -0700 (PDT) X-Received: by 10.66.145.35 with SMTP id sr3mr23990211pab.82.1465856562470; Mon, 13 Jun 2016 15:22:42 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v76si34436908pfa.20.2016.06.13.15.22.42; Mon, 13 Jun 2016 15:22:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@amdcloud.onmicrosoft.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1423250AbcFMWWY (ORCPT + 30 others); Mon, 13 Jun 2016 18:22:24 -0400 Received: from mail-bn1on0062.outbound.protection.outlook.com ([157.56.110.62]:8544 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1422977AbcFMWWU (ORCPT ); Mon, 13 Jun 2016 18:22:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=P22rywR4sXRejYcbzuWN2VNruLh5pwXjPs3BCeBrqyQ=; b=Q/7QZ8yvDsFUFkYMawxvvlrtMZMb2QVlm129KI843VXEcWEjiCro6ChtI4bxDdAmJt4RnoOEKOLWz07nmPfV4zKE5ggLyl1C++gSRhCzDMNyeUbJvUv38X2f2LXrJEKaSpUDZ+ISXR/tHuEFKKHYavRf/WabrQ0PM+erVKbsEVg= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; Received: from ssuthiku-cz-dev.amd.com (165.204.77.1) by BLUPR12MB0434.namprd12.prod.outlook.com (10.162.92.14) with Microsoft SMTP Server (TLS) id 15.1.517.8; Mon, 13 Jun 2016 22:07:01 +0000 From: Suravee Suthikulpanit To: , , , CC: , , , Suravee Suthikulpanit Subject: [PART2 RFC v2 02/10] iommu/amd: Add support for 128-bit IRTE Date: Mon, 13 Jun 2016 17:06:42 -0500 Message-ID: <1465855611-10092-3-git-send-email-suravee.suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1465855611-10092-1-git-send-email-suravee.suthikulpanit@amd.com> References: <1465855611-10092-1-git-send-email-suravee.suthikulpanit@amd.com> MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SN1PR0701CA0005.namprd07.prod.outlook.com (10.162.96.15) To BLUPR12MB0434.namprd12.prod.outlook.com (10.162.92.14) X-MS-Office365-Filtering-Correlation-Id: 5a8adf97-ad91-46cd-ef8a-08d393d70c28 X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0434; 2:jChFLLzuBOlKd/BI36+SbTx2/UtN3l9rxyfIqND7DcrE/5TrI6RGOdaakTC8jlT8gjyOIx9TdpmhXwjZUrTOpEF9EI2hgJeaNO/AA35uUXtyIWKvjhznoisw1Eus3Spd/jPeA3TRh29Oi8/sZ3Mpbd4G9N/7EB/dCfe5nMhPsjB7VN12yeBVrGZFtO4Oc6wm; 3:PrQpplJT2jDYpSk0d7TCYlRBy0XGWr7KOJDep2aEn9mEJUn8iNuyIkCS+oRwzRSwryjsjlNpw48Po9XdqU6pwmzLfwtL/N1WczumGh1o127rpxlDp7EPuOcBSua4EOK6; 25:IuUd8TfVQgTrAIZOlQA3QfOqfqhR0hsNCtDJCwVfPbPOhAMcI73MiQaKzKvHWXGuLTWWxEradweN0JnS3zb+dQRYBTYxECRSts4kduBHJtRndHMa/6n/yUy2C+TnU29WZLOURiiaphEI3R/yYqAtZvk8qjdWfF83ddXU+4Kf4zhFcafe3REIwBDzj35/6gbeGX4CXe2LB60mcb5+UdGvcwIu0kdUcOkE2TBYxc89qUh9A+ch02PFsp5mFAbiqUGJWISlGU0EHxUVXdWXx+nj1ENOUv2i0NJeYvgQWEVZ66ACXTJ20KhZcd5AgIxjPBnEZDI5YKKf+DJc9bqJPqvLUAZCxdgrH2rJg/kXv6kU407ZsPp8PVpZndx5SDUU6yxQcOXAPr84wBMuh7UZG4wH0RuvGSlc0hlFWF5HjzHDFnQ= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR12MB0434; X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0434; 20:wu/YiHaI6g2EMbm+HqN0BxHDpDDytdRvhcC0+ewM/lgd6CR7Inxb+84DN5Xgm2z08t/iJQKBLcwYlMAvWJqpcgZx0h/lF3Pm9j4cx54BtratfQttKZzJuWToYQX2j8J3t5Z61Gx4X0mrUvn2QhpXgYf5kNZqK1/T144BoCBtmnKnuwK0D/OFQvP9Un1xS7lmSdbf98FTAm3juyTN6EnnLyvIgi4Q59NChWuMLIAWrltzWWZf2HYu9FaNw41/N+kPDuThvH1GfeXwpj4x1n72aAK0UO2imFtobceW5zoebCWOCQLVIO2DIR4WhJ0iHI/FCWmHckdsoRw/kcD3USPQCCfrhKOqGrVfgjJNrRRcBwTT0zv2UiBs51jSHFH9PnXuqEQ/NuuQmAI2XDMTofVop4NXSracjCVH5VZim1WF2tRAzRnAVBlllAiAEe21nGdkVyUaYTr8DEGJeUfdcGLS0w6EXj2fhKA1MDIb8S+0od87D8SvLN/K+FTDvQ9OKVrT; 4:0dJoxWz+lRx7xJO/hCryr+EUfcmuJmCh603RzL/TKwB1SeFvxK9yK2S1U7Ikfb3qrtsQyiNZdrgSbwVnqLHW2fp1Wmug4aYmmOZJIUdFY5L3yiAuhRDYQ5EaasNHBCKx2VIZBBnTuhNDv4sS9FbJf+Cge9SdjscT/VPvUnCq1ngIT/3yLm9W6eiW1rM384XgSUxaD531bjprfz/cqH9ptRdW7g50JIVDozzTYZrFJ5cqBaXaEfdDpj2a7uBL4K3dxkusgLPxooRTbEePOKyb09jb1hsfbjjjCJiigDKOBLcDc+4o0bsQS9LnUdtLKarfHqJ8kWuC3Mx7UocQxMmXBHuT/HlbCVgl99Q5BQdCZetFaOBa0Vy/DlFwoOmsyJnJTqULJdHxOPlH2Ds//iGzRNMDAqYW3XAZjd9HxyUfgkvorw2LVt1Oreukm6z0et/x X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026); SRVR:BLUPR12MB0434; BCL:0; PCL:0; RULEID:; SRVR:BLUPR12MB0434; X-Forefront-PRVS: 0972DEC1D9 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(7916002)(189002)(199003)(53416004)(50226002)(5008740100001)(50466002)(36756003)(19580405001)(19580395003)(106356001)(189998001)(68736007)(105586002)(42186005)(2906002)(586003)(5001770100001)(101416001)(50986999)(4326007)(8676002)(81156014)(2950100001)(3846002)(6116002)(76176999)(77096005)(81166006)(97736004)(5003940100001)(5004730100002)(47776003)(86362001)(48376002)(92566002)(229853001)(33646002)(2201001)(66066001); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR12MB0434; H:ssuthiku-cz-dev.amd.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; CAT:NONE; LANG:en; CAT:NONE; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR12MB0434; 23:7arrSvwMJXjlKgDp6hcuZCeIzRs5moD4KqUiVqxEt?= =?us-ascii?Q?w6PkGFrPXEmjHuqFLJVaHaxeZr5TW+HVKhUbkzpYWRgm4b1uW7heLLTjkP5P?= =?us-ascii?Q?JfupW0UduEyZQKJxHKMYT7LgXHwHkqLnQNJyJDDssCq5k1fhnpNwJpvZRHnN?= =?us-ascii?Q?vAn11Pv6yJx/F4RYaT60jyEwsOurWLEmuHt95YZWD1qEWH9umXHaeicAK7m3?= =?us-ascii?Q?r4j9Nbr/KZxoZQY8pLWp9w3HF4iFYMlUVU9jg0RsODf1JB7VXtz7VJFxy197?= =?us-ascii?Q?AgIQ0TemacYie1LmTk73o7lYrnRHy/yeQuISC0y8KcS0ciwJfnFpTNQq4Syc?= =?us-ascii?Q?fL63mIZVjUr0w7bZX9l4iAQuTNsELpKpWbsT6JmQJjryS39fv98Q9Xb3BtWQ?= =?us-ascii?Q?NE/BQJaXF8+vPYvPXTVoYYSMzKFFW903xSuqdKJX7BwvWcgt1z6sVLzid9/q?= =?us-ascii?Q?+8WUsC+fK/ITqZpeUKoVAuUpi5AayGOS6E4n+rPDGotXVynPlUb3ru95GDBg?= =?us-ascii?Q?Jz8tU4R19xDqnrj8q7IO6jfRcsn6fJ+KHwpgCqcHiglrW4okP+8g02y3rFUi?= =?us-ascii?Q?VsXWnJ1ENmMhzgB3M3SeSCsVXeTS1YCYY8/bnv+9SbPGAMSN9m6t4lMG0FHV?= =?us-ascii?Q?/O0NC7kKuSKxuuAPlrEnuQYTd3KLpjZrufz3mjcZXB3wtWQb4UNQ0cnihvZN?= =?us-ascii?Q?fccr6lJiAzare86dL3swztghe+qVrnK/omJ9V2ROR5Rtb4aQ3JxlzAcazLRu?= =?us-ascii?Q?OnL+66l7xLzIzTG30ApzN5fAy61SO+hmrnKeXBZnECNdHdlOWBb5E0WAOLgN?= =?us-ascii?Q?8Qa7+UZmxi1j1YI3fLddYDK4gcLgVZX0GyfnGTuZQavScODvC2U+irOf3Ewe?= =?us-ascii?Q?HgKZFo9QojUnC6u/xwO1DXe18oVqmvVw+nwrzeoJBeg+mxhoWU2IYu3RRK38?= =?us-ascii?Q?YZOmIlaWGLCL7kkVuT04mcqxTjcn1Nf03Ch6qq4D6J1rVYdPrtVX4q4i7vcG?= =?us-ascii?Q?lPoOLWqKF6K7a76odi4RrDry+scRGKr8IoIn6SiF6zBIoyr1LXbqHrBjdb1V?= =?us-ascii?Q?2ds4mm3FKYy0PrtOchnkRpjkzV9mW+4tx7GnI8GfBZWpwfGeg=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0434; 6:pj+nxf+1clqQLa1jI9CjEll4Frw6QTKZ6+zVY+VAOpzOHlUdvgVX46Qdpu/ubGKWJNdSx690r8P4slkVbVhoObmUquJZO+SPhz+jk7tGOp44nqk1E5eJoxKJEF3l5P8dHeBIYM1SItLaGW4/l817AkOn1J8n2emdNbmuMFC0th3gh55fo+8bfHvcy33rJ+mTES51WH3XRV2kZhRENgUk1qaP1TtscrbrV61pjzNojxfTyA/iLT91UxBmlGHOdqaNo/OOyCpbvljoPJj+9uFJqh9B9rJ19tPuWo1nt70gkNjJdScFJST++5hlpg5j3eaz; 5:qcmgMO7lLieFL+JWZtZTVYAfeUsBHpj9v6u1kbjNbKDuUK2OJYw8J0AgNqC9KP5bG0Ck4gVdXvHH2hMpj3nXCHMPRHOemE6hY9h8Mh4y5Ph6dc6jTdRm73GwZB5NF7BplmgyO5c0Bnh5+ncTHEFjfA==; 24:KQSCuCKiSflrfElQ1ABT5iZOBoQe4XEK3uBGMaBL0wmXHs5Pulpjn82Up2vHui++Mrl5Vxr5CMCatESqbvuQtKn4av6voiT0pBmm9MUvHGU=; 7:1QHLFeTP2I+91lIHGnfdYTKQO6hWp09YyiJ/aq55gf8100jhYcMu36kmmWmuEfFzIEyElh+tsW663H9UFRQO1GwYfKDZZmHXGCKgNiKX+MSY1ws2AawWlQMhavHu6hyiCVqPzyhGEN5hjLEMkNhTnz0X4ZIQRrAp6RiK2nxEBRwggYdXIbgWFKTcX5YNHHAzHP3F6/AR8POV3upGi3UO6w== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0434; 20:9qxRGzytvx76YYcd06bZcqV4g8e4VfE70AZRWrN9FJNiDcfXKFCrN8cZlkBrV9pqpTfNy0mrVHafrvz0VUN8WdcbOiZ91HGg9ZkCtqgwCD55ka+qe3f2hbYWxRKBii8gwHd5JIuqXbacTsPYaDiqE9FvrGelH+Lyu+1o1nHN4dVF0PKoTEmYE4P+u4yQvkrCCHQh0x6td42XgTjDOtua3MKpJDUnjP2lMBVeyX8Jp2OPS0ziZul5emZ4SBZF5sX0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jun 2016 22:07:01.5632 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR12MB0434 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds new data structure for the 128-bit IOMMU IRTE format, which can support both legacy and vapic interrupt remapping modes. It also provides helper functions for setting up, accessing, and updating interrupt remapping table entries in different mode. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd_iommu.c | 180 ++++++++++++++++++++++++++++++++-------- drivers/iommu/amd_iommu_types.h | 64 ++++++++++++++ 2 files changed, 210 insertions(+), 34 deletions(-) -- 1.9.1 diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 634f636..7dac927 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -3693,21 +3693,6 @@ EXPORT_SYMBOL(amd_iommu_device_info); * *****************************************************************************/ -union irte { - u32 val; - struct { - u32 valid : 1, - no_fault : 1, - int_type : 3, - rq_eoi : 1, - dm : 1, - rsvd_1 : 1, - destination : 8, - vector : 8, - rsvd_2 : 8; - } fields; -}; - struct irq_2_irte { u16 devid; /* Device ID for IRTE table */ u16 index; /* Index into IRTE table*/ @@ -3716,6 +3701,7 @@ struct irq_2_irte { struct amd_ir_data { struct irq_2_irte irq_2_irte; union irte irte_entry; + struct irte_ga irte_ga_entry; union { struct msi_msg msi_entry; }; @@ -3742,7 +3728,60 @@ static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) amd_iommu_dev_table[devid].data[2] = dte; } +void *amd_iommu_get_irte(struct irq_remap_table *table, int index) +{ + void *ret = NULL; + + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + union irte *ptr = (union irte *)table->table; + + ret = &ptr[index]; + } else { + struct irte_ga *ptr = (struct irte_ga *)table->table; + + ret = &ptr[index]; + } + return ret; +} + #define IRTE_ALLOCATED (~1U) +static void set_irte_allocated(struct irq_remap_table *table, int index) +{ + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + table->table[index] = IRTE_ALLOCATED; + } else { + struct irte_ga *irte = amd_iommu_get_irte(table, index); + + memset(&irte->lo.val, 0, sizeof(u64)); + memset(&irte->hi.val, 0, sizeof(u64)); + irte->hi.fields.vector = 0xff; + } +} + +static bool is_irte_allocated(struct irq_remap_table *table, int index) +{ + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + union irte *irte = amd_iommu_get_irte(table, index); + + return irte->val != 0; + } else { + struct irte_ga *irte = amd_iommu_get_irte(table, index); + + return irte->hi.fields.vector != 0; + } +} + +static void clear_irte(struct irq_remap_table *table, int index) +{ + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + table->table[index] = 0; + } else { + struct irte_ga *irte = amd_iommu_get_irte(table, index); + + memset(&irte->lo.val, 0, sizeof(u64)); + memset(&irte->hi.val, 0, sizeof(u64)); + } +} static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) { @@ -3789,13 +3828,18 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic) goto out; } - memset(table->table, 0, MAX_IRQS_PER_TABLE * sizeof(u32)); + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) + memset(table->table, 0, + MAX_IRQS_PER_TABLE * sizeof(u32)); + else + memset(table->table, 0, + (MAX_IRQS_PER_TABLE * (sizeof(u64) * 2))); if (ioapic) { int i; for (i = 0; i < 32; ++i) - table->table[i] = IRTE_ALLOCATED; + set_irte_allocated(table, i); } irq_lookup_table[devid] = table; @@ -3832,14 +3876,14 @@ static int alloc_irq_index(u16 devid, int count) for (c = 0, index = table->min_index; index < MAX_IRQS_PER_TABLE; ++index) { - if (table->table[index] == 0) + if (!is_irte_allocated(table, index)) c += 1; else c = 0; if (c == count) { for (; c != 0; --c) - table->table[index - c + 1] = IRTE_ALLOCATED; + set_irte_allocated(table, index - c + 1); index -= count - 1; goto out; @@ -3854,6 +3898,40 @@ out: return index; } +static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte) +{ + struct irq_remap_table *table; + struct amd_iommu *iommu; + unsigned long flags; + struct irte_ga *entry; + struct irte_ga tmp; + + iommu = amd_iommu_rlookup_table[devid]; + if (iommu == NULL) + return -EINVAL; + + table = get_irq_table(devid, false); + if (!table) + return -ENOMEM; + + spin_lock_irqsave(&table->lock, flags); + + entry = amd_iommu_get_irte(table, index); + memcpy(&tmp, entry, sizeof(struct irte_ga)); + entry->lo.fields_remap.valid = 0; + entry->hi.val = irte->hi.val; + entry->hi.fields.ga_root_ptr = tmp.hi.fields.ga_root_ptr; + entry->lo.val = irte->lo.val; + entry->lo.fields_remap.valid = 1; + + spin_unlock_irqrestore(&table->lock, flags); + + iommu_flush_irt(iommu, devid); + iommu_completion_wait(iommu); + + return 0; +} + static int modify_irte(u16 devid, int index, union irte irte) { struct irq_remap_table *table; @@ -3893,7 +3971,7 @@ static void free_irte(u16 devid, int index) return; spin_lock_irqsave(&table->lock, flags); - table->table[index] = 0; + clear_irte(table, index); spin_unlock_irqrestore(&table->lock, flags); iommu_flush_irt(iommu, devid); @@ -3984,19 +4062,33 @@ static void irq_remapping_prepare_irte(struct amd_ir_data *data, { struct irq_2_irte *irte_info = &data->irq_2_irte; struct msi_msg *msg = &data->msi_entry; - union irte *irte = &data->irte_entry; struct IO_APIC_route_entry *entry; data->irq_2_irte.devid = devid; data->irq_2_irte.index = index + sub_handle; /* Setup IRTE for IOMMU */ - irte->val = 0; - irte->fields.vector = irq_cfg->vector; - irte->fields.int_type = apic->irq_delivery_mode; - irte->fields.destination = irq_cfg->dest_apicid; - irte->fields.dm = apic->irq_dest_mode; - irte->fields.valid = 1; + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + union irte *irte = &data->irte_entry; + + irte->val = 0; + irte->fields.vector = irq_cfg->vector; + irte->fields.int_type = apic->irq_delivery_mode; + irte->fields.destination = irq_cfg->dest_apicid; + irte->fields.dm = apic->irq_dest_mode; + irte->fields.valid = 1; + } else { + struct irte_ga *irte = &data->irte_ga_entry; + + irte->lo.val = 0; + irte->hi.val = 0; + irte->lo.fields_remap.guest_mode = 0; + irte->lo.fields_remap.int_type = apic->irq_delivery_mode; + irte->lo.fields_remap.dm = apic->irq_dest_mode; + irte->hi.fields.vector = irq_cfg->vector; + irte->lo.fields_remap.destination = irq_cfg->dest_apicid; + irte->lo.fields_remap.valid = 1; + } switch (info->type) { case X86_IRQ_ALLOC_TYPE_IOAPIC: @@ -4132,7 +4224,13 @@ static void irq_remapping_activate(struct irq_domain *domain, struct amd_ir_data *data = irq_data->chip_data; struct irq_2_irte *irte_info = &data->irq_2_irte; - modify_irte(irte_info->devid, irte_info->index, data->irte_entry); + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + data->irte_entry.fields.valid = 1; + modify_irte(irte_info->devid, irte_info->index, data->irte_entry); + } else { + data->irte_ga_entry.lo.fields_remap.valid = 1; + modify_irte_ga(irte_info->devid, irte_info->index, &data->irte_ga_entry); + } } static void irq_remapping_deactivate(struct irq_domain *domain, @@ -4140,10 +4238,14 @@ static void irq_remapping_deactivate(struct irq_domain *domain, { struct amd_ir_data *data = irq_data->chip_data; struct irq_2_irte *irte_info = &data->irq_2_irte; - union irte entry; - entry.val = 0; - modify_irte(irte_info->devid, irte_info->index, data->irte_entry); + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + data->irte_entry.fields.valid = 0; + modify_irte(irte_info->devid, irte_info->index, data->irte_entry); + } else { + data->irte_ga_entry.lo.fields_remap.valid = 0; + modify_irte_ga(irte_info->devid, irte_info->index, &data->irte_ga_entry); + } } static struct irq_domain_ops amd_ir_domain_ops = { @@ -4170,9 +4272,19 @@ static int amd_ir_set_affinity(struct irq_data *data, * Atomically updates the IRTE with the new destination, vector * and flushes the interrupt entry cache. */ - ir_data->irte_entry.fields.vector = cfg->vector; - ir_data->irte_entry.fields.destination = cfg->dest_apicid; - modify_irte(irte_info->devid, irte_info->index, ir_data->irte_entry); + if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) { + ir_data->irte_entry.fields.vector = cfg->vector; + ir_data->irte_entry.fields.destination = cfg->dest_apicid; + modify_irte(irte_info->devid, irte_info->index, + ir_data->irte_entry); + } else { + struct irte_ga *entry = &ir_data->irte_ga_entry; + + entry->hi.fields.vector = cfg->vector; + entry->lo.fields_remap.destination = cfg->dest_apicid; + entry->lo.fields_remap.guest_mode = 0; + modify_irte_ga(irte_info->devid, irte_info->index, entry); + } /* * After this point, all the interrupts will start arriving diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 5884a1e..f3f8baa 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -700,4 +700,68 @@ enum amd_iommu_intr_mode_type { x == AMD_IOMMU_GUEST_IR_LEGACY_GA) #define AMD_IOMMU_GUEST_IR_VAPIC(x) (x == AMD_IOMMU_GUEST_IR_VAPIC) + +union irte { + u32 val; + struct { + u32 valid : 1, + no_fault : 1, + int_type : 3, + rq_eoi : 1, + dm : 1, + rsvd_1 : 1, + destination : 8, + vector : 8, + rsvd_2 : 8; + } fields; +}; + +union irte_ga_lo { + u64 val; + + /* For int remapping */ + struct { + u64 valid : 1, + no_fault : 1, + /* ------ */ + int_type : 3, + rq_eoi : 1, + dm : 1, + /* ------ */ + guest_mode : 1, + destination : 8, + rsvd : 48; + } fields_remap; + + /* For guest vAPIC */ + struct { + u64 valid : 1, + no_fault : 1, + /* ------ */ + ga_log_intr : 1, + rsvd1 : 3, + is_run : 1, + /* ------ */ + guest_mode : 1, + destination : 8, + rsvd2 : 16, + ga_tag : 32; + } fields_vapic; +}; + +union irte_ga_hi { + u64 val; + struct { + u64 vector : 8, + rsvd_1 : 4, + ga_root_ptr : 40, + rsvd_2 : 12; + } fields; +}; + +struct irte_ga { + union irte_ga_lo lo; + union irte_ga_hi hi; +}; + #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */