forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KVM: riscv: selftests: Prove Zawrs support works
The proof is that the test will run much, much faster with the --zawrs command line option given than without. Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
- Loading branch information
1 parent
221e34b
commit 2e712b1
Showing
2 changed files
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <sched.h> | ||
#include <pthread.h> | ||
#include "kvm_util.h" | ||
#include "test_util.h" | ||
|
||
static uint32_t count; | ||
static bool use_zawrs; | ||
|
||
static void wrs_nto(void) | ||
{ | ||
if (!use_zawrs) | ||
return; | ||
|
||
asm volatile( | ||
".option push\n" | ||
".option norvc\n" | ||
".option norelax\n" | ||
".long 0x00d00073\n" | ||
".option pop\n" | ||
); | ||
} | ||
|
||
static void guest_code(void) | ||
{ | ||
uint32_t cpu = guest_get_vcpuid(); | ||
uint32_t tmp = 0; | ||
|
||
while (tmp < 4000) { | ||
tmp = READ_ONCE(count); | ||
if ((tmp & 1) == cpu) | ||
WRITE_ONCE(count, tmp + 1); | ||
wrs_nto(); | ||
} | ||
|
||
GUEST_DONE(); | ||
} | ||
|
||
static void *run_test(void *arg) | ||
{ | ||
struct kvm_vcpu *vcpu = arg; | ||
|
||
vcpu_run(vcpu); | ||
|
||
assert(vcpu->run->exit_reason == UCALL_EXIT_REASON); | ||
assert(get_ucall(vcpu, NULL) == UCALL_DONE); | ||
|
||
return NULL; | ||
} | ||
|
||
int main(int ac, char **av) | ||
{ | ||
struct kvm_vcpu *vcpus[2]; | ||
struct kvm_vm *vm; | ||
pthread_t threads[2]; | ||
pthread_attr_t attr; | ||
cpu_set_t cpuset; | ||
int i, ret; | ||
|
||
vm = vm_create_with_vcpus(2, guest_code, vcpus); | ||
|
||
if (ac > 1 && !strcmp(av[1], "--zawrs")) { | ||
use_zawrs = true; | ||
sync_global_to_guest(vm, use_zawrs); | ||
} | ||
|
||
/* Force both vcpus onto cpu0 */ | ||
CPU_ZERO(&cpuset); | ||
CPU_SET(0, &cpuset); | ||
pthread_attr_init(&attr); | ||
pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset); | ||
|
||
for (i = 0; i < 2; ++i) { | ||
ret = pthread_create(&threads[i], &attr, run_test, vcpus[i]); | ||
assert(ret == 0); | ||
} | ||
for (i = 0; i < 2; ++i) | ||
pthread_join(threads[i], NULL); | ||
|
||
kvm_vm_free(vm); | ||
return 0; | ||
} |