#include #include #include #include #include int main(int argc, char **argv) { xc_interface *xch; int dom; struct { struct hvm_save_descriptor hdesc; struct hvm_save_header header; struct hvm_save_descriptor cdesc; struct hvm_hw_cpu cpu; struct hvm_save_descriptor ndesc; } buf; if (argc != 2 || (dom = atoi(argv[1])) <= 0) errx(1, "usage: injectiontest "); buf.hdesc = (struct hvm_save_descriptor) { .typecode = HVM_SAVE_CODE(HEADER), .instance = 0, .length = sizeof buf.header, }; buf.header = (struct hvm_save_header) { .magic = HVM_FILE_MAGIC, .version = HVM_FILE_VERSION, }; buf.cdesc = (struct hvm_save_descriptor) { .typecode = HVM_SAVE_CODE(CPU), .instance = 0, .length = sizeof buf.cpu, }; buf.ndesc = (struct hvm_save_descriptor) { 0 }; xch = xc_interface_open(NULL, NULL, 0); printf("pausing domain\n"); if (xc_domain_pause(xch, dom)) err(1, "could not pause"); printf("reading vcpu 0\n"); if (xc_domain_hvm_getcontext_partial(xch, dom, HVM_SAVE_CODE(CPU), 0, &buf.cpu, sizeof(buf.cpu))) err(1, "could not read vcpu state"); printf("injecting an event\n"); buf.cpu.pending_valid = 1; buf.cpu.pending_vector = 14; // page fault buf.cpu.pending_type = 3; // H/W exception buf.cpu.pending_error_valid = 1; buf.cpu.error_code = 1; if (xc_domain_hvm_setcontext(xch, dom, (uint8_t *)&buf, sizeof buf)) err(1, "could not set vcpu state"); if (xc_domain_hvm_getcontext_partial(xch, dom, HVM_SAVE_CODE(CPU), 0, &buf.cpu, sizeof(buf.cpu))) err(1, "could not read vcpu state"); if (buf.cpu.pending_valid) printf("good: vcpu shows an event is pending\n"); else { printf("bad: no event pending after one was injected\n"); exit(-1); } printf("clearing the event\n"); buf.cpu.pending_event = 0; if (xc_domain_hvm_setcontext(xch, dom, (uint8_t *)&buf, sizeof buf)) err(1, "could not set vcpu state"); if (xc_domain_hvm_getcontext_partial(xch, dom, HVM_SAVE_CODE(CPU), 0, &buf.cpu, sizeof(buf.cpu))) err(1, "could not read vcpu state"); if (!buf.cpu.pending_valid) printf("good: vcpu shows no event pending\n"); else { printf("bad: existing event is still pending\n"); exit(-1); } return 0; }