Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

virt: vbox: Add vbg_set_host_capabilities() helper function

Add vbg_set_host_capabilities() helper function, this is a preparation
patch for adding support for the VBGL_IOCTL_GUEST_CAPS_ACQUIRE ioctl.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200709120858.63928-5-hdegoede@redhat.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Hans de Goede and committed by
Greg Kroah-Hartman
412f84cf fd01cc59

+46 -33
+46 -33
drivers/virt/vboxguest/vboxguest_core.c
··· 662 662 } 663 663 664 664 /** 665 + * Set guest capabilities on the host. 666 + * Must be called with gdev->session_mutex hold. 667 + * Return: 0 or negative errno value. 668 + * @gdev: The Guest extension device. 669 + * @session: The session. 670 + * @session_termination: Set if we're called by the session cleanup code. 671 + */ 672 + static int vbg_set_host_capabilities(struct vbg_dev *gdev, 673 + struct vbg_session *session, 674 + bool session_termination) 675 + { 676 + struct vmmdev_mask *req; 677 + u32 caps; 678 + int rc; 679 + 680 + WARN_ON(!mutex_is_locked(&gdev->session_mutex)); 681 + 682 + caps = gdev->set_guest_caps_tracker.mask; 683 + 684 + if (gdev->guest_caps_host == caps) 685 + return 0; 686 + 687 + /* On termination the requestor is the kernel, as we're cleaning up. */ 688 + req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES, 689 + session_termination ? VBG_KERNEL_REQUEST : 690 + session->requestor); 691 + if (!req) { 692 + gdev->guest_caps_host = U32_MAX; 693 + return -ENOMEM; 694 + } 695 + 696 + req->or_mask = caps; 697 + req->not_mask = ~caps; 698 + rc = vbg_req_perform(gdev, req); 699 + vbg_req_free(req, sizeof(*req)); 700 + 701 + gdev->guest_caps_host = (rc >= 0) ? caps : U32_MAX; 702 + 703 + return vbg_status_code_to_errno(rc); 704 + } 705 + 706 + /** 665 707 * Sets the guest capabilities for a session. Takes the session spinlock. 666 708 * Return: 0 or negative errno value. 667 709 * @gdev: The Guest extension device. ··· 720 678 u32 or_mask, u32 not_mask, 721 679 bool session_termination) 722 680 { 723 - struct vmmdev_mask *req; 724 681 u32 changed, previous; 725 - int rc, ret = 0; 726 - 727 - /* 728 - * Allocate a request buffer before taking the spinlock, when 729 - * the session is being terminated the requestor is the kernel, 730 - * as we're cleaning up. 731 - */ 732 - req = vbg_req_alloc(sizeof(*req), VMMDEVREQ_SET_GUEST_CAPABILITIES, 733 - session_termination ? VBG_KERNEL_REQUEST : 734 - session->requestor); 735 - if (!req) { 736 - if (!session_termination) 737 - return -ENOMEM; 738 - /* Ignore allocation failure, we must do session cleanup. */ 739 - } 682 + int ret = 0; 740 683 741 684 mutex_lock(&gdev->session_mutex); 742 685 ··· 736 709 goto out; 737 710 738 711 vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed, previous); 739 - or_mask = gdev->set_guest_caps_tracker.mask; 740 712 741 - if (gdev->guest_caps_host == or_mask || !req) 742 - goto out; 743 - 744 - gdev->guest_caps_host = or_mask; 745 - req->or_mask = or_mask; 746 - req->not_mask = ~or_mask; 747 - rc = vbg_req_perform(gdev, req); 748 - if (rc < 0) { 749 - ret = vbg_status_code_to_errno(rc); 750 - 751 - /* Failed, roll back (unless it's session termination time). */ 752 - gdev->guest_caps_host = U32_MAX; 753 - if (session_termination) 754 - goto out; 755 - 713 + ret = vbg_set_host_capabilities(gdev, session, session_termination); 714 + /* Roll back on failure, unless it's session termination time. */ 715 + if (ret < 0 && !session_termination) { 756 716 vbg_track_bit_usage(&gdev->set_guest_caps_tracker, changed, 757 717 session->set_guest_caps); 758 718 session->set_guest_caps = previous; ··· 747 733 748 734 out: 749 735 mutex_unlock(&gdev->session_mutex); 750 - vbg_req_free(req, sizeof(*req)); 751 736 752 737 return ret; 753 738 }