2

I have a small function which I have added in kernel source (linux 3.0) which does some task and works fine in SVC mode. But in interrupt mode (i.e., when timer interrupts are enabled in kernel through local_irq_enable) it does not work. So I am thinking of switching to SVC mode before executing my function. I have taken code for switching modes from one of the posts.

void myfunction(..some args)
{ 
    unsigned int oldmode = get_cpsr() & 0x1f;

    if (oldmode == 18) // Check for IRQ mode
        change_mode(MODE_SVC);
    // ...My code ....
    restore_mode(oldmode);
}

Definitions are as follows:

#define MODE_IRQ        0x12
#define MODE_SVC        0x13

#define change_mode(mode) asm("cps %0" : : "I"(mode))

#define restore_mode(mode) \
    mode &= 0x1f; \
    asm(" msr cpsr, %0\n" : : "r"(mode) : "cc")

static inline unsigned int get_cpsr(void)
{
    unsigned int val;

    __asm__ __volatile__ (" mrs %0, cpsr\n"
                          : "=r" (val));
    return val;
}

Even after this I am not getting correct output. Function execution gets stuck somewhere. I have debugged the address where it gets stuck and it is pointing to these symbols of System.map

__exception_text_start _stext asm_do_IRQ

Is my usage of function correct. Can you suggest me any other solution for this problem. I am running this image then on ARMv7 board. And lastly there are calls to some kernel APIs like printch() in my function after changing mode.

Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
arceus
  • 327
  • 4
  • 15
  • @artlessnoise Any suggestions on how to achieve this. – arceus Jan 08 '17 at 13:48
  • Look at [this question and answer](http://stackoverflow.com/questions/41534450/how-does-ftrace-track-interrupt-service-routines). I think you have some mis-conceptions. ARM Linux almost never executes in IRQ mode. The most likely issue is *My code* has something which is non-re-entrant, including other functions called by your code. – artless noise Jan 08 '17 at 20:57
  • @artlessnoise But where is timer interrupt handled then.The code works fine before timer interrupt comes.I found the last functions that were executed and which kept repeating were : `handle_edge_irq` -> `_raw_spin_lock` -> `__raw_spin_lock` -> `add_preempt_count` -> `sub_preempt_count`. Could you point out where might it be going wrong. And the exception I stated comes after call to `gic_irq`. – arceus Jan 09 '17 at 07:11
  • @notlikethat Any points on the matter. There is also irq_check_poll that is being called inside `handle_edge_irq`. – arceus Jan 10 '17 at 09:07

0 Answers0