From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: joro@8bytes.org, pbonzini@redhat.com, alex.williamson@redhat.com,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
sherry.hurwitz@amd.com
Subject: Re: [PART2 PATCH v5 10/12] svm: Introduces AVIC per-VM ID
Date: Fri, 12 Aug 2016 16:16:04 +0200 [thread overview]
Message-ID: <20160812141604.GC22322@potion> (raw)
In-Reply-To: <1469439131-11308-11-git-send-email-suravee.suthikulpanit@amd.com>
2016-07-25 04:32-0500, Suravee Suthikulpanit:
> 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>
> ---
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> @@ -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;
Please expand "bm" to "bitmap" to match KVM conventions.
> +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),
Allocation is off by one. avic_get_next_vm_id() uses
if (id <= AVIC_VM_ID_MASK)
__set_bit(id, avic_vm_id_bm);
and id=AVIC_VM_ID_MASK is stored in the AVIC_VM_ID_MASK+1 th bit.
> + 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. */
Why?
> + id = find_next_zero_bit(avic_vm_id_bm, 1, 1);
The second argument is size, so this should always return 1. :)
> + if (id <= AVIC_VM_ID_MASK)
> + __set_bit(id, avic_vm_id_bm);
> + else
> + id = -EINVAL;
It is not really a problem that can be handled with changing the values,
so a temporary error would be nicer ... ENOMEM could be confusing and
EAGAIN lead to a loop, but I still like them better.
> +
> + 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();
This is certainly useless when the CPU doesn't have AVIC, so we could
make it conditional.
I would prefer to make the bitmap allocated at module load, though:
static DECLARE_BITMAP(avic_vm_id_bm, AVIC_VM_ID_MASK + 1);
The size is 2 KiB with 24 bit AVIC_VM_ID_MASK, which is IMO much better
than having extra lines of code dealing with allocation and failures.
> + if (ret)
> + return ret;
> +
> return kvm_init(&svm_x86_ops, sizeof(struct vcpu_svm),
> __alignof__(struct vcpu_svm), THIS_MODULE);
> }
next prev parent reply other threads:[~2016-08-12 14:16 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 ` [PART2 PATCH v5 10/12] svm: Introduces AVIC per-VM ID Suravee Suthikulpanit
2016-08-12 14:16 ` Radim Krčmář [this message]
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=20160812141604.GC22322@potion \
--to=rkrcmar@redhat.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=sherry.hurwitz@amd.com \
--cc=suravee.suthikulpanit@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.