2002-07-18 06:24:43

by Irfan Hamid

[permalink] [raw]
Subject: cli()/sti() clarification

Hi,

I added two system calls, blockintr() and unblockintr() to give cli()/sti()
control to userland programs (yes I know its not advisable) but I only want
to do it as a test. My test program looks like this:

blockintr();
/* Some long calculations */
unblockintr();

The problem is that if I press Ctrl+C during the calculation, the program
terminates. So I checked the _syscallN() and __syscall_return() macros to
see if they explicitly call sti() before returning to userspace, but they
dont.

Reading the lkml archives, I found that cli() disables only the interrupts,
exceptions are allowed, so it makes sense that the SIGINT was delivered, but
if thats the case, then how come the SIGINT was delivered from the Ctrl+C?
Doesnt this mean that the SIGINT signal was generated as a result of the
keyboard interrupt?

I know I am missing something here, would appreciate if someone could point
me in the right direction.

Regards,
Irfan Hamid.


2002-07-18 06:56:18

by George Anzinger

[permalink] [raw]
Subject: Re: cli()/sti() clarification

[email protected] wrote:
>
> Hi,
>
> I added two system calls, blockintr() and unblockintr() to give cli()/sti()
> control to userland programs (yes I know its not advisable) but I only want
> to do it as a test. My test program looks like this:
>
> blockintr();
> /* Some long calculations */
> unblockintr();
>
> The problem is that if I press Ctrl+C during the calculation, the program
> terminates. So I checked the _syscallN() and __syscall_return() macros to
> see if they explicitly call sti() before returning to userspace, but they
> dont.
>
> Reading the lkml archives, I found that cli() disables only the interrupts,
> exceptions are allowed, so it makes sense that the SIGINT was delivered, but
> if thats the case, then how come the SIGINT was delivered from the Ctrl+C?
> Doesnt this mean that the SIGINT signal was generated as a result of the
> keyboard interrupt?
>
> I know I am missing something here, would appreciate if someone could point
> me in the right direction.

Return from sys to user space is done by executing a "iret"
instruction. In addition to picking up the return address
and segment it pick up EFLAGS which will contain the
interrupt flag as it was saved when the system call was
made...
>
> Regards,
> Irfan Hamid.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

--
George Anzinger [email protected]
High-res-timers:
http://sourceforge.net/projects/high-res-timers/
Real time sched: http://sourceforge.net/projects/rtsched/
Preemption patch:
http://www.kernel.org/pub/linux/kernel/people/rml

2002-07-18 09:30:30

by Kasper Dupont

[permalink] [raw]
Subject: Re: cli()/sti() clarification

/* This piece of code is ugly and inefficient. */

#include <stdlib.h>
#include <linux/module.h>
#include <asm/current.h>
#include "cli.h"

struct my_module {
struct module m;
char name[64];
unsigned long jmp;
unsigned long delta;
} my_module;

static int do_cli()
{
(*(unsigned long*)(((char*)current)+0x1FF4)) &= ~0x200;
return 0;
}

static int do_sti()
{
(*(unsigned long*)(((char*)current)+0x1FF4)) |= 0x200;
return 0;
}

void init_struct(int (*func)(),struct my_module *dst, struct my_module *p)
{
dst->m.size_of_struct = sizeof(struct module);
dst->m.next=NULL;
dst->m.name=p->name;
dst->m.size=sizeof(my_module);
dst->m.flags=0;
dst->m.nsyms=0;
dst->m.ndeps=0;
dst->m.syms=NULL;
dst->m.deps=NULL;
dst->m.refs=NULL;
dst->m.init=(void*)&(p->jmp);
dst->m.cleanup=NULL;
dst->m.ex_table_start=NULL;
dst->m.ex_table_end=NULL;
dst->m.persist_start=NULL;
dst->m.persist_end=NULL;
dst->m.can_unload=NULL;
sprintf(dst->name,"hack_%d_hack",getpid());
dst->jmp=0xE9909090;
dst->delta=(unsigned long)func-(unsigned long)(p+1);
}

static void kernel_call(int (*func)())
{
struct my_module my_module;
init_struct(func,&my_module,&my_module);
init_struct(func,&my_module,(void*)create_module(my_module.name,my_module.m.size));
init_module(my_module.name,&my_module.m);
delete_module(my_module.name);
}

void cli()
{
kernel_call(do_cli);
}

void sti()
{
kernel_call(do_sti);
}


Attachments:
cli.c (1.41 kB)

2002-07-18 14:49:10

by Marco Colombo

[permalink] [raw]
Subject: Re: cli()/sti() clarification

On Thu, 18 Jul 2002 [email protected] wrote:

> Hi,
>
> I added two system calls, blockintr() and unblockintr() to give cli()/sti()
> control to userland programs (yes I know its not advisable) but I only want
> to do it as a test. My test program looks like this:
>
> blockintr();
> /* Some long calculations */
> unblockintr();

May I ask what are you trying to achieve?

.TM.

2002-07-22 07:18:15

by Irfan Hamid

[permalink] [raw]
Subject: Re: cli()/sti() clarification

Thankyou all for explaining the system call internals to me. Feel like an
idiot now :)

Marco Colombo: As for what I am trying to achieve, it is simply this. I need
to do plot extraction from radar raw returns. The scan time for one
revolution is 2.44 secs. I need to extract plots for each pi/2 radians in
less than 2.44/4 secs. I have already optimized the extraction algo upto
SSE2 in assembly and am running the process as realtime, but it just cant
seem to cut it. So now I am going to try and block interrupts while I do the
DSP.

Regards,
Irfan Hamid.