diff --git a/vmm/handler.c b/vmm/handler.c index 65c476afad22c1a9a0bf29a4f97be0022792276b..31ef2c42c3efe3a81f9cc6caf12f6658f331a345 100644 --- a/vmm/handler.c +++ b/vmm/handler.c @@ -3,6 +3,7 @@ #include <err.h> #include <stdio.h> #include <stdint.h> +#include <stdarg.h> #include <unistd.h> #include <stdbool.h> @@ -165,12 +166,26 @@ static void wrapper_op_gfx_init(uint8_t *shared_buf) { // - VMM EXIT REASON HANDLER - -void handle_halt(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem) { +void handle_halt(struct kvm_run *run, ...) { - // printf("KVM_EXIT_HLT\n"); + va_list args; va_start(args, run); + + va_arg(args, uint8_t *); va_arg(args, uint8_t *); // skip two first args + bool *done = va_arg(args, bool *); + + printf("guest halted\n"); + *done = true; + + va_end(args); } -void handle_pmio(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem) { +// waiting for : uint8_t *shared_buf, uint8_t *mem +void handle_pmio(struct kvm_run *run, ...) { + + va_list args; va_start(args, run); + + uint8_t *shared_buf = va_arg(args, uint8_t *); + uint8_t *mem = va_arg(args, uint8_t *); if (run->io.direction == KVM_EXIT_IO_OUT) { @@ -189,9 +204,12 @@ void handle_pmio(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem) { state_compute(current_state, value); } } + + va_end(args); } -void handle_mmio(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem) { +// waiting for : uint8_t *shared_buf, uint8_t *mem +void handle_mmio(struct kvm_run *run, ...) { if (run->mmio.is_write) { @@ -219,7 +237,7 @@ void handle_hypercall(uint32_t code, uint8_t *shared_buf, uint8_t *mem) { wrapper_op_timer(shared_buf); break; - case HYPERCALL_CODE_GFX_INIT: + case HYPERCALL_CODE_GFX_INIT: wrapper_op_gfx_init(shared_buf); break; diff --git a/vmm/handler.h b/vmm/handler.h index ee1d2176d7049036136e9fd4559ccaf88efe85f9..d604a76884170fbbe2f0fc7228cbc6031e53393d 100644 --- a/vmm/handler.h +++ b/vmm/handler.h @@ -2,11 +2,12 @@ #define _STATES_H_ #include <stdint.h> +#include <stdbool.h> #include <linux/kvm.h> // --- DEFINE --- -typedef void (*state_handler_t)(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem); +typedef void (*state_handler_t)(struct kvm_run *run, ...); extern state_handler_t const STATE_HANDLERS[]; @@ -19,7 +20,7 @@ extern state_handler_t const STATE_HANDLERS[]; * @param shared_buf Buffer shared between the host and guest. * @param mem Pointer to the VM's memory. */ -void handle_halt(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem); +void handle_halt(struct kvm_run *run, ...); /** * @brief Handles the I/O port access (PMIO) exit from the virtual machine. @@ -30,7 +31,7 @@ void handle_halt(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem); * @param shared_buf Buffer shared between the host and guest. * @param mem Pointer to the VM's memory. */ -void handle_pmio(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem); +void handle_pmio(struct kvm_run *run, ...); /** * @brief Handles the memory-mapped I/O (MMIO) exit from the virtual machine. @@ -41,7 +42,7 @@ void handle_pmio(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem); * @param shared_buf Buffer shared between the host and guest. * @param mem Pointer to the VM's memory. */ -void handle_mmio(struct kvm_run *run, uint8_t *shared_buf, uint8_t *mem); +void handle_mmio(struct kvm_run *run, ...); /** * @brief Handles hypercalls issued by the virtual machine. diff --git a/vmm/operation.c b/vmm/operation.c index 471256fd52eca87574b9e7aa731aefccb81d20d3..54035b2fe3cffc2ae74f593a30fb700b8dd0ee14 100644 --- a/vmm/operation.c +++ b/vmm/operation.c @@ -3,6 +3,7 @@ #include <stdio.h> #include <stdint.h> #include <unistd.h> +#include <semaphore.h> #include "shared/hypercall_params.h" @@ -57,7 +58,7 @@ void op_callback_timer_conclude(void *addr) { hyper_timer_sleep_params_t *p_timer = (addr == NULL) ? ¶m_timer : (hyper_timer_sleep_params_t *)addr; printf("hypercall : setting up a %dus timer...\n", p_timer->us); - sleep(p_timer->us / 1e6); + usleep(p_timer->us); } void op_callback_gfx_init_store_w(void *addr) { @@ -75,5 +76,7 @@ void op_callback_gfx_init_conclude(void *addr) { hyper_init_gfx_params_t *p_gfx_init = (addr == NULL) ? ¶m_gfx_init : (hyper_init_gfx_params_t *)addr; printf("hypercall : initializing gfx %dx%d...\n", p_gfx_init->width, p_gfx_init->height); - // TODO: + width_gfx = p_gfx_init->width; + height_gfx = p_gfx_init->height; + sem_post(&sem_gfx); } diff --git a/vmm/operation.h b/vmm/operation.h index b57c453d9a8a77878cc7d7a0e4834e47b1178ac0..05f95d806affcfd172a0a81ef3f42adb544aecf8 100644 --- a/vmm/operation.h +++ b/vmm/operation.h @@ -3,6 +3,8 @@ #include <stdint.h> #include <unistd.h> +#include <pthread.h> +#include <semaphore.h> // --- DEFINE --- @@ -26,6 +28,10 @@ typedef struct { void (*callback)(void *addr); // custom function that would be executed at the end of the state } state_t; +extern sem_t sem_gfx; +extern uint32_t width_gfx; +extern uint32_t height_gfx; + extern state_t *STATE_ALL_STARTERS[]; extern state_t STATE_TIMER[]; diff --git a/vmm/vmm_main.c b/vmm/vmm_main.c index 2660c38121f3eb73bb61b6551286fbd4bc9fc845..91771d21bf2628e458287ea9f16f8527b120d4f8 100644 --- a/vmm/vmm_main.c +++ b/vmm/vmm_main.c @@ -11,8 +11,12 @@ #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> +#include <pthread.h> +#include <semaphore.h> +#include "gfx.h" #include "handler.h" +#include "operation.h" #include "shared/hypercall_params.h" // -- DEFINE -- @@ -20,15 +24,47 @@ #define KVM_API_VERSION 12 #define RAM_SIZE (512 * 1024) +#define SEM_THREAD 0 + +sem_t sem_gfx; +uint32_t width_gfx; +uint32_t height_gfx; + +static uint8_t *mem, *shared_buf; +static struct kvm_run *run; +static int vcpufd; + +// -- THREAD -- + +static void *thread_hypercall() { + + bool done = false; + while (!done) { + + if (ioctl(vcpufd, KVM_RUN, NULL) == -1) err(1, "KVM_RUN"); + + state_handler_t handler = STATE_HANDLERS[run->exit_reason]; + + if (handler) { + + handler(run, shared_buf, mem, &done); + } + else { + + errx(1, "exit_reason = 0x%x", run->exit_reason); + } + } + + return NULL; +} + // -- MAIN -- int main(int argc, char* argv[]) { - int kvmfd, vmfd, vcpufd; + int kvmfd, vmfd; struct kvm_sregs sregs; - struct kvm_run *run; int32_t mmap_size; - uint8_t *mem, *shared_buf; // -- 0. Handle Args -- if (argc != 2) err(1, "Number of args invalide"); @@ -139,20 +175,23 @@ int main(int argc, char* argv[]) // -- 7. Run the vCPU -- - bool done = false; - while (!done) { + sem_init(&sem_gfx, SEM_THREAD, 0); - if (ioctl(vcpufd, KVM_RUN, NULL) == -1) err(1, "KVM_RUN"); + pthread_t t_hypercall; + pthread_create(&t_hypercall, NULL, thread_hypercall, NULL); - state_handler_t handler = STATE_HANDLERS[run->exit_reason]; + sem_wait(&sem_gfx); - if (handler) { + // -- 8. Manage gfx -- - handler(run, shared_buf, mem); - } - else { + gfx_context_t *ctxt = gfx_create("Basic Example", width_gfx, height_gfx); + if (!ctxt) err(1, "KVM_SET_REGS"); - errx(1, "exit_reason = 0x%x", run->exit_reason); - } - } + // -- X. Finalize -- + pthread_join(t_hypercall, NULL); + + gfx_destroy(ctxt); + sem_destroy(&sem_gfx); + + return 0; }