Re: [PATCH 3/3] KVM: selftests: Fix dirty bitmap offset calculation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Sep 15, 2021 at 2:30 PM David Matlack <dmatlack@xxxxxxxxxx> wrote:
>
> The calculation to get the per-slot dirty bitmap was incorrect leading
> to a buffer overrun. Fix it by dividing the number of pages by
> BITS_PER_LONG, since each element of the bitmap is a long and there is
> one bit per page.
>
> Fixes: 609e6202ea5f ("KVM: selftests: Support multiple slots in dirty_log_perf_test")
> Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>

I was a little confused initially because we're allocating only one
dirty bitmap in userspace even when we have multiple slots, but that's
not a problem.

Reviewed-by: Ben Gardon <bgardon@xxxxxxxxxx>


>
> ---
>  tools/testing/selftests/kvm/dirty_log_perf_test.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c
> index 5ad9f2bc7369..0dd4626571e9 100644
> --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c
> +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c
> @@ -118,6 +118,12 @@ static inline void disable_dirty_logging(struct kvm_vm *vm, int slots)
>         toggle_dirty_logging(vm, slots, false);
>  }
>
> +static unsigned long *get_slot_bitmap(unsigned long *bitmap, uint64_t page_offset)
> +{
> +       /* Guaranteed to be evenly divisible by the TEST_ASSERT in run_test. */
> +       return &bitmap[page_offset / BITS_PER_LONG];
> +}
> +
>  static void get_dirty_log(struct kvm_vm *vm, int slots, unsigned long *bitmap,
>                           uint64_t nr_pages)
>  {
> @@ -126,7 +132,8 @@ static void get_dirty_log(struct kvm_vm *vm, int slots, unsigned long *bitmap,
>
>         for (i = 0; i < slots; i++) {
>                 int slot = PERF_TEST_MEM_SLOT_INDEX + i;
> -               unsigned long *slot_bitmap = bitmap + i * slot_pages;
> +               uint64_t page_offset = slot_pages * i;
> +               unsigned long *slot_bitmap = get_slot_bitmap(bitmap, page_offset);
>
>                 kvm_vm_get_dirty_log(vm, slot, slot_bitmap);
>         }
> @@ -140,7 +147,8 @@ static void clear_dirty_log(struct kvm_vm *vm, int slots, unsigned long *bitmap,
>
>         for (i = 0; i < slots; i++) {
>                 int slot = PERF_TEST_MEM_SLOT_INDEX + i;
> -               unsigned long *slot_bitmap = bitmap + i * slot_pages;
> +               uint64_t page_offset = slot_pages * i;
> +               unsigned long *slot_bitmap = get_slot_bitmap(bitmap, page_offset);
>
>                 kvm_vm_clear_dirty_log(vm, slot, slot_bitmap, 0, slot_pages);
>         }
> @@ -172,6 +180,9 @@ static void run_test(enum vm_guest_mode mode, void *arg)
>         guest_num_pages = vm_adjust_num_guest_pages(mode, guest_num_pages);
>         host_num_pages = vm_num_host_pages(mode, guest_num_pages);
>         bmap = bitmap_alloc(host_num_pages);
> +       TEST_ASSERT((host_num_pages / p->slots) % BITS_PER_LONG == 0,
> +                   "The number of pages per slot must be divisible by %d.",
> +                   BITS_PER_LONG);
>
>         if (dirty_log_manual_caps) {
>                 cap.cap = KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2;
> --
> 2.33.0.309.g3052b89438-goog
>



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux