From patchwork Fri Sep 14 18:27:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brijesh Singh X-Patchwork-Id: 970025 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=amd.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=amdcloud.onmicrosoft.com header.i=@amdcloud.onmicrosoft.com header.b="VBeD5zxu"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42Bkgp3PqDz9sBJ for ; Sat, 15 Sep 2018 04:34:13 +1000 (AEST) Received: from localhost ([::1]:52896 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g0sux-0003zZ-Em for incoming@patchwork.ozlabs.org; Fri, 14 Sep 2018 14:34:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35638) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g0soY-0008P0-QQ for qemu-devel@nongnu.org; Fri, 14 Sep 2018 14:27:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g0soW-0003iS-06 for qemu-devel@nongnu.org; Fri, 14 Sep 2018 14:27:34 -0400 Received: from mail-eopbgr690086.outbound.protection.outlook.com ([40.107.69.86]:22784 helo=NAM04-CO1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g0soV-0003fI-OT for qemu-devel@nongnu.org; Fri, 14 Sep 2018 14:27:31 -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:X-MS-Exchange-SenderADCheck; bh=jcqhKYHTzXz8P1+bDLFY7eNhD5t8+xBKPT8S7d67RF4=; b=VBeD5zxuIlYwDEpUGkeymYHvPBgenFvo+oi6zdTR7R2h/TyLq99GIwx7YTSE7uPf2TT44JXY8k1CVKAlR1IOF7hhjQOhSIlpwNOzIeybDfNPrtGGMxFNPzxTdhYx1MtnkS9OtVFg1kg13dCqsnITIV2Kaba8LOp6CeYxIDaMOgw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; Received: from sbrijesh-desktop.amd.com (165.204.77.1) by DM6PR12MB2684.namprd12.prod.outlook.com (2603:10b6:5:4a::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1122.16; Fri, 14 Sep 2018 18:27:28 +0000 From: Brijesh Singh To: qemu-devel@nongnu.org Date: Fri, 14 Sep 2018 13:27:00 -0500 Message-Id: <1536949623-23564-6-git-send-email-brijesh.singh@amd.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1536949623-23564-1-git-send-email-brijesh.singh@amd.com> References: <1536949623-23564-1-git-send-email-brijesh.singh@amd.com> MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: BYAPR01CA0001.prod.exchangelabs.com (2603:10b6:a02:80::14) To DM6PR12MB2684.namprd12.prod.outlook.com (2603:10b6:5:4a::33) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: eeb691ff-703c-4e45-a6ab-08d61a6fbacd X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989137)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DM6PR12MB2684; X-Microsoft-Exchange-Diagnostics: 1; DM6PR12MB2684; 3:uONkOseDH/uUaYeHJEYwXYeYBWD+m9j2PZIyVt0yqGzFEXsR28d6br+kH81ctjiOX6tyllSMnLSs7Id0BgTC+XJkqtwHIflOZZr22pSsEy4xiHILzQLFlSXpDJjjz14lcUsGbLS57OppvP2Ysv4d7l7tceYBLraO0SHp/AYgVnTYkYqwIRtzNJqmcrC42Pnda3/YJ/CQG4QaOEFp8pddSogvIu39RZpLbu2HymqNcixreEO0N3Vt5Do2d4f1Zr56; 25:F/HZp0a0wqH0sLtPHQIm+GCYn6A7LcGwDY/UgOjgG0qZJkOm47LUplqIkjsr4vvOSQ2yVQ6P29Y98WVGYI0nwguEV+ZP0eVEFg6noFrg6JoOaBAjVVdo4u5paU1UUKLduNg+bA2u2p+TFv2adCDXX4Q7O+7VXkp+nFQ5djthCVaA6pyKEVnqbKtbMe78RrihPUdHUDwrhR9nlRi76kmd+hpUwRgB7UCjdB+xDJPUJfLb3jB4/sVx48QJoh11TeDTBB3DGQPFXDJqsJw1aBUfB6SOes5JICn4wNnIQq5Dd+OLlL/RjVlmg4xPhIsdUve7xicVaQQ8xwXdmQmKv+3pXQ==; 31:ccyEri8V51RN8KPYqIPd8p3HojKV1aakQsWXVNdDrnPjdqyMRiVCxzCzusTInpTNDNxK2lAK4R5cNG1+J2DVMuSOu45nrgoIhropmxMTDiivG8ECTqH6aXOznujpEi8mmY4HUsrI8o8J6yX0ZaRg+mGTT8rQ25lD6hLfqBs4CL1kOUy/deRe2qKgsq1J0FWMJ6ZMUydrQrIgrIpM40I8GpXh8LY72w0FFG6gJQPWH4o= X-MS-TrafficTypeDiagnostic: DM6PR12MB2684: X-Microsoft-Exchange-Diagnostics: 1; DM6PR12MB2684; 20:RmxhhFz3njgBMqwlzfPWu1F5XUs5bGLAMYCnHLJWj6xn79+JVjHvVjABb3JtESbALw037L3yxznqw2tTVBq/vOcdJa1Ft9MzDKx2a6zFjm9/yfjAFY41qRbudxBdYVNS6OqyWqBUJokCcNCUFaEyne+HgjHC6Ah+EvmuQEUGFNZ6Nh/ZomERbNW/1vBUOiFjr/KQcTY8+LgRYQ7qhcuvLmmsCV24YKJBlnjkVdDQWlhamB7XsEp0JFQ7nop6pn4AUdnN0dDfmUPR5FMdJnvckFZkXyYVQ3iRNgb2qh4MS8Vm0/FExSjZm3YdbYkKCNUjrWJq3SKtqYxmAneXFUGxwPbtza4bif6CagubdehYCX35yJcxnedeV+pnbFgF8WLkuTlKS+pXq8+mydfQEZX96CWeM/FxU5QTtatrhBHpubd86+4Cp0WqzIjTl6AQ/CjiG0poJYm4z9ShuLUmNZmukLMUdbryLfwF2z5SCM3DDQgkYCajzaanYkTGK41DXYJd; 4:Orm+OCW/BqwcljClmKLXIBm6F3pu5eW8MB3BHJipDt7VoLbDS3BvzIiH9YeabSp5tsDNfr1WPbe4aSdT3Yy4kLdKX36TxZ/S+r3Y5bLHu46kdnMd14tBWl+TuTLA3f0jgmk88cZf3+2QYqkBM7RsMLp1z8/RC7bflfG8xA5zxnPjMdoIrHo/QCguUTNgQmCeQ956vEpsEcLmWQEo1m+Ym5MA4ve4XYad/qy8OGbQjNQA4ZVPN7IdmyEynNn9zqEkCLUuacQ1KokgtkcNcAfKwykMQ5RS6j0RlVhQuA1JLy67Q+SYfUgLH0p8bD1HHW0skBPhUiUUbbUHnPZ5mR395SefSnVBnYhsN4aJPUZfiHk= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(85827821059158)(767451399110); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(823301075)(3002001)(10201501046)(3231311)(944501410)(52105095)(93006095)(93001095)(6055026)(149027)(150027)(6041310)(20161123562045)(20161123558120)(20161123564045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699050); SRVR:DM6PR12MB2684; BCL:0; PCL:0; RULEID:; SRVR:DM6PR12MB2684; X-Forefront-PRVS: 07954CC105 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(396003)(136003)(39860400002)(346002)(376002)(366004)(189003)(199004)(50466002)(66066001)(48376002)(2906002)(25786009)(446003)(16586007)(6486002)(76176011)(39060400002)(7736002)(68736007)(51416003)(7696005)(305945005)(316002)(6666003)(6916009)(47776003)(53936002)(52116002)(386003)(956004)(486006)(11346002)(5660300001)(54906003)(2616005)(8676002)(478600001)(36756003)(476003)(186003)(44832011)(105586002)(2361001)(3846002)(106356001)(26005)(81166006)(14444005)(81156014)(8936002)(2351001)(53416004)(16526019)(50226002)(4326008)(97736004)(6116002)(86362001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM6PR12MB2684; H:sbrijesh-desktop.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM6PR12MB2684; 23:qW6TvdJaVmOrHRLNg5NN2SiMbDYr31fvbA8+bU1tS?= JbFdTMfJf8MfbB1OAAWjJMubPFMDzpU6O6Ws8JqNyG8SinCwtp+eXfuJw/pp9hL6JHSPYc9/wGYIaX/eV0DxPPci2eu8Ni9uHbUwTOXSHAPgzD+d7kUNxDSdYj1OXzKWA/DV3S4cWhBIQ89gkA8BkFcqpH4iAH+O/BIpApstyVRdRMUhpe+UU51fRJqfzXVkDwHlZhLhmQYgrxg8tyYY9ahXcjP7PjF4lAe+pc0UYTM7DDvoKax9prr/QngHHSD7RqI/O0oKsurez7iz3MVpWvbIp/7fDlT/4iN8/XydQwiGWXlcXMHE8nDG2dpAulwYmIYSyi3nGg0AugErPmA6EBJ2QBxVLsVcNS7NWsbhogl8PbcVtoReIYiqG/KPuIX3i0TGBllpXBKQgn6kpMc2DY11q46nvPOkQy8SYqzWtie2bUQqChTsGP2xP1o/oSLWxkcTCMgZmX3PmoL7SbJgJjwsH4CkOsslOcMB79tVkZPXtqIdEqzn+/ixbqCnw2VlPI9Lyl4PZjVPJKE/KpwBLN8pIYTezXRNa2/boUmRTPpAo8jmceln9SX2eiPWQBkAUj6HyniCGkbF2d54dKr8FtFxPSpJWKeA1NMmmwmM2F1wO5+iacvwKWA5bcRGAMwcG5y7kO3OPGjVrWO/sRJnsiL4hiOPVHAPeGqzVXp4WuubX5YgWFpCm+a61njYiPLAba66B0veLeEYMM/ukg0yiem/SEqTmwzGyO7k4BcmZE4WMWviTMz7Y4UTgwUiU3kS3Wh9FyWmAVYUfbXD+K4dGuLATi+/P+chsBFaNyWTWdzVgmIxyqEB0VsUZZ4fe0tRu6LEM6nUgU71tXhEGc9+7bSzrJK1wPJjDH8rjTk+tzqYUVXt4T+lAFts38ajx7TNFTxMZARWwmhhSb9nFUQMYTORvKgJ1mbWur64+dGQW5ywY/AGEooTwKYlUjQNK/FkYk4GayxZClk19q64a6bUwDO0BmmK/PHelQay1Nglst1v+Dbi51FIiJCfAXj824eJdcsiZiX3wPOOA9Iz8SPbsr60aZs3fi5YqtSV6WRLzVgEeYNBoWkmy1qNTLK/lNEhbEVDGIM1oHlTvNKOdJwDJ7KNUSm+ifLOFbaW4aiLHRP19s2z/YQf1SIUX093Ft+oQGY5pAIxPZl11Cjn9cSRMFcL3flaiM60Kt+8xRCtRWP00STBQTSxkGZ1Xsgd1TLSZn48fZERCA9P1rQ56F+LUvXbMgPI6h8WFJjHb71+3ewDg== X-Microsoft-Antispam-Message-Info: PQigvpz/OhEqlpPf0qVeKm+6eegzAZ0WplqaBKlTxWDcvDyRcjyBO2wEOooKiAv3vX1jPBJbrkL5kGz5lFIaTCv7UU/E/J0XGLMoOs/kX4nU+InqtpUj+XTJ4PmAuS3AX1Xtkb1EuBY8RnGJ+73DR7TjmwDgGDXDDSKz+qnH5FM4Ihvny0DIhp1+PBnR6BlIa5QHUKJ8y98y4B2f3Q6TTNUg48xhSQqMHEOdeAWMWCv2wc0Z0ovSdLjvzQMsEBpD5k3GQ+c+Uq7as3ogzKTtvnyr7LO2nVn56fBGoluIkHYTn3D6HXxhCTPmTrBVYj0Ll+pM6lcC/shzx12O7jy/n1jGKV15GUghmdGHtJs4jm4= X-Microsoft-Exchange-Diagnostics: 1; DM6PR12MB2684; 6:d5AriHRU3FUmIuLueIX7Z0vPjwvtOKFZy86R6XffBG3HSOThyr3UBDvWGpJR2vPFcSKXOW73b9MzXlog15+lcSjXwLT0nX2IKpjLlbn7hqSAB4DZltV2ScHIDiAA9beCN2oybmrcR1JTLv7DmHOFNBBywu2oQrboz+pUeUm1TwwOgLzL65EB5RnlnYrGNI/w5JtTvoRwzL7oqFenUPJ3NhsLiidc4MDjTpmqCkmWtVaY0pRM4jamub8sxWup0GcNFGxzAmIP8AwU/diWNFxUqYZnuKfERXLbS3MMzagdFtOrxs8XlK/c3aSExL6qSOdChyZkY90XFAndav/52g591t9kVW0gXaRNdWtKUIavnOoojQJn2vsZt/gBC822LqFIbHtJtQKv/isHwloA8e8AsuzVN2qgPdHg/yjbhs+1MqzLrY7hRuIzAVJPWPlcaQmMAyEVkVQm3h2IFyqkJaS4aw==; 5:kJCdF7+rqj2UxkercBxjGmJuc55TpVFiusCrIhbBCS0jwEteaaSoKskNB0MMmy776LB78kupwfvCToWVB4KR5CFrF3fZVpKYamIRMteQfKREELbiFPpSr9xQNnL+uaX6wsjyzuHaa3XBMRdTIPyeGvY2Onc7R2Gz6Itr0hYdXiw=; 7:TypScEl/4mQQaRCWzDDZugjxLslxsA7Ow1J9uWXJHEix9wEuoSYmfvPOu+HoTXVsbh8seSanW8UreiXSYc1EEbWw5XbckY2zT3uUepOk5BC5h6teXzIf4HyFYW3rBwW1HA7dzvug4bqWVwOyis+jOu8KsG5m/vAf+0M5RhoTREFuNchwb4VUUf8TkPSAyEcDCb2V/vIlhbNsDzvO5MYeEOHKGECdf6deVxtZKjDh0URG032kHXmqJZqY537Qo3q3 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM6PR12MB2684; 20:P6xjzW1ZjkNtxopsvhWIWx9HFw65FM4qt6N17w3oTaeRHSKqNVw1pS6/JRhuCQSHARxen5RGtmjrjU+pVOjngvaxAxVQuSx/rCDlFHDgCUIfgG8V3KMluFNrzBFGX7DVx24wqhV3bxNWdYWRoQxnCuTfULgrWFOK9cYEnprHQz8/OZ7ieaoUVFEN233rEmobs1aOnZYb0RE7S0JzFYEkL4ESHANyoRAW/+kHGs6o/B+H+KGIdBGXMYSErcPeBcp0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Sep 2018 18:27:28.5096 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: eeb691ff-703c-4e45-a6ab-08d61a6fbacd X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB2684 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 40.107.69.86 Subject: [Qemu-devel] [PATCH v2 5/8] x86_iommu/amd: Add interrupt remap support when VAPIC is not enabled X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tom Lendacky , Brijesh Singh , Eduardo Habkost , "Michael S. Tsirkin" , Paolo Bonzini , Suravee Suthikulpanit , Richard Henderson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Emulate the interrupt remapping support when guest virtual APIC is not enabled. For more info Refer: AMD IOMMU spec Rev 3.0 - section 2.2.5.1 When VAPIC is not enabled, it uses interrupt remapping as defined in Table 20 and Figure 15 from IOMMU spec. Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Signed-off-by: Brijesh Singh --- hw/i386/amd_iommu.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++- hw/i386/amd_iommu.h | 46 ++++++++++++- hw/i386/trace-events | 7 ++ 3 files changed, 240 insertions(+), 2 deletions(-) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index b15962b..9c8e4de 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -28,6 +28,8 @@ #include "qemu/error-report.h" #include "hw/i386/apic_internal.h" #include "trace.h" +#include "cpu.h" +#include "hw/i386/apic-msidef.h" /* used AMD-Vi MMIO registers */ const char *amdvi_mmio_low[] = { @@ -1029,17 +1031,144 @@ static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr, return ret; } +static int amdvi_get_irte(AMDVIState *s, MSIMessage *origin, uint64_t *dte, + union irte *irte, uint16_t devid) +{ + uint64_t irte_root, offset; + + irte_root = dte[2] & AMDVI_IR_PHYS_ADDR_MASK; + offset = (origin->data & AMDVI_IRTE_OFFSET) << 2; + + trace_amdvi_ir_irte(irte_root, offset); + + if (dma_memory_read(&address_space_memory, irte_root + offset, + irte, sizeof(*irte))) { + trace_amdvi_ir_err("failed to get irte"); + return -AMDVI_IR_GET_IRTE; + } + + trace_amdvi_ir_irte_val(irte->val); + + return 0; +} + +static int amdvi_int_remap_legacy(AMDVIState *iommu, + MSIMessage *origin, + MSIMessage *translated, + uint64_t *dte, + X86IOMMUIrq *irq, + uint16_t sid) +{ + int ret; + union irte irte; + + /* get interrupt remapping table */ + ret = amdvi_get_irte(iommu, origin, dte, &irte, sid); + if (ret < 0) { + return ret; + } + + if (!irte.fields.valid) { + trace_amdvi_ir_target_abort("RemapEn is disabled"); + return -AMDVI_IR_TARGET_ABORT; + } + + if (irte.fields.guest_mode) { + trace_amdvi_ir_target_abort("guest mode is not zero"); + return -AMDVI_IR_TARGET_ABORT; + } + + if (irte.fields.int_type > AMDVI_IOAPIC_INT_TYPE_ARBITRATED) { + trace_amdvi_ir_target_abort("reserved int_type"); + return -AMDVI_IR_TARGET_ABORT; + } + + irq->delivery_mode = irte.fields.int_type; + irq->vector = irte.fields.vector; + irq->dest_mode = irte.fields.dm; + irq->redir_hint = irte.fields.rq_eoi; + irq->dest = irte.fields.destination; + + return 0; +} + +static int __amdvi_int_remap_msi(AMDVIState *iommu, + MSIMessage *origin, + MSIMessage *translated, + uint64_t *dte, + X86IOMMUIrq *irq, + uint16_t sid) +{ + uint8_t int_ctl; + + int_ctl = (dte[2] >> AMDVI_IR_INTCTL_SHIFT) & 3; + trace_amdvi_ir_intctl(int_ctl); + + switch (int_ctl) { + case AMDVI_IR_INTCTL_PASS: + memcpy(translated, origin, sizeof(*origin)); + return 0; + case AMDVI_IR_INTCTL_REMAP: + break; + case AMDVI_IR_INTCTL_ABORT: + trace_amdvi_ir_target_abort("int_ctl abort"); + return -AMDVI_IR_TARGET_ABORT; + default: + trace_amdvi_ir_target_abort("int_ctl reserved"); + return -AMDVI_IR_TARGET_ABORT; + } + + return amdvi_int_remap_legacy(iommu, origin, translated, dte, irq, sid); +} + +static bool amdvi_validate_int_reamp(AMDVIState *s, uint64_t *dte) +{ + /* Check if IR is enabled in DTE */ + if (!(dte[2] & AMDVI_IR_REMAP_ENABLE)) { + return false; + } + + /* validate that we are configure with intremap=on */ + if (!s->intr_enabled) { + error_report("Interrupt remapping is enabled in the guest but " + "not in the host. Use intremap=on to enable interrupt " + "remapping in amd-iommu."); + exit(1); + } + + return true; +} + /* Interrupt remapping for MSI/MSI-X entry */ static int amdvi_int_remap_msi(AMDVIState *iommu, MSIMessage *origin, MSIMessage *translated, uint16_t sid) { + int ret = 0; + uint64_t pass = 0; + uint64_t dte[4] = { 0 }; + X86IOMMUIrq irq = { 0 }; + uint8_t dest_mode, delivery_mode; + assert(origin && translated); + /* + * When IOMMU is enabled, interrupt remap request will come either from + * IO-APIC or PCI device. If interrupt is from PCI device then it will + * have a valid requester id but if the interrupt is from IO-APIC + * then requester id will be invalid. + */ + if (sid == X86_IOMMU_SID_INVALID) { + sid = AMDVI_IOAPIC_SB_DEVID; + } + trace_amdvi_ir_remap_msi_req(origin->address, origin->data, sid); - if (!iommu || !iommu->intr_enabled) { + /* verify that interrupt remapping is enabled before going further. */ + if (!iommu || + !amdvi_get_dte(iommu, sid, dte) || + !amdvi_validate_int_reamp(iommu, dte)) { memcpy(translated, origin, sizeof(*origin)); goto out; } @@ -1055,10 +1184,68 @@ static int amdvi_int_remap_msi(AMDVIState *iommu, return -AMDVI_IR_ERR; } + delivery_mode = (origin->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 7; + + switch (delivery_mode) { + case AMDVI_IOAPIC_INT_TYPE_FIXED: + case AMDVI_IOAPIC_INT_TYPE_ARBITRATED: + trace_amdvi_ir_delivery_mode("fixed/arbitrated"); + ret = __amdvi_int_remap_msi(iommu, origin, translated, dte, &irq, sid); + if (ret < 0) { + goto remap_fail; + } else { + /* Translate IRQ to MSI messages */ + x86_iommu_irq_to_msi_message(&irq, translated); + goto out; + } + break; + case AMDVI_IOAPIC_INT_TYPE_SMI: + error_report("SMI is not supported!"); + ret = -AMDVI_IR_ERR; + case AMDVI_IOAPIC_INT_TYPE_NMI: + pass = dte[3] & AMDVI_DEV_NMI_PASS_MASK; + trace_amdvi_ir_delivery_mode("nmi"); + break; + case AMDVI_IOAPIC_INT_TYPE_INIT: + pass = dte[3] & AMDVI_DEV_INT_PASS_MASK; + trace_amdvi_ir_delivery_mode("init"); + break; + case AMDVI_IOAPIC_INT_TYPE_EINT: + pass = dte[3] & AMDVI_DEV_EINT_PASS_MASK; + trace_amdvi_ir_delivery_mode("eint"); + break; + default: + trace_amdvi_ir_delivery_mode("unsupported delivery_mode"); + ret = -AMDVI_IR_ERR; + break; + } + + if (ret < 0) { + goto remap_fail; + } + + /* dest_mode 1 is valid for fixed and arbitrated interrupts only */ + dest_mode = (origin->address >> MSI_ADDR_DEST_MODE_SHIFT) & 1; + if (dest_mode) { + trace_amdvi_ir_err("invalid dest_mode"); + goto remap_fail; + } + + if (pass) { + memcpy(translated, origin, sizeof(*origin)); + } else { + /* pass through is not enabled */ + trace_amdvi_ir_err("passthrough is not enabled"); + goto remap_fail; + } + out: trace_amdvi_ir_remap_msi(origin->address, origin->data, translated->address, translated->data); return 0; + +remap_fail: + return -AMDVI_IR_TARGET_ABORT; } static int amdvi_int_remap(X86IOMMUState *iommu, diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index 71ff3c1..bd27cd2 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -217,7 +217,51 @@ /* Interrupt remapping errors */ #define AMDVI_IR_ERR 0x1 - +#define AMDVI_IR_GET_IRTE 0x2 +#define AMDVI_IR_TARGET_ABORT 0x3 + +/* Interrupt remapping */ +#define AMDVI_IR_REMAP_ENABLE 1ULL +#define AMDVI_IR_INTCTL_SHIFT 60 +#define AMDVI_IR_INTCTL_ABORT 0 +#define AMDVI_IR_INTCTL_PASS 1 +#define AMDVI_IR_INTCTL_REMAP 2 + +#define AMDVI_IR_PHYS_ADDR_MASK (((1ULL << 45) - 1) << 6) + +/* MSI data 10:0 bits (section 2.2.5.1 Fig 14) */ +#define AMDVI_IRTE_OFFSET 0x7ff + +/* Delivery mode of MSI data (same as IOAPIC deilver mode encoding) */ +#define AMDVI_IOAPIC_INT_TYPE_FIXED 0x0 +#define AMDVI_IOAPIC_INT_TYPE_ARBITRATED 0x1 +#define AMDVI_IOAPIC_INT_TYPE_SMI 0x2 +#define AMDVI_IOAPIC_INT_TYPE_NMI 0x4 +#define AMDVI_IOAPIC_INT_TYPE_INIT 0x5 +#define AMDVI_IOAPIC_INT_TYPE_EINT 0x7 + +/* Pass through interrupt */ +#define AMDVI_DEV_INT_PASS_MASK (1UL << 56) +#define AMDVI_DEV_EINT_PASS_MASK (1UL << 57) +#define AMDVI_DEV_NMI_PASS_MASK (1UL << 58) +#define AMDVI_DEV_LINT0_PASS_MASK (1UL << 62) +#define AMDVI_DEV_LINT1_PASS_MASK (1UL << 63) + +/* Interrupt remapping table fields (Guest VAPIC not enabled) */ +union irte { + uint32_t val; + struct { + uint32_t valid:1, + no_fault:1, + int_type:3, + rq_eoi:1, + dm:1, + guest_mode:1, + destination:8, + vector:8, + rsvd:8; + } fields; +}; #define TYPE_AMD_IOMMU_DEVICE "amd-iommu" #define AMD_IOMMU_DEVICE(obj)\ diff --git a/hw/i386/trace-events b/hw/i386/trace-events index 41d533c..98150c9 100644 --- a/hw/i386/trace-events +++ b/hw/i386/trace-events @@ -106,6 +106,13 @@ amdvi_mem_ir_write(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" data 0x%"PRIx6 amdvi_ir_remap_msi_req(uint64_t addr, uint64_t data, uint8_t devid) "addr 0x%"PRIx64" data 0x%"PRIx64" devid 0x%"PRIx8 amdvi_ir_remap_msi(uint64_t addr, uint64_t data, uint64_t addr2, uint64_t data2) "(addr 0x%"PRIx64", data 0x%"PRIx64") -> (addr 0x%"PRIx64", data 0x%"PRIx64")" amdvi_err(const char *str) "%s" +amdvi_ir_irte(uint64_t addr, uint64_t data) "addr 0x%"PRIx64" offset 0x%"PRIx64 +amdvi_ir_irte_val(uint32_t data) "data 0x%"PRIx32 +amdvi_ir_err(const char *str) "%s" +amdvi_ir_intctl(uint8_t val) "int_ctl 0x%"PRIx8 +amdvi_ir_target_abort(const char *str) "%s" +amdvi_ir_delivery_mode(const char *str) "%s" +amdvi_ir_generate_msi_message(uint8_t vector, uint8_t delivery_mode, uint8_t dest_mode, uint8_t dest, uint8_t rh) "vector %d delivery-mode %d dest-mode %d dest-id %d rh %d" # hw/i386/vmport.c vmport_register(unsigned char command, void *func, void *opaque) "command: 0x%02x func: %p opaque: %p"