Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update kvm.c #1131

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 52 additions & 31 deletions kernel/entry/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,68 @@
#include <linux/entry-kvm.h>
#include <linux/kvm_host.h>

/**
* xfer_to_guest_mode_work - Handle work for transitioning to guest mode
* @vcpu: Pointer to the virtual CPU structure
* @ti_work: Thread flags indicating the state of the vCPU
*
* This function processes various flags that indicate work to be done
* when transitioning a virtual CPU to guest mode. It handles signals,
* rescheduling, and architecture-specific work.
*
* Returns: 0 on success, or a negative error code on failure.
*/
static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
{
do {
int ret;
do {
int ret;

if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
kvm_handle_signal_exit(vcpu);
return -EINTR;
}
// Check for pending signals and handle them
if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
kvm_handle_signal_exit(vcpu);
return -EINTR; // Interrupted by a signal
}

if (ti_work & (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY))
schedule();
// Check if rescheduling is needed
if (ti_work & (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY))
schedule();

if (ti_work & _TIF_NOTIFY_RESUME)
resume_user_mode_work(NULL);
// Resume user mode work if notified
if (ti_work & _TIF_NOTIFY_RESUME)
resume_user_mode_work(NULL);

ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
if (ret)
return ret;
// Handle architecture-specific work
ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
if (ret)
return ret; // Return on error

ti_work = read_thread_flags();
} while (ti_work & XFER_TO_GUEST_MODE_WORK);
return 0;
// Read thread flags for the next iteration
ti_work = read_thread_flags();
} while (ti_work & XFER_TO_GUEST_MODE_WORK); // Continue if more work is pending

return 0; // Success
}

/**
* xfer_to_guest_mode_handle_work - Check and handle guest mode work
* @vcpu: Pointer to the virtual CPU structure
*
* This function checks if there is any work pending for the vCPU
* before invoking xfer_to_guest_mode_work. It ensures that the work
* is only processed if the relevant flags are set.
*
* Returns: 0 if no work is pending, or the result of
* xfer_to_guest_mode_work on success.
*/
int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
{
unsigned long ti_work;

/*
* This is invoked from the outer guest loop with interrupts and
* preemption enabled.
*
* KVM invokes xfer_to_guest_mode_work_pending() with interrupts
* disabled in the inner loop before going into guest mode. No need
* to disable interrupts here.
*/
ti_work = read_thread_flags();
if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
return 0;

return xfer_to_guest_mode_work(vcpu, ti_work);
unsigned long ti_work;

// Read thread flags to check for pending work
ti_work = read_thread_flags();
if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
return 0; // No work to do

return xfer_to_guest_mode_work(vcpu, ti_work); // Delegate to work function
}
EXPORT_SYMBOL_GPL(xfer_to_guest_mode_handle_work);