mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-12 11:54:04 -04:00
KVM: selftests: Add macros to read/write+sync to/from guest memory
Add SYNC_FROM_GUEST_AND_READ(vm, variable), to read a variable value from the guest. Add WRITE_AND_SYNC_TO_GUEST(vm, variable, value) to write a value to a guest variable. These macros improve the readability of code which reads and writes data between host and guest in tests. Use the new macro in existing tests that do back-to-back write+sync. No functional changes are intended. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: David Matlack <dmatlack@google.com> Co-developed-by: Josh Hilke <jrhilke@google.com> Signed-off-by: Josh Hilke <jrhilke@google.com> [sean: massage changelog] Link: https://patch.msgid.link/20260626213534.3866178-3-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
committed by
Sean Christopherson
parent
a262fc49e0
commit
ac050f2adc
@@ -708,8 +708,7 @@ static void run_test(enum vm_guest_mode mode, void *arg)
|
||||
|
||||
sync_global_to_guest(vm, iteration);
|
||||
|
||||
WRITE_ONCE(nr_writes, 0);
|
||||
sync_global_to_guest(vm, nr_writes);
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, nr_writes, 0);
|
||||
|
||||
dirty_ring_prev_iteration_last_page = dirty_ring_last_page;
|
||||
WRITE_ONCE(dirty_ring_vcpu_ring_full, false);
|
||||
@@ -775,16 +774,14 @@ static void run_test(enum vm_guest_mode mode, void *arg)
|
||||
* writing memory during verification, pages that this thread
|
||||
* sees as clean may be written with this iteration's value.
|
||||
*/
|
||||
WRITE_ONCE(vcpu_stop, true);
|
||||
sync_global_to_guest(vm, vcpu_stop);
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, vcpu_stop, true);
|
||||
sem_wait(&sem_vcpu_stop);
|
||||
|
||||
/*
|
||||
* Clear vcpu_stop after the vCPU thread has acknowledge the
|
||||
* stop request and is waiting, i.e. is definitely not running!
|
||||
*/
|
||||
WRITE_ONCE(vcpu_stop, false);
|
||||
sync_global_to_guest(vm, vcpu_stop);
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, vcpu_stop, false);
|
||||
|
||||
/*
|
||||
* Sync the number of writes performed before verification, the
|
||||
|
||||
@@ -1138,6 +1138,16 @@ vm_adjust_num_guest_pages(enum vm_guest_mode mode, unsigned int num_guest_pages)
|
||||
memcpy(&(g), _p, sizeof(g)); \
|
||||
})
|
||||
|
||||
#define SYNC_FROM_GUEST_AND_READ(_vm, _variable) ({ \
|
||||
sync_global_from_guest(_vm, _variable); \
|
||||
READ_ONCE(_variable); \
|
||||
})
|
||||
|
||||
#define WRITE_AND_SYNC_TO_GUEST(_vm, _variable, _value) do { \
|
||||
WRITE_ONCE(_variable, _value); \
|
||||
sync_global_to_guest(_vm, _variable); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Write a global value, but only in the VM's (guest's) domain. Primarily used
|
||||
* for "globals" that hold per-VM values (VMs always duplicate code and global
|
||||
|
||||
@@ -155,10 +155,8 @@ static void *vcpu_worker(void *data)
|
||||
"Expected EFAULT on write to RO memory, got r = %d, errno = %d", r, errno);
|
||||
|
||||
atomic_inc(&nr_ro_faults);
|
||||
if (atomic_read(&nr_ro_faults) == nr_vcpus) {
|
||||
WRITE_ONCE(all_vcpus_hit_ro_fault, true);
|
||||
sync_global_to_guest(vm, all_vcpus_hit_ro_fault);
|
||||
}
|
||||
if (atomic_read(&nr_ro_faults) == nr_vcpus)
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, all_vcpus_hit_ro_fault, true);
|
||||
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
/*
|
||||
@@ -383,8 +381,7 @@ int main(int argc, char *argv[])
|
||||
rendezvous_with_vcpus(&time_run2, "run 2");
|
||||
|
||||
mprotect(mem, slot_size, PROT_READ);
|
||||
mprotect_ro_done = true;
|
||||
sync_global_to_guest(vm, mprotect_ro_done);
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, mprotect_ro_done, true);
|
||||
|
||||
rendezvous_with_vcpus(&time_ro, "mprotect RO");
|
||||
mprotect(mem, slot_size, PROT_READ | PROT_WRITE);
|
||||
|
||||
@@ -70,8 +70,8 @@ static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
|
||||
static void steal_time_init(struct kvm_vcpu *vcpu, u32 i)
|
||||
{
|
||||
/* ST_GPA_BASE is identity mapped */
|
||||
st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
|
||||
sync_global_to_guest(vcpu->vm, st_gva[i]);
|
||||
WRITE_AND_SYNC_TO_GUEST(vcpu->vm, st_gva[i],
|
||||
(void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE));
|
||||
|
||||
vcpu_set_msr(vcpu, MSR_KVM_STEAL_TIME, (ulong)st_gva[i] | KVM_MSR_ENABLED);
|
||||
}
|
||||
@@ -187,8 +187,7 @@ static void steal_time_init(struct kvm_vcpu *vcpu, u32 i)
|
||||
};
|
||||
|
||||
/* ST_GPA_BASE is identity mapped */
|
||||
st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
|
||||
sync_global_to_guest(vm, st_gva[i]);
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, st_gva[i], (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE));
|
||||
|
||||
st_ipa = (ulong)st_gva[i];
|
||||
vcpu_ioctl(vcpu, KVM_SET_DEVICE_ATTR, &dev);
|
||||
@@ -310,10 +309,8 @@ static bool is_steal_time_supported(struct kvm_vcpu *vcpu)
|
||||
static void steal_time_init(struct kvm_vcpu *vcpu, u32 i)
|
||||
{
|
||||
/* ST_GPA_BASE is identity mapped */
|
||||
st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
|
||||
st_gpa[i] = addr_gva2gpa(vcpu->vm, (gva_t)st_gva[i]);
|
||||
sync_global_to_guest(vcpu->vm, st_gva[i]);
|
||||
sync_global_to_guest(vcpu->vm, st_gpa[i]);
|
||||
WRITE_AND_SYNC_TO_GUEST(vcpu->vm, st_gva[i], (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE));
|
||||
WRITE_AND_SYNC_TO_GUEST(vcpu->vm, st_gpa[i], addr_gva2gpa(vcpu->vm, (gva_t)st_gva[i]));
|
||||
}
|
||||
|
||||
static void steal_time_dump(struct kvm_vm *vm, u32 vcpu_idx)
|
||||
@@ -442,8 +439,7 @@ static void steal_time_init(struct kvm_vcpu *vcpu, u32 i)
|
||||
};
|
||||
|
||||
/* ST_GPA_BASE is identity mapped */
|
||||
st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
|
||||
sync_global_to_guest(vm, st_gva[i]);
|
||||
WRITE_AND_SYNC_TO_GUEST(vm, st_gva[i], (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE));
|
||||
|
||||
err = __vcpu_ioctl(vcpu, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
TEST_ASSERT(err == 0, "No PV stealtime Feature");
|
||||
@@ -549,8 +545,7 @@ int main(int ac, char **av)
|
||||
|
||||
/* Second VCPU run, expect guest stolen time to be <= run_delay */
|
||||
run_vcpu(vcpus[i]);
|
||||
sync_global_from_guest(vm, guest_stolen_time[i]);
|
||||
stolen_time = guest_stolen_time[i];
|
||||
stolen_time = SYNC_FROM_GUEST_AND_READ(vm, guest_stolen_time[i]);
|
||||
run_delay = get_run_delay();
|
||||
TEST_ASSERT(stolen_time <= run_delay,
|
||||
"Expected stolen time <= %ld, got %ld",
|
||||
@@ -570,8 +565,7 @@ int main(int ac, char **av)
|
||||
|
||||
/* Run VCPU again to confirm stolen time is consistent with run_delay */
|
||||
run_vcpu(vcpus[i]);
|
||||
sync_global_from_guest(vm, guest_stolen_time[i]);
|
||||
stolen_time = guest_stolen_time[i] - stolen_time;
|
||||
stolen_time = SYNC_FROM_GUEST_AND_READ(vm, guest_stolen_time[i]) - stolen_time;
|
||||
TEST_ASSERT(stolen_time >= run_delay,
|
||||
"Expected stolen time >= %ld, got %ld",
|
||||
run_delay, stolen_time);
|
||||
|
||||
Reference in New Issue
Block a user