linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* extending callbacks?
@ 2002-03-19 10:23 Matthias Scheidegger
  2002-03-19 23:08 ` H. Peter Anvin
  2002-03-20 15:59 ` Eric W. Biederman
  0 siblings, 2 replies; 7+ messages in thread
From: Matthias Scheidegger @ 2002-03-19 10:23 UTC (permalink / raw)
  To: linux-kernel

Hi,

I've got the following problem: I want to register a callback in a kernel
structure, but I need to supply an additional argument to my own code. I.e. I
need a callback

int (*cb)(int u)

to really call

int (*real_cb)(int u, void* my_arg)

At the moment, I'm only focussing on the i386 architecture.
In user space, I'd do this by generating some machine code, which takes the
original args, pushes my_fixed_arg and calls real_cb (using mprotect to make
the generated code callable). That way I'd use a function

int (*)(int) create_callback(int (*real_cb)(int, void*), void *arg);

Is there a good way to do that in the kernel?
Not necessarily using self modifying code, I'll only use it if I must.

Please CC answers to my address, I'm not subscribed.

thanks very much,

Matthias


| Matthias Scheidegger   Institute of Computer Science and Applied Mathematics |
| University of Bern     Neubrueckstr. 10, CH-3012 Bern, Switzerland	       |
| http://www.iam.unibe.ch/~mscheid  Phone: +41 31-6318692  Fax: +41 31-6313261 |


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: extending callbacks?
  2002-03-19 23:08 ` H. Peter Anvin
@ 2002-03-19 19:32   ` Andreas Dilger
  2002-03-20 15:55   ` Eric W. Biederman
  1 sibling, 0 replies; 7+ messages in thread
From: Andreas Dilger @ 2002-03-19 19:32 UTC (permalink / raw)
  To: linux-kernel

Matthias Scheidegger <mscheid@iam.unibe.ch> writes:
> I've got the following problem: I want to register a callback in a kernel
> structure, but I need to supply an additional argument to my own code. I.e. I
> need a callback
> 
> int (*cb)(int u)
> 
> to really call
> 
> int (*real_cb)(int u, void* my_arg)
> 
> At the moment, I'm only focussing on the i386 architecture.

In general, you would pass "my_arg" in a private pointer in a data
struct somewhere.  What function is it that you are calling?  That
may already have the possibility of passing the extra data somewhere.

Cheers, Andreas
--
Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
                 \  would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: extending callbacks?
  2002-03-19 10:23 extending callbacks? Matthias Scheidegger
@ 2002-03-19 23:08 ` H. Peter Anvin
  2002-03-19 19:32   ` Andreas Dilger
  2002-03-20 15:55   ` Eric W. Biederman
  2002-03-20 15:59 ` Eric W. Biederman
  1 sibling, 2 replies; 7+ messages in thread
From: H. Peter Anvin @ 2002-03-19 23:08 UTC (permalink / raw)
  To: linux-kernel

Followup to:  <Pine.GSO.4.44.0203191111320.20995-100000@speedy>
By author:    Matthias Scheidegger <mscheid@iam.unibe.ch>
In newsgroup: linux.dev.kernel
> 
> I've got the following problem: I want to register a callback in a kernel
> structure, but I need to supply an additional argument to my own code. I.e. I
> need a callback
> 
> int (*cb)(int u)
> 
> to really call
> 
> int (*real_cb)(int u, void* my_arg)
> 
> At the moment, I'm only focussing on the i386 architecture.
> In user space, I'd do this by generating some machine code, which takes the
> original args, pushes my_fixed_arg and calls real_cb (using mprotect to make
> the generated code callable). That way I'd use a function
> 
> int (*)(int) create_callback(int (*real_cb)(int, void*), void *arg);
> 
> Is there a good way to do that in the kernel?
> Not necessarily using self modifying code, I'll only use it if I must.
> 

In general, it's impossible.  On a lot of architectures, it happens to
"just work" with the appropriate cast, but that's completely dependent
on the ABI.

The extra arguemnt, of course, contains garbage.

	-hpa
-- 
<hpa@transmeta.com> at work, <hpa@zytor.com> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt	<amsp@zytor.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: extending callbacks?
  2002-03-19 23:08 ` H. Peter Anvin
  2002-03-19 19:32   ` Andreas Dilger
@ 2002-03-20 15:55   ` Eric W. Biederman
  2002-03-20 18:32     ` H. Peter Anvin
  1 sibling, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2002-03-20 15:55 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: linux-kernel

"H. Peter Anvin" <hpa@zytor.com> writes:

> Followup to:  <Pine.GSO.4.44.0203191111320.20995-100000@speedy>
> By author:    Matthias Scheidegger <mscheid@iam.unibe.ch>
> In newsgroup: linux.dev.kernel
> > 
> > I've got the following problem: I want to register a callback in a kernel
> > structure, but I need to supply an additional argument to my own code. I.e. I
> > need a callback
> > 
> > int (*cb)(int u)
> > 
> > to really call
> > 
> > int (*real_cb)(int u, void* my_arg)
> > 
> > At the moment, I'm only focussing on the i386 architecture.
> > In user space, I'd do this by generating some machine code, which takes the
> > original args, pushes my_fixed_arg and calls real_cb (using mprotect to make
> > the generated code callable). That way I'd use a function
> > 
> > int (*)(int) create_callback(int (*real_cb)(int, void*), void *arg);
> > 
> > Is there a good way to do that in the kernel?
> > Not necessarily using self modifying code, I'll only use it if I must.
> > 
> 
> In general, it's impossible.  On a lot of architectures, it happens to
> "just work" with the appropriate cast, but that's completely dependent
> on the ABI.
> 
> The extra arguemnt, of course, contains garbage.

???

static void *my_fixed_arg;
int temp_cb(int u)
{
        return real_cb(u, my_fixed_arg);
}

Generally works.  The variant that builds that code on the fly for
create_callback is a little more interesting of course.


Eric




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: extending callbacks?
  2002-03-19 10:23 extending callbacks? Matthias Scheidegger
  2002-03-19 23:08 ` H. Peter Anvin
@ 2002-03-20 15:59 ` Eric W. Biederman
  2002-03-20 21:02   ` Matthias Scheidegger
  1 sibling, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2002-03-20 15:59 UTC (permalink / raw)
  To: Matthias Scheidegger; +Cc: linux-kernel

Matthias Scheidegger <mscheid@iam.unibe.ch> writes:

> Hi,
> 
> I've got the following problem: I want to register a callback in a kernel
> structure, but I need to supply an additional argument to my own code. I.e. I
> need a callback
> 
> int (*cb)(int u)
> 
> to really call
> 
> int (*real_cb)(int u, void* my_arg)
> 
> At the moment, I'm only focussing on the i386 architecture.
> In user space, I'd do this by generating some machine code, which takes the
> original args, pushes my_fixed_arg and calls real_cb (using mprotect to make
> the generated code callable). That way I'd use a function
> 
> int (*)(int) create_callback(int (*real_cb)(int, void*), void *arg);
> 
> Is there a good way to do that in the kernel?
> Not necessarily using self modifying code, I'll only use it if I must.

The general case requires self modifying code.  Where do you need this in the
kernel.  For most callbacks the kernel is already passing a fairly generic
parameter you can use.  So this trick should be unnecessary.  

In general it would be better to modify what the kernel is passing the function
than to build up an infrastructure to avoid fixing the code.  Especially
as runtime generated code tends to have a performance penalty.

Eric


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: extending callbacks?
  2002-03-20 15:55   ` Eric W. Biederman
@ 2002-03-20 18:32     ` H. Peter Anvin
  0 siblings, 0 replies; 7+ messages in thread
From: H. Peter Anvin @ 2002-03-20 18:32 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-kernel

Eric W. Biederman wrote:
> 
> ???
> 
> static void *my_fixed_arg;
> int temp_cb(int u)
> {
>         return real_cb(u, my_fixed_arg);
> }
> 
> Generally works.  The variant that builds that code on the fly for
> create_callback is a little more interesting of course.
> 

Well, of course you can do anything with a thunk.  I thought the 
question was if you can do the call *directly*.

	-hpa



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: extending callbacks?
  2002-03-20 15:59 ` Eric W. Biederman
@ 2002-03-20 21:02   ` Matthias Scheidegger
  0 siblings, 0 replies; 7+ messages in thread
From: Matthias Scheidegger @ 2002-03-20 21:02 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-kernel

Hi Eric,

> The general case requires self modifying code.  Where do you need this in the
> kernel.  For most callbacks the kernel is already passing a fairly generic
> parameter you can use.  So this trick should be unnecessary.

In my case the problem is indeed fairly general, so I can't seem to count on a
generic parameter. Most callbacks do have them, but not all of them.

Anyway, since you agree the general case requires self modifying code I'll do it
that way. Now I just need to know how to make a page executable in a portable
way (get_free_page on i386 already returns executable pages...)

If anyone's interested in the background of this:
I'm writing a kernel module containing an interpreter for the Python language,
which in turn accesses the kernel functions through a wrapper layer. This
makes writing kernel modules in pure Python possible. I know this is rather sick :)


cheers

Matthias


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2002-03-20 21:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-19 10:23 extending callbacks? Matthias Scheidegger
2002-03-19 23:08 ` H. Peter Anvin
2002-03-19 19:32   ` Andreas Dilger
2002-03-20 15:55   ` Eric W. Biederman
2002-03-20 18:32     ` H. Peter Anvin
2002-03-20 15:59 ` Eric W. Biederman
2002-03-20 21:02   ` Matthias Scheidegger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).