bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

send messages from the kernel to the user space


From: Da Zheng
Subject: send messages from the kernel to the user space
Date: Wed, 05 Aug 2009 21:38:28 +0800
User-agent: Thunderbird 2.0.0.22 (Macintosh/20090605)

Hi,

Whenever an interrupt occurs, I need to send a message to the user space.

An RPC device_intr_notify is defined, so the user-level driver can register its 
port in the kernel. The server side of the RPC is below:
io_return_t
ds_device_intr_notify (ipc_port_t master_port, int irq,
                       int id, ipc_port_t receive_port)
{
  /* Open must be called on the master device port.  */
  if (master_port != master_device_port)
    return D_INVALID_OPERATION;

  if (irq < 0 || irq >= 16)
    return D_INVALID_OPERATION;

  intr_rcv_ports[irq] = receive_port;
  return 0;
}

deliver_irq() is to send a notification message to the port registered by the 
user. The code is below:
boolean_t
deliver_irq (int irq)
{
  ipc_kmsg_t kmsg;
  mach_irq_notification_t *n;
  ipc_port_t dest_port = intr_rcv_ports[irq];
  mach_port_t dest = (mach_port_t) dest_port;

  if (dest == MACH_PORT_NULL)
    return FALSE;

  kmsg = ikm_alloc(sizeof *n);
  if (kmsg == IKM_NULL)
    return FALSE;

  ikm_init(kmsg, sizeof *n);
  n = (mach_irq_notification_t *) &kmsg->ikm_header;

  mach_msg_header_t *m = &n->irq_header;
  mach_msg_type_t *t = &n->irq_type;

  m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
  m->msgh_size = sizeof *n;
  m->msgh_seqno = IRQ_NOTIFY_MSGH_SEQNO;
  m->msgh_local_port = MACH_PORT_NULL;
  m->msgh_remote_port = MACH_PORT_NULL;
  m->msgh_id = MACH_NOTIFY_IRQ;

  t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
  t->msgt_size = 32;
  t->msgt_number = 1;
  t->msgt_inline = TRUE;
  t->msgt_longform = FALSE;
  t->msgt_deallocate = FALSE;
  t->msgt_unused = 0;
                              
  n->irq_header.msgh_remote_port = dest;
  n->irq = irq;

  ipc_port_copy_send (dest_port);
  ipc_mqueue_send_always(kmsg);

  return TRUE;
}

It can work most of time. However, it seems that the code above causes a bug in 
the kernel.
The kernel might crash with the following error:
Assertion '(&dest_mqueue->imq_threads)->ithq_base == (receiver)' failed in file 
"../gnumach/ipc/mach_msg.c", line 998

I traced the stack, and it is:
(null):~/gnumach# addr2line -e ../gnumach-build/gnumach 0x117a06 0x117a57 
0x145b57
/root/gnumach-build/../gnumach/kern/debug.c:103
??:0
/root/gnumach-build/../gnumach/ipc/mach_msg.c:892

I don't understand how the assertion can fail here. mach_msg_trap() locks the 
message queue before accessing it and my code seems to do the same.

Could anyone tell me whether I did something wrong in the code above?

Thank you,
Zheng Da




reply via email to

[Prev in Thread] Current Thread [Next in Thread]