linux/drivers/virt/vboxguest/vboxguest_core.c

/* SPDX-License-Identifier: (GPL-2.0 OR CDDL-1.0) */
/*
 * vboxguest core guest-device handling code, VBoxGuest.cpp in upstream svn.
 *
 * Copyright (C) 2007-2016 Oracle Corporation
 */

#include <linux/device.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/vbox_err.h>
#include <linux/vbox_utils.h>
#include <linux/vmalloc.h>
#include "vboxguest_core.h"
#include "vboxguest_version.h"

/* Get the pointer to the first HGCM parameter. */
#define VBG_IOCTL_HGCM_CALL_PARMS(a)
/* Get the pointer to the first HGCM parameter in a 32-bit request. */
#define VBG_IOCTL_HGCM_CALL_PARMS32(a)

#define GUEST_MAPPINGS_TRIES

#define VBG_KERNEL_REQUEST

/**
 * vbg_guest_mappings_init - Reserves memory in which the VMM can
 *	relocate any guest mappings that are floating around.
 * @gdev:		The Guest extension device.
 *
 * This operation is a little bit tricky since the VMM might not accept
 * just any address because of address clashes between the three contexts
 * it operates in, so we try several times.
 *
 * Failure to reserve the guest mappings is ignored.
 */
static void vbg_guest_mappings_init(struct vbg_dev *gdev)
{}

/**
 * vbg_guest_mappings_exit - Undo what vbg_guest_mappings_init did.
 *
 * @gdev:		The Guest extension device.
 */
static void vbg_guest_mappings_exit(struct vbg_dev *gdev)
{}

/**
 * vbg_report_guest_info - Report the guest information to the host.
 * @gdev:		The Guest extension device.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_report_guest_info(struct vbg_dev *gdev)
{}

/**
 * vbg_report_driver_status - Report the guest driver status to the host.
 * @gdev:		The Guest extension device.
 * @active:		Flag whether the driver is now active or not.
 *
 * Return: 0 or negative errno value.
 */
static int vbg_report_driver_status(struct vbg_dev *gdev, bool active)
{}

/**
 * vbg_balloon_inflate - Inflate the balloon by one chunk. The caller
 * owns the balloon mutex.
 * @gdev:		The Guest extension device.
 * @chunk_idx:		Index of the chunk.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_balloon_inflate(struct vbg_dev *gdev, u32 chunk_idx)
{}

/**
 * vbg_balloon_deflate - Deflate the balloon by one chunk. The caller
 * owns the balloon mutex.
 * @gdev:		The Guest extension device.
 * @chunk_idx:		Index of the chunk.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_balloon_deflate(struct vbg_dev *gdev, u32 chunk_idx)
{}

/*
 * Respond to VMMDEV_EVENT_BALLOON_CHANGE_REQUEST events, query the size
 * the host wants the balloon to be and adjust accordingly.
 */
static void vbg_balloon_work(struct work_struct *work)
{}

/*
 * Callback for heartbeat timer.
 */
static void vbg_heartbeat_timer(struct timer_list *t)
{}

/**
 * vbg_heartbeat_host_config - Configure the host to check guest's heartbeat
 *	and get heartbeat interval from the host.
 * @gdev:		The Guest extension device.
 * @enabled:		Set true to enable guest heartbeat checks on host.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_heartbeat_host_config(struct vbg_dev *gdev, bool enabled)
{}

/**
 * vbg_heartbeat_init - Initializes the heartbeat timer. This feature
 * may be disabled by the host.
 * @gdev:		The Guest extension device.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_heartbeat_init(struct vbg_dev *gdev)
{}

/**
 * vbg_heartbeat_exit - Cleanup heartbeat code, stop HB timer and disable
 *	host heartbeat checking.
 * @gdev:		The Guest extension device.
 */
static void vbg_heartbeat_exit(struct vbg_dev *gdev)
{}

/**
 * vbg_track_bit_usage - Applies a change to the bit usage tracker.
 * @tracker:		The bit usage tracker.
 * @changed:		The bits to change.
 * @previous:		The previous value of the bits.
 *
 * Return: %true if the mask changed, %false if not.
 */
static bool vbg_track_bit_usage(struct vbg_bit_usage_tracker *tracker,
				u32 changed, u32 previous)
{}

/**
 * vbg_reset_host_event_filter - Init and termination worker for
 *	resetting the (host) event filter on the host
 * @gdev:		   The Guest extension device.
 * @fixed_events:	   Fixed events (init time).
 *
 * Return: %0 or negative errno value.
 */
static int vbg_reset_host_event_filter(struct vbg_dev *gdev,
				       u32 fixed_events)
{}

/**
 * vbg_set_session_event_filter - Changes the event filter mask for the
 *	given session.
 * @gdev:			The Guest extension device.
 * @session:			The session.
 * @or_mask:			The events to add.
 * @not_mask:			The events to remove.
 * @session_termination:	Set if we're called by the session cleanup code.
 *				This tweaks the error handling so we perform
 *				proper session cleanup even if the host
 *				misbehaves.
 *
 * This is called in response to VBG_IOCTL_CHANGE_FILTER_MASK as well as to
 * do session cleanup. Takes the session mutex.
 *
 * Return: 0 or negative errno value.
 */
static int vbg_set_session_event_filter(struct vbg_dev *gdev,
					struct vbg_session *session,
					u32 or_mask, u32 not_mask,
					bool session_termination)
{}

/**
 * vbg_reset_host_capabilities - Init and termination worker for set
 *	guest capabilities to zero on the host.
 * @gdev:		The Guest extension device.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_reset_host_capabilities(struct vbg_dev *gdev)
{}

/**
 * vbg_set_host_capabilities - Set guest capabilities on the host.
 * @gdev:			The Guest extension device.
 * @session:			The session.
 * @session_termination:	Set if we're called by the session cleanup code.
 *
 * Must be called with gdev->session_mutex hold.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_set_host_capabilities(struct vbg_dev *gdev,
				     struct vbg_session *session,
				     bool session_termination)
{}

/**
 * vbg_acquire_session_capabilities - Acquire (get exclusive access)
 *	guest capabilities for a session.
 * @gdev:			The Guest extension device.
 * @session:			The session.
 * @flags:			Flags (VBGL_IOC_AGC_FLAGS_XXX).
 * @or_mask:			The capabilities to add.
 * @not_mask:			The capabilities to remove.
 * @session_termination:	Set if we're called by the session cleanup code.
 *				This tweaks the error handling so we perform
 *				proper session cleanup even if the host
 *				misbehaves.
 *
 * Takes the session mutex.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_acquire_session_capabilities(struct vbg_dev *gdev,
					    struct vbg_session *session,
					    u32 or_mask, u32 not_mask,
					    u32 flags, bool session_termination)
{}

/**
 * vbg_set_session_capabilities - Sets the guest capabilities for a
 *	session. Takes the session mutex.
 * @gdev:			The Guest extension device.
 * @session:			The session.
 * @or_mask:			The capabilities to add.
 * @not_mask:			The capabilities to remove.
 * @session_termination:	Set if we're called by the session cleanup code.
 *				This tweaks the error handling so we perform
 *				proper session cleanup even if the host
 *				misbehaves.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_set_session_capabilities(struct vbg_dev *gdev,
					struct vbg_session *session,
					u32 or_mask, u32 not_mask,
					bool session_termination)
{}

/**
 * vbg_query_host_version - get the host feature mask and version information.
 * @gdev:		The Guest extension device.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_query_host_version(struct vbg_dev *gdev)
{}

/**
 * vbg_core_init - Initializes the VBoxGuest device extension when the
 *	device driver is loaded.
 * @gdev:		The Guest extension device.
 * @fixed_events:	Events that will be enabled upon init and no client
 *			will ever be allowed to mask.
 *
 * The native code locates the VMMDev on the PCI bus and retrieve
 * the MMIO and I/O port ranges, this function will take care of
 * mapping the MMIO memory (if present). Upon successful return
 * the native code should set up the interrupt handler.
 *
 * Return: %0 or negative errno value.
 */
int vbg_core_init(struct vbg_dev *gdev, u32 fixed_events)
{}

/**
 * vbg_core_exit - Call this on exit to clean-up vboxguest-core managed
 *	resources.
 * @gdev:		The Guest extension device.
 *
 * The native code should call this before the driver is loaded,
 * but don't call this on shutdown.
 */
void vbg_core_exit(struct vbg_dev *gdev)
{}

/**
 * vbg_core_open_session - Creates a VBoxGuest user session.
 * @gdev:		The Guest extension device.
 * @requestor:		VMMDEV_REQUESTOR_* flags
 *
 * vboxguest_linux.c calls this when userspace opens the char-device.
 *
 * Return: A pointer to the new session or an ERR_PTR on error.
 */
struct vbg_session *vbg_core_open_session(struct vbg_dev *gdev, u32 requestor)
{}

/**
 * vbg_core_close_session - Closes a VBoxGuest session.
 * @session:		The session to close (and free).
 */
void vbg_core_close_session(struct vbg_session *session)
{}

static int vbg_ioctl_chk(struct vbg_ioctl_hdr *hdr, size_t in_size,
			 size_t out_size)
{}

static int vbg_ioctl_driver_version_info(
	struct vbg_ioctl_driver_version_info *info)
{}

/* Must be called with the event_lock held */
static u32 vbg_get_allowed_event_mask_for_session(struct vbg_dev *gdev,
						  struct vbg_session *session)
{}

static bool vbg_wait_event_cond(struct vbg_dev *gdev,
				struct vbg_session *session,
				u32 event_mask)
{}

/* Must be called with the event_lock held */
static u32 vbg_consume_events_locked(struct vbg_dev *gdev,
				     struct vbg_session *session,
				     u32 event_mask)
{}

static int vbg_ioctl_wait_for_events(struct vbg_dev *gdev,
				     struct vbg_session *session,
				     struct vbg_ioctl_wait_for_events *wait)
{}

static int vbg_ioctl_interrupt_all_wait_events(struct vbg_dev *gdev,
					       struct vbg_session *session,
					       struct vbg_ioctl_hdr *hdr)
{}

/**
 * vbg_req_allowed - Checks if the VMM request is allowed in the
 *	context of the given session.
 * @gdev:		The Guest extension device.
 * @session:		The calling session.
 * @req:		The request.
 *
 * Return: %0 or negative errno value.
 */
static int vbg_req_allowed(struct vbg_dev *gdev, struct vbg_session *session,
			   const struct vmmdev_request_header *req)
{}

static int vbg_ioctl_vmmrequest(struct vbg_dev *gdev,
				struct vbg_session *session, void *data)
{}

static int vbg_ioctl_hgcm_connect(struct vbg_dev *gdev,
				  struct vbg_session *session,
				  struct vbg_ioctl_hgcm_connect *conn)
{}

static int vbg_ioctl_hgcm_disconnect(struct vbg_dev *gdev,
				     struct vbg_session *session,
				     struct vbg_ioctl_hgcm_disconnect *disconn)
{}

static bool vbg_param_valid(enum vmmdev_hgcm_function_parameter_type type)
{}

static int vbg_ioctl_hgcm_call(struct vbg_dev *gdev,
			       struct vbg_session *session, bool f32bit,
			       struct vbg_ioctl_hgcm_call *call)
{}

static int vbg_ioctl_log(struct vbg_ioctl_log *log)
{}

static int vbg_ioctl_change_filter_mask(struct vbg_dev *gdev,
					struct vbg_session *session,
					struct vbg_ioctl_change_filter *filter)
{}

static int vbg_ioctl_acquire_guest_capabilities(struct vbg_dev *gdev,
	     struct vbg_session *session,
	     struct vbg_ioctl_acquire_guest_caps *caps)
{}

static int vbg_ioctl_change_guest_capabilities(struct vbg_dev *gdev,
	     struct vbg_session *session, struct vbg_ioctl_set_guest_caps *caps)
{}

static int vbg_ioctl_check_balloon(struct vbg_dev *gdev,
				   struct vbg_ioctl_check_balloon *balloon_info)
{}

static int vbg_ioctl_write_core_dump(struct vbg_dev *gdev,
				     struct vbg_session *session,
				     struct vbg_ioctl_write_coredump *dump)
{}

/**
 * vbg_core_ioctl - Common IOCtl for user to kernel communication.
 * @session:	The client session.
 * @req:	The requested function.
 * @data:	The i/o data buffer, minimum size sizeof(struct vbg_ioctl_hdr).
 *
 * Return: %0 or negative errno value.
 */
int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
{}

/**
 * vbg_core_set_mouse_status - Report guest supported mouse-features to the host.
 *
 * @gdev:		The Guest extension device.
 * @features:		The set of features to report to the host.
 *
 * Return: %0 or negative errno value.
 */
int vbg_core_set_mouse_status(struct vbg_dev *gdev, u32 features)
{}

/* Core interrupt service routine. */
irqreturn_t vbg_core_isr(int irq, void *dev_id)
{}