Skip to content
This repository was archived by the owner on Apr 2, 2019. It is now read-only.
This repository was archived by the owner on Apr 2, 2019. It is now read-only.

runtime: kevent on fd 8 failed with 14 #35

@yuval-k

Description

@yuval-k

To reproduce, run a go http server (i used the one here: https://github.com/emc-advanced-dev/unik/tree/master/docs/examples/example_go_httpd)
and perform a lot of requests:
while true; do curl http://192.168.4.141:8080/ ; done (192.168.4.141 is the address of the rumprun unikernel in my setup)

This issue happens due to a mismatch in assembly calling conventions.

In go:

func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32

in c (rumprun/src-netbsd/sys/kern/kern_event.c):

int kevent1(register_t *retval, int fd,
    const struct kevent *changelist, size_t nchanges,
    struct kevent *eventlist, size_t nevents,
    const struct timespec *timeout,
    const struct kevent_ops *keops)

The variables fd, nchanges, nevents are 32 bit in go BUT are 64 bit in C.
When they are copied to the stack as arguments, they take 8 bytes from the stack (as this is 64bit), but only 4 bytes are copied. leaving 4 bytes of garbage.
If the garbage is not zero, the c system call gets the wrong value for the variable.
in my case, i had
nchanges = 0x2100000000
while changelist was null, and hense the EFAULT error (number 14)

As a hacky solution, I modified runtime·kevent in runtime/sys_rumprun_amd64.s right after the line
ADDQ $0x18, SI // args
I added:

    MOVL    $0, 0x04(SI)
    MOVL    $0, 0x14(SI)
    MOVL    $0, 0x24(SI)

to zero out the garbage part of the stack.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions