vm86 patch updated to 2.5.67 / oops in blank_screen()?

From: Jurriaan <hidden>
Date: 2003-04-12 12:56:20

I've been playing with Antonino Daplas' vm86 patch.

First of all, the /dev/vm86 device should read:

crw-------    1 root     root      10, 201 Apr 10 07:07 /dev/vm86

Then, I split the patch in a vm86 and a edid-vbe patch, and dropped all
refereces to the non-vesa framebuffers. There were a number of other
changes in the patch which made it difficult to port since it affected
all other framebuffers.

The resulting patches worked quite well, I'm testing here on a single
CPU system with linux-2.5.67 and a Matrox G450 video-card. Once I'm
satisfied it works, I hope to get my Elsa GeForce 3 Ti500 working with
vesa framebuffer and nvidia proprietary drivers.

But, while I was away for some lunch, the computer decided to spoil the
general good feeling; it oopsed.

The backtrace was like this:

sys_sched_yield
vm86_exec
vbe_writedac
vbe_setcolreg
fb_set_cmap
fb_blank
timer_do_blank
blank_screen

Could anyone look at the patch (I've appended my version below) and tell
me what's going on? I'm no expert in locking in linux. I've tried adding
a disable_preempt() calls in vm86_exec(), but that got me lots of
'scheduling while atomic' backtraces.

I suspect this routine isn't quite good:

/**
 * vm86_exec - execute instructions
 * @request: pointer to instruction request data
 * @buffer: 1024-byte min sized buffer for extra data
 *
 * ON ENTRY: @buffer must point to a valid buffer (1024 bytes).
 * ON EXIT: @request contains results of x86 instructions.  @request->buffer
 *          may contain additional data, depending on the code.  Check
 *          @request->buf_len.
 * WARNING:
 * Will sleep
 */
int vm86_exec(struct vm86_request *request, void *buffer)
{
        int len;

        if (!info || !info->enabled)
                return -ENODEV;

        if (request->flags & VM86_TEST)
                return 0;

        len = sizeof(struct vm86_request) + request->buf_len;
        if (len > 1024)
                return -EINVAL;

        down(&vm86_sem);

        info->request = *request;
        info->buffer = buffer;
        info->error = 0;
        info->event = 1;
        info->poll_mask = POLLIN | POLLRDNORM;
        kill_fasync(&info->async_queue, SIGIO, POLL_IN);  /* send signal */

        wake_up(&vm86_wait);
        while (info->event)
                yield();

        info->request.flags = (info->error) ?
                VM86_FAILED : VM86_SUCCESS;
        *request = info->request;

        up(&vm86_sem);

        return 0;
}

The call to yield() seems not to happen to often in the kernel, but I
don't know how to change this.

The patch below is against linux-2.5.67 (vanilla). There's some residual
printk's in there, btw.

I appreciate your help!

Thanks,
Jurriaan
-- 
Debian (Unstable) GNU/Linux 2.5.67-ac1 1970 bogomips load av: 0.04 0.32 0.33

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help