vfio-helpers.c (71e3038c1500e2d6075b306f26d565f982287756) vfio-helpers.c (453095e98dc2cefba81dae800614f136f3c1c341)
1/*
2 * VFIO utility
3 *
4 * Copyright 2016 - 2018 Red Hat, Inc.
5 *
6 * Authors:
7 * Fam Zheng <famz@redhat.com>
8 *

--- 663 unchanged lines hidden (view full) ---

672 qemu_vfio_dump_mappings(s);
673 return false;
674 }
675 }
676 }
677 return true;
678}
679
1/*
2 * VFIO utility
3 *
4 * Copyright 2016 - 2018 Red Hat, Inc.
5 *
6 * Authors:
7 * Fam Zheng <famz@redhat.com>
8 *

--- 663 unchanged lines hidden (view full) ---

672 qemu_vfio_dump_mappings(s);
673 return false;
674 }
675 }
676 }
677 return true;
678}
679
680static int
681qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
680static bool qemu_vfio_find_fixed_iova(QEMUVFIOState *s, size_t size,
681 uint64_t *iova, Error **errp)
682{
683 int i;
684
685 for (i = 0; i < s->nb_iova_ranges; i++) {
686 if (s->usable_iova_ranges[i].end < s->low_water_mark) {
687 continue;
688 }
689 s->low_water_mark =
690 MAX(s->low_water_mark, s->usable_iova_ranges[i].start);
691
692 if (s->usable_iova_ranges[i].end - s->low_water_mark + 1 >= size ||
693 s->usable_iova_ranges[i].end - s->low_water_mark + 1 == 0) {
694 *iova = s->low_water_mark;
695 s->low_water_mark += size;
682{
683 int i;
684
685 for (i = 0; i < s->nb_iova_ranges; i++) {
686 if (s->usable_iova_ranges[i].end < s->low_water_mark) {
687 continue;
688 }
689 s->low_water_mark =
690 MAX(s->low_water_mark, s->usable_iova_ranges[i].start);
691
692 if (s->usable_iova_ranges[i].end - s->low_water_mark + 1 >= size ||
693 s->usable_iova_ranges[i].end - s->low_water_mark + 1 == 0) {
694 *iova = s->low_water_mark;
695 s->low_water_mark += size;
696 return 0;
696 return true;
697 }
698 }
697 }
698 }
699 return -ENOMEM;
699 error_setg(errp, "fixed iova range not found");
700
701 return false;
700}
701
702}
703
702static int
703qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size, uint64_t *iova)
704static bool qemu_vfio_find_temp_iova(QEMUVFIOState *s, size_t size,
705 uint64_t *iova, Error **errp)
704{
705 int i;
706
707 for (i = s->nb_iova_ranges - 1; i >= 0; i--) {
708 if (s->usable_iova_ranges[i].start > s->high_water_mark) {
709 continue;
710 }
711 s->high_water_mark =
712 MIN(s->high_water_mark, s->usable_iova_ranges[i].end + 1);
713
714 if (s->high_water_mark - s->usable_iova_ranges[i].start + 1 >= size ||
715 s->high_water_mark - s->usable_iova_ranges[i].start + 1 == 0) {
716 *iova = s->high_water_mark - size;
717 s->high_water_mark = *iova;
706{
707 int i;
708
709 for (i = s->nb_iova_ranges - 1; i >= 0; i--) {
710 if (s->usable_iova_ranges[i].start > s->high_water_mark) {
711 continue;
712 }
713 s->high_water_mark =
714 MIN(s->high_water_mark, s->usable_iova_ranges[i].end + 1);
715
716 if (s->high_water_mark - s->usable_iova_ranges[i].start + 1 >= size ||
717 s->high_water_mark - s->usable_iova_ranges[i].start + 1 == 0) {
718 *iova = s->high_water_mark - size;
719 s->high_water_mark = *iova;
718 return 0;
720 return true;
719 }
720 }
721 }
722 }
721 return -ENOMEM;
723 error_setg(errp, "temporary iova range not found");
724
725 return false;
722}
723
724/**
725 * qemu_vfio_water_mark_reached:
726 *
727 * Returns %true if high watermark has been reached, %false otherwise.
728 */
729static bool qemu_vfio_water_mark_reached(QEMUVFIOState *s, size_t size,

--- 27 unchanged lines hidden (view full) ---

757 if (mapping) {
758 iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host);
759 } else {
760 if (qemu_vfio_water_mark_reached(s, size, errp)) {
761 ret = -ENOMEM;
762 goto out;
763 }
764 if (!temporary) {
726}
727
728/**
729 * qemu_vfio_water_mark_reached:
730 *
731 * Returns %true if high watermark has been reached, %false otherwise.
732 */
733static bool qemu_vfio_water_mark_reached(QEMUVFIOState *s, size_t size,

--- 27 unchanged lines hidden (view full) ---

761 if (mapping) {
762 iova0 = mapping->iova + ((uint8_t *)host - (uint8_t *)mapping->host);
763 } else {
764 if (qemu_vfio_water_mark_reached(s, size, errp)) {
765 ret = -ENOMEM;
766 goto out;
767 }
768 if (!temporary) {
765 if (qemu_vfio_find_fixed_iova(s, size, &iova0)) {
769 if (!qemu_vfio_find_fixed_iova(s, size, &iova0, errp)) {
766 ret = -ENOMEM;
767 goto out;
768 }
769
770 mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0);
771 assert(qemu_vfio_verify_mappings(s));
772 ret = qemu_vfio_do_mapping(s, host, size, iova0);
773 if (ret) {
774 qemu_vfio_undo_mapping(s, mapping, NULL);
775 goto out;
776 }
777 qemu_vfio_dump_mappings(s);
778 } else {
770 ret = -ENOMEM;
771 goto out;
772 }
773
774 mapping = qemu_vfio_add_mapping(s, host, size, index + 1, iova0);
775 assert(qemu_vfio_verify_mappings(s));
776 ret = qemu_vfio_do_mapping(s, host, size, iova0);
777 if (ret) {
778 qemu_vfio_undo_mapping(s, mapping, NULL);
779 goto out;
780 }
781 qemu_vfio_dump_mappings(s);
782 } else {
779 if (qemu_vfio_find_temp_iova(s, size, &iova0)) {
783 if (!qemu_vfio_find_temp_iova(s, size, &iova0, errp)) {
780 ret = -ENOMEM;
781 goto out;
782 }
783 ret = qemu_vfio_do_mapping(s, host, size, iova0);
784 if (ret) {
785 goto out;
786 }
787 }

--- 73 unchanged lines hidden ---
784 ret = -ENOMEM;
785 goto out;
786 }
787 ret = qemu_vfio_do_mapping(s, host, size, iova0);
788 if (ret) {
789 goto out;
790 }
791 }

--- 73 unchanged lines hidden ---