forked from OpenCloudOS/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_misc.c
149 lines (138 loc) · 4.79 KB
/
test_misc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <stdio.h>
#include <stdlib.h>
#include <linux/kvm.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
typedef unsigned long uint64_t;
const unsigned char code[] = {
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
0x00, 0xd8, /* add %bl, %al */
0x04, '0', /* add $'0', %al */
0xee, /* out %al, (%dx) */
0xb0, '\n', /* mov $'\n', %al */
0xee, /* out %al, (%dx) */
0xf4, /* hlt */
};
struct kvm_userspace_memory_region region = {
.slot = 0,
.flags = 0,
.guest_phys_addr = 0x1000,
.memory_size = 0x1000,
};
struct kvm_regs regs = {
.rip = 0x1000,
.rax = 2,
.rbx = 2,
.rflags = 0x2,
};
void print_run(struct kvm_run *run)
{
printf(" exit_reason 0x%x,", run->exit_reason );
printf(" 0x%x,", run->request_interrupt_window );
printf(" 0x%x \n", run->if_flag );
}
void print_regs(struct kvm_regs * regs)
{
printf("rax = 0x%lx,", regs->rax);
printf("rbx = 0x%lx,", regs->rbx);
printf("rcx = 0x%lx,", regs->rcx);
printf("rdx = 0x%lx,", regs->rdx);
printf("rsi = 0x%lx,", regs->rsi);
printf("rdi = 0x%lx,", regs->rdi);
printf("rbp = 0x%lx,", regs->rbp);
printf("rsp = 0x%lx,", regs->rsp);
printf("rip = 0x%lx,", regs->rip);
printf("r8 = 0x%lx,", regs->r8);
printf("r9 = 0x%lx,", regs->r9);
printf("r10 = 0x%lx,", regs->r10);
printf("r11 = 0x%lx,", regs->r11);
printf("r12 = 0x%lx,", regs->r12);
printf("r13 = 0x%lx,", regs->r13);
printf("r14 = 0x%lx,", regs->r14);
printf("r15 = 0x%lx,", regs->r15);
printf("rflags = 0x%lx \n,", regs->rflags);
}
void main(void)
{
int fd, ret;
struct kvm_sregs sregs;
struct kvm_run * run;
unsigned long mem = 0;
char buf[4096];
fd = open("/dev/rust_kvm",O_RDWR);
if (fd < 0) {
printf(" open fd failed \n");
exit(1);
}
printf(" open success \n");
ret = ioctl(fd, KVM_CREATE_VM, 0);
if (ret < 0) {
printf(" ioctl failed \n");
exit(1);
}
mem = (unsigned long)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
memcpy((char *)mem, code, sizeof(code));
region.userspace_addr = (uint64_t)mem;
ret = ioctl(fd, KVM_SET_USER_MEMORY_REGION, ®ion);
if (ret < 0) {
printf(" ioctl set memory failed, ret=%d, errno=%d \n",ret, errno);
exit(1);
}
printf(" set mmeory success \n");
ret = ioctl(fd, KVM_CREATE_VCPU, 0);
if (ret < 0) {
printf(" ioctl vcpu failed \n");
exit(1);
}
run = (struct kvm_run *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
memset((char *)run, 0, 4096);
printf(" mmap success \n");
memset((char*)&sregs, 0, sizeof(sregs));
ioctl(fd, KVM_GET_SREGS, &sregs);
printf(" get_sregs success \n");
sregs.cs.base = 0;
sregs.cs.selector = 0;
ioctl(fd, KVM_SET_SREGS, &sregs);
ioctl(fd, KVM_SET_REGS, ®s);
ioctl(fd, KVM_GET_REGS, ®s);
print_regs(®s);
printf(" set regs success \n");
while (1) {
ioctl(fd, KVM_RUN, NULL);
switch (run->exit_reason) {
/* Handle exit */
case KVM_EXIT_HLT:
printf("KVM_EXIT_HLT \n");
return;
case KVM_EXIT_IO:
if (run->io.direction == KVM_EXIT_IO_OUT &&
run->io.size == 1 &&
run->io.port == 0x3f8 &&
run->io.count == 1)
printf("exit io:%c \n", (*(((char *)run) + run->io.data_offset)));
else
exit(1);
break;
case KVM_EXIT_FAIL_ENTRY:
printf(" fail entry\n");
return;
case KVM_EXIT_INTERNAL_ERROR:
printf(" internal error\n");
return;
default:
printf(" default:0x%x\n", run->exit_reason);
memset((char*)®s, 0, sizeof(regs));
ioctl(fd, KVM_GET_REGS, ®s);
print_regs(®s);
print_run(run);
return;
}
}
printf(" end \n");
}