From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
To: <rkrcmar@redhat.com>, <joro@8bytes.org>, <pbonzini@redhat.com>,
<alex.williamson@redhat.com>
Cc: <kvm@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<sherry.hurwitz@amd.com>,
Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: [PART2 PATCH v5 10/12] svm: Introduces AVIC per-VM ID
Date: Mon, 25 Jul 2016 04:32:09 -0500 [thread overview]
Message-ID: <1469439131-11308-11-git-send-email-suravee.suthikulpanit@amd.com> (raw)
In-Reply-To: <1469439131-11308-1-git-send-email-suravee.suthikulpanit@amd.com>
From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Introduces per-VM AVIC ID and helper functions to manage the IDs.
Currently, the ID will be used to implement 32-bit AVIC IOMMU GA tag.
The ID is 24-bit one-based indexing value, and is managed via helper
functions to get the next ID, or to free an ID once a VM is destroyed.
There should be no ID conflict for any active VMs.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/svm.c | 78 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 69e62862..16b4d1d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -776,6 +776,7 @@ struct kvm_arch {
bool disabled_lapic_found;
/* Struct members for AVIC */
+ u32 avic_vm_id;
u32 ldr_mode;
struct page *avic_logical_id_table_page;
struct page *avic_physical_id_table_page;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 16ef31b..90dc0fb 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -96,6 +96,18 @@ MODULE_DEVICE_TABLE(x86cpu, svm_cpu_id);
#define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0
#define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF
+/* AVIC GATAG is encoded using VM and VCPU IDs */
+#define AVIC_VCPU_ID_BITS 8
+#define AVIC_VCPU_ID_MASK ((1 << AVIC_VCPU_ID_BITS) - 1)
+
+#define AVIC_VM_ID_BITS 24
+#define AVIC_VM_ID_MASK ((1 << AVIC_VM_ID_BITS) - 1)
+
+#define AVIC_GATAG(x, y) (((x & AVIC_VM_ID_MASK) << AVIC_VCPU_ID_BITS) | \
+ (y & AVIC_VCPU_ID_MASK))
+#define AVIC_GATAG_TO_VMID(x) ((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
+#define AVIC_GATAG_TO_VCPUID(x) (x & AVIC_VM_ID_BITS)
+
static bool erratum_383_found __read_mostly;
static const u32 host_save_user_msrs[] = {
@@ -242,6 +254,10 @@ static int avic;
module_param(avic, int, S_IRUGO);
#endif
+/* AVIC VM ID bit masks and lock */
+static unsigned long *avic_vm_id_bm;
+static DEFINE_SPINLOCK(avic_vm_id_lock);
+
static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
static void svm_flush_tlb(struct kvm_vcpu *vcpu);
static void svm_complete_interrupts(struct vcpu_svm *svm);
@@ -1280,10 +1296,61 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
return 0;
}
+static inline int avic_vm_id_init(void)
+{
+ if (avic_vm_id_bm)
+ return 0;
+
+ avic_vm_id_bm = kcalloc(BITS_TO_LONGS(AVIC_VM_ID_MASK),
+ sizeof(long), GFP_KERNEL);
+ if (!avic_vm_id_bm)
+ return -ENOMEM;
+ return 0;
+}
+
+static inline void avic_vm_id_deinit(void)
+{
+ if (!avic_vm_id_bm)
+ return;
+
+ kfree(avic_vm_id_bm);
+ avic_vm_id_bm = NULL;
+}
+
+static inline int avic_get_next_vm_id(void)
+{
+ int id;
+
+ spin_lock(&avic_vm_id_lock);
+
+ /* AVIC VM ID is one-based. */
+ id = find_next_zero_bit(avic_vm_id_bm, 1, 1);
+ if (id <= AVIC_VM_ID_MASK)
+ __set_bit(id, avic_vm_id_bm);
+ else
+ id = -EINVAL;
+
+ spin_unlock(&avic_vm_id_lock);
+ return id;
+}
+
+static inline int avic_free_vm_id(int id)
+{
+ if (id <= 0 || id > AVIC_VM_ID_MASK)
+ return -EINVAL;
+
+ spin_lock(&avic_vm_id_lock);
+ __clear_bit(id, avic_vm_id_bm);
+ spin_unlock(&avic_vm_id_lock);
+ return 0;
+}
+
static void avic_vm_destroy(struct kvm *kvm)
{
struct kvm_arch *vm_data = &kvm->arch;
+ avic_free_vm_id(vm_data->avic_vm_id);
+
if (vm_data->avic_logical_id_table_page)
__free_page(vm_data->avic_logical_id_table_page);
if (vm_data->avic_physical_id_table_page)
@@ -1300,6 +1367,10 @@ static int avic_vm_init(struct kvm *kvm)
if (!avic)
return 0;
+ vm_data->avic_vm_id = avic_get_next_vm_id();
+ if (vm_data->avic_vm_id < 0)
+ return vm_data->avic_vm_id;
+
/* Allocating physical APIC ID table (4KB) */
p_page = alloc_page(GFP_KERNEL);
if (!p_page)
@@ -5076,6 +5147,12 @@ static struct kvm_x86_ops svm_x86_ops = {
static int __init svm_init(void)
{
+ int ret;
+
+ ret = avic_vm_id_init();
+ if (ret)
+ return ret;
+
return kvm_init(&svm_x86_ops, sizeof(struct vcpu_svm),
__alignof__(struct vcpu_svm), THIS_MODULE);
}
@@ -5083,6 +5160,7 @@ static int __init svm_init(void)
static void __exit svm_exit(void)
{
kvm_exit();
+ avic_vm_id_deinit();
}
module_init(svm_init)
--
1.9.1
next prev parent reply other threads:[~2016-07-25 9:33 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-25 9:31 [PART2 PATCH v5 00/12] iommu/AMD: Introduce IOMMU AVIC support Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 01/12] iommu/amd: Detect and enable guest vAPIC support Suravee Suthikulpanit
2016-08-09 14:30 ` Joerg Roedel
2016-07-25 9:32 ` [PART2 PATCH v5 02/12] iommu/amd: Move and introduce new IRTE-related unions and structures Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 03/12] iommu/amd: Introduce interrupt remapping ops structure Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 04/12] iommu/amd: Add support for multiple IRTE formats Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 05/12] iommu/amd: Detect and initialize guest vAPIC log Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 06/12] iommu/amd: Adding GALOG interrupt handler Suravee Suthikulpanit
2016-08-09 14:43 ` Joerg Roedel
2016-08-16 2:43 ` Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 07/12] iommu/amd: Introduce amd_iommu_update_ga() Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 08/12] iommu/amd: Implements irq_set_vcpu_affinity() hook to setup vapic mode for pass-through devices Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 09/12] iommu/amd: Enable vAPIC interrupt remapping mode by default Suravee Suthikulpanit
2016-08-09 14:54 ` Joerg Roedel
2016-07-25 9:32 ` Suravee Suthikulpanit [this message]
2016-08-12 14:16 ` [PART2 PATCH v5 10/12] svm: Introduces AVIC per-VM ID Radim Krčmář
2016-08-18 12:24 ` Suravee Suthikulpanit
2016-07-25 9:32 ` [PART2 PATCH v5 11/12] svm: Introduce AMD IOMMU avic_ga_log_notifier Suravee Suthikulpanit
2016-08-12 14:27 ` Radim Krčmář
2016-07-25 9:32 ` [PART2 PATCH v5 12/12] svm: Implements update_pi_irte hook to setup posted interrupt Suravee Suthikulpanit
2016-08-13 12:03 ` Radim Krčmář
2016-08-16 15:19 ` Suravee Suthikulpanit
2016-08-16 16:33 ` Radim Krčmář
2016-08-18 15:43 ` Suravee Suthikulpanit
2016-08-08 14:42 ` [PART2 PATCH v5 00/12] iommu/AMD: Introduce IOMMU AVIC support Suravee Suthikulpanit
2016-08-09 14:58 ` Joerg Roedel
2016-08-12 4:11 ` Suravee Suthikulpanit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1469439131-11308-11-git-send-email-suravee.suthikulpanit@amd.com \
--to=suravee.suthikulpanit@amd.com \
--cc=alex.williamson@redhat.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=rkrcmar@redhat.com \
--cc=sherry.hurwitz@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).