| #include <stdio.h> |
| #include <pthread.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <arch/arch.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <dirent.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <ros/syscall.h> |
| #include <sys/mman.h> |
| |
| int *mmap_blob; |
| unsigned long long stack[1024]; |
| volatile int shared = 0; |
| int mcp = 1; |
| #define V(x, t) (*((volatile t*)(x))) |
| |
| static void *fail(void*arg) |
| { |
| |
| *mmap_blob = 1337; |
| if (mcp) |
| while (V(&shared, int) < 31) { |
| if (! (V(&shared, int) & 1)) |
| V(&shared, int) = V(&shared, int) + 1; |
| // cpu_relax(); |
| } |
| V(&shared, int) = 55; |
| |
| __asm__ __volatile__("vmcall\n"); |
| __asm__ __volatile__("mov $0xdeadbeef, %rbx; mov 5, %rax\n"); |
| } |
| |
| unsigned long long *p512, *p1, *p2m; |
| |
| void *talk_thread(void *arg) |
| { |
| printf("talk thread ..\n"); |
| for(; V(&shared, int) < 32; ){ |
| if (V(&shared, int) & 1) { |
| printf("shared %d\n", V(&shared, int) ); |
| V(&shared, int) = V(&shared, int) + 1; |
| } |
| cpu_relax(); |
| } |
| printf("All done, read %d\n", *mmap_blob); |
| return NULL; |
| } |
| |
| pthread_t *my_threads; |
| void **my_retvals; |
| int nr_threads = 2; |
| |
| int main(int argc, char **argv) |
| { |
| int nr_gpcs = 1; |
| int fd = open("#c/sysctl", O_RDWR), ret; |
| void * x; |
| static char cmd[512]; |
| if (fd < 0) { |
| perror("#c/sysctl"); |
| exit(1); |
| } |
| if (ros_syscall(SYS_setup_vmm, nr_gpcs, 0, 0, 0, 0, 0) != nr_gpcs) { |
| perror("Guest pcore setup failed"); |
| exit(1); |
| } |
| /* blob that is faulted in from the EPT first. we need this to be in low |
| * memory (not above the normal mmap_break), so the EPT can look it up. |
| * Note that we won't get 4096. The min is 1MB now, and ld is there. */ |
| mmap_blob = mmap((int*)4096, PGSIZE, PROT_READ | PROT_WRITE, |
| MAP_ANONYMOUS, -1, 0); |
| if (mmap_blob == MAP_FAILED) { |
| perror("Unable to mmap"); |
| exit(1); |
| } |
| |
| mcp = 1; //argc - 1; |
| if (mcp) { |
| my_threads = malloc(sizeof(pthread_t) * nr_threads); |
| my_retvals = malloc(sizeof(void*) * nr_threads); |
| if (!(my_retvals && my_threads)) |
| perror("Init threads/malloc"); |
| |
| pthread_can_vcore_request(FALSE); /* 2LS won't manage vcores */ |
| pthread_need_tls(FALSE); |
| pthread_lib_init(); /* gives us one vcore */ |
| vcore_request(nr_threads - 1); /* ghetto incremental interface */ |
| for (int i = 0; i < nr_threads; i++) { |
| x = __procinfo.vcoremap; |
| printf("%p\n", __procinfo.vcoremap); |
| printf("Vcore %d mapped to pcore %d\n", i, |
| __procinfo.vcoremap[i].pcoreid); |
| } |
| } |
| |
| if (mcp) { |
| if (pthread_create(&my_threads[0], NULL, &talk_thread, NULL)) |
| perror("pth_create failed"); |
| // if (pthread_create(&my_threads[1], NULL, &fail, NULL)) |
| // perror("pth_create failed"); |
| } |
| printf("threads started\n"); |
| |
| if (0) for (int i = 0; i < nr_threads-1; i++) { |
| int ret; |
| if (pthread_join(my_threads[i], &my_retvals[i])) |
| perror("pth_join failed"); |
| printf("%d %d\n", i, ret); |
| } |
| |
| |
| ret = syscall(33, 1); |
| if (ret < 0) { |
| perror("vm setup"); |
| exit(1); |
| } |
| ret = posix_memalign((void **)&p512, 4096, 3*4096); |
| if (ret) { |
| perror("ptp alloc"); |
| exit(1); |
| } |
| p1 = &p512[512]; |
| p2m = &p512[1024]; |
| p512[0] = (unsigned long long)p1 | 7; |
| p1[0] = /*0x87; */(unsigned long long)p2m | 7; |
| p2m[0] = 0x87; |
| p2m[1] = 0x200000 | 0x87; |
| p2m[2] = 0x400000 | 0x87; |
| p2m[3] = 0x600000 | 0x87; |
| |
| printf("p512 %p p512[0] is 0x%lx p1 %p p1[0] is 0x%x\n", p512, p512[0], p1, p1[0]); |
| sprintf(cmd, "V 0x%x 0x%x 0x%x", (unsigned long long)fail, (unsigned long long) &stack[1024], (unsigned long long) p512); |
| printf("Writing command :%s:\n", cmd); |
| ret = write(fd, cmd, strlen(cmd)); |
| if (ret != strlen(cmd)) { |
| perror(cmd); |
| } |
| printf("shared is %d, blob is %d\n", shared, *mmap_blob); |
| |
| return 0; |
| } |