Understanding Exception Handling in ARMv8

A traveler asked the old monk, “What did you do before you attained enlightenment?” The old monk replied, “Chopping wood, carrying water, and cooking.” The traveler asked, “And after attaining enlightenment?” The old monk said, “Chopping wood, carrying water, and cooking.” The traveler further inquired, “What does it mean to attain enlightenment?” The old monk replied, “Before enlightenment, when chopping wood, I thought about carrying water; when carrying water, I thought about cooking; after enlightenment, chopping wood is just chopping wood, carrying water is just carrying water, cooking is just cooking.”

Many times, ordinary days are extraordinary.

Last time we discussed the exception vector table in ARM v8 (click here for the previous episode). We used the data abort exception as an example. Suppose a data abort occurs at exception level EL1. It will jump from the exception vector table to the el1_sync assembly function.

Understanding Exception Handling in ARMv8

Line 270’s kernel_entry is an assembly macro used to save the exception context, storing relevant CPU registers onto the EL1 stack. This is similar to ARM32 code, where there will be a stack frame, and the size of this stack frame is S_FRAME_SIZE, which is software-defined rather than hardware-defined. This means you can implement a stack frame different from that of Linux.

Next, we read the value of the esr_el1 register. The full name of the ESR_EL1 register is the exception syndrome register, which can be referenced in Chapter D10.2.36 of the ARM v8 manual. This register is somewhat similar to the DFSR register in ARM v7. The specific definition of this register is in Chapter D10.2.39.

Understanding Exception Handling in ARMv8

In this register, the EC field stores the type of exception (exception class). For a current EL data abort, you can refer to the manual’s definition; when EC == 100101, it indicates that a data abort exception has occurred at the current EL.

Understanding Exception Handling in ARMv8

This value matches the definition of ESR_ELx_EC_DABT_CUR in line 273 of the code, which is defined in the arch/arm64/include/asm/esr.h file.

Understanding Exception Handling in ARMv8

Thus, according to line 274 of the code, it will jump to the el1_da assembly function. This function is also in the entry.S file.

Understanding Exception Handling in ARMv8

First, read the far_el1 register. This register is described in Chapter D10.2.40. It stores the virtual address that caused the exception, allowing the operating system to read this register to continue subsequent exception handling. It is quite similar to the DFAR register in ARM V7.

Understanding Exception Handling in ARMv8

The second step is to enable interrupts.

The third step is to jump to the do_mem_abort function.

Understanding Exception Handling in ARMv8

This function has three parameters, with the first and second parameters needing attention. The first parameter is the erroneous virtual address at the time of the exception, i.e., the value read from the FAR_EL1 register, while the second parameter is the ESR_EL1 register. However, the second parameter has many complexities.

The bits 26-31 of the ESR_EL1 register are the Exception class, and bits 0-24 are the ISS field. The interpretation of the ISS field varies depending on the exception class. In the case of a data abort, the ISS encoding can be found on page 2460 of the ARM v8 manual. See the image below.

Understanding Exception Handling in ARMv8

Bits 0-5 indicate the specific type of data abort that occurred. Taking the level 3 page table translation error as an example (translation fault level 3), we see that in the DFSC field, it is 000111, which is 7.

Understanding Exception Handling in ARMv8

Let’s look at the Linux kernel code; in the arch/arm64/mm/fault.c file, there is an array fault_info[]. Let’s see what corresponds to 7.

Understanding Exception Handling in ARMv8

We are surprised to find that the fault_info[] array at index 7 corresponds to level 3 translation fault, with the handling function being do_page_fault, as seen in line 386 of the code. You can count this array starting from 0.

Through these two episodes of the series, we have gone through the behind-the-scenes of exception handling in ARM V8. We hope this helps everyone. For more exciting content, please pay attention to the second season of Uncle Ben’s “Running Linux Kernel” video series.

Understanding Exception Handling in ARMv8

The Second Season Is Here

The eagerly awaited second season video is here. This time it combines process management, locking mechanisms, and interrupt management into one, more content at no extra cost. The flagship edition is still priced at 1199, now on special for 999.

Beginner Edition: Uncle Ben will thoroughly clarify the concepts related to process management, locking mechanisms, and interrupt management. For example:

  1. The lifecycle of a process

  2. Process control block

  3. The essence of process scheduling

  4. CFS scheduler

  5. How process switching works

  6. SMP load balancing

  7. What is big-little core scheduling

  8. Why do we need interrupts

  9. What ARMv7 and ARMv8 processors do when an interrupt occurs

  10. Low-level assembly handling of interrupts

  11. Interrupt bottom half and top half

  12. How to write a good interrupt handler

  13. What are soft interrupts

  14. How to play with tasklets and workqueues

  15. What is interrupt context

  16. Why do we need locks

  17. What are atomic operations

  18. How do ARMv7 and ARMv8 processors perform atomic operations

  19. What are memory barriers

  20. How to use spinlocks

  21. Semaphore or mutex, which one to choose

  22. How to use RCU

  23. Why add a lock here

The flagship edition includes all beginner edition content, along with the following features:

  1. Additional introduction to core code, achieving true autonomy.

  2. Comprehensive innovative experiments, Uncle Ben leads everyone to play with a small OS on Raspberry Pi.

  3. Interview guide, those interview questions that tortured us back in the day.

Understanding Exception Handling in ARMv8

The second season flagship and beginner editions are now hot for pre-order, expected to start shipping on August 28. Click “Read the original text” to enter the subscription page.

Subscription benefits for the flagship edition:

  1. For those who have subscribed to the first season flagship edition, you can get a 100 yuan cash back when subscribing to the second season flagship edition. Similarly, those who subscribe to both the first and second season flagship editions will also receive a 100 yuan cash back (the cash back is via WeChat).

  2. Those who subscribe to both the first and second season flagship editions and participate in the forwarding of Uncle Ben’s series can receive a signed new book of “Running Linux Kernel”. The new book is expected to be published around Double Eleven or Double Twelve in 2018.

[Previous Highlights]

The second season flagship edition is finally here, integrating process management, interrupt management, and locking mechanisms.

[Flagship Edition] First season flagship edition resource summary

Essential VIM+GIT

Preview of the traditional version of “Running Linux Kernel”

[Uncle Ben’s Notes 14] What Exceptions Are Handled in ARMv8 1

[Uncle Ben’s Notes 13] Matters Regarding Exception Handling

[Uncle Ben’s Notes 12] Must-know for Interviews: What Happens If a Page Fault Occurs in an Interrupt Handler? Why?

[Uncle Ben’s Notes 11] The Trouble Caused by malloc

[Uncle Ben’s Notes 10] Did the Interrupt Go “Down”?

[Uncle Ben’s Notes 9] GNU GCC Extensions 2

[Uncle Ben’s Notes 8] Extensions of GNU C Language

[Uncle Ben’s Notes 7] The Unreturnable C Language

[Uncle Ben’s Notes 6] Uncle, how to play with git?

[Uncle Ben’s Notes 5] What’s the difference between git rebase and git merge?

[Uncle Ben’s Notes 4] “Stack” Who Got Cheaper 2

[Uncle Ben’s Notes 3] “Stack” Who Got Cheaper?

[Uncle Ben’s Notes 2] Why Does Each Processing Mode in ARM32 Architecture Have a Separate Stack?

[Uncle Ben’s Notes 1] Why Does the do_page_fault Function Need to Determine User Mode or Kernel Mode?

LinuxCon 2018 Beijing Travelogue (1)

LinuxCon 2018 Beijing Uncle Ben’s Travelogue 2

Resources for “Running Linux Kernel” Migrated to Gitee

Key Points: Video Update on April 18

Code Introduction: How to Use QEMU for Step-by-Step Debugging of head.S

Code Introduction: Memory Management Initialization – Startup Assembly

Video Update: Introduction to Memory Management Code Framework

DMA Matters

Private VIP Group Q&A

Advanced Operations Skills: How to Graphically Step Through Kernel in RHEL/Centos 7?

First Release: Meltdown Vulnerability Analysis and Practice

[Running Linux Kernel] Hometown

Salute to Beyond

Leave a Comment