From patchwork Thu Apr 7 08:20:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Suthikulpanit, Suravee" X-Patchwork-Id: 65245 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp335627lbc; Thu, 7 Apr 2016 01:37:51 -0700 (PDT) X-Received: by 10.66.221.167 with SMTP id qf7mr3128056pac.94.1460018271745; Thu, 07 Apr 2016 01:37:51 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id hc2si10332269pac.65.2016.04.07.01.37.51; Thu, 07 Apr 2016 01:37:51 -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 S1755510AbcDGIhs (ORCPT + 29 others); Thu, 7 Apr 2016 04:37:48 -0400 Received: from mail-bn1bon0098.outbound.protection.outlook.com ([157.56.111.98]:11632 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751802AbcDGIhm (ORCPT ); Thu, 7 Apr 2016 04:37:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Gr+8Q05rvC1ifakMIcVwe1wcNiZuvOrNRlSXFAh149I=; b=xQZrnHc7WHCc39LRCw181cM8S32sG1Odk0A94sS/ijQFIKzYamVWf3AN+8TsF1cdQqJW5WK7zEOm1iHpWUrnRT+PMxF35/trkYgDBm+uXJCyqWn435cb/LYvbuwCbBTxKntBCcSRM25mxtHTULCc2nK4Kpnk8pgJgRuZ8GXSkSY= Authentication-Results: redhat.com; dkim=none (message not signed) header.d=none; redhat.com; dmarc=none action=none header.from=amd.com; Received: from localhost.localdomain (124.121.8.20) by SN1PR12MB0445.namprd12.prod.outlook.com (10.162.105.139) with Microsoft SMTP Server (TLS) id 15.1.447.15; Thu, 7 Apr 2016 08:21:59 +0000 From: Suravee Suthikulpanit To: , , , , , CC: , , , , Suravee Suthikulpanit Subject: [PART1 RFC v4 08/11] svm: Add VMEXIT handlers for AVIC Date: Thu, 7 Apr 2016 03:20:29 -0500 Message-ID: <1460017232-17429-9-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1460017232-17429-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1460017232-17429-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 X-Originating-IP: [124.121.8.20] X-ClientProxiedBy: KL1PR02CA0009.apcprd02.prod.outlook.com (10.165.15.19) To SN1PR12MB0445.namprd12.prod.outlook.com (10.162.105.139) X-MS-Office365-Filtering-Correlation-Id: 985788f1-b6b1-43f3-1084-08d35ebdb2ee X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 2:dPU84jERL/l5JKjf1GtBve5nL7ZQZj4qeGmUY6relrWKNrQYD1ESt7rrUYMow28wH3GNjwfVlyFfhfgoJeYS+uHrcx6EYqpwSpuVzrT6wPOupX1gb5wO0EZwWi8xTjK0V3r6rNDryqnz85S1CBrfP/ylTFzwn49k9c8c5MyFmGVUUai2cMd64ZmmVkrJNZgx; 3:ODxHd6lIzBI3tsYvkTyfHK0RhJgbWzfaZPNfiMeP3NlnMKTSDdQRep5oHA9+t5VvNtGD4wDwyQ1wIQ5wX6lN0A+LLsM7tU9r4NM4ar3zUrGg3bfndNOgDXS4SxEf5VVv; 25:WhRzNrOxg0i1IwrXDUnN1SCDon5ET0MNq3AzOZweaPkGDqAWvT+3zTDU1wqGFKIOFKhWWFK9z1hAnxMAazTIKE4jU4POLhuSK+i5YpUeNPTgMNN2maQvT+nVvyRPPWUD5QM2k0SxDjRMluxuNmEcPJ/ZOGb3G08vIB2K/6a3DA8ueuKsV5xUPTHeCAbBM9A46GYQwfIzSOAr+6fNkta0RH2WL3NGjguiMYTk3OQ75xMxliS5ptKOA2D6UoB1H27ZieCRmy+ciAsuqrT35/DvTQid79jTfzYwG9QNpYCx67DqzWTbeoMAszpK8vmHOEJ9cyK/VemU2131Rw50LllHuA== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0445; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 20:hA7z4GDFu8lZG5FZQhksNLfRKsH906dIEiCqk61m21eNOdqPlwAapfLEw5d5qkzuYXDIYfjA26CSLBjkCuB3W8D73sPx5TNhUUaDhgO568M/gPc45VCrteyij5O+1wUzVmjX26c+K8oBNxY8Sm1/g/HMnAcS3Az0CHTt2sYuZ0gE6RH9jWnC/uVAWCNP9oG0BPpENFzwRgV3fId97ChI65Dj2tQXOSTQR3GdG490fkQNA08yw2/WH/QaTIs+AZKPGOlqvsG8b1j1LrRYuqxXSTfkkwXiqW5zzx5F7JqnCHj6a2MO7MAKIyq91NQ/4sN/H2eyoAZmDzJpBz3HcLUlw4MFosbegADOWmY8Jh4YQK8SPjf0vKVwZWOXaes94nURTa8wtulclTowzgK1kmetU/HgFU/aQwsP2TwnhrQFXvrJvVo+YMemLtdVu6cqSbuRyFjrsMDn3aWhNq5bJKX3tXCEVh0eu9M39kK8b5kj4R2ncgvv2h779wHFpVHsNi/l; 4:KxY4QYXr5lN992hOurkMFPPehIwqAetKdDGQ4EHqaO2Ye8W4pM/GiVx7mpJ1bNo9NSfKrUSzoB+E7WybUT+6YuOD/kktWvJ2fGNp08zbXxgiKfErT8pJAZ38rbVEK6Rbd29kcL/jIUayngUtDHbV0Vp2Tqwx1CkSgkladQ4430X9pChnJfktpX2TxdSPqg4MihSDCdoT69GCPQg+WsOEGgrmlTfk/DIY6M8u0krJd29sYRAt3Oq1LnHNE8UFe/7eBXa9O97qh7oL7U4PWEh4txM4pSZOAtT55P2V1HskPlgwvP9pBr8UuTidhP9or3aCp3IOIfm/Me4WMz20mBV693lmoExHHyesKaIK4YJnbjTYGSbk5yJLrgtEFe3LFi1x X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001); SRVR:SN1PR12MB0445; BCL:0; PCL:0; RULEID:; SRVR:SN1PR12MB0445; X-Forefront-PRVS: 0905A6B2C7 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6069001)(6009001)(5001770100001)(50466002)(2906002)(48376002)(575784001)(50986999)(189998001)(77096005)(4326007)(2950100001)(36756003)(5003940100001)(92566002)(76176999)(47776003)(19580395003)(19580405001)(81166005)(2201001)(229853001)(50226001)(86362001)(42186005)(586003)(3846002)(5008740100001)(66066001)(1096002)(6116002); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR12MB0445; H:localhost.localdomain; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 23:/WVFOLlifa4AI7srV4jDLN1S+w277zUPi60dKJGGp8WJEY4B8l9Fa2yzUd6JSS1OEezfKELyUFZrSeRESo05lM4VVR9pfnHltK/j7PXYumOOXESG9jNNTEIOFvu/GblAZP2b+F3xFapI7FklwFJzx2dYHDQBJj0NlEdveVvTmnZtM+PF6T8Avn3vfkXodkXvGo79ysYWwq6PSUDcdoa9ZQ9zPUNu1/qFBqifRGfthCZIL3iNx9TaBDll9C5jhrYBKFesVqOqqKM7UVLu1xiqdzM+PdVPAHv2aeBUJDS7tcJUwWMJEO3fK1P0hmfYfAFdDJ3h8/NdjZdpfCq+fFP+TlW8WNBCS1KPUQk3xyKYsUzLh3ywIhpkFtoiQQN2BDkOLWEEPhzFvEDOU5YmFHX4Jdf8yDAqJBFSGMIiR8sYan2zqO+2GTpFDREZa4PjHOv+8tIK1IMGXt9Z2sJa94taFxLuvktmnuc05za4iaff8dlyITW9AGsszOfnciBBMnKoFsb+JtQ/s1Vy2QtTbOwcxHb5PwDu68/+nmPHzfTuvIBQfF2eqChNEMmRuWSHAqe+SWV7JdRLeCFJjJ5TZwmryRhixaccmzG5y/ho2nSh3LLwNd4b/D2jXMcjhavvWq032RyYzFQEDxYEuMpb0z0rInmZq0pdAmCWtFnMEYb/Q2X4VZDuldVXMD5kjR+RiVSKv/jMZEm2T1hE/y+vbqWgOh6ZB4jdVWICYywxh8UIqRWlqSwGixyahqU58nq0rH72YIB757+JyZISF0w/IigtyGQWsJGNz49tfNKmRlvRGBLNcwww1JPcNS1jy1omt6OhGWkJyym6fwKno5eJf1IG35ZQI1G5DcBSZvsSMrgSfP+snUMDypCVivRop7WzS4lT X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0445; 5:a+Q6xxlrly50Df9kaKFTk0I75t7PxsK9d73M2dpD6D+qI3mrArCZ0uJPx4OTngpjrGxgjWwIk51FQybI+Mxwu2RG8nXjAr0QCb2M/Y0LOe5MhkLHk8UkOS5nXn0OLw26odI3Kz1ZEDTVJevoQB5zKw==; 24:D96qJge/iCmDIjeRhSP9RL9lWqWSelM6ADJK0jymEY1azsDBLN/eXPHB1Bh4tmxjFjPX2Q4c5li0K9yyzBiVPVyJXBAcaBtUeHAigiuaXTo=; 20:8IuHyH1IhrQQqkMmy2ntoIY5zL0xnWmGVmPxzzbfuWRPXOGLIha274tCfilOHxZrews0LD7KtESdKgfgB2NOmgzyZAEQyXSZiSnpEgrWl2nl/oMyGv9BG4UfmoRwGdL72XRIhj6626TfeSj4+tvyNwGTMlbvLKJd8yH1srm3Y4hbJM6+IcnbChVBxOvh1U34YRyvswmnPaNqWCtMRMDDYqpZm9WBb4BfJaNJtMp6WyVn5A0QtC8kP4gsLNAeaNpT X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Apr 2016 08:21:59.9084 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0445 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Suravee Suthikulpanit This patch introduces VMEXIT handlers, avic_incomplete_ipi_interception() and avic_unaccelerated_access_interception() along with two trace points (trace_kvm_avic_incomplete_ipi and trace_kvm_avic_unaccelerated_access). Signed-off-by: Suravee Suthikulpanit --- arch/x86/include/uapi/asm/svm.h | 9 +- arch/x86/kvm/lapic.h | 3 + arch/x86/kvm/svm.c | 246 ++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/trace.h | 57 ++++++++++ arch/x86/kvm/x86.c | 2 + 5 files changed, 316 insertions(+), 1 deletion(-) -- 1.9.1 diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index 8a4add8..b9e9bb2 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -73,6 +73,8 @@ #define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_XSETBV 0x08d #define SVM_EXIT_NPF 0x400 +#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 +#define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 #define SVM_EXIT_ERR -1 @@ -107,8 +109,10 @@ { SVM_EXIT_SMI, "smi" }, \ { SVM_EXIT_INIT, "init" }, \ { SVM_EXIT_VINTR, "vintr" }, \ + { SVM_EXIT_CR0_SEL_WRITE, "cr0_sel_write" }, \ { SVM_EXIT_CPUID, "cpuid" }, \ { SVM_EXIT_INVD, "invd" }, \ + { SVM_EXIT_PAUSE, "pause" }, \ { SVM_EXIT_HLT, "hlt" }, \ { SVM_EXIT_INVLPG, "invlpg" }, \ { SVM_EXIT_INVLPGA, "invlpga" }, \ @@ -127,7 +131,10 @@ { SVM_EXIT_MONITOR, "monitor" }, \ { SVM_EXIT_MWAIT, "mwait" }, \ { SVM_EXIT_XSETBV, "xsetbv" }, \ - { SVM_EXIT_NPF, "npf" } + { SVM_EXIT_NPF, "npf" }, \ + { SVM_EXIT_RSM, "rsm" }, \ + { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, \ + { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" } #endif /* _UAPI__SVM_H */ diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index a70cb62..2fc86b7 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -9,6 +9,9 @@ #define KVM_APIC_SIPI 1 #define KVM_APIC_LVT_NUM 6 +#define KVM_APIC_SHORT_MASK 0xc0000 +#define KVM_APIC_DEST_MASK 0x800 + struct kvm_timer { struct hrtimer timer; s64 period; /* unit: ns */ diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f9547bc..13fba3b 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3515,6 +3515,250 @@ static int mwait_interception(struct vcpu_svm *svm) return nop_interception(svm); } +enum avic_ipi_failure_cause { + AVIC_IPI_FAILURE_INVALID_INT_TYPE, + AVIC_IPI_FAILURE_TARGET_NOT_RUNNING, + AVIC_IPI_FAILURE_INVALID_TARGET, + AVIC_IPI_FAILURE_INVALID_BACKING_PAGE, +}; + +static int avic_incomplete_ipi_interception(struct vcpu_svm *svm) +{ + u32 icrh = svm->vmcb->control.exit_info_1 >> 32; + u32 icrl = svm->vmcb->control.exit_info_1; + u32 id = svm->vmcb->control.exit_info_2 >> 32; + u32 index = svm->vmcb->control.exit_info_2 && 0xFF; + struct kvm_lapic *apic = svm->vcpu.arch.apic; + + trace_kvm_avic_incomplete_ipi(svm->vcpu.vcpu_id, icrh, icrl, id, index); + + switch (id) { + case AVIC_IPI_FAILURE_INVALID_INT_TYPE: + /* + * AVIC hardware handles the generation of + * IPIs when the specified Message Type is Fixed + * (also known as fixed delivery mode) and + * the Trigger Mode is edge-triggered. The hardware + * also supports self and broadcast delivery modes + * specified via the Destination Shorthand(DSH) + * field of the ICRL. Logical and physical APIC ID + * formats are supported. All other IPI types cause + * a #VMEXIT, which needs to emulated. + */ + kvm_lapic_reg_write(apic, APIC_ICR2, icrh); + kvm_lapic_reg_write(apic, APIC_ICR, icrl); + break; + case AVIC_IPI_FAILURE_TARGET_NOT_RUNNING: { + int i; + struct kvm_vcpu *vcpu; + struct kvm *kvm = svm->vcpu.kvm; + struct kvm_lapic *apic = svm->vcpu.arch.apic; + + /* + * At this point, we expect that the AVIC HW has already + * set the appropriate IRR bits on the valid target + * vcpus. So, we just need to kick the appropriate vcpu. + */ + kvm_for_each_vcpu(i, vcpu, kvm) { + bool m = kvm_apic_match_dest(vcpu, apic, + icrl & KVM_APIC_SHORT_MASK, + GET_APIC_DEST_FIELD(icrh), + icrl & KVM_APIC_DEST_MASK); + + if (m && !avic_vcpu_is_running(vcpu)) + kvm_vcpu_wake_up(vcpu); + } + break; + } + case AVIC_IPI_FAILURE_INVALID_TARGET: + break; + case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE: + WARN_ONCE(1, "Invalid backing page\n"); + break; + default: + pr_err("Unknown IPI interception\n"); + } + + return 1; +} + +static u32 *avic_get_logical_id_entry(struct kvm_vcpu *vcpu, u8 mda, bool flat) +{ + struct kvm_arch *vm_data = &vcpu->kvm->arch; + int index; + u32 *logical_apic_id_table; + + if (flat) { /* flat */ + if (mda > 7) + return NULL; + index = mda; + } else { /* cluster */ + int apic_id = mda & 0xf; + int cluster_id = (mda & 0xf0) >> 8; + + if (apic_id > 4 || cluster_id >= 0xf) + return NULL; + index = (cluster_id << 2) + apic_id; + } + logical_apic_id_table = (u32 *) page_address(vm_data->avic_logical_id_table_page); + + return &logical_apic_id_table[index]; +} + +static int avic_handle_ldr_write(struct kvm_vcpu *vcpu, u8 g_physical_id, + u8 logical_id) +{ + u32 mod; + u32 *entry, new_entry; + struct vcpu_svm *svm = to_svm(vcpu); + + if (!svm) + return -EINVAL; + + mod = (kvm_apic_get_reg(svm->vcpu.arch.apic, APIC_DFR) >> 28) & 0xf; + entry = avic_get_logical_id_entry(vcpu, logical_id, (mod == 0xf)); + if (!entry) + return -EINVAL; + + new_entry = READ_ONCE(*entry); + new_entry &= ~AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK; + new_entry |= (g_physical_id & AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK); + new_entry |= AVIC_LOGICAL_ID_ENTRY_VALID_MASK; + WRITE_ONCE(*entry, new_entry); + + return 0; +} + +static int avic_unaccel_trap_write(struct vcpu_svm *svm) +{ + u32 offset = svm->vmcb->control.exit_info_1 & 0xFF0; + struct kvm_lapic *apic = svm->vcpu.arch.apic; + u32 reg = kvm_apic_get_reg(apic, offset); + + switch (offset) { + case APIC_ID: { + u32 aid = (reg >> 24) & 0xff; + u64 *o_ent = avic_get_physical_id_entry(&svm->vcpu, + svm->vcpu.vcpu_id); + u64 *n_ent = avic_get_physical_id_entry(&svm->vcpu, aid); + + if (!n_ent || !o_ent) + return 0; + + /* We need to move physical_id_entry to new offset */ + *n_ent = *o_ent; + *o_ent = 0ULL; + svm->avic_physical_id_cache = n_ent; + break; + } + case APIC_LDR: { + int ret, lid; + int dlid = (reg >> 24) & 0xff; + + if (!dlid) + return 0; + + lid = ffs(dlid) - 1; + ret = avic_handle_ldr_write(&svm->vcpu, svm->vcpu.vcpu_id, lid); + if (ret) + return 0; + + break; + } + case APIC_DFR: { + struct kvm_arch *vm_data = &svm->vcpu.kvm->arch; + u32 mod = (reg >> 28) & 0xf; + + /* + * We assume that all local APICs are using the same type. + * If this changes, we need to rebuild the AVIC logical + * APID id table with subsequent write to APIC_LDR. + */ + if (vm_data->ldr_mode != mod) { + clear_page(page_address(vm_data->avic_logical_id_table_page)); + vm_data->ldr_mode = mod; + } + break; + } + default: + break; + } + + kvm_lapic_reg_write(apic, offset, reg); + + return 1; +} + +static bool is_avic_unaccelerated_access_trap(u32 offset) +{ + bool ret = false; + + switch (offset) { + case APIC_ID: + case APIC_EOI: + case APIC_RRR: + case APIC_LDR: + case APIC_DFR: + case APIC_SPIV: + case APIC_ESR: + case APIC_ICR: + case APIC_LVTT: + case APIC_LVTTHMR: + case APIC_LVTPC: + case APIC_LVT0: + case APIC_LVT1: + case APIC_LVTERR: + case APIC_TMICT: + case APIC_TDCR: + ret = true; + break; + default: + break; + } + return ret; +} + +#define AVIC_UNACCEL_ACCESS_WRITE_MASK 1 +#define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0 +#define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF + +static int avic_unaccelerated_access_interception(struct vcpu_svm *svm) +{ + int ret = 0; + u32 offset = svm->vmcb->control.exit_info_1 & + AVIC_UNACCEL_ACCESS_OFFSET_MASK; + u32 vector = svm->vmcb->control.exit_info_2 & + AVIC_UNACCEL_ACCESS_VECTOR_MASK; + bool write = (svm->vmcb->control.exit_info_1 >> 32) & + AVIC_UNACCEL_ACCESS_WRITE_MASK; + bool trap = is_avic_unaccelerated_access_trap(offset); + + trace_kvm_avic_unaccelerated_access(svm->vcpu.vcpu_id, offset, + trap, write, vector); + + /** + * AVIC does not support x2APIC registers, and we only advertise + * xAPIC when enable AVIC. Therefore, access to these registers + * will not be supported. + */ + if (offset >= 0x400) { + WARN(1, "Unsupported APIC offset %#x\n", offset); + return ret; + } + + if (trap) { + /* Handling Trap */ + if (!write) /* Trap read should never happens */ + BUG(); + ret = avic_unaccel_trap_write(svm); + } else { + /* Handling Fault */ + ret = (emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE); + } + + return ret; +} + static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_READ_CR0] = cr_interception, [SVM_EXIT_READ_CR3] = cr_interception, @@ -3578,6 +3822,8 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_XSETBV] = xsetbv_interception, [SVM_EXIT_NPF] = pf_interception, [SVM_EXIT_RSM] = emulate_on_interception, + [SVM_EXIT_AVIC_INCOMPLETE_IPI] = avic_incomplete_ipi_interception, + [SVM_EXIT_AVIC_UNACCELERATED_ACCESS] = avic_unaccelerated_access_interception, }; static void dump_vmcb(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 2f1ea2f..39f264c 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -1292,6 +1292,63 @@ TRACE_EVENT(kvm_hv_stimer_cleanup, __entry->vcpu_id, __entry->timer_index) ); +/* + * Tracepoint for AMD AVIC + */ +TRACE_EVENT(kvm_avic_incomplete_ipi, + TP_PROTO(u32 vcpu, u32 icrh, u32 icrl, u32 id, u32 index), + TP_ARGS(vcpu, icrh, icrl, id, index), + + TP_STRUCT__entry( + __field(u32, vcpu) + __field(u32, icrh) + __field(u32, icrl) + __field(u32, id) + __field(u32, index) + ), + + TP_fast_assign( + __entry->vcpu = vcpu; + __entry->icrh = icrh; + __entry->icrl = icrl; + __entry->id = id; + __entry->index = index; + ), + + TP_printk("vcpu=%u, icrh:icrl=%#010x:%08x, id=%u, index=%u\n", + __entry->vcpu, __entry->icrh, __entry->icrl, + __entry->id, __entry->index) +); + +TRACE_EVENT(kvm_avic_unaccelerated_access, + TP_PROTO(u32 vcpu, u32 offset, bool ft, bool rw, u32 vec), + TP_ARGS(vcpu, offset, ft, rw, vec), + + TP_STRUCT__entry( + __field(u32, vcpu) + __field(u32, offset) + __field(bool, ft) + __field(bool, rw) + __field(u32, vec) + ), + + TP_fast_assign( + __entry->vcpu = vcpu; + __entry->offset = offset; + __entry->ft = ft; + __entry->rw = rw; + __entry->vec = vec; + ), + + TP_printk("vcpu=%u, offset=%#x(%s), %s, %s, vec=%#x\n", + __entry->vcpu, + __entry->offset, + __print_symbolic(__entry->offset, kvm_trace_symbol_apic), + __entry->ft ? "trap" : "fault", + __entry->rw ? "write" : "read", + __entry->vec) +); + #endif /* _TRACE_KVM_H */ #undef TRACE_INCLUDE_PATH diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d12583e..b0f211c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8437,3 +8437,5 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_write_tsc_offset); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ple_window); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pml_full); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pi_irte_update); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_unaccelerated_access); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_incomplete_ipi);