My kernel is modular, and the default modules are loaded from a boot-time initramfs. They can include a hook, which is called after loading like so:
Code: Select all
if (mod_info->entry != 0) {
((void (*)()) ((uint32_t) load_addr + mod_info->entry - CONTENT_OFFSET(mod_info)))();
}
Code: Select all
#define REG_ENTRIES 65536
static struct reg_device devices[REG_ENTRIES];
size_t last_dev = 0;
void register_dev (struct reg_device dev) {
devices[last_dev++] = dev;
}
Code: Select all
struct reg_device {
enum proto proto;
uint32_t ident_lo;
uint32_t ident_hi;
uint32_t pad;
};
Code: Select all
__asm__ __volatile__ ( "int $0xDE" : : "a"(ident_hi), "c"(PROTO_PCI_OLD), "d"(ident_lo) : );
Code: Select all
void isr_222 () {
uint32_t eax;
uint32_t ecx;
uint32_t edx;
struct reg_device dev;
__asm__ ( "movl %%eax, %0\n\t"
"movl %%ecx, %1\n\t"
"movl %%edx, %2" : "=m"(eax), "=m"(ecx), "=m"(edx) : : );
dev.proto = (enum proto) ecx;
dev.ident_hi = eax;
dev.ident_lo = edx;
dev.pad = 0;
register_dev(dev);
}
- No segment-related errors, since the interrupt works the first time it's called and we don't change CS, SS or the GDT.
- We're in ring 0.
- We don't change CR0.
- We're in 32-bit mode, without paging yet.
- The reg_device structure should be 32-bit aligned.
It's also well-known that a GPF can occur from a nonexistent vector, which was my first suspicion but isn't the case here either.
Here's the evidence that it's a GPF, in the form of QEMU interrupt logs (minus SMIs):
Code: Select all
0: v=de e=0000 i=1 cpl=0 IP=0008:002103b5 pc=002103b5 SP=0010:00304f50 env->regs[R_EAX]=12378086
EAX=12378086 EBX=002114d4 ECX=00000001 EDX=06000000
ESI=00000000 EDI=00210469 EBP=00304f98 ESP=00304f50
EIP=002103b5 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
[...]
1: v=de e=0000 i=1 cpl=0 IP=0008:002103b5 pc=002103b5 SP=0010:00304f50 env->regs[R_EAX]=70008086
EAX=70008086 EBX=002114d4 ECX=00000001 EDX=06010008
ESI=00000000 EDI=00210469 EBP=00304f98 ESP=00304f50
EIP=002103b5 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
[...]
2: v=0d e=06f2 i=0 cpl=0 IP=0008:002103b5 pc=002103b5 SP=0010:00304f50 env->regs[R_EAX]=70008086
EAX=70008086 EBX=002114d4 ECX=00000001 EDX=06010008
ESI=00000000 EDI=00210469 EBP=00304f98 ESP=00304f50
EIP=002103b5 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
[...]
Can anyone help figure out why this is happening?