On Fri, Dec 14, 2018 at 03:25:45PM +0100, Andrew Jones wrote: > > Hi Dave, > > The below looks like a nice kvm selftest. Care to fit it into that > framework (tools/testing/selftests/kvm/) and post it? Sure, it makes sense not to drop this on the floor. Do you feel the test needs to go in alongside the fix, or is it alright if I repost this later on? It will need a bit of cleanup, and I'm juggling other stuff too... Cheers ---Dave > > Thanks, > drew > > > [1] > > > > #include <assert.h> > > #include <errno.h> > > #include <limits.h> > > #include <stddef.h> > > #include <stdio.h> > > #include <stdlib.h> > > #include <stdint.h> > > #include <string.h> > > #include <fcntl.h> > > #include <sys/ioctl.h> > > #include <linux/kvm.h> > > > > #define KVM_PATH "/dev/kvm" > > > > #define ARRAY_SIZE(array) (sizeof (array) / sizeof *(array)) > > > > static int get_reg_list(int vcpu, struct kvm_reg_list **pregs, size_t *psize) > > { > > struct kvm_reg_list *regs = *pregs; > > size_t num_needed = 0; > > const size_t reg_offset = (char *)®s->reg - (char *)regs; > > > > while (1) { > > size_t size_needed = num_needed * sizeof regs->reg[0] > > + reg_offset; > > if (size_needed > *psize) { > > regs = realloc(regs, size_needed); > > if (!regs) > > goto nomem; > > > > *pregs = regs; > > *psize = size_needed; > > } > > > > regs->n = (*psize - reg_offset) / sizeof regs->reg[0]; > > if (!ioctl(vcpu, KVM_GET_REG_LIST, regs)) > > break; > > > > if (errno != E2BIG) { > > perror("KVM_GET_REG_LIST"); > > goto error; > > } > > > > num_needed = regs->n; > > } > > > > return 0; > > > > nomem: > > errno = ENOMEM; > > perror(NULL); > > error: > > return -1; > > } > > > > int main(void) > > { > > int fail = 0; > > int kvm_fd, vm, vcpu; > > struct kvm_vcpu_init init; > > size_t i; > > struct kvm_reg_list *regs = NULL; > > size_t regs_size = 0; > > uint64_t regdata[2]; > > struct kvm_one_reg reg; > > > > kvm_fd = open(KVM_PATH, O_RDWR); > > if (kvm_fd == -1) { > > perror(KVM_PATH); > > goto error; > > } > > > > vm = ioctl(kvm_fd, KVM_CREATE_VM, 0); > > if (vm == -1) { > > perror("KVM_CREATE_VM"); > > goto error; > > } > > > > if (ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init)) { > > perror("KVM_ARM_PREFERRED_TARGET"); > > goto error; > > } > > > > printf("KVM_ARM_PREFERRED_TARGET:\n" > > "\ttarget = %lu\n", > > (unsigned long)init.target); > > for (i = 0; i < ARRAY_SIZE(init.features); ++i) > > printf("\tfeatures[0] = 0x%.8lx\n", > > (unsigned long)init.features[i]); > > > > vcpu = ioctl(vm, KVM_CREATE_VCPU, 0); > > if (vcpu == -1) { > > perror("KVM_CREATE_VCPU"); > > goto error; > > } > > > > if (!get_reg_list(vcpu, ®s, ®s_size)) { > > fputs("Strange, KVM_GET_REG_LIST succeeded before KVM_VCPU_INIT!\n", > > stderr); > > > > goto error; > > } > > > > if (ioctl(vcpu, KVM_ARM_VCPU_INIT, &init)) { > > perror("KVM_ARM_VCPU_INIT"); > > goto error; > > } > > > > if (get_reg_list(vcpu, ®s, ®s_size)) > > goto error; > > > > assert(1 <= -1ULL >> 32); > > assert(ULONG_MAX >= (1ULL << 32) - 1); > > for (i = 0; i < regs->n; ++i) { > > size_t size; > > char const *s1 = "OK", *s2 = "", *s3 = "";; > > > > size = (size_t)1 << ((regs->reg[i] & KVM_REG_SIZE_MASK) >> > > KVM_REG_SIZE_SHIFT); > > if (size < 4 || size > 16) { > > s1 = "BADSIZE"; > > fail = 1; > > } else { > > memset(®, 0, sizeof reg); > > > > reg.id = regs->reg[i]; > > reg.addr = (__u64)®data; > > if (ioctl(vcpu, KVM_GET_ONE_REG, ®)) { > > s1 = "FAIL ("; > > s2 = strerror(errno); > > s3 = ")"; > > fail = 1; > > } > > } > > > > printf("\t0x%.16lx\t%s%s%s\n", > > (unsigned long)reg.id, s1, s2, s3); > > > > } > > > > if (ferror(stdout) || fflush(stdout)) > > goto stdout_error; > > > > if (fail) { > > puts("FAIL"); > > goto error; > > } > > > > if (puts("\nPASS") == EOF || fclose(stdout)) > > goto stdout_error; > > > > return EXIT_SUCCESS; > > > > stdout_error: > > fputs("I/O error", stderr); > > error: > > return EXIT_FAILURE; > > } > > _______________________________________________ > > kvmarm mailing list > > kvmarm@xxxxxxxxxxxxxxxxxxxxx > > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm > _______________________________________________ > kvmarm mailing list > kvmarm@xxxxxxxxxxxxxxxxxxxxx > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm