From a5603f401e8dc1785b93917adc035d5cbbc00723 Mon Sep 17 00:00:00 2001 From: jewelcodes Date: Mon, 30 Sep 2024 15:06:57 -0400 Subject: [PATCH] x86_64: performance fixes when switching I/O port permissions --- src/platform/x86_64/include/platform/context.h | 1 + src/platform/x86_64/io.c | 1 + src/platform/x86_64/sched/context.c | 10 ++++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/platform/x86_64/include/platform/context.h b/src/platform/x86_64/include/platform/context.h index b205ffb7..5fae4a48 100644 --- a/src/platform/x86_64/include/platform/context.h +++ b/src/platform/x86_64/include/platform/context.h @@ -44,6 +44,7 @@ typedef struct { ThreadGPR regs; // register state + int iopl; // set to 1 if I/O port privileges have been modified uint8_t ioports[8192]; // I/O port privileges } __attribute__((packed)) ThreadContext; diff --git a/src/platform/x86_64/io.c b/src/platform/x86_64/io.c index 9a874ef1..31ad6945 100644 --- a/src/platform/x86_64/io.c +++ b/src/platform/x86_64/io.c @@ -22,6 +22,7 @@ int platformIoperm(Thread *t, uintptr_t from, uintptr_t count, int enable) { if((from+count-1) > 0xFFFF) return -EINVAL; // 65536 I/O ports on x86 ThreadContext *ctx = (ThreadContext *) t->context; + ctx->iopl = 1; for(int i = 0; i < count; i++) { int byte = (from + i) / 8; diff --git a/src/platform/x86_64/sched/context.c b/src/platform/x86_64/sched/context.c index 6887d4d2..28730fad 100644 --- a/src/platform/x86_64/sched/context.c +++ b/src/platform/x86_64/sched/context.c @@ -97,8 +97,14 @@ void platformSwitchContext(Thread *t) { ThreadContext *ctx = (ThreadContext *)t->context; ctx->regs.rflags |= 0x202; // interrupts can never be switched off outside of the kernel - // modify the TSS with the current thread's I/O permissions - memcpy(kinfo->tss->ioports, ctx->ioports, 8192); + // modify the TSS with the current thread's I/O permissions if necessary + Thread *old = kinfo->thread; + ThreadContext *oldctx = NULL; + if(old) oldctx = (ThreadContext *) old->context; + + if(ctx->iopl || (oldctx && oldctx->iopl)) { + memcpy(kinfo->tss->ioports, ctx->ioports, 8192); + } kinfo->thread = t; kinfo->process = getProcess(t->pid);