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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions