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