Verified Commit 4f339d60 authored by SIMONIN Matthieu's avatar SIMONIN Matthieu
Browse files

add some element about interruptions

parent b1663bd3
Pipeline #153907 failed with stages
in 2 minutes and 26 seconds
* MMIO management
- MMIO: https://en.wikipedia.org/wiki/Memory-mapped_I%2FO
- Question: What happens when the guest want to output a network packet ?
- Configuration under consideration:
+ full emulation (soft qemu, tcg accelerated) with e1000 emulated network card (network frontend) and and a TAP network backend
+ example of corresponding command:
~qemu-system-x86_64 --accel tcg -m 1g -drive file=tantap.qcow2 -netdev tap,id=mynet0,ifname=tap0,script=no,downscript=no -device e1000,netdev=mynet0,mac=52:55:00:d1:55:01~
* Guest to Host network communication : MMIO management
- Question: What happens when the guest want to output a network packet ?
- MMIO: https://en.wikipedia.org/wiki/Memory-mapped_I%2FO
- Initialisation
When the device is initialised it declares a MMIO region which is a special
Memory Region with callbacks associated for ~read~ and ~write~ operation.
......@@ -53,20 +54,44 @@
+ e.g for inc if the operant is a memory address it is detected and special load instruction is generated (instead of a move)
+ instruction for loading the operand (address in this case) is generated here: https://github.com/qemu/qemu/blob/v4.2.0/target/i386/translate.c#L1413
+ instruction for storing the operand (address in this case) is generated here: https://github.com/qemu/qemu/blob/v4.2.0/target/i386/translate.c#L439
+ Second phase: TCG to Host -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg.c#L4013
- ~tcg_gen_code~ go through all the TCG instructions -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg.c#L4131-L4138
- But now we have special ld/st instruction when memory is accessed.
this code is specific to the host arch. For i386: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L2255
for ld/st instruction -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L2527-L2538
opcode are macro generated by: https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg-opc.h#L52-L59
- For load/store opcode, qemu relies on a tlb to do guest to host address translation and proceed with the operations
+ e.g for ld instruction: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L2122-L2130
+ the host address from the TLB are generated: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1699
+ if a cache miss occurs (at the execution time (not now)) qemu generate a conditional jump: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1759-L1761
- When all the TCG instructions are generated, Qemu generates all the slow path blocks (needed in cas of cache miss)
+ here -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg.c#L4209
+ for i386/ld op: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1810
+ and here ... is the magic ... it generate a call to a c helper function: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1850
- ld/store helper calls ~io_readx~/~io_writex~ if the ~tlb_addr~ is flagged as an MMIO region: e.g https://github.com/qemu/qemu/blob/v4.2.0/accel/tcg/cputlb.c#L1715-L1718
+ Second phase: TCG to Host -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg.c#L4013
- ~tcg_gen_code~ go through all the TCG instructions -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg.c#L4131-L4138
- But now we have special ld/st instruction when memory is accessed.
this code is specific to the host arch. For i386: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L2255
for ld/st instruction -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L2527-L2538
opcode are macro generated by: https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg-opc.h#L52-L59
- For load/store opcode, qemu relies on a tlb to do guest to host address translation and proceed with the operations
+ e.g for ld instruction: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L2122-L2130
+ the host address from the TLB are generated: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1699
+ if a cache miss occurs (at the execution time (not now)) qemu generate a conditional jump: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1759-L1761
- When all the TCG instructions are generated, Qemu generates all the slow path blocks (needed in cas of cache miss)
+ here -- https://github.com/qemu/qemu/blob/v4.2.0/tcg/tcg.c#L4209
+ for i386/ld op: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1810
+ and here ... is the magic ... it generate a call to a c helper function: https://github.com/qemu/qemu/blob/v4.2.0/tcg/i386/tcg-target.inc.c#L1850
- ld/store helper calls ~io_readx~/~io_writex~ if the ~tlb_addr~ is flagged as an MMIO region: e.g https://github.com/qemu/qemu/blob/v4.2.0/accel/tcg/cputlb.c#L1715-L1718
- TODO who's flagging the ~tlb_addr~ as MMIO ?
* Host to Guest network communication: interruptions
- e1000 receive routine
+ a incoming packet on the TAP interface is seen by the main-loop
+ The TAP device has registered a callback when such event occur : ~tap.c:tap_send~
+ ~tap_send~ (after some indirection) call the ~receive~ method of the network frontend (the ~e1000~ emulated NIC)
-> ~e1000.c:e1000_receive_iov~
+ the network card has now the packet and uses DMA to write it somewhere in RAM
- calls ~pci_dma_write~ -- https://github.com/qemu/qemu/blob/v4.2.0/hw/net/e1000.c#L968
- This function eventually write in RAM the incoming packet: -- https://github.com/qemu/qemu/blob/v4.2.0/exec.c#L3132-L3135
(au passage cela va invalider tous les TB qui utiliserait les pages concernés.)
- ~e1000~ sets an interruption -- https://github.com/qemu/qemu/blob/v4.2.0/hw/net/e1000.c#L1013
+ TODO: understand why it will be seen by the CPU on the next loop.
- the interruption flows until reaching the CPU ( though pci and i8259 PIC)
- CPU hardware interruption in QEMU
+ in between two TB executions the CPU check the interruption status -- https://github.com/qemu/qemu/blob/v4.2.0/accel/tcg/cpu-exec.c#L715
+ cpu interruption routine is deferred to a specific harware (e.g x86) -- https://github.com/qemu/qemu/blob/v4.2.0/target/i386/cpu.c#L7061
+ which filter the interruption source (e.g hardware) -- https://github.com/qemu/qemu/blob/v4.2.0/target/i386/seg_helper.c#L1357-L1365
+ finally look up on the Interruption Table Descriptor to find the (kernel) interruption handler to call -- https://github.com/qemu/qemu/blob/v4.2.0/target/i386/seg_helper.c#L872-L879
+ TODO: understand how/when the packet is actually read by the guest driver (when the interruption handler is called ?)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment