Long mode external interrupt causes #GP fault - osdev

I am trying to write a long mode guest program under hypervision. When I inject an external interrupt to the guest, the guest immediately triggered a #GP fault. The error code is 0x11, indicating that cs selector is 0x10, and that this fault is external. (The #GP fault was intercepted by my hypervisor. In other words, I did not set up #GP handler in IDT.)
I conjecture there is something wrong with my GDT. However, I specified the same cs selector (i.e: cs.selector=0x10) of interrupt handler as the normal control flow. The normal control flow went well with this cs selector, so what could be the real specific cause of the #GP fault?
An exhaustive checklist would be appreciated as well.

It turns out that I forgot to initialize GDT for the Guest in my hypervisor. Therefore, external interrupt was referencing a null code segment and thereby triggers #GP fault.
In a word, segment state saved in VMCB does not necessarily synchronize with the Guest's GDT memory region.

Related

Getting notified when an I2C-Value changes in C++

I recently started experimenting with I2C-Hardware on my raspberry pi. Following this tutorial Using the I2C interface I already know how to read and set values. However, the program I want to realize needs the current value on a specific address all the time. So, I made a thread and query the value constantly in a never ending loop, which seems primitive to me. Is it possible to get notified in an event-like manner when a value on an I2C-adress changes?
A platform independend solution would also be much welcomed.
I was able to get what I wanted.
I use the following repeater for the I2C-Bus: link and it turns out there is a soldering bridge (LB2) you can set that sets a signal on GPIO17 whenever a value on the I2C-Bus changes since it has last been changed. I can now listen on this events accordingly.
Generally speaking, the I2C bus has no interrupt capability. So with only I2C, all you can do is poll the chip for a certain event to happen or value to change.
Most chips do have an interrupt line (sometimes even more than one) that can be programmed to trigger on certain events. The behavior of this line depends on the chip. Usually it needs to be enabled (using I2C commands) and it needs to be linked to a GPIO input line. For these, interrupt support is available.

debug port problem while running Lauterbach CMM script

Currently Im developing Lauterbach CMM scripts to automate test cases for SPC58NG84
As part of Test case:
- Need to reset target system before and after test case.
- Need to read and wrte variable values from C code.
When I run test scripts I got error 'debug port problem' and in 'watch window' all variable values showing BUS ERROR.
Can you please let me know how to debug this issue?.
What are the reasons causing 'debug port problem'?
Error Message in Area winodw:
CO:2 error: CPU suddenly left debug mode (OSR=0x3C1)
CO:0 JTAGID=0x11110041
Warning: CO:1 Core currently in reset. Stopping core on activation.
CMM Script:
Test Pre condition: Reset target
Break.Delete
WAIT 100.ms
SYStem.Mode Down
SYStem.DETECT.CPU
SYStem.Mode Up
B:: Go
WAIT 500.ms
Test case Execution:
--Read and write Variables in software-----
Test Post condition: Reset target
Break
Break.Delete
WAIT 100.ms
SYStem.Mode Down
SYStem.Mode Up
B:: Go
WAIT 1000.ms
The error 'debug port problem' after the Break command usually means that the target application crashed so badly that core does not respond to the debugger's halt command anymore.
In order to debug the problem, make sure that your boot loader sets up the interrupt vector start address (IVPR) as early as possible, and also put branch-to-self instructions to all interrupt handler addresses, unless interrupt handler code already exists.
Once this is done, set program preakpoints to the interrupt handlers typically involved in crashes: machine check, data storage, instruction storage, program interrupt. Doing so should catch the core when the crash occurs, and the SRR0 (CSRR or MCSRR, depending on interrupt type) will show you at which address the problem occurred.

Conditional breakpoint with trace32

I have what I think is a stack corruption.
I have an stack variable (a pointer ) in the position:
0x7000C0E4 ; the normal information stored is 0x700022A5
I know that from time to time some unexpected code trashes the high part of the word getting one of these values:
0x000022A5 or 0x005122A5; I guess is a 16 bits write operation.
I'd like to set a breakpoint to stop when someone writes in that address but only when after the write the content of the stack address is 0x000022A5 or 0x005122A5
I guess I need two conditional breakpoints.
Anyone knows idf this is possible and the syntax to setup such breakpoints.
After #Holger comments I've setup what I think is the conditional breakpoint I need. But it does not work as expected. See he attached picture. Let me recall:
I know someone is corruption the 0x7000c0de position, writing a 0x0000 instead of the expected value 0x7000. I use that as a pointer and the resulted pointer is 0x000022A5 instead of the expected 0x700022A5. I've setup 2 breakpoints , one at the trap function (I fall here after trying to access to the bad address) and a conditional Write breakpoint which should stop only when some writes the 0x0000 and additionaly the 0x7000c0dc address content is 0x000022A5. As you see in the picture my debugger stops only in the TRap function and at that moment the content of the 0x7000c0dc is effectively 0x000022A5. So why this conditional breakpoint is not working?
This should be done with data breakpoints.
The command in TRACE32 for data breakpoints is this one:
Break.Set <address> /Write /Data.<width> <value>
In your particular case you'll need two data-breakpoints. E.g. like this:
Break.Set 0x7000C0E6 /Write /Data.Word 0x0000
Break.Set 0x7000C0E6 /Write /Data.Word 0x0051
This will only work if your CPU supports data breakpoints and if the change on the stack was actually done by the CPU. It will not stop if the memory was altered by DMA or a peripheral hardware component or so.
If your CPU does not support data breakpoints TRACE32 will emulate the data breakpoints in a way that it will actually stop every time data is written to the given address, but immediately restart the CPU if the written data does not match.

Generate core file even after handling SIGSEGV signal

Scenario:
I have a process which is running in my board. Sometimes process getting crash because of segmentation fault. So, when segmentation fault happen then I need to blink one LED. LED code is also part of process only.
But, when segmentation fault happen, then process getting crash and end user of the board does not happen any idea about the process getting crash.
Expectation
I want to handle SIGSEGV signal. When SIGSEGV raise, then handler would be called and from handler, I need to call gracefullyDownFunction(). gracefullyDownFunction() function would blink that LED.
The problem which I am facing with this is, CORE file is not generating.
Hence, my expectation is CORE file also need to generate as well as gracefullyDownFunction() also called.
I am looking for the solution for this requirement.
Thanks in Advance.

what happens if interrupt occurs while ISR running?

I am programming arduino, I attached an interrupt on pin2 falling edge. While I am in the ISR and the ISR has not executed all the lines. Before finishing all the lines if falling edge comes again what happens? Does interrupt start from begining or ignor it. Here I am talking about only interrupt on pin2.
The Atmel processor disables interrupts when an interrupt is taken:
(Section 4.4: Bit 7 – I: Global Interrupt Enable)
The Global Interrupt Enable bit must be set for the interrupts to be
enabled. The individual interrupt enable control is then performed
in separate control registers. If the Global Interrupt Enable Register
is cleared, none of the interrupts are enabled independent of the
individual interrupt enable settings. The I-bit is cleared by hardware
after an interrupt has occurred, and is set by the RETI instruction to
enable subsequent interrupts. The I-bit can also be set and cleared by
the application with the SEI and CLI instructions, as described in the
instruction set reference.
Further:
External Interrupt Flag Register – EIFR
• Bits 7..0 – INTF6, INTF3 - INTF0: External Interrupt Flags 6, 3 - 0
When an edge or logic change on the INT[6;3:0] pin triggers an
interrupt request, INTF7:0 becomes set (one). If the I-bit in SREG and
the corresponding interrupt enable bit, INT[6;3:0] in EIMSK, are set
(one), the MCU will jump to the interrupt vector. The flag is cleared
when the interrupt routine is executed. Alternatively, the flag can be
cleared by writing a logical one to it. These flags are always cleared
when INT[6;3:0] are configured as level interrupt. Note that when
entering sleep mode with the INT3:0 interrupts disabled, the input
buffers on these pins will be disabled. This may cause a logic change
in internal signals which will set the INTF3:0 flags.
In other words, when another interrupt is detected, the flag register will have that bit set, and that interrupt taken when interrupts are enabled again (at return from interrupts if no separate action is taken).
http://www.atmel.com/Images/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_%20Datasheet.pdf
If you want to, you could implement code that enables interrupt during that interrupt service routine, but you have to make sure that the code after such a point is fully re-entrant, and/or mask the current interrupt (some interrupt service routines are pretty darn hard to handle when you don't get another interrupt soon after, and it gets almost impossible if you get another one when you are currently in that handler). However, it is often the case for proper operating systems to enable all other interrupts - which means writing to the EIMSK register.
As a general rule, it's best to simply collect the necessary information in the interrupt handler, store it away in "safe" place (circular buffers are good for this), and signal that new data is available to a regular task in the system, and process the data there.
[Additionally, as far as I can tell, there is nothing stopping function calls inside an interrupt - as long as you understand what you are doing and there is no problems for example from calling the function from both the interrupt and the regular code at the same time]