[커널 18차] 76-77주차

2022.11.12 22:24

kkr 조회 수:386

exception 완료

 

git :

https://github.com/iamroot18/5.10/commit/6de3bb5187eae9aa69a7a6bc570683c1bc91a8cb

https://github.com/iamroot18/5.10/commit/920b07300f7a0c3ea533d136bcefc91baec01e55

https://github.com/iamroot18/5.10/commit/81c78bfa7d4c45af6dfb1961c1d61c209dbda755

https://github.com/iamroot18/5.10/commit/be82bd40a371a05391f890dd255a5050f0411889

https://github.com/iamroot18/5.10/commit/829397b8e9a9a45fa55f40e98cfe06aa4a5f936d

https://github.com/iamroot18/5.10/commit/6096d76e81813bcb33e9f5f227b21a490fcd1b1a

 

diff --git a/README.md b/README.md
index 9dacd6ea30e0..3b3d290c097b 100644
--- a/README.md
+++ b/README.md
@@ -331,3 +331,7 @@
 - 2022.10.29, Zoom 온라인(6명 참석)
 - gicv3 - gic_of_init() 진행중
 
+### 76주차
+- 2022.11.05, Zoom 온라인(5명 참석)
+- exception 부터 irq 처리 흐름 진행중
+
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 1771cd2e5d38..1d752c3fb5ed 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -38,6 +38,11 @@ static __always_inline void gic_write_dir(u32 irq)
     isb();
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Interrupt Controller Interrupt Acknowledge Register를 읽어
+ * 인터럽트 번호를 알아온다.
+ */
 static inline u64 gic_read_iar_common(void)
 {
     u64 irqstat;
@@ -168,13 +173,17 @@ static inline u32 gic_read_rpr(void)
 
 /*
  * IAMROOT, 2022.10.08:
- * - priority masking 지원여부 확인.
+ * - GIC의 priority masking 지원여부 확인.
  */
 static inline bool gic_prio_masking_enabled(void)
 {
     return system_uses_irq_prio_masking();
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Pesudo-NMI 지원하는 시스템에서 일반 인터럽트를 disable 한다.
+ */
 static inline void gic_pmr_mask_irqs(void)
 {
     BUILD_BUG_ON(GICD_INT_DEF_PRI < (__GIC_PRIO_IRQOFF |
@@ -195,6 +204,10 @@ static inline void gic_pmr_mask_irqs(void)
     gic_write_pmr(GIC_PRIO_IRQOFF);
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * DAIF중 I와 F를 클리어한다.
+ */
 static inline void gic_arch_enable_irqs(void)
 {
     asm volatile ("msr daifclr, #3" : : : "memory");
diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h
index ccedf548dac9..98cc8cb94662 100644
--- a/arch/arm64/include/asm/asm-uaccess.h
+++ b/arch/arm64/include/asm/asm-uaccess.h
@@ -12,6 +12,14 @@
  * User access enabling/disabling macros.
  */
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
+/*
+ * IAMROOT, 2022.11.08:
+ * - uaccess(user access)
+ * 1. ttbr1_el1의 값을 가져와 asid를 지우고, reserved_pg_dir을 ttbr0_el1에 set한다.
+ * 2. ttbr1_e1에도 reserved asid(0 clear)로 set한다.
+ * ttbr0_el1에 asid가 0가된 reserved_pg_dir을 가리키게 함으로써 kernel이
+ * user space에 접근하는것을 막는다.
+ */
     .macro    __uaccess_ttbr0_disable, tmp1
     mrs    \tmp1, ttbr1_el1            // swapper_pg_dir
     bic    \tmp1, \tmp1, #TTBR_ASID_MASK
diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
index f1bba5fc61c4..c4ec2c138fdc 100644
--- a/arch/arm64/include/asm/asm_pointer_auth.h
+++ b/arch/arm64/include/asm/asm_pointer_auth.h
@@ -9,6 +9,11 @@
 
 #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - @tsk에서 thread.keys_kernel.apia의 lo, hi를 를 가져와서
+ *   SYS_APIAKEYLO_EL1, SYS_APIAKEYHI_EL1에 넣는다.
+ */
     .macro __ptrauth_keys_install_kernel_nosync tsk, tmp1, tmp2, tmp3
     mov    \tmp1, #THREAD_KEYS_KERNEL
     add    \tmp1, \tsk, \tmp1
@@ -48,6 +53,15 @@ alternative_else_nop_endif
  * thread.keys_user.ap* as offset exceeds the #imm offset range
  * so use the base value of ldp as thread.keys_user and offset as
  * thread.keys_user.ap*.
+ */
+/*
+ * IAMROOT, 2022.11.09:
+ * - papago
+ *   thread.keys_user.ap*는 오프셋이 #imm 오프셋 범위를 초과하므로 ldp의 기본 값을
+ *   thread.keys_user로 사용하고 오프셋을 thread.keys_user.ap*으로 사용합니다.
+ *
+ * - @tsk에서 thread.keys_user.apia의 lo, hi를 를 가져와서
+ *   SYS_APIAKEYLO_EL1, SYS_APIAKEYHI_EL1에 넣는다.
  */
     .macro __ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
     mov    \tmp1, #THREAD_KEYS_USER
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 06951ebfe90a..11b59cc4e258 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -81,6 +81,12 @@
     msr    daifclr, #8
     .endm
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * thread_info->flags에서 TIF_SINGLESTEP 플래그가 있는 경우에 한해
+ * software step control을 disable한다.
+ * (mdscr_el1.ss 비트를 clear한다.)
+ */
     .macro    disable_step_tsk, flgs, tmp
     tbz    \flgs, #TIF_SINGLESTEP, 9990f
     mrs    \tmp, mdscr_el1
@@ -90,6 +96,12 @@
 9990:
     .endm
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * thread_info->flags에서 TIF_SINGLESTEP 플래그가 있는 경우에 한해
+ * software step control을 enable한다.
+ * (mdscr_el1.ss 비트를 set한다.)
+ */
     /* call with daif masked */
     .macro    enable_step_tsk, flgs, tmp
     tbz    \flgs, #TIF_SINGLESTEP, 9990f
@@ -324,6 +336,12 @@ alternative_endif
      * @sym: The name of the per-cpu variable
      * @tmp: scratch register
      */
+/*
+ * IAMROOT, 2022.11.07:
+ * - @sym에 대한 pcpu address를 가져온다.
+ * - @tmp 임시 변수. cpu offset을 저장해놓는다.
+ *   dst = adr_l(sym) + tmp
+ */
     .macro ldr_this_cpu dst, sym, tmp
     adr_l    \dst, \sym
     get_this_cpu_offset \tmp
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index e1c79406d464..bccec8a412b7 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -69,6 +69,13 @@
  * and 0 otherwise.
  */
 #define array_index_mask_nospec array_index_mask_nospec
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 0 <= idx < sz
+ *   범위내라면 ~0
+ * - sz보다 크면 0으로 고정시킨다.
+ */
 static inline unsigned long array_index_mask_nospec(unsigned long idx,
                             unsigned long sz)
 {
diff --git a/arch/arm64/include/asm/daifflags.h b/arch/arm64/include/asm/daifflags.h
index 57b269c81ad3..76081f86a16e 100644
--- a/arch/arm64/include/asm/daifflags.h
+++ b/arch/arm64/include/asm/daifflags.h
@@ -13,12 +13,21 @@
 #include <asm/ptrace.h>
 
 #define DAIF_PROCCTX        0
+/*
+ * IAMROOT, 2022.11.07:
+ * - irq, fiq disable
+ */
 #define DAIF_PROCCTX_NOIRQ    (PSR_I_BIT | PSR_F_BIT)
 #define DAIF_ERRCTX        (PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
 #define DAIF_MASK        (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
 
 
 /* mask/save/unmask/restore all exceptions, including interrupts. */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - irq disable
+ */
 static inline void local_daif_mask(void)
 {
     WARN_ON(system_has_prio_mask_debugging() &&
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 29f97eb3dad4..c7bb3f3c0e3c 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -39,6 +39,11 @@
 #define ESR_ELx_EC_FPAC        (0x1C)    /* EL1 and above */
 /* Unallocated EC: 0x1D - 0x1E */
 #define ESR_ELx_EC_IMP_DEF    (0x1f)    /* EL3 only */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - LOW : low exception level
+ */
 #define ESR_ELx_EC_IABT_LOW    (0x20)
 #define ESR_ELx_EC_IABT_CUR    (0x21)
 #define ESR_ELx_EC_PC_ALIGN    (0x22)
@@ -102,6 +107,10 @@
 #define ESR_ELx_S1PTW        (UL(1) << ESR_ELx_S1PTW_SHIFT)
 
 /* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */
+/*
+ * IAMROOT, 2022.11.12:
+ * - ISS의 Data Fault Status Code.
+ */
 #define ESR_ELx_FSC        (0x3F)
 #define ESR_ELx_FSC_TYPE    (0x3C)
 #define ESR_ELx_FSC_LEVEL    (0x03)
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index c586cc0caf3c..bbfe40ceaf47 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -285,6 +285,10 @@
 #define THREAD_ALIGN        THREAD_SIZE
 #endif
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - THREAD_SIZE == page size
+ */
 #define IRQ_STACK_SIZE        THREAD_SIZE
 
 #define OVERFLOW_STACK_SIZE    SZ_4K
@@ -350,12 +354,22 @@
  *  Open-coded (swapper_pg_dir - reserved_pg_dir) as this cannot be calculated
  *  until link time.
  */
+/*
+ * IAMROOT, 2022.11.10:
+ * - vmlinux.lds.S를 참고하면 reserved_이 swapper_pg_dir에서 PAGE_SIZE만큼
+ *   멀리있다.
+ */
 #define RESERVED_SWAPPER_OFFSET    (PAGE_SIZE)
 
 /*
  *  Open-coded (swapper_pg_dir - tramp_pg_dir) as this cannot be calculated
  *  until link time.
  */
+/*
+ * IAMROOT, 2022.11.10:
+ * - vmlinux.lds.S를 참고하면 tramp_pg_dir이 swapper_pg_dir에서 2 PAGE_SIZE만큼
+ *   멀리있다.
+ */
 #define TRAMP_SWAPPER_OFFSET    (2 * PAGE_SIZE)
 
 #ifndef __ASSEMBLY__
@@ -412,6 +426,13 @@ static inline unsigned long kaslr_offset(void)
  * up with a tagged userland pointer. Clear the tag to get a sane pointer to
  * pass on to access_ok(), for instance.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   데이터 중단, 감시점 또는 명령 트랩을 처리할 때 태그가 지정된 사용자
+ *   영역 포인터로 끝날 수 있습니다. 예를 들어 access_ok()에 전달할 정상적인
+ *   포인터를 얻으려면 태그를 지우십시오.
+ */
 #define __untagged_addr(addr)    \
     ((__force __typeof__(addr))sign_extend64((__force u64)(addr), 55))
 
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index e9c30859f80c..1495c294264f 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -9,6 +9,9 @@
 
 #define MMCF_AARCH32    0x1    /* mm context flag for AArch32 executables */
 #define USER_ASID_BIT    48
+/*
+ * IAMROOT, 2022.11.10:
+ * - */
 #define USER_ASID_FLAG    (UL(1) << USER_ASID_BIT)
 #define TTBR_ASID_MASK    (UL(0xffff) << 48)
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 496dcebcb8c8..043dc88e8fd9 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -345,6 +345,14 @@ long get_tagged_addr_ctrl(struct task_struct *task);
     BUG_ON(!on_accessible_stack(current, current_stack_pointer, 1, &_info));    \
     _info.high;                                    \
 })
+
+/*
+ * IAMROOT, 2022.11.05: 
+ * 현재 태스크가 가리키는 스택 범위에 current_stack_pointer가 포함되는지 
+ * 여부를 알아온다.
+ * - current_stack_pointer(arch/arm64/include/asm/stack_pointer.h)
+ *   asm("sp")
+ */
 #define on_thread_stack()    (on_task_stack(current, current_stack_pointer, 1, NULL))
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 61617c32301e..9cf85b2eddc9 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -59,6 +59,12 @@
  *   명시적으로 요구합니다. 비트 GIC_PRIO_PSR_I_SET이 우선 순위 마스크에 포함되어 있으면
  *   PSR.I가 설정되어야 하고 일시적으로 인터럽트 비활성화가 IRQ 우선 순위에 의존하지
  *   않음을 나타냅니다.
+ * --------
+ *                 
+ *  GIC_PRIO_IRQON       0b1110_0000
+ *  __GIC_PRIO_IRQOFF    0b0110_0000   
+ *  __GIC_PRIO_IRQOFF_NS 0b1010_0000
+ *  GIC_PRIO_PSR_I_SET   0b0001_0000
  */
 #define GIC_PRIO_IRQON            0xe0
 #define __GIC_PRIO_IRQOFF        (GIC_PRIO_IRQON & ~0x80)
@@ -74,7 +80,7 @@
  *                ..
  *  0b1110_0000   0xe0 enable (0b1110_0000)               0b1111_0000 0xf0
  *                             ^
- *                             | 이 부분을 dsiable
+ *                             | 이 부분을 disable
  *                             v
  *  0b1010_0000   0xa0 normal irq(GICD_INT_DEF_PRI)       0b1101_0000 0xd0
  *  0b1010_0000   0xa0 disable (__GIC_PRIO_IRQOFF_NS) 
@@ -176,6 +182,14 @@
  *
  * This must have the value -1, for ABI compatibility with ptrace etc.
  */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   pt_regs.syscallno == NO_SYSCALL이면 스레드가 시스템 호출을 실행하지 않는
+ *   것입니다.
+ *
+ *   ptrace 등과의 ABI 호환성을 위해 이 값은 -1이어야 합니다.
+ */
 #define NO_SYSCALL (-1)
 
 #ifndef __ASSEMBLY__
@@ -254,6 +268,11 @@ struct pt_regs {
     s32 syscallno;
     u32 unused2;
 #endif
+/*
+ * IAMROOT, 2022.11.05: 
+ * Software_Delegated_Exception_Interface
+ */
+
     u64 sdei_ttbr1;
     /* Only valid when ARM64_HAS_IRQ_PRIO_MASKING is enabled. */
     u64 pmr_save;
@@ -295,11 +314,23 @@ static inline void forget_syscall(struct pt_regs *regs)
 #define processor_mode(regs) \
     ((regs)->pstate & PSR_MODE_MASK)
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Pesudo-NMI를 사용할 때 irq가 unmask 상태인지 여부를 알아온다.
+ */
 #define irqs_priority_unmasked(regs)                    \
     (system_uses_irq_prio_masking() ?                \
         (regs)->pmr_save == GIC_PRIO_IRQON :            \
         true)
 
+/*
+ * IAMROOT, 2022.11.10:
+ * - !((regs)->pstate & PSR_I_BIT)
+ *   I가 없고, 즉 daif의 interrupt가 켜져있고,
+ * - irqs_priority_unmasked(regs)
+ *   PMR이 ON인 상태
+ * daif도 I가 꺼져있고 PMR도 ON이면 interrupt가 가능한 상태다.
+ */
 #define interrupts_enabled(regs)            \
     (!((regs)->pstate & PSR_I_BIT) && irqs_priority_unmasked(regs))
 
@@ -366,6 +397,11 @@ static inline unsigned long pt_regs_read_reg(const struct pt_regs *regs, int r)
  * Write a register given an architectural register index r.
  * This handles the common case where 31 means XZR, not SP.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - @r registe numbver(X0~X30)
+ *   @val register에 들어갈 값.
+ */
 static inline void pt_regs_write_reg(struct pt_regs *regs, int r,
                      unsigned long val)
 {
diff --git a/arch/arm64/include/asm/rwonce.h b/arch/arm64/include/asm/rwonce.h
index 1bce62fa908a..384cfb85c5b0 100644
--- a/arch/arm64/include/asm/rwonce.h
+++ b/arch/arm64/include/asm/rwonce.h
@@ -13,6 +13,27 @@
 #ifndef BUILD_VDSO
 
 #ifdef CONFIG_AS_HAS_LDAPR
+/*
+ * IAMROOT, 2022.11.11:
+ * - consistency
+ *   https://www.youtube.com/watch?v=Fm8iUFM2iWU
+ *   https://www.cs.colostate.edu/~cs551/CourseNotes/Consistency/TypesConsistency.html
+ *   https://www.inf.ed.ac.uk/teaching/courses/pa/Notes/lecture07-sc.pdf
+ *   https://www.youtube.com/watch?v=6OLnU27wDb0
+ *   https://en.wikipedia.org/wiki/Release_consistency
+ *
+ * - processor consistency
+ *   https://en.wikipedia.org/wiki/Processor_consistency
+ *   process에 실행된 write의 순서가 다른 process에서 동일하게 read된다는것.
+ *
+ * - RCpc(release consistent processor consisten),
+ *   RCsc (release consistent sequential consistent)
+ *   https://stackoverflow.com/questions/68676666/armv8-3-meaning-of-rcpc
+ *   https://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf
+ *
+ * - ldapr(load acquire RCpc Register)
+ *   https://www.dpdk.org/wp-content/uploads/sites/35/2019/10/StateofC11Code.pdf
+ */
 #define __LOAD_RCPC(sfx, regs...)                    \
     ALTERNATIVE(                            \
         "ldar"    #sfx "\t" #regs,                \
@@ -33,6 +54,19 @@
  * READ_ONCE() definition with one that provides RCpc acquire semantics
  * when building with LTO.
  */
+/*
+ * IAMROOT, 2022.11.11:
+ * - papago
+ *   LTO로 빌드할 때 컴파일러가 READ_ONCE() 호출이 이끄는 주소 종속성을 제어
+ *   종속성으로 변환하고 결과적으로 CPU에 의한 유해한 재정렬을 허용할 위험이
+ *   증가합니다.
+ *
+ *   LTO로 구축할 때 RCpc 획득 의미 체계를 제공하는 일반 READ_ONCE() 정의를
+ *   재정의하여 이러한 변환이 무해한지 확인합니다.
+ *
+ * - LTO(Link Time Optimization)
+ *   https://gcc.gnu.org/wiki/LinkTimeOptimization
+ */
 #define __READ_ONCE(x)                            \
 ({                                    \
     typeof(&(x)) __x = &(x);                    \
diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
index 8297bccf0784..54dd5ca7744a 100644
--- a/arch/arm64/include/asm/scs.h
+++ b/arch/arm64/include/asm/scs.h
@@ -8,11 +8,17 @@
 
 #ifdef CONFIG_SHADOW_CALL_STACK
     scs_sp    .req    x18
-
+/*
+ * IAMROOT, 2022.11.08:
+ * - x18에 thread_info.scs_sp 를 load
+ */
     .macro scs_load tsk
     ldr    scs_sp, [\tsk, #TSK_TI_SCS_SP]
     .endm
-
+/*
+ * IAMROOT, 2022.11.08:
+ * - x18을 thread_ifo.scs_sp 로 넣기.
+ */
     .macro scs_save tsk
     str    scs_sp, [\tsk, #TSK_TI_SCS_SP]
     .endm
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 6d1344a40010..8bde34c14954 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -107,6 +107,10 @@ extern void __cpu_die(unsigned int cpu);
 extern void cpu_die(void);
 extern void cpu_die_early(void);
 
+/*
+ * IAMROOT, 2022.11.07:
+ * - cpu park.
+ */
 static inline void cpu_park_loop(void)
 {
     for (;;) {
diff --git a/arch/arm64/include/asm/spectre.h b/arch/arm64/include/asm/spectre.h
index f62ca39da6c5..e9c19e532a45 100644
--- a/arch/arm64/include/asm/spectre.h
+++ b/arch/arm64/include/asm/spectre.h
@@ -67,6 +67,11 @@ struct bp_hardening_data {
 
 DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * SoC에 SPECTRE_V2 이슈가 있는 경우 
+ * Branch predict 관련 취약점을 숨길 수 있는 콜백함수를 호출한다. 
+ */
 static inline void arm64_apply_bp_hardening(void)
 {
     struct bp_hardening_data *d;
diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 8aebc00c1718..cac44fc5160e 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -69,6 +69,10 @@ extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 
 DECLARE_PER_CPU(unsigned long *, irq_stack_ptr);
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 스택 포인터 + size가 low ~ high 범위에 있는지 여부를 알아온다.
+ */
 static inline bool on_stack(unsigned long sp, unsigned long size,
                 unsigned long low, unsigned long high,
                 enum stack_type type, struct stack_info *info)
@@ -87,6 +91,10 @@ static inline bool on_stack(unsigned long sp, unsigned long size,
     return true;
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * irq 전용 스택 범위에 스택 포인터 @sp + @size가 포함되는지 여부를 알아온다.
+ */
 static inline bool on_irq_stack(unsigned long sp, unsigned long size,
                 struct stack_info *info)
 {
@@ -96,6 +104,11 @@ static inline bool on_irq_stack(unsigned long sp, unsigned long size,
     return on_stack(sp, size, low, high, STACK_TYPE_IRQ, info);
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 태스크가 가리키는 스택 범위에 스택 포인터 @sp + @size가 포함되는지 
+ * 여부를 알아온다.
+ */
 static inline bool on_task_stack(const struct task_struct *tsk,
                  unsigned long sp, unsigned long size,
                  struct stack_info *info)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 5993d900f862..3444b95be800 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -23,6 +23,14 @@
  *    [11-8]  : CRm
  *    [7-5]   : Op2
  */
+/*
+ * IAMROOT, 2022.11.08:
+ * - 주석에 적혀있다 ARMv8 Ref System instruction class encoding overview 참고
+ * |31 30 29 28|27 26 25 24|23 22 21 20|19 18 16|15 12| 11 8| 7 5 4| 0|
+ * |1  1  0  1 0   1  0  1  0  0 |L | Op0 | OP1 | CRn | CRm | op2| Rt |
+ *  __________ ___________
+ *  d          5 
+ */
 #define Op0_shift    19
 #define Op0_mask    0x3
 #define Op1_shift    16
@@ -90,14 +98,49 @@
  *    CRm = Imm4 for the instruction.
  *    Rt = 0x1f
  */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   PSTATE 필드 수정 지침. 
+ *   Arm v8-A용 ARM ARM, 섹션 C.5.1.3 op0 == 0b00, 아키텍처 힌트,
+ *   장벽 및 CLREX, PSTATE 액세스, ARM DDI 0487 C.a에 따라 PSTATE 필드에
+ *   액세스하기 위한 시스템 명령어에는 다음 인코딩이 있습니다.
+ *   Op0 = 0, CRn = 4Op1, Op2는 수정된 PSTATE 필드를 인코딩하고 제약 조건을
+ *   정의합니다.
+ *   명령의 경우 CRm = Imm4입니다.
+ *   Rt = 0x1f.
+ */
 #define pstate_field(op1, op2)        ((op1) << Op1_shift | (op2) << Op2_shift)
 #define PSTATE_Imm_shift        CRm_shift
 
 #define PSTATE_PAN            pstate_field(0, 4)
 #define PSTATE_UAO            pstate_field(0, 3)
 #define PSTATE_SSBS            pstate_field(3, 1)
+/*
+ * IAMROOT, 2022.11.08:
+ * - TCO(Tag Check Override)
+ *   https://developer.arm.com/documentation/ddi0601/2020-12/AArch64-Registers/TCO--Tag-Check-Override
+ *   https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/SPSR-EL1--Saved-Program-Status-Register--EL1-
+ *   ARM ref. Chapter D6 Memory Tagging Extension
+ *   Tag Check Override. Set to the value of PSTATE.TCO on taking an exception to
+ *   EL1, and copied to PSTATE.TCO on executing an exception return operation in EL1.
+ *   When FEAT_MTE2 is not implemented, it is CONSTRAINED UNPREDICTABLE whether
+ *   this field is RES0 or behaves as if FEAT_MTE is implemented.
+ * - When the value of PSTATE.TCO is 1, all loads and stores are Tag Unchecked.
+ * - When PSTATE.TCO is 1, all loads and stores generate Tag Unchecked accesses.
+ * - set 0 : enable, set 1 : disable
+ */
 #define PSTATE_TCO            pstate_field(3, 4)
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - ARMv8 Ref System instruction class encoding overview 참고
+ * |31 30 29 28|27 26 25 24|23 22 21 20|19 18 16|15 14 13 12| 11 8| 7 5 4|3 2 1 0|
+ * |1  1  0  1 0   1  0  1  0  0 |0 | 0 0 | OP1 | 0  1  0 0 | CRm | op2|1 1 1 1 1|
+ *                                    Op0         CRn        
+ *  __________ ___________ ____________ _________ __________ ______ _____ _______
+ *  d          5           0            0         4          0      1     f
+ */
 #define SET_PSTATE_PAN(x)        __emit_inst(0xd500401f | PSTATE_PAN | ((!!x) << PSTATE_Imm_shift))
 #define SET_PSTATE_UAO(x)        __emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift))
 #define SET_PSTATE_SSBS(x)        __emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift))
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 6623c99f0984..fec3868dcdd3 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -60,6 +60,13 @@ int arch_dup_task_struct(struct task_struct *dst,
 
 #endif
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * thread_info->flags에서 사용되는 플래그들
+ * 가장 대표적인 것인 
+ *  - TIF_SIGPENDING (태스크에 시그널이 pending 상태)
+ *  - TIF_NEED_RESCHED (리스케쥴링 요청)
+ */
 #define TIF_SIGPENDING        0    /* signal pending */
 #define TIF_NEED_RESCHED    1    /* rescheduling necessary */
 #define TIF_NOTIFY_RESUME    2    /* callback before returning to user */
@@ -103,6 +110,10 @@ int arch_dup_task_struct(struct task_struct *dst,
                  _TIF_UPROBE | _TIF_MTE_ASYNC_FAULT | \
                  _TIF_NOTIFY_SIGNAL)
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - debug / log용
+ */
 #define _TIF_SYSCALL_WORK    (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
                  _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
                  _TIF_SYSCALL_EMU)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 868979dcbf4e..537ba887ed6c 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -3144,6 +3144,10 @@ static inline bool __attribute_const__ is_emulated(u32 id)
  * With CRm == 0, reg should be one of :
  * MIDR_EL1, MPIDR_EL1 or REVIDR_EL1.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - @id에 해당하는 value를 얻어온다.
+ */
 static inline int emulate_id_reg(u32 id, u64 *valp)
 {
     switch (id) {
@@ -3164,6 +3168,10 @@ static inline int emulate_id_reg(u32 id, u64 *valp)
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - @id에 해당하는 value를 찾아와서 @valp에 기록한다.
+ */
 static int emulate_sys_reg(u32 id, u64 *valp)
 {
     struct arm64_ftr_reg *regp;
@@ -3186,6 +3194,10 @@ static int emulate_sys_reg(u32 id, u64 *valp)
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - @sys_reg를 통해서 val을 얻어온후, regs에 기록한다.
+ */
 int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt)
 {
     int rc;
@@ -3199,6 +3211,10 @@ int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt)
     return rc;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - mrs emulate.
+ */
 static int emulate_mrs(struct pt_regs *regs, u32 insn)
 {
     u32 sys_reg, rt;
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 09368e4c5092..f039f868d35f 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -347,6 +347,10 @@ static int brk_handler(unsigned long unused, unsigned int esr,
 }
 NOKPROBE_SYMBOL(brk_handler);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - arm32 break 관련 inst인지 확인
+ */
 int aarch32_break_handler(struct pt_regs *regs)
 {
     u32 arm_instr;
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 32f9796c4ffe..d60985d55875 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -96,6 +96,14 @@ static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
  * Before this function is called it is not safe to call regular kernel code,
  * intrumentable code, or any code which may trigger an exception.
  */
+/*
+ * IAMROOT, 2022.11.07:
+ * - papago
+ *   사용자 모드에서 진입할 때 IRQ/컨텍스트 상태 관리를 처리합니다. 
+ *   이 함수가 호출되기 전에는 일반 커널 코드, 계측 가능 코드 또는 예외를
+ *   유발할 수 있는 모든 코드를 호출하는 것이 안전하지 않습니다.
+ * - dubug, context tracking 관련.
+ */
 static __always_inline void __enter_from_user_mode(void)
 {
     lockdep_hardirqs_off(CALLER_ADDR0);
@@ -104,6 +112,10 @@ static __always_inline void __enter_from_user_mode(void)
     trace_hardirqs_off_finish();
 }
 
+/*
+ * IAMROOT, 2022.11.07:
+ * - irq 진입시 debug, context tracking 관련 처리.
+ */
 static __always_inline void enter_from_user_mode(struct pt_regs *regs)
 {
     __enter_from_user_mode();
@@ -114,6 +126,10 @@ static __always_inline void enter_from_user_mode(struct pt_regs *regs)
  * After this function returns it is not safe to call regular kernel code,
  * intrumentable code, or any code which may trigger an exception.
  */
+/*
+ * IAMROOT, 2022.11.07:
+ * - irq 퇴장시 debug, context tracking 관련 처리.
+ */
 static __always_inline void __exit_to_user_mode(void)
 {
     trace_hardirqs_on_prepare();
@@ -121,7 +137,10 @@ static __always_inline void __exit_to_user_mode(void)
     user_enter_irqoff();
     lockdep_hardirqs_on(CALLER_ADDR0);
 }
-
+/*
+ * IAMROOT, 2022.11.07:
+ * - irq disable
+ */
 static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
 {
     unsigned long flags;
@@ -133,6 +152,10 @@ static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
         do_notify_resume(regs, flags);
 }
 
+/*
+ * IAMROOT, 2022.11.07:
+ * - irq disable
+ */
 static __always_inline void exit_to_user_mode(struct pt_regs *regs)
 {
     prepare_exit_to_user_mode(regs);
@@ -260,9 +283,33 @@ static void __sched arm64_preempt_schedule_irq(void)
         preempt_schedule_irq();
 }
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - @handler 실행
+ * - irq 흐름.
+ *   vectors(arch/arm64/kernel/entry.S)
+ *     |
+ *     |(kernel_ventry)
+ *     |(entry_handler)
+ *     |(el0_interrupt or el1_interrupt)
+ *     |(do_interrupt_handler) <---------- 현재
+ *     |(handler_arch_irq 실행) <----------/
+ *     v
+ *   chip handler(handler_arch_irq, gic의 경우 gic_handle_irq)
+ *     v
+ *   flow handler
+ *     v
+ *   irq_handler
+ */
 static void do_interrupt_handler(struct pt_regs *regs,
                  void (*handler)(struct pt_regs *))
 {
+/*
+ * IAMROOT, 2022.11.05: 
+ * sp가 현재 태스크의 스택 포인터 범위안에 존재하는 경우
+ * call_on_irq_stack() 내부에서 전용 irq 스택에 LR, SP를 백업하고,
+ * handler(regs)를 호출한다.
+ */
     if (on_thread_stack())
         call_on_irq_stack(regs, handler);
     else
@@ -457,6 +504,10 @@ asmlinkage void noinstr el1h_64_irq_handler(struct pt_regs *regs)
     el1_interrupt(regs, handle_arch_irq);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - handler_arch_fiq실행
+ */
 asmlinkage void noinstr el1h_64_fiq_handler(struct pt_regs *regs)
 {
     el1_interrupt(regs, handle_arch_fiq);
@@ -472,8 +523,16 @@ asmlinkage void noinstr el1h_64_error_handler(struct pt_regs *regs)
     arm64_exit_nmi(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - data fault
+ */
 static void noinstr el0_da(struct pt_regs *regs, unsigned long esr)
 {
+/*
+ * IAMROOT, 2022.11.12:
+ * - fault address register. fault 발생 주소를 가져온다.
+ */
     unsigned long far = read_sysreg(far_el1);
 
     enter_from_user_mode(regs);
@@ -482,6 +541,11 @@ static void noinstr el0_da(struct pt_regs *regs, unsigned long esr)
     exit_to_user_mode(regs);
 }
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - inst fault
+ */
 static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr)
 {
     unsigned long far = read_sysreg(far_el1);
@@ -500,6 +564,10 @@ static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr)
     exit_to_user_mode(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - warnning을 띄운다.
+ */
 static void noinstr el0_fpsimd_acc(struct pt_regs *regs, unsigned long esr)
 {
     enter_from_user_mode(regs);
@@ -553,6 +621,10 @@ static void noinstr el0_sp(struct pt_regs *regs, unsigned long esr)
     exit_to_user_mode(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - undef 처리.
+ */
 static void noinstr el0_undef(struct pt_regs *regs)
 {
     enter_from_user_mode(regs);
@@ -588,6 +660,10 @@ static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
     exit_to_user_mode(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - syscall
+ */
 static void noinstr el0_svc(struct pt_regs *regs)
 {
     enter_from_user_mode(regs);
@@ -604,51 +680,125 @@ static void noinstr el0_fpac(struct pt_regs *regs, unsigned long esr)
     exit_to_user_mode(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - 
+ */
 asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
 {
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - Exception Syndrome Register
+ */
     unsigned long esr = read_sysreg(esr_el1);
 
     switch (ESR_ELx_EC(esr)) {
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - systemcall
+ */
     case ESR_ELx_EC_SVC64:
         el0_svc(regs);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - data abort
+ */
     case ESR_ELx_EC_DABT_LOW:
         el0_da(regs, esr);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - inst abort
+ */
     case ESR_ELx_EC_IABT_LOW:
         el0_ia(regs, esr);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - advanced SIMD
+ */
     case ESR_ELx_EC_FP_ASIMD:
         el0_fpsimd_acc(regs, esr);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - SVE
+ */
     case ESR_ELx_EC_SVE:
         el0_sve_acc(regs, esr);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - float pointer
+ */
     case ESR_ELx_EC_FP_EXC64:
         el0_fpsimd_exc(regs, esr);
         break;
+/*
+ * IAMROOT, 2022.11.12:
+ * - mrs/msr exception
+ */
     case ESR_ELx_EC_SYS64:
+/*
+ * IAMROOT, 2022.11.12:
+ * - WFI,WFE exception
+ */
     case ESR_ELx_EC_WFx:
         el0_sys(regs, esr);
         break;
+/*
+ * IAMROOT, 2022.11.12:
+ * - sp align
+ */
     case ESR_ELx_EC_SP_ALIGN:
         el0_sp(regs, esr);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - pc align
+ */
     case ESR_ELx_EC_PC_ALIGN:
         el0_pc(regs, esr);
         break;
+/*
+ * IAMROOT, 2022.11.12:
+ * - undef inst
+ */
     case ESR_ELx_EC_UNKNOWN:
         el0_undef(regs);
         break;
+/*
+ * IAMROOT, 2022.11.12:
+ * - byte top ignore
+ */
     case ESR_ELx_EC_BTI:
         el0_bti(regs);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - debug용
+ */
     case ESR_ELx_EC_BREAKPT_LOW:
     case ESR_ELx_EC_SOFTSTP_LOW:
     case ESR_ELx_EC_WATCHPT_LOW:
     case ESR_ELx_EC_BRK64:
         el0_dbg(regs, esr);
         break;
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - point authentication exception
+ */
     case ESR_ELx_EC_FPAC:
         el0_fpac(regs, esr);
         break;
@@ -657,26 +807,59 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
     }
 }
 
+/*
+ * IAMROOT, 2022.11.07:
+ * - irq, fiq disable후 @handler 수행
+ */
 static void noinstr el0_interrupt(struct pt_regs *regs,
                   void (*handler)(struct pt_regs *))
 {
+/*
+ * IAMROOT, 2022.11.05: 
+ * 유저에서 진입하여 irq 처리가 시작 되기 전 trace 출력 등
+ */
     enter_from_user_mode(regs);
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * PSTATE의 DAIF 중 IF에 해당하는 irq & fiq를 1로 mask하여 두 기능을 disable한다.
+ */
     write_sysreg(DAIF_PROCCTX_NOIRQ, daif);
 
     if (regs->pc & BIT(55))
         arm64_apply_bp_hardening();
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 인터럽트 핸들러로 연동
+ */
     do_interrupt_handler(regs, handler);
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * irq 처리가 끝난 후 유저로 빠져나갈때의 trace 출력 등
+ */
     exit_to_user_mode(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 인터럽트가 진입하는 경우 대표 인터럽트 컨트롤러의 핸들러로 향한다.
+ * 예) GICv3: gic_handle_irq
+ * - handle_arch_irq
+ *   arch/arm64/kernel/irq.c
+ *   gic의 경우 gic_init_bases-> set_handle_irq를 통해서 gic_handle_irq가 설정된다.
+ */
 static void noinstr __el0_irq_handler_common(struct pt_regs *regs)
 {
     el0_interrupt(regs, handle_arch_irq);
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 64bit user appl ----(irq)-----> vectors -> 아래 핸들러 호출
+ */
+
 asmlinkage void noinstr el0t_64_irq_handler(struct pt_regs *regs)
 {
     __el0_irq_handler_common(regs);
@@ -793,6 +976,10 @@ UNHANDLED(el0t, 32, error)
 #endif /* CONFIG_COMPAT */
 
 #ifdef CONFIG_VMAP_STACK
+/*
+ * IAMROOT, 2022.11.07:
+ * - interrupt수행중 overflow_stack시 진입.  arm64_enter_nmi, regs print후 죽는다
+ */
 asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
 {
     unsigned int esr = read_sysreg(esr_el1);
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index ece280f2f7bc..a9319d11a998 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -29,6 +29,10 @@
 #include <asm/asm-uaccess.h>
 #include <asm/unistd.h>
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - x0 ~ x29까지 mov xN, xzr
+ */
     .macro    clear_gp_regs
     .irp    n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
     mov    x\n, xzr
@@ -40,10 +44,108 @@
  * 인자로 만들어지는 branch 함수들은 entry_handler macro에 의해 만들어지는
  * 함수들이며 결국 해당 함수에서 _handler가 붙은 함수를 호출한다.
  * ex) el1h_64_sync -> el1h_64_sync_handler
+ */
+/*
+ * IAMROOT, 2022.11.07:
+ * - macro 정리
+ *   el ht regsize label
+ *   1  t  64      sync    
+ *   1  t  64      irq    
+ *   1  t  64      fiq    
+ *   1  t  64      error
+ *                
+ *   1  h  64      sync    
+ *   1  h  64      irq        
+ *   1  h  64      fiq        
+ *   1  h  64      error    
+ *                
+ *   0  t  64      sync
+ *   0  t  64      irq    
+ *   0  t  64      fiq    
+ *   0  t  64      error
+ *                
+ *   0  t  32      sync
+ *   0  t  32      irq        
+ *   0  t  32      fiq        
+ *   0  t  32      error        
+ * - ex) el1 64bit irq발생시 흐름
+ *   vectors
+ *     v
+ *   kernel_ventry 1, h, 64, irq  <--현재 여기
+ *     v
+ *   el1h_64_irq
+ *     v
+ *   kernel_entry 1, 64
+ *     v
+ *   el1h_64_irq_handler
+ *     v
+ *   (chip -> flow -> irq handler 수행후 복귀)
+ *     v
+ *   ret_to_kernel
+ *
+ * - irq 흐름.
+ *   vectors(arch/arm64/kernel/entry.S)
+ *     |
+ *     |(kernel_ventry) <--현재 여기
+ *     |(entry_handler)
+ *     |(el0_interrupt or el1_interrupt)
+ *     |(do_interrupt_handler) 
+ *     |(handler_arch_irq 실행) 
+ *     v
+ *   chip handler(handler_arch_irq, gic의 경우 gic_handle_irq)
+ *     v
+ *   flow handler(handle_fasteoi_nmi()등)
+ *     v
+ *   irq_handler(user isr)
  */
     .macro kernel_ventry, el:req, ht:req, regsize:req, label:req
     .align 7
+/*
+ * IAMROOT, 2022.11.07:
+ * - UNMAP_KERNEL_AT_EL0
+ *   bool "Unmap kernel when running in userspace (aka \"KAISER\")" if EXPERT
+ *   default y
+ *   help
+ *   Speculation attacks against some high-performance processors can
+ *   be used to bypass MMU permission checks and leak kernel data to
+ *   userspace. This can be defended against by unmapping the kernel
+ *   when running in userspace, mapping it back in on exception entry
+ *   via a trampoline page in the vector table.  
+ *   -- papago
+ *   일부 고성능 프로세서에 대한 추측 공격은 MMU 권한 검사를 우회하고 커널
+ *   데이터를 사용자 공간으로 유출하는 데 사용할 수 있습니다. 이것은 사용자
+ *   공간에서 실행될 때 커널을 매핑 해제하고 벡터 테이블의 트램폴린 페이지를
+ *   통해 예외 항목에 다시 매핑하여 방어할 수 있습니다.
+ *
+ *   user 영역에서 kernel영역이 보이지 않게 unmap을 하겠다는것.
+ */
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+/*
+ * IAMROOT, 2022.11.07:
+ * - tpidrro_el0은 원래용도로 사용안하고 scratch로 사용한다.
+ * - CONFIG_UNMAP_KERNEL_AT_EL0을 사용했다는건 exception이 tramp_ventry
+ *   를 통해서 진입을 한 상태고 tramp_ventry에서 tpidrro_el0에
+ *   x30(lr)을 넣어놓은 상태이다. 해당 값을 x30으로 다시 가져오고
+ *   tpidrro_el0를 지워놓는다.
+ *
+ * - tpidrro_el0의 원래 용도.
+ *   TPIDRRO_EL0, EL0 Read-Only Software Thread ID Register
+ *   참고) https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/TPIDRRO-EL0--EL0-Read-Only-Software-Thread-ID-Register
+ *   Provides a location where software executing at EL1 or higher can store
+ *   thread identifying information that is visible to software executing
+ *   at EL0, for OS management purposes.
+ *
+ *   The PE makes no use of this register.
+ *   -- papago
+ *   OS 관리 목적으로 EL1 이상에서 실행되는 소프트웨어가 EL0에서 실행하는
+ *   소프트웨어에 표시되는 스레드 식별 정보를 저장할 수 있는 위치를 제공합니다.
+ *   PE는 이 레지스터를 사용하지 않습니다.
+ *
+ *   -- Bits [63:0]
+ *   Thread ID. Thread identifying information stored by software running at
+ *   this Exception level.
+ *
+ */
     .if    \el == 0
 alternative_if ARM64_UNMAP_KERNEL_AT_EL0
     .if    \regsize == 64
@@ -56,6 +158,10 @@ alternative_else_nop_endif
     .endif
 #endif
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * context save(모든 레지스터)를 위해 struct pt_regs 구조체 크기만 스택을 확보한다.
+ */
     sub    sp, sp, #PT_REGS_SIZE
 #ifdef CONFIG_VMAP_STACK
     /*
@@ -63,11 +169,69 @@ alternative_else_nop_endif
      * Task and IRQ stacks are aligned so that SP & (1 << THREAD_SHIFT)
      * should always be zero.
      */
+/*
+ * IAMROOT, 2022.11.07:
+ * -papago
+ *  GPR을 손상시키지 않고 SP가 오버플로되었는지 테스트합니다.
+ *  Task 및 IRQ 스택은 SP & (1 << THREAD_SHIFT)가 항상 0이 되도록 정렬됩니다.
+ *
+ * - x0에 stack size를 구한다. stack size는 THREAD_SHIFT로 정렬되잇다.
+ *   THREAD_SHIFT bit가 깨지면 align이 깨졌다고 러프하게 판단한다.
+ *
+ * - sp <-> x0값을 교환해서 sp를 검사하는 방식으로 수행한다.
+ *   register끼리의 교환이므로 속도가 빠르다.
+ *
+ * - add sp, sp, x0 --> sp : sp(old) + x0(old)
+ *   sub x0, sp, x0 --> x0 : sp - x0(old) = sp(old) + x0(old) - x0(old) = sp(old).
+ *                      x0에 sp(old) 위치완료.
+ *   tbnz    x0, #THREAD_SHIFT, 0f --> x0(old sp) 의 THREAD_SHIFT bit 검사.
+ *                                    0가 아니면 깨진것으로 판단
+ *   sub x0, sp, x0 --> x0 : sp - x0 = (sp(old) + x0(old)) - sp(old) = x0(old)
+ *                      x0원복 완료
+ *   sub sp, sp, x0 --> sp : sp - x0(old) = sp(old) + x0(old) - x0(old)
+ *                      sp 원복 완료
+ */
     add    sp, sp, x0            // sp' = sp + x0
     sub    x0, sp, x0            // x0' = sp' - x0 = (sp + x0) - x0 = sp
     tbnz    x0, #THREAD_SHIFT, 0f
     sub    x0, sp, x0            // x0'' = sp' - x0' = (sp + x0) - sp = x0
     sub    sp, sp, x0            // sp'' = sp' - x0 = (sp + x0) - x0 = sp
+/*
+ * IAMROOT, 2022.11.07:
+ * - entry_handler 참고
+ *   el1t_64_sync    
+ *   el1t_64_irq    
+ *   el1t_64_fiq    
+ *   el1t_64_error
+ *  
+ *   el1h_64_sync    
+ *   el1h_64_irq        
+ *   el1h_64_fiq        
+ *   el1h_64_error    
+ *  
+ *   el0t_64_sync
+ *   el0t_64_irq    
+ *   el0t_64_fiq    
+ *   el0t_64_error
+ *  
+ *   el0t_32_sync
+ *   el0t_32_irq        
+ *   el0t_32_fiq        
+ *   el0t_32_error        
+ *
+ * - ex) el1 64bit irq발생시 flow
+ *   vectors 
+ *     v
+ *   kernel_ventry 1, h, 64, irq
+ *     v
+ *   el1h_64_irq <-- 여기로 이제 진입.
+ *     v
+ *   kernel_entry 1, 64
+ *     v
+ *   el1h_64_irq_handler
+ *     v
+ *   ret_to_kernel
+ */
     b    el\el\ht\()_\regsize\()_\label
 
 0:
@@ -78,19 +242,52 @@ alternative_else_nop_endif
      */
 
     /* Stash the original SP (minus PT_REGS_SIZE) in tpidr_el0. */
+/*
+ * IAMROOT, 2022.11.07:
+ * - papago
+ *   방금 오버플로를 감지했거나 오버플로 스택에서 예외가 발생했습니다.
+ *   어느 쪽이든, 우리는 사용자 공간으로 돌아가지 않을 것이며 GPR을 해제하기
+ *   위해 EL0 레지스터를 방해할 수 있습니다.
+ *
+ *   원래 SP(PT_REGS_SIZE 빼기)를 tpidr_el0에 숨깁니다.
+ * - 여기 라벨이 온시점에 x0엔 sp가 있을것이다. 그걸 tpidr_el0로 넣어놓는다.
+ */
     msr    tpidr_el0, x0
 
     /* Recover the original x0 value and stash it in tpidrro_el0 */
+/*
+ * IAMROOT, 2022.11.07:
+ * - x0도 원래의 x0값으로 원복해주고 tpidrro_el0에 넣어놓는다.
+ */
     sub    x0, sp, x0
     msr    tpidrro_el0, x0
 
     /* Switch to the overflow stack */
+/*
+ * IAMROOT, 2022.11.07:
+ * - adr_this_cpu
+ *   arch/arm64/include/asm/stacktrace.h 에 pcpu로 overflow_stack이 정의되있다.
+ *   현재 cpu에 대한 pcpu address를 가져온다.
+ * - overflow_stack + OVERFLOW_STACK_SIZE 의 현재 cpu에 대한 pcpu address를
+ *   가져와 sp로 사용한다.
+ *   x0는 임시변수로 쓴다.
+ */
     adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0
 
     /*
      * Check whether we were already on the overflow stack. This may happen
      * after panic() re-enables interrupts.
      */
+/*
+ * IAMROOT, 2022.11.07:
+ * - tpider_el0에 저장되있는 old sp를 가져와서 현재 sp와 비교한다
+ *   OVERFLOW_STACK_SIZE보다 차이가 안난다면 overflow stack처리과정에서 다시한번
+ *   overflow stack처리로 진입하게 된것이다.
+ *
+ * - tst is 0 => 이미 overflow_stack 진입한 상태. __bad_stack으로
+ *               안가고 entry_handler로 간다. 어짜피 곧 죽을거 적당히 처리하는듯.
+ *   not 0 => overflow_stack으로 진입하기 시작. __bad_stack으로 이동한다.
+ */
     mrs    x0, tpidr_el0            // sp of interrupted context
     sub    x0, sp, x0            // delta with top of overflow stack
     tst    x0, #~(OVERFLOW_STACK_SIZE - 1)    // within range?
@@ -100,9 +297,19 @@ alternative_else_nop_endif
     sub    sp, sp, x0
     mrs    x0, tpidrro_el0
 #endif
+/*
+ * IAMROOT, 2022.11.05: 
+ * 예) el0 64bit user -----(irq)----> b el0t_64_irq
+ * entry_handler 참고
+ */
+
     b    el\el\ht\()_\regsize\()_\label
     .endm
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - TRAMP_VALIAS + offset으로  sym의 주소를 얻어온다.
+ */
     .macro tramp_alias, dst, sym
     mov_q    \dst, TRAMP_VALIAS
     add    \dst, \dst, #(\sym - .entry.tramp.text)
@@ -112,6 +319,11 @@ alternative_else_nop_endif
      * This macro corrupts x0-x3. It is the caller's duty  to save/restore
      * them if required.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - SSBD(Speculative Store Bypass Disabl)
+ * - SKIP
+ */
     .macro    apply_ssbd, state, tmp1, tmp2
 alternative_cb    spectre_v4_patch_fw_mitigation_enable
     b    .L__asm_ssbd_skip\@        // Patched to NOP
@@ -129,6 +341,17 @@ alternative_cb_end
     .endm
 
     /* Check for MTE asynchronous tag check faults */
+/*
+ * IAMROOT, 2022.11.08:
+ * - async tag check fault mode 인지 확인.
+ *   맞다면 SYS_TFSR_EL1_TF0_SHIFT를 검사했는지 확인하고 발생했으면
+ *   ti-flags에 _TIF_MTE_ASYNC_FAULT를 추가한다.
+ *
+ * - tcf(tag check fault)
+ *   Documentation/arm64/memory-tagging-extension.rst
+ * - SCTLR_EL1_TCF0_SHIFT + 1가 set됬으면
+ *   Tag Check Faults are asynchronously accumulated.
+ */
     .macro check_mte_async_tcf, tmp, ti_flags, thread_sctlr
 #ifdef CONFIG_ARM64_MTE
     .arch_extension lse
@@ -140,18 +363,41 @@ alternative_else_nop_endif
      * ASYM (3) modes. In each of these modes bit 1 of SCTLR_EL1.TCF0 is
      * set, so skip the check if it is unset.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   비동기식 태그 검사 오류는 ASYNC(2) 또는 ASYM(3) 모드에서만 가능합니다.
+ *   이러한 각 모드에서 SCTLR_EL1.TCF0의 비트 1이 설정되므로 설정되지 않은 경우
+ *   확인을 건너뜁니다.
+ * - async tcf mode인지 확인한다. 아니면 1f로 이동하고 종료
+ */
     tbz    \thread_sctlr, #(SCTLR_EL1_TCF0_SHIFT + 1), 1f
     mrs_s    \tmp, SYS_TFSRE0_EL1
+/*
+ * IAMROOT, 2022.11.08:
+ * - SYS_TFSR_EL1_TF0_SHIFT를 검사한다. set되있다면 async tcf가 발생한것이므로
+ *   ti_flags에 _TIF_MTE_ASYNC_FAULT flag bit를 추가해준다. 이는 추후 처리된다.
+ */
     tbz    \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f
     /* Asynchronous TCF occurred for TTBR0 access, set the TI flag */
     mov    \tmp, #_TIF_MTE_ASYNC_FAULT
     add    \ti_flags, tsk, #TSK_TI_FLAGS
+/*
+ * IAMROOT, 2022.11.08:
+ * - stset
+ *  ti_flags |= tmp
+ *  https://developer.arm.com/documentation/dui0801/g/A64-Data-Transfer-Instructions/STSET--STSETL--STSETL
+ */
     stset    \tmp, [\ti_flags]
 1:
 #endif
     .endm
 
     /* Clear the MTE asynchronous tag check faults */
+/*
+ * IAMROOT, 2022.11.09:
+ * - async2, async3 mode인지 판단하여 clear
+ */
     .macro clear_mte_async_tcf thread_sctlr
 #ifdef CONFIG_ARM64_MTE
 alternative_if ARM64_MTE
@@ -172,6 +418,10 @@ alternative_else_nop_endif
 #endif
     .endm
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - kernel의 gcr 설정값을 hw에 적용한다.
+ */
     .macro mte_set_kernel_gcr, tmp, tmp2
 #ifdef CONFIG_KASAN_HW_TAGS
 alternative_if_not ARM64_MTE
@@ -183,6 +433,10 @@ alternative_else_nop_endif
 #endif
     .endm
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - user(tsk)의 gcr 설정값을 hw에 적용한다.
+ */
     .macro mte_set_user_gcr, tsk, tmp, tmp2
 #ifdef CONFIG_ARM64_MTE
 alternative_if_not ARM64_MTE
@@ -195,7 +449,20 @@ alternative_else_nop_endif
 #endif
     .endm
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * - @x0 pt_regs 저장할 주소
+ * exception이 발생하여 context 를 백업한다. (전체 레지스터)
+ * 그 외 mte, ptr_auth, hw debuger 관련 동작 등을 체크한다.
+ */
     .macro    kernel_entry, el, regsize = 64
+/*
+ * IAMROOT, 2022.11.05: 
+ * 32bit 유저에서 진입한 경우 x0의 상위 32비트를 클리어한다.
+ * - pt_regs 상태
+ *   regs[0~28] = registers
+ *   regs[29]   =  x29(fp)
+ */
     .if    \regsize == 32
     mov    w0, w0                // zero upper 32 bits of x0
     .endif
@@ -215,7 +482,23 @@ alternative_else_nop_endif
     stp    x26, x27, [sp, #16 * 13]
     stp    x28, x29, [sp, #16 * 14]
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - el0
+ */
     .if    \el == 0
+/*
+ * IAMROOT, 2022.11.08:
+ * 1. x0~x29 clear
+ * 2. sp_el0를 x21에 backup
+ * 3. tsk(x29), sp_el0 에 pcp __entry_task(armch/arm64/process.c) 를 가져온다.
+ *   (pcp task_struct *)
+ * - sp_el0
+ *   user에서 kernel mode를 진입할때 current task를 저장하고 kernel mode에서는
+ *   현재 thread_info를 빠르게 알아내는 용도로 사용한다.
+ * 4. ss(debug single step), MTE, PAC, SCS, SSBD 처리
+ *
+*/
     clear_gp_regs
     mrs    x21, sp_el0
     ldr_this_cpu    tsk, __entry_task, x20
@@ -226,12 +509,26 @@ alternative_else_nop_endif
      * when scheduling.
      */
     ldr    x19, [tsk, #TSK_TI_FLAGS]
+/*
+ * IAMROOT, 2022.11.09:
+ * - ret_to_user등에서 다시 enable한다.
+ */
     disable_step_tsk x19, x20
 
     /* Check for asynchronous tag check faults in user space */
     ldr    x0, [tsk, THREAD_SCTLR_USER]
     check_mte_async_tcf x22, x23, x0
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - PAC(Pointer Authentication)
+ *   Documentation/arm64/pointer-authentication.rst
+ *   https://www.kernel.org/doc/html/latest/arm64/pointer-authentication.html
+ *   https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/code-reuse-attacks-the-compiler-story
+ * - ENAI
+ *   Controls enabling of pointer authentication (using the APIAKey_EL1 key)
+ *   of instruction addresses in the EL1&0 translation regime.
+ */
 #ifdef CONFIG_ARM64_PTR_AUTH
 alternative_if ARM64_HAS_ADDRESS_AUTH
     /*
@@ -243,6 +540,18 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
      * was disabled on kernel exit then we would have left the kernel IA
      * installed so there is no need to install it again.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   task에서 비활성화된 경우 커널 내 PAC에 대해 IA를 활성화합니다. 이것은
+ *   부하를 피하는 무조건적인 MRS로 구현할 수 있지만 Cortex-A75 및
+ *   Cortex-A76에서 더 느린 것으로 측정되었습니다.
+ *
+ *   task에서 IA가 활성화된 경우에만 커널 IA 키를 설치합니다. kernel exit시
+ *   IA가 비활성화된 경우 커널 IA가 설치된 상태로남아 있으므로 다시 설치할
+ *   필요가 없습니다.
+ * - PAC IA가 disable되있다면 install한다. 
+ */
     tbz    x0, SCTLR_ELx_ENIA_SHIFT, 1f
     __ptrauth_keys_install_kernel_nosync tsk, x20, x22, x23
     b    2f
@@ -262,6 +571,10 @@ alternative_else_nop_endif
      * Any non-self-synchronizing system register updates required for
      * kernel entry should be placed before this point.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - MTE, PAC 둘중하나라도 사용중이라면 isb를 한번 하겠다는것.
+ */
 alternative_if ARM64_MTE
     isb
     b    1f
@@ -272,10 +585,27 @@ alternative_else_nop_endif
 1:
 
     scs_load tsk
+/*
+ * IAMROOT, 2022.11.08:
+ * - el1
+ *   1. el0와는 다르게 register clear를 안한다.
+ *   2. sp를 x21에 백업한다.
+ *   3. task를 current task로 그대로 사용한다.
+ */
     .else
     add    x21, sp, #PT_REGS_SIZE
     get_current_task tsk
     .endif /* \el == 0 */
+/*
+ * IAMROOT, 2022.11.08:
+ * - elr_el1, spsr_el1을 x22, x23에 백업한다.
+ * - lr, x21(backup sp)를 sp(pt_regs.regs[30], pt_regs.sp)에 backup한다.
+ * - pt_regs 상태
+ *   regs[0~28] = registers
+ *   regs[29] =  x29(fp)
+ *   regs[30] = lr
+ *   sp = sp(before) + PT_REGS_SIZE
+ */
     mrs    x22, elr_el1
     mrs    x23, spsr_el1
     stp    lr, x21, [sp, #S_LR]
@@ -285,6 +615,22 @@ alternative_else_nop_endif
      * For exceptions from EL1, create a synthetic frame record so the
      * interrupted code shows up in the backtrace.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   EL0의 예외에 대해 최종 프레임 레코드를 생성합니다. 
+ *   EL1 예외의 경우 중단된 코드가 역추적에 표시되도록 합성 프레임 레코드를
+ *   만듭니다.
+ *
+ * - el1인 경우 fp, elr_el1이 backup될것이다.
+ * - pt_regs 상태
+ *   regs[0~28]    = registers
+ *   regs[29]      = x29(fp)
+ *   regs[30]      = lr
+ *   sp            = sp(before) + PT_REGS_SIZE
+ *   stackframe[0] = el0: 0, el1: fp
+ *   stackframe[1] = el0: 0, el1: elr_el1
+ */
     .if \el == 0
     stp    xzr, xzr, [sp, #S_STACKFRAME]
     .else
@@ -294,10 +640,26 @@ alternative_else_nop_endif
 
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
 alternative_if_not ARM64_HAS_PAN
+/*
+ * IAMROOT, 2022.11.08:
+ * - el1인 경우 이미 disabled 됬을 경우 x23(backup spsr)에 PSR_PAN_BIT가
+ *   추가될 수 있다.
+ */
     bl    __swpan_entry_el\el
 alternative_else_nop_endif
 #endif
-
+/*
+ * IAMROOT, 2022.11.08:
+ * - pt_regs 상태
+ *   regs[0~28]    = registers
+ *   regs[29]      = x29(fp)
+ *   regs[30]      = lr
+ *   sp            = sp(before) + PT_REGS_SIZE
+ *   stackframe[0] = el0: 0, el1: fp
+ *   stackframe[1] = el0: 0, el1: elr_el1
+ *   pc            = elr_el1
+ *   pstate        = spsr
+ */
     stp    x22, x23, [sp, #S_PC]
 
     /* Not in a syscall by default (el0_svc overwrites for real syscall) */
@@ -305,17 +667,53 @@ alternative_else_nop_endif
     mov    w21, #NO_SYSCALL
     str    w21, [sp, #S_SYSCALLNO]
     .endif
+/*
+ * IAMROOT, 2022.11.08:
+ * - pt_regs 상태
+ *   regs[0~28]    = registers
+ *   regs[29]      = x29(fp)
+ *   regs[30]      = lr
+ *   sp            = sp + PT_REGS_SIZE
+ *   stackframe[0] = el0: 0, el1: fp
+ *   stackframe[1] = el0: 0, el1: elr_el1
+ *   pc            = elr_el1
+ *   pstate        = spsr
+ *   syscallno     = el0 : -1
+ */
 
     /* Save pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
     mrs_s    x20, SYS_ICC_PMR_EL1
+/*
+ * IAMROOT, 2022.11.08:
+ * - pt_regs 상태
+ *   regs[0~28]    = registers
+ *   regs[29]      = x29(fp)
+ *   regs[30]      = lr
+ *   sp            = sp + PT_REGS_SIZE
+ *   stackframe[0] = el0: 0, el1: fp
+ *   stackframe[1] = el0: 0, el1: elr_el1
+ *   pc            = elr_el1
+ *   pstate        = spsr
+ *   syscallno     = el0 : -1
+ *   pmr_save      = SYS_ICC_PMR_EL1(before)
+ */
     str    x20, [sp, #S_PMR_SAVE]
+/*
+ * IAMROOT, 2022.11.08:
+ * - git blame 참고
+ *   debug시 경고문때문인듯 하며 local_daif_save와 일관성을 유지한다.
+ */
     mov    x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
     msr_s    SYS_ICC_PMR_EL1, x20
 alternative_else_nop_endif
 
     /* Re-enable tag checking (TCO set on exception entry) */
 #ifdef CONFIG_ARM64_MTE
+/*
+ * IAMROOT, 2022.11.09:
+ * - set 0 를 함으로써 enable시킨다.
+ */
 alternative_if ARM64_MTE
     SET_PSTATE_TCO(0)
 alternative_else_nop_endif
@@ -331,11 +729,25 @@ alternative_else_nop_endif
     */
     .endm
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * exceptino 처리 후 커널 또는 유저로 복귀하기 전에 수행할 루틴
+ * - kernel_entry에서 백업해뒀던 값들을 복구한다.
+ */
     .macro    kernel_exit, el
+/*
+ * IAMROOT, 2022.11.05: 
+ * 커널로 북귀하는 경우 DAIF 플래그를 모두 disable 한다.
+ * el0의 경우 handler에서 이미 disable했었다.
+ */
     .if    \el != 0
     disable_daif
     .endif
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * kernel_entry에서 backup해두었던 pmr을 다시 복구한다.
+ */
     /* Restore pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
     ldr    x20, [sp, #S_PMR_SAVE]
@@ -348,18 +760,40 @@ alternative_else_nop_endif
 
     ldp    x21, x22, [sp, #S_PC]        // load ELR, SPSR
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * ttbr0를 조작하는 방법으로 즉, sw emulation 방법으로 커널에서 유저 영역의
+ * 가상 주소에 접근하지 못하게 한다.
+ * (최신 armv8에는 hardware 방식의 PAN 방식을 지원한다)
+ */
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
 alternative_if_not ARM64_HAS_PAN
     bl    __swpan_exit_el\el
 alternative_else_nop_endif
 #endif
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 유저용 sp를 복구한다.
+ */
+
     .if    \el == 0
     ldr    x23, [sp, #S_SP]        // load return stack pointer
     msr    sp_el0, x23
+/*
+ * IAMROOT, 2022.11.10:
+ * - x22에 #PSR_MODE32_BIT set.
+ *   tst => 1 => Z 0 => b.eq동작안함
+ * - x22에 #PSR_MODE32_BIT unset
+ *   tst => 0 => Z 1 => b.eq동작.
+ */
     tst    x22, #PSR_MODE32_BIT        // native task?
     b.eq    3f
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 32bit 유저로 돌아가는 경우에만 workaround 코드를 수행한다.
+ */
 #ifdef CONFIG_ARM64_ERRATUM_845719
 alternative_if ARM64_WORKAROUND_845719
 #ifdef CONFIG_PID_IN_CONTEXTIDR
@@ -371,8 +805,16 @@ alternative_if ARM64_WORKAROUND_845719
 alternative_else_nop_endif
 #endif
 3:
+/*
+ * IAMROOT, 2022.11.05: 
+ * shadow call stack 커널 옵션을 사용하는 경우엔 관련 정보도 복구한다.
+ */
     scs_save tsk
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * mte 관련
+ */
     /* Ignore asynchronous tag check faults in the uaccess routines */
     ldr    x0, [tsk, THREAD_SCTLR_USER]
     clear_mte_async_tcf x0
@@ -402,6 +844,10 @@ alternative_else_nop_endif
     apply_ssbd 0, x0, x1
     .endif
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 나머지 레지스터들을 복구한다.
+ */
     msr    elr_el1, x21            // set up the return data
     msr    spsr_el1, x22
     ldp    x0, x1, [sp, #16 * 0]
@@ -425,23 +871,72 @@ alternative_else_nop_endif
     .if    \el == 0
 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+/*
+ * IAMROOT, 2022.11.09:
+ * - el0
+ *   ARM64_UNMAP_KERNEL_AT_EL0가 없으면 eret을 하며 user로 복귀.
+ *   그게 아니면 nop가 대신 한번 실행되면서 해당 처리를 해준다.
+ *   kernel_ventry에서 64bit인경우 x30에 tramp_ventry에서 저장해놨던 lr,
+ *   32bit인경우 0를 저장해 놨엇다.
+ * - trampoline
+ *   https://en.wikipedia.org/wiki/Trampoline_(computing)
+ *   https://xiayingp.gitbook.io/build_a_os/traps-and-interrupts/untitled-3
+ *
+ * - 위에 tst    x22, #PSR_MODE32_BIT
+ *   이 code에서 user mode가 32bit인지 64bit인지 확인한채로 Z가
+ *   그대로 있는상태다.
+ *   64bit면 tramp_exit_native, 32bit면 tramp_exit_compat.
+ * - far_el1은 scratch register로 사용한다. x30(tramp_ventry에서 가져온 lr)을 여기서
+ *   far_el1에 넣어놓는다.
+ *   x30을 계속 다른용도로 사용해야되기 때문이다.
+ */
     bne    4f
     msr    far_el1, x30
+/*
+ * IAMROOT, 2022.11.09:
+ * - 각각의 가상주소를 가져와서 br tramp_exit_native, tramp_exit_compat로 넘어간다.
+ * - 해당함수에서 eret이 일어난다.
+ */
     tramp_alias    x30, tramp_exit_native
     br    x30
 4:
     tramp_alias    x30, tramp_exit_compat
     br    x30
 #endif
+/*
+ * IAMROOT, 2022.11.09:
+ * - el1인 경우 eret으로 el1 -> el1으로 복귀 되거나 할것이다.
+ */
     .else
     /* Ensure any device/NC reads complete */
     alternative_insn nop, "dmb sy", ARM64_WORKAROUND_1508412
 
     eret
     .endif
+/*
+ * IAMROOT, 2022.11.09:
+ * - SB(Speculation Barrier) sequence
+ *   (Git blame 참고, ARM ref. Speculation Barrier (SB) 참고)
+ *   https://developer.arm.com/documentation/ddi0597/2022-06/Base-Instructions/SB--Speculation-Barrier-
+ * - eret의 뒤에 보통 위치한다. 일부 cpu에서 eret지점에서 낮은 권한 수준에 의해 제어되고,
+ *   eret이 수행되기전에 memory speculative access가 수행될수있어 side-channel공격에
+ *   사용될수 있다고 한다.
+ *   sb 명령을 사용함으로 이전 명령어가 완료될때까지 speculative를 실행할수없게한다.
+ * - What is speculative execution?
+ *   https://www.extremetech.com/computing/261792-what-is-speculative-execution
+ * - isb, dsb, sb
+ *   처음에 isb, dsb에서 i,d를 뺀거인줄알았는데 아니였다.
+ *   sb : Speculation Barrier
+ *   isb : Instruction Synchronization Barrier
+ *   dsb : data Synchronization Barrier
+ */
     sb
     .endm
 
+/*
+ * IAMROOT, 2022.11.08:
+ * - Emulate Privileged Access Never using TTBR0_EL1 switching
+ */
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
     /*
      * Set the TTBR0 PAN bit in SPSR. When the exception is taken from
@@ -451,11 +946,29 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
      * feature as all TTBR0_EL1 accesses are disabled, not just those to
      * user mappings.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   SPSR에서 TTBR0 PAN 비트를 설정합니다. EL0에서 예외가 발생하면 항상 액세스가
+ *   활성화되어 있으므로 TTBR0_EL1의 상태를 확인할 필요가 없습니다. 
+ *   사용자 매핑뿐만 아니라 모든 TTBR0_EL1 액세스가 비활성화되므로 이 비트의
+ *   의미는 ARMv8.1 PAN 기능과 다릅니다.
+ * - @x23 : register로 backup해놓은 spsr
+ * - ttbr0 user access disable을 수행한다.
+ */
 SYM_CODE_START_LOCAL(__swpan_entry_el1)
     mrs    x21, ttbr0_el1
     tst    x21, #TTBR_ASID_MASK        // Check for the reserved ASID
     orr    x23, x23, #PSR_PAN_BIT        // Set the emulated PAN in the saved SPSR
+/*
+ * IAMROOT, 2022.11.08:
+ * - TTBR_ASID_MASK가 0이라는건 이미 꺼놧다는것. 1f로 점프
+ */
     b.eq    1f                // TTBR0 access already disabled
+/*
+ * IAMROOT, 2022.11.08:
+ * - 다시 spsr을 복원하고 __uaccess_ttbr0_disable을 수행한다.
+ */
     and    x23, x23, #~PSR_PAN_BIT        // Clear the emulated PAN in the saved SPSR
 SYM_INNER_LABEL(__swpan_entry_el0, SYM_L_LOCAL)
     __uaccess_ttbr0_disable x21
@@ -466,13 +979,26 @@ SYM_CODE_END(__swpan_entry_el1)
      * Restore access to TTBR0_EL1. If returning to EL0, no need for SPSR
      * PAN bit checking.
      */
+/*
+ * IAMROOT, 2022.11.09:
+ * @x22 spsr
+ * - ttbr0 user access enable을 수행하고 PSR_PAN_BIT를 clear한다.
+ */
 SYM_CODE_START_LOCAL(__swpan_exit_el1)
+/*
+ * IAMROOT, 2022.11.09:
+ * - PSR_PAN_BIT가 set되있다면 ttbr0를 그대로 놔뚠다.(disable 상태 유지)
+ */
     tbnz    x22, #22, 1f            // Skip re-enabling TTBR0 access if the PSR_PAN_BIT is set
     __uaccess_ttbr0_enable x0, x1
 1:    and    x22, x22, #~PSR_PAN_BIT        // ARMv8.0 CPUs do not understand this bit
     ret
 SYM_CODE_END(__swpan_exit_el1)
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - ttbr0 user access enable을 수행한다. el0는 PSR_PAN_BIT확인을 안하므로 필요없다.
+ */
 SYM_CODE_START_LOCAL(__swpan_exit_el0)
     __uaccess_ttbr0_enable x0, x1
     /*
@@ -481,6 +1007,13 @@ SYM_CODE_START_LOCAL(__swpan_exit_el0)
      * Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache
      * corruption).
      */
+/*
+ * IAMROOT, 2022.11.09:
+ * - papago
+ *   사용자에게 돌아가는 경우에만 에라타 해결 방법을 활성화하십시오.
+ *   현재 TTBR0_EL1 변경에 필요한 유일한 해결 방법은 Cavium erratum 27456에 대한
+ *   것입니다(방송 TLBI 명령으로 인해 I-캐시 손상이 발생할 수 있음).
+ */
     b    post_ttbr_update_workaround
 SYM_CODE_END(__swpan_exit_el0)
 #endif
@@ -497,26 +1030,66 @@ tsk    .req    x28        // current thread_info
 
 /*
  * IAMROOT, 2022.02.08:
+ * - exception 발생시 발생하는 일들
+ *   1. pstate -> spsr_elx로 백업
+ *   2. pc -> elr_elx로 백업
+ *   3. pstate에서 i가 autu set.
+ *   참고
+ *   https://developer.arm.com/documentation/100933/0100/Exception-handling
+ *   aarch64_exception_and_interrupt_handling
+ *
  * - exception 함수들은 include/asm/exception.h에 위치
- *   ex) el1h_64_sync_handler
+ * 예) el0 64bit user -----(irq)----> b el0t_64_irq_handler
+ * - t(thread)
+ * - h(handler)
+ * - ex) el1 64bit irq발생시 flow
+ *   vectors 
+ *     v
+ *   kernel_ventry 1, h, 64, irq
+ *     v
+ *   el1h_64_irq
+ *     v
+ *   kernel_entry 1, 64
+ *     v
+ *   el1h_64_irq_handler
+ *     v
+ *   ret_to_kernel
  */
     .align    11
 SYM_CODE_START(vectors)
+/*
+ * IAMROOT, 2022.11.07:
+ * - thread
+ * - sp가 sp_el0를 가리킬때 동작. user app용. kernel은 미사용.
+ */
     kernel_ventry    1, t, 64, sync        // Synchronous EL1t
     kernel_ventry    1, t, 64, irq        // IRQ EL1t
     kernel_ventry    1, t, 64, fiq        // FIQ EL1h
     kernel_ventry    1, t, 64, error        // Error EL1t
-
+/*
+ * IAMROOT, 2022.11.07:
+ * - handler
+ * - sp가 sp_el1을 가리킬때 동작.
+ *   kernel thread등의 동작중일때 진입.
+ */
     kernel_ventry    1, h, 64, sync        // Synchronous EL1h
     kernel_ventry    1, h, 64, irq        // IRQ EL1h
     kernel_ventry    1, h, 64, fiq        // FIQ EL1h
     kernel_ventry    1, h, 64, error        // Error EL1h
-
+/*
+ * IAMROOT, 2022.11.07:
+ * - lower64
+ *   64bit app용
+ */
     kernel_ventry    0, t, 64, sync        // Synchronous 64-bit EL0
     kernel_ventry    0, t, 64, irq        // IRQ 64-bit EL0
     kernel_ventry    0, t, 64, fiq        // FIQ 64-bit EL0
     kernel_ventry    0, t, 64, error        // Error 64-bit EL0
-
+/*
+ * IAMROOT, 2022.11.07:
+ * - lower32
+ *   32bit app용
+ */
     kernel_ventry    0, t, 32, sync        // Synchronous 32-bit EL0
     kernel_ventry    0, t, 32, irq        // IRQ 32-bit EL0
     kernel_ventry    0, t, 32, fiq        // FIQ 32-bit EL0
@@ -524,6 +1097,10 @@ SYM_CODE_START(vectors)
 SYM_CODE_END(vectors)
 
 #ifdef CONFIG_VMAP_STACK
+/*
+ * IAMROOT, 2022.11.07:
+ * - overflow_stack진입시 들어간다.
+ */
 SYM_CODE_START_LOCAL(__bad_stack)
     /*
      * We detected an overflow in kernel_ventry, which switched to the
@@ -532,6 +1109,15 @@ SYM_CODE_START_LOCAL(__bad_stack)
      */
 
     /* Restore the original x0 value */
+/*
+ * IAMROOT, 2022.11.07:
+ * - papago
+ *   오버플로 스택으로 전환된 kernel_ventry에서 오버플로를 감지했습니다.
+ *   예외 규정을 숨기고 오버플로 처리기로 이동합니다.
+ *
+ * - tpidrro_el0에 x0(pt_regs address)를 이 함수 진입전에 저장해놨었다.
+ *   x0에 복원한다.
+ */
     mrs    x0, tpidrro_el0
 
     /*
@@ -540,6 +1126,12 @@ SYM_CODE_START_LOCAL(__bad_stack)
      */
     sub    sp, sp, #PT_REGS_SIZE
     kernel_entry 1
+/*
+ * IAMROOT, 2022.11.07:
+ * - overflow_stack진입전 sp를 tpidr_el0에 넣어놨었다. x0에 불러와서
+ *   sp + PT_REGS_SIZE의 주소를 overflow_stack의 sp에 저장한다.
+ *
+ */
     mrs    x0, tpidr_el0
     add    x0, x0, #PT_REGS_SIZE
     str    x0, [sp, #S_SP]
@@ -555,9 +1147,49 @@ SYM_CODE_END(__bad_stack)
 
 /*
  * IAMROOT, 2022.02.08:
- * ex) el1h_64_sync_handler
+ *
+ * 1. kernel_entry에서 exception이 발생하여 context 를 백업한다. (전체 레지스터)
+ * 2. exception에 해당하는 핸들러를 호출한다.
+ *    ex) el1h_64_sync_handler
+ * 3. 유저 or 커널로 복귀하기 전에 context를 복구한다.
  */
     .macro entry_handler el:req, ht:req, regsize:req, label:req
+/*
+ * IAMROOT, 2022.11.07:
+ * - 함수가 macro로 만들어진다. 내부에선 뒤에 _handler가 붙은 함수로 호출된다.
+ *   el1t_64_sync    0x000
+ *   el1t_64_irq    0x080
+ *   el1t_64_fiq    0x100
+ *   el1t_64_error    0x180
+ *  
+ *   el1h_64_sync    0x200
+ *   el1h_64_irq    0x280    
+ *   el1h_64_fiq    0x300
+ *   el1h_64_error    0x380
+ *  
+ *   el0t_64_sync    0x400
+ *   el0t_64_irq    0x480
+ *   el0t_64_fiq    0x500
+ *   el0t_64_error    0x580
+ *  
+ *   el0t_32_sync    0x600
+ *   el0t_32_irq    0x680
+ *   el0t_32_fiq    0x700
+ *   el0t_32_error    0x780
+ *
+ * - ex) el1 64bit irq발생시 flow
+ *   vectors 
+ *     v
+ *   kernel_ventry 1, h, 64, irq
+ *     v
+ *   el1h_64_irq  <-- 시작
+ *     v
+ *   kernel_entry 1, 64
+ *     v
+ *   el1h_64_irq_handler
+ *     v
+ *   ret_to_kernel <-- 끝
+ */
 SYM_CODE_START_LOCAL(el\el\ht\()_\regsize\()_\label)
     kernel_entry \el, \regsize
     mov    x0, sp
@@ -572,6 +1204,11 @@ SYM_CODE_END(el\el\ht\()_\regsize\()_\label)
 
 /*
  * Early exception handlers
+ */
+/*
+ * IAMROOT, 2022.11.05: 
+ * 부팅 후 곧바로 동작할 16개의 함수
+ * 예) el0t_64_irq
  */
     entry_handler    1, t, 64, sync
     entry_handler    1, t, 64, irq
@@ -593,10 +1230,21 @@ SYM_CODE_END(el\el\ht\()_\regsize\()_\label)
     entry_handler    0, t, 32, fiq
     entry_handler    0, t, 32, error
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - 원래 지점으로 돌아간다.
+ */
 SYM_CODE_START_LOCAL(ret_to_kernel)
     kernel_exit 1
 SYM_CODE_END(ret_to_kernel)
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 유저로 복귀하기 전에 동작하는 루틴.
+ *  x19 <- tsk->thread_info.flags
+ * - el0 exception시 exception handler를 완료하고 진입한다.
+ * - kernel_entry에서 disable했던 single step debug를 다시 enable한다.
+ */
 SYM_CODE_START_LOCAL(ret_to_user)
     ldr    x19, [tsk, #TSK_TI_FLAGS]    // re-check for single-step
     enable_step_tsk x19, x2
@@ -615,6 +1263,10 @@ SYM_CODE_END(ret_to_user)
     .pushsection ".entry.tramp.text", "ax"
 
     // Move from tramp_pg_dir to swapper_pg_dir
+/*
+ * IAMROOT, 2022.11.10:
+ * - tramp_pg_dir -> swapper_pg_dir로 전환. 전환하며 USER_ASID_FLAG를 unset한다.
+ */
     .macro tramp_map_kernel, tmp
     mrs    \tmp, ttbr1_el1
     add    \tmp, \tmp, #TRAMP_SWAPPER_OFFSET
@@ -634,6 +1286,10 @@ alternative_else_nop_endif
 #endif /* CONFIG_QCOM_FALKOR_ERRATUM_1003 */
     .endm
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - swapper_pg_dir -> tramp_pg_dir로 교체하면서 USER_ASID_FLAG로 넣어놓는다.
+ */
     // Move from swapper_pg_dir to tramp_pg_dir
     .macro tramp_unmap_kernel, tmp
     mrs    \tmp, ttbr1_el1
@@ -647,9 +1303,18 @@ alternative_else_nop_endif
      */
     .endm
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - exception -> tramp_ventry -> kernel_ventry ....
+ * - ttbr1_el1이 tramp_pg_dir -> swapper_pg_dir로 전환된다.
+ */
     .macro tramp_ventry, regsize = 64
     .align    7
 1:
+/*
+ * IAMROOT, 2022.11.10:
+ * - tpidrro_el0에 x30(lr) 에 저장해놨다가 kernel_ventry에서 꺼내서 사용한다.
+ */
     .if    \regsize == 64
     msr    tpidrro_el0, x30    // Restored in kernel_ventry
     .endif
@@ -658,10 +1323,26 @@ alternative_else_nop_endif
      * entry onto the return stack and using a RET instruction to
      * enter the full-fat kernel vectors.
      */
+/*
+ * IAMROOT, 2022.11.10:
+ * - papago
+ *   반환 스택에 더미 항목을 밀어넣고 RET 명령을 사용하여 전체 팻 커널 벡터를
+ *   입력하여 분기 앨리어싱 공격으로부터 방어합니다.
+ */
     bl    2f
     b    .
+/*
+ * IAMROOT, 2022.11.10:
+ * - tramp_pg_dir -> swapper_pg_dir로 전환.
+ */
 2:
     tramp_map_kernel    x30
+/*
+ * IAMROOT, 2022.11.10:
+ * - randomize가 없으면 vectors를 즉시 가져온다.
+ *   그게 아니라면 tramp_vectors + PAGE_SIZE에 vectors가 있다.
+ *   (map_entry_trampoline()참고)
+ */
 #ifdef CONFIG_RANDOMIZE_BASE
     adr    x30, tramp_vectors + PAGE_SIZE
 alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
@@ -672,12 +1353,27 @@ alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
 alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM
     prfm    plil1strm, [x30, #(1b - tramp_vectors)]
 alternative_else_nop_endif
+/*
+ * IAMROOT, 2022.11.10:
+ * - vbar_el1에 vectors를 넣어놓고 x30(lr)을 수정후 ret으로 수정된 x30으로
+ *   점프한다.
+ * - 1b - tramp_vectors
+ *   tramp_vectors에서 현재 발생한 tramp_ventry의 offset.
+ *   즉 이걸 vectors에 적용하면 vectors + offset이므로 현재 offset에 해당하는
+ *   kernel_ventry로 진입할수있게된다.
+ */
     msr    vbar_el1, x30
     add    x30, x30, #(1b - tramp_vectors)
     isb
     ret
     .endm
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - vbar_el1에 tramp_vectors를 넣고, ttbr1_el1도 tramp_pg_dir로
+ *   USER_ASID_FLAG를 넣어서 교체해준다.
+ *   far_el1에 저장해놨던 lr를 x30에 원복한다.
+ */
     .macro tramp_exit, regsize = 64
     adr    x30, tramp_vectors
     msr    vbar_el1, x30
@@ -690,6 +1386,11 @@ alternative_else_nop_endif
     .endm
 
     .align    11
+
+/*
+ * IAMROOT, 2022.11.10:
+ * - user용만 있는게 확인된다.
+ */
 SYM_CODE_START_NOALIGN(tramp_vectors)
     .space    0x400
 
@@ -704,16 +1405,30 @@ SYM_CODE_START_NOALIGN(tramp_vectors)
     tramp_ventry    32
 SYM_CODE_END(tramp_vectors)
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - 64로 실행
+ */
 SYM_CODE_START(tramp_exit_native)
     tramp_exit
 SYM_CODE_END(tramp_exit_native)
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - 32bit로 실행
+*/
 SYM_CODE_START(tramp_exit_compat)
     tramp_exit    32
 SYM_CODE_END(tramp_exit_compat)
 
     .ltorg
     .popsection                // .entry.tramp.text
+/*
+ * IAMROOT, 2022.11.10:
+ * - randomize가 적용되면 vecotrs address를 여기에 저장해놓는다.
+ *   해당주소는 fixmap으로 TRAMP_VALIAS + PAGE_SIZE에 mapping된다.
+ *   (map_entry_trampoline() 참고)
+ */
 #ifdef CONFIG_RANDOMIZE_BASE
     .pushsection ".rodata", "a"
     .align PAGE_SHIFT
@@ -781,27 +1496,52 @@ NOKPROBE(ret_from_fork)
  *
  * Calls func(regs) using this CPU's irq stack and shadow irq stack.
  */
+/*
+ * IAMROOT, 2022.11.08:
+ * - pcp irq_stack_ptr로 sp를 전환하여 @func(x1)을 실행한다.
+ * - @func실행 전후로 fp, lr 저장 / 원복 등이 이루어진다.
+ * - SCS(Shadow call stack)
+ *   https://clang.llvm.org/docs/ShadowCallStack.html
+ */
 SYM_FUNC_START(call_on_irq_stack)
 #ifdef CONFIG_SHADOW_CALL_STACK
     stp    scs_sp, xzr, [sp, #-16]!
     ldr_this_cpu scs_sp, irq_shadow_call_stack_ptr, x17
 #endif
     /* Create a frame record to save our LR and SP (implicit in FP) */
+/*
+ * IAMROOT, 2022.11.08:
+ * - x30은 lr로 사용한다
+ *   https://developer.arm.com/documentation/100933/0100/Returning-from-an-exception
+ * - 기존 x29, x30(fp, lr)을 sp에 저장해놓고, 갱신된 sp를 x29에 저장해놓는다.
+ */
     stp    x29, x30, [sp, #-16]!
     mov    x29, sp
-
+/*
+ * IAMROOT, 2022.11.08:
+ * - pcp irq_stack_ptr을 구해와 sp를 대체한다.
+ */
     ldr_this_cpu x16, irq_stack_ptr, x17
     mov    x15, #IRQ_STACK_SIZE
     add    x16, x16, x15
 
     /* Move to the new stack and call the function there */
     mov    sp, x16
+/*
+ * IAMROOT, 2022.11.08:
+ * - func실행. func(regs). 형태로 0번인자가 regs로 진입한다.
+ */
     blr    x1
 
     /*
      * Restore the SP from the FP, and restore the FP and LR from the frame
      * record.
      */
+/*
+ * IAMROOT, 2022.11.08:
+ * - func실행전 x29에 저장해놓은 sp를 복구하고, 저장해놓은 sp에서 기존 fp, lr을
+ *   x29, x30에 원복한다.
+ */
     mov    sp, x29
     ldp    x29, x30, [sp], #16
 #ifdef CONFIG_SHADOW_CALL_STACK
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8b6799176aca..c0b00522be2d 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1000,6 +1000,10 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
 /*
  * Trapped FP/ASIMD access.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - warrning. arm64는 필요없다.
+ */
 void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs)
 {
     /* TODO: implement lazy context saving/restoring */
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index bda49430c9ea..660e7d8f0000 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -81,9 +81,19 @@ static void default_handle_fiq(struct pt_regs *regs)
     panic("FIQ taken without a root FIQ handler\n");
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 대표 인터럽트 controller의 핸들러가 호출되는 콜백
+ * 예) GICv3: gic_handle_irq
+ *  gic의 경우 gic_init_bases-> set_handle_irq를 통해서 gic_handle_irq가 설정된다.
+ */
 void (*handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq;
 void (*handle_arch_fiq)(struct pt_regs *) __ro_after_init = default_handle_fiq;
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 이 함수에서 대표 인터럽트 컨트롤러의 핸들러를 지정한다.
+ */
 int __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
 {
     if (handle_arch_irq != default_handle_irq)
@@ -94,6 +104,10 @@ int __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - fiq handler set
+ */
 int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *))
 {
     if (handle_arch_fiq != default_handle_fiq)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 782917bbc63f..1129c5a80a96 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -436,6 +436,15 @@ static void ssbs_thread_switch(struct task_struct *next)
  * This is *only* for exception entry from EL0, and is not valid until we
  * __switch_to() a user task.
  */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   current task를 sp_el0에 저장합니다. 사용자 공간에서 입력할 때 이를 복원할 수
+ *   있도록 섀도 복사본을 유지합니다.
+ *
+ *   이것은 EL0의 예외 항목에 대한 *only*이며 사용자 작업을 __switch_to()할
+ *   때까지 유효하지 않습니다.
+ */
 DEFINE_PER_CPU(struct task_struct *, __entry_task);
 
 static void entry_task_switch(struct task_struct *next)
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 1dbd51918b25..712d376b22cf 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -96,6 +96,12 @@ asmlinkage long __arm64_sys_ni_syscall(const struct pt_regs *__unused)
 #undef __SYSCALL
 #define __SYSCALL(nr, sym)    [nr] = __arm64_##sym,
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - arch/arm64/include/asm/unistd.h
+ *   -> arch/arm64/include/uapi/asm/unistd.h
+ *   -> include/uapi/asm-generic/unistd.h
+ */
 const syscall_fn_t sys_call_table[__NR_syscalls] = {
     [0 ... __NR_syscalls - 1] = __arm64_sys_ni_syscall,
 #include <asm/unistd.h>
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 50a0f1a38e84..3ad27ff26c07 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -19,6 +19,10 @@
 long compat_arm_syscall(struct pt_regs *regs, int scno);
 long sys_ni_syscall(void);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - arm전용 syscall
+ */
 static long do_ni_syscall(struct pt_regs *regs, int scno)
 {
 #ifdef CONFIG_COMPAT
@@ -33,11 +37,20 @@ static long do_ni_syscall(struct pt_regs *regs, int scno)
     return sys_ni_syscall();
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - syscall_fn 실행.
+ *   ex)sys_clone
+ */
 static long __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
 {
     return syscall_fn(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - @scno 에따라 syscall.
+ */
 static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
                unsigned int sc_nr,
                const syscall_fn_t syscall_table[])
@@ -47,6 +60,10 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
     add_random_kstack_offset();
 
     if (scno < sc_nr) {
+/*
+ * IAMROOT, 2022.11.12:
+ * - posix syscall
+ */
         syscall_fn_t syscall_fn;
         syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)];
         ret = __invoke_syscall(regs, syscall_fn);
@@ -70,6 +87,10 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
     choose_random_kstack_offset(get_random_int() & 0x1FF);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - debug flag가 있는지 확인한다.
+ */
 static inline bool has_syscall_work(unsigned long flags)
 {
     return unlikely(flags & _TIF_SYSCALL_WORK);
@@ -78,11 +99,18 @@ static inline bool has_syscall_work(unsigned long flags)
 int syscall_trace_enter(struct pt_regs *regs);
 void syscall_trace_exit(struct pt_regs *regs);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - syscall
+ */
 static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
                const syscall_fn_t syscall_table[])
 {
     unsigned long flags = current_thread_info()->flags;
-
+/*
+ * IAMROOT, 2022.11.12:
+ * - x0는 syscall nr로 사용해야되서 backup해놓는다.
+ */
     regs->orig_x0 = regs->regs[0];
     regs->syscallno = scno;
 
@@ -103,7 +131,28 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
      * So, don't touch regs->pstate & PSR_BTYPE_MASK here.
      * (Similarly for HVC and SMC elsewhere.)
      */
-
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   BTI 참고:
+ *   아키텍처는 SVC를 사용할 때 SPSR.BTYPE이 0임을 보장하지 않으므로 시스템 호출 후 0이 아닌
+ *   BTYPE을 사용하여 사용자 공간으로 돌아갈 수 있습니다.
+ *
+ *   이는 사용자 공간이 BTI/PACIxSP 지침을 준수하지 않는 페이지에서 PROT_BTI를 설정하거나,
+ *   PROT_BTI가 다른 실행 페이지에서 다른 실행 페이지로 넘어가거나, ptrace를 통해 BTYPE을
+ *   엉망으로 만드는 것과 같이 명시적으로 어리석은 일을 하는 경우를 제외하고는 중요하지
+ *   않습니다.
+ *   이러한 경우 시스템 호출 반환 시 SIGILL이 발생하더라도 사용자 공간은 놀라지 않아야
+ *   합니다.
+ *
+ *   따라서 여기에서 regs->pstate & PSR_BTYPE_MASK를 건드리지 마십시오. 
+ *   (다른 곳에서 HVC 및 SMC와 유사합니다.).
+ *
+ * - PSTATE.BTYPE(Branch target identification bit)
+ *
+ * - irq enable
+ *   syscall 호출 도중에 irq가 들어올수있다.
+ */
     local_daif_restore(DAIF_PROCCTX);
 
     if (flags & _TIF_MTE_ASYNC_FAULT) {
@@ -112,6 +161,12 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
          * syscall. do_notify_resume() will send a signal to userspace
          * before the syscall is restarted.
          */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   실제 시스템 호출 전에 비동기 태그 검사 오류를 처리합니다. do_notify_resume()은
+ *   시스템 호출이 다시 시작되기 전에 사용자 공간에 신호를 보냅니다.
+ */
         syscall_set_return_value(current, regs, -ERESTARTNOINTR, 0);
         return;
     }
@@ -132,6 +187,20 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
          * setting the return value is unlikely to do anything sensible
          * anyway.
          */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   ptrace를 사용하여 시스템 호출을 건너뛰는 사실상의 표준 방법은 시스템 호출을
+ *   -1(NO_SYSCALL)로 설정하고 x0을 사용자 공간에서 사용하기에 적합한 error 코드로 설정하는
+ *   것입니다. 그러나 이것은 사용자가 발행한 syscall(-1)과 구별할 수 없으므로 추적
+ *   프로그램에서 건너뛰기를 실행하지 않고 x0이 보존된 trace_exit에 빠질 경우를 대비하여
+ *   여기에서 x0을 -ENOSYS로 설정해야 합니다.
+ *
+ *   이것은 추적자가 시스템 호출 번호를 -1로 설정하지만 x0을 초기화하지 않으면 사용자가
+ *   발행한 syscall(-1)을 제외한 모든 시스템 호출에 대해 x0이 보존된다는 의미이기 때문에
+ *   약간 이상합니다. 그러나 건너뛰기를 요청하고 반환 값을 설정하지 않는 것은 어쨌든
+ *   합리적이지 않을 것입니다.
+ */
         if (scno == NO_SYSCALL)
             syscall_set_return_value(current, regs, -ENOSYS, 0);
         scno = syscall_trace_enter(regs);
@@ -158,11 +227,19 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
     syscall_trace_exit(regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - sve를 지원중이라면 discard시킨다.
+ */
 static inline void sve_user_discard(void)
 {
     if (!system_supports_sve())
         return;
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - SVE를 지원하는 system이라면 thread flag에서 TIF_SVE flag를 지운다.
+ */
     clear_thread_flag(TIF_SVE);
 
     /*
@@ -172,9 +249,22 @@ static inline void sve_user_discard(void)
      * modification (sigreturn, ptrace) intervenes.
      * So, ensure that CPACR_EL1 is already correct for the fast-path case.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   task_fpsimd_load()는 TIF_FOREIGN_FPSTATE가 아직 설정되어 있지 않으면
+ *   ret_to_user에서 CPACR_EL1을 업데이트하기 위해 호출되지 않습니다.
+ *   이는 컨텍스트 전환 또는 kernel_neon_begin() 또는 컨텍스트
+ *   수정(sigreturn, ptrace)이 개입하는 경우에만 발생합니다.
+ *   따라서 CPACR_EL1이 빠른 경로의 경우에 이미 올바른지 확인하십시오.
+ */
     sve_user_disable();
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - syscall
+ */
 void do_el0_svc(struct pt_regs *regs)
 {
     sve_user_discard();
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 04e3387ade06..dc731007e611 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -286,17 +286,29 @@ void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far,
     force_sig_ptrace_errno_trap(errno, (void __user *)far);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - user / kernel 에 따라 kill / die를 동작한다.
+ */
 void arm64_notify_die(const char *str, struct pt_regs *regs,
               int signo, int sicode, unsigned long far,
               int err)
 {
     if (user_mode(regs)) {
+/*
+ * IAMROOT, 2022.11.12:
+ * - user에서 발생한경우 해당 process kill
+ */
         WARN_ON(regs != current_pt_regs());
         current->thread.fault_address = 0;
         current->thread.fault_code = err;
 
         arm64_force_sig_fault(signo, sicode, far, str);
     } else {
+/*
+ * IAMROOT, 2022.11.12:
+ * - 자살
+ */
         die(str, regs, err);
     }
 }
@@ -376,6 +388,11 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size)
 static LIST_HEAD(undef_hook);
 static DEFINE_RAW_SPINLOCK(undef_lock);
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - unref_hook에 @hook를 등록한다.
+ */
 void register_undef_hook(struct undef_hook *hook)
 {
     unsigned long flags;
@@ -394,6 +411,10 @@ void unregister_undef_hook(struct undef_hook *hook)
     raw_spin_unlock_irqrestore(&undef_lock, flags);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - 특정 inst에 hook를 걸수있다. 그것을 호출해준다.
+ */
 static int call_undef_hook(struct pt_regs *regs)
 {
     struct undef_hook *hook;
@@ -429,6 +450,10 @@ static int call_undef_hook(struct pt_regs *regs)
         instr = le32_to_cpu(instr_le);
     }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - undef_hook에서 찾아서 fn을 호출한다.
+ */
     raw_spin_lock_irqsave(&undef_lock, flags);
     list_for_each_entry(hook, &undef_hook, node)
         if ((instr & hook->instr_mask) == hook->instr_val &&
@@ -486,6 +511,10 @@ void arm64_notify_segfault(unsigned long addr)
     force_signal_inject(SIGSEGV, code, addr, 0);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - unref_hook 에 unref가 있는지 찾아본다.
+ */
 void do_undefinstr(struct pt_regs *regs)
 {
     /* check for AArch32 breakpoint instructions */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index d1c152666a43..fa532b5d16b9 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -53,6 +53,10 @@ struct fault_info {
 static const struct fault_info fault_info[];
 static struct fault_info debug_fault_info[];
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - ISS의 Data Fault Status Code.
+ */
 static inline const struct fault_info *esr_to_fault_info(unsigned int esr)
 {
     return fault_info + (esr & ESR_ELx_FSC);
@@ -462,6 +466,10 @@ static void set_thread_esr(unsigned long address, unsigned int esr)
     current->thread.fault_code = esr;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - user에서 발생했으면 send sig. kernel이면 fault.
+ */
 static void do_bad_area(unsigned long far, unsigned int esr,
             struct pt_regs *regs)
 {
@@ -477,6 +485,10 @@ static void do_bad_area(unsigned long far, unsigned int esr,
         set_thread_esr(addr, esr);
         arm64_force_sig_fault(inf->sig, inf->code, far, inf->name);
     } else {
+/*
+ * IAMROOT, 2022.11.12:
+ * - kernel fault.
+ */
         __do_kernel_fault(addr, esr, regs);
     }
 }
@@ -484,6 +496,10 @@ static void do_bad_area(unsigned long far, unsigned int esr,
 #define VM_FAULT_BADMAP        0x010000
 #define VM_FAULT_BADACCESS    0x020000
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - mm fault 수행
+ */
 static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr,
                   unsigned int mm_flags, unsigned long vm_flags,
                   struct pt_regs *regs)
@@ -497,6 +513,10 @@ static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr,
      * Ok, we have a good vm_area for this memory access, so we can handle
      * it.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - 범위검사.
+ */
     if (unlikely(vma->vm_start > addr)) {
         if (!(vma->vm_flags & VM_GROWSDOWN))
             return VM_FAULT_BADMAP;
@@ -527,6 +547,10 @@ static bool is_write_abort(unsigned int esr)
     return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - user page fault
+ */
 static int __kprobes do_page_fault(unsigned long far, unsigned int esr,
                    struct pt_regs *regs)
 {
@@ -556,6 +580,12 @@ static int __kprobes do_page_fault(unsigned long far, unsigned int esr,
      * vma->vm_flags & vm_flags and returns an error if the
      * intersection is empty
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - inst fault -> VM_EXEC
+ *   write abort -> VM_WRITE
+ *   read abort(그외) -> VM_READ
+ */
     if (is_el0_instruction_abort(esr)) {
         /* It was exec fault */
         vm_flags = VM_EXEC;
@@ -610,6 +640,10 @@ static int __kprobes do_page_fault(unsigned long far, unsigned int esr,
 #endif
     }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - page fualt 수행
+ */
     fault = __do_page_fault(mm, addr, mm_flags, vm_flags, regs);
 
     /* Quick path to respond to signals */
@@ -684,15 +718,27 @@ static int __kprobes do_page_fault(unsigned long far, unsigned int esr,
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - mapping이 없을때 fault.
+ */
 static int __kprobes do_translation_fault(unsigned long far,
                       unsigned int esr,
                       struct pt_regs *regs)
 {
     unsigned long addr = untagged_addr(far);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - user라면 do page fault
+ */
     if (is_ttbr0_addr(addr))
         return do_page_fault(far, esr, regs);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - kernel은 전부 mapping이 되있는데 fault인건 말이안된다.
+ */
     do_bad_area(far, esr, regs);
     return 0;
 }
@@ -819,14 +865,27 @@ static const struct fault_info fault_info[] = {
     { do_bad,        SIGKILL, SI_KERNEL,    "unknown 63"            },
 };
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - 
+ */
 void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs)
 {
     const struct fault_info *inf = esr_to_fault_info(esr);
     unsigned long addr = untagged_addr(far);
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 성공하면 빠져나간다.
+ */
     if (!inf->fn(far, esr, regs))
         return;
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - kernel에서 호출된경우면 alert.
+ */
     if (!user_mode(regs)) {
         pr_alert("Unhandled fault at 0x%016lx\n", addr);
         mem_abort_decode(esr);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 395790f4d3b9..a27e6ea53161 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -811,6 +811,10 @@ static int __init parse_rodata(char *arg)
 early_param("rodata", parse_rodata);
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+/*
+ * IAMROOT, 2022.11.10:
+ * - fixmap에 tramp 관련 데이터들을 mapping한다.
+ */
 static int __init map_entry_trampoline(void)
 {
     pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
@@ -826,6 +830,23 @@ static int __init map_entry_trampoline(void)
 
     /* Map both the text and data into the kernel page table */
     __set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
+/*
+ * IAMROOT, 2022.11.10:
+ * - FIX_ENTRY_TRAMP_DATA는 FIX_ENTRY_TRAMP_TEXT + PAGE_SIZE 에 위치할것이다.
+ *   해당 fixmap으로 __entry_tramp_data_start를 mapping한다.
+ *   이걸 함으로써 가상주소적으로
+ *
+ *   -- high --
+ *   .quad vectors
+ *   __entry_tramp_data_start
+ *   (PAGE_SIZE)
+ *   tramp_vectors
+ *   -- low --
+ *
+ *   의 address 체계가 성립함으로서 tramp_vectors로 vectors address가 저장된
+ *   .quad로 접근이 가능하며, 이 값을 ldr X, [.quad vecors]함으로써 
+ *   vectors의 주소를 가져올수있다.
+ */
     if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
         extern char __entry_tramp_data_start[];
 
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 8f1445bdb67b..aa010fb07304 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -73,7 +73,9 @@ static struct gic_chip_data gic_data __read_mostly;
 /*
  * IAMROOT, 2022.10.01:
  * - gic_init_bases에서 hyp_mode가 안켜져있으면 disable시킨다.
- *   eoi를 drop / deactivate의 두개의 기능으로 나누는 것에 대한 지원여부
+ *   EL2로 진입하여 hyp_mode가 사용되면 eoi를 drop 시켜 사용한다.
+ *   그리고, Guest OS가 EL1으로 진입하여 hyp_mode가 사용되지 않으면 eoi를 
+ *   deactivate 하여 사용하도록, eoi를 2개로 분리하여 처리한다.
  */
 static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
 
@@ -711,6 +713,10 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
     gic_irq_set_prio(d, GICD_INT_DEF_PRI);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - write eoi.
+ */
 static void gic_eoi_irq(struct irq_data *d)
 {
     gic_write_eoir(gic_irq(d));
@@ -837,10 +843,19 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
         nmi_exit();
 }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Interrupt Controller Interrupt Acknowledge Register를 읽어
+ * 인터럽트 번호를 알아온다.
+ */
 static u32 do_read_iar(struct pt_regs *regs)
 {
     u32 iar;
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Pesudo-NMI를 사용하면서 일반 irq가 disable 상태라면 pmr이 설정된 상태인것이다.
+ */
     if (gic_supports_nmi() && unlikely(!interrupts_enabled(regs))) {
         u64 pmr;
 
@@ -857,6 +872,32 @@ static u32 do_read_iar(struct pt_regs *regs)
          * actually only allow NMIs before reading IAR, and then
          * restore it to what it was.
          */
+/*
+ * IAMROOT, 2022.11.05: 
+ * - papago
+ *   우리는 IRQ가 비활성화된 상황에 있었습니다. 그러나 입력 코드는
+ *   PMR을 NMI뿐만 아니라 모든 인터럽트를 승인할 수 있는 값으로 설정했습니다.
+ *   NMI가 그 사이에 폐기되고 IRQ가 보류 중인 경우 이는 놀라운 효과로 이어질
+ *   수 있습니다. 그런 다음 IRQ는 NMI 컨텍스트에서 수행되며 아무도 두 번
+ *   디버그하기를 원하지 않습니다.
+ *
+ *   이것을 정렬할 때까지 PMR을 IAR을 읽기 전에 실제로 NMI만 허용하는 수준으로
+ *   다시 떨어뜨린 다음 원래 상태로 복원합니다.
+ *
+ * - spurious interrupts
+ *   https://developer.arm.com/documentation/ihi0048/b/Introduction/Terminology/Spurious-interrupts
+ *   https://en.wikipedia.org/wiki/Interrupt
+ * - Git Blame
+ *   spurious interrupt(nmi)가 발생(iar을 읽기전에 retired)한 상황에서 irq가
+ *   pending중일때, nmi context에서 pending중인 irq에 대한 ack가 나갈수있다는것
+ *   같다.
+ *   그래서 spurious interrupt를 handle_bad_irq로 처리할려고
+ *   (core-api/generic.rst) 확실히 off시킨후 iar을 얻어올려는거 같다.
+ *   (부정확)
+ *
+ * - pmr을 사용하여 일반 인터럽트를 disable 한상태에서 iar을 통해 인터럽트 번호를
+ * 읽어온다. 그 후 pmr을 원래 값으로 복구한다.
+ */
         pmr = gic_read_pmr();
         gic_pmr_mask_irqs();
         isb();
@@ -873,10 +914,39 @@ static u32 do_read_iar(struct pt_regs *regs)
 
 /*
  * IAMROOT, 2022.10.08:
- * - TODO
  * - gic control handler.
  *   interrupt가 vector table다음으로 받는 handler.
- * - vector table -> gic_handle_irq -> irq flow handler
+ * - irq 흐름
+ *   vectors(arch/arm64/kernel/entry.S)
+ *     v
+ *   chip handler(handler_arch_irq, gic의 경우 gic_handle_irq) <--- 현재
+ *     v
+ *   flow handler
+ *     v
+ *   irq_handler
+ *
+ * - gic 흐름
+ *   interrupt 발생
+ *    v
+ *   register backup
+ *    v 
+ *    gic_handle_irq(진입)
+ *                v
+ *               ack(iar)
+ *                v
+ *               interrupt enable(PSR의 IF clear 및 PMR-NMI 적용)
+ *              (NMI의 경우 PMR-NMI 우선순위보다 높은 interrupt만
+ *              들어올수있게 enable된다.)
+ *                v
+ *              (eoimode1: drop)
+ *                v
+ *              flow handler 실행
+ *                v
+ *              (eoimode:0 eoi + drop)
+ *                v
+ *    gic_handle_irq(완료)
+ *    v
+ *    register restore
  */
 static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 {
@@ -884,21 +954,46 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 
     irqnr = do_read_iar(regs);
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * 1020~1023번 인터럽트는 스페셜 인터럽트로 핸들러에 대한 호출을 할 필요 없다.
+ */
     /* Check for special IDs first */
     if ((irqnr >= 1020 && irqnr <= 1023))
         return;
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Pesudo-NMI 인터럽트에 대한 핸들러 호출이다.
+ * 예) request_nmi() & request_percpu_nmi()
+ */
     if (gic_supports_nmi() &&
         unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) {
         gic_handle_nmi(irqnr, regs);
         return;
     }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * Pesudo-NMI를 지원하면서 GIC 역시 priority masking을 지원하는 경우 
+ * pmr을 사용하여 일반 인터럽트를 disable 하고, DAIF 중 IF를 clear한다.
+ *
+ * 중요) 이렇게 하면 인터럽트 처리 중에도 IF를 clear하여 NMI 인터럽트는 
+ * 진입이 가능하도록 허용한다.
+ */
     if (gic_prio_masking_enabled()) {
         gic_pmr_mask_irqs();
         gic_arch_enable_irqs();
     }
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * EL2 하이퍼 바이저를 지원하여 eoimode=1을 사용하는 경우에는
+ * 이 시점에서 eoi drop을 한다. 이러한 경우 해당 인터럽트 번호만
+ * drop 되기 때문에 다른 인터럽트들이 진입할 수 있게된다.
+ *
+ * 물론, Pesudo-NMI를 제외하면 아직 cpu의 irq가 enable(IF mask)상태는 아니다.
+ */
     if (static_branch_likely(&supports_deactivate_key))
         gic_write_eoir(irqnr);
     else
@@ -1471,7 +1566,7 @@ static void gic_cpu_sys_reg_init(void)
  * --- eoimode example,  guest os한테 int50이 들어오는 상황
  *  1. eoimode0
  *    guest os한테 넘겨줌. drop / inactivate 둘다 발생. 
- *    guest of가 다 처리할때까지 int50을 못받음.
+ *    guest os가 다 처리할때까지 int50을 못받음.
  *
  *  1. eoimode1
  *    guest os한테 넘겨줌. drop 발생. 
diff --git a/include/asm-generic/irq_regs.h b/include/asm-generic/irq_regs.h
index 2e7c6e89d42e..86b17320b652 100644
--- a/include/asm-generic/irq_regs.h
+++ b/include/asm-generic/irq_regs.h
@@ -14,6 +14,10 @@
  * Per-cpu current frame pointer - the location of the last exception frame on
  * the stack
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - 현재 실행중인 irq context register.
+ */
 DECLARE_PER_CPU(struct pt_regs *, __irq_regs);
 
 static inline struct pt_regs *get_irq_regs(void)
@@ -21,6 +25,11 @@ static inline struct pt_regs *get_irq_regs(void)
     return __this_cpu_read(__irq_regs);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - @new_regs를 현재 regs에 넣으면서, old를 return한다.
+ * - 전역 percpu __irq_regs에 현재 실행중인 irq의 regs를 저장해놓는다.
+ */
 static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
 {
     struct pt_regs *old_regs;
diff --git a/include/asm-generic/softirq_stack.h b/include/asm-generic/softirq_stack.h
index eceeecf6a5bd..5d94a1a83f7a 100644
--- a/include/asm-generic/softirq_stack.h
+++ b/include/asm-generic/softirq_stack.h
@@ -5,6 +5,11 @@
 #ifdef CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK
 void do_softirq_own_stack(void);
 #else
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - TODO
+ */
 static inline void do_softirq_own_stack(void)
 {
     __do_softirq();
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 02ad54c90805..8fc44f0be084 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -554,8 +554,17 @@ DECLARE_STATIC_KEY_FALSE(force_irqthreads_key);
 #define local_softirq_pending_ref irq_stat.__softirq_pending
 #endif
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - __raise_softirq_irqoff()참고. pending중인 softirq가 있는지 확인한다.
+ */
 #define local_softirq_pending()    (__this_cpu_read(local_softirq_pending_ref))
 #define set_softirq_pending(x)    (__this_cpu_write(local_softirq_pending_ref, (x)))
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - @x로 current cpu에 or.
+ */
 #define or_softirq_pending(x)    (__this_cpu_or(local_softirq_pending_ref, (x)))
 
 #endif /* local_softirq_pending */
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 056bc42ad034..7e8d196ba9c1 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -258,6 +258,10 @@ enum {
  * - IRQ_TYPE_SENSE_MASK
  * - IRQD_AFFINITY_MANAGED, IRQD_MANAGED_SHUTDOWN (alloc_descs() 참고)
  *   affinity->is_managed가 되있는경우 irq desc할당에서 flag로 사용한다.
+ * - IRQD_IRQ_INPROGRESS
+ *   irq 진행중
+ * - IRQD_WAKEUP_ARMED
+ *   mode armed 상태. interrupt가 뭔가 펼쳐진상태
  *
  */
     IRQD_TRIGGER_MASK        = 0xf,
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index b2c6391f5495..97b80265471b 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -185,6 +185,30 @@ static inline void *irq_desc_get_handler_data(struct irq_desc *desc)
  * Architectures call this to let the generic IRQ layer
  * handle an interrupt.
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - vector -> chip handler -> flow handler ->  action handler..
+ *                             ^여기를 호출하는 상황.
+ * ex) (일반 irq) handle_fasteoi_irq, handle_percpu_devid_irq
+ *     (nmi)      handle_fasteoi_nmi, handle_percpu_devid_fasteoi_nmi
+ *                ^spi용              ^ppi, sgi용
+ *
+ * -
+ *             spi(handle_fasteoi_irq)     ppi(handle_percpu_devid_irq)
+ *  ---------+---------------------------------------------------------
+ *  oneshot, | 고려해서 처리여부 판단    고려없이 모든 인터럽트 처리.      
+ *  thread등 |
+ *  ---------+----------------------------------------------------
+ *  eoi,     | 상황에 따라 처리여부 판단.   무조건 eoi만 수행. 
+ *  unmask   |
+ *  ---------+---------------------------------------------------------
+ *  poll     | wait후 처리                  poll 없음
+ *  ---------+---------------------------------------------------------
+ *  
+ *
+ *
+ */
 static inline void generic_handle_irq_desc(struct irq_desc *desc)
 {
     desc->handle_irq(desc);
diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h
index bd4c066ad39b..b7385413bfac 100644
--- a/include/linux/irqreturn.h
+++ b/include/linux/irqreturn.h
@@ -8,6 +8,16 @@
  * @IRQ_HANDLED        interrupt was handled by this device
  * @IRQ_WAKE_THREAD    handler requests to wake the handler thread
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - IRQ_NONE
+ *   error 표시
+ * - IRQ_HANDLED
+ *   정상 처리
+ * - IRQ_WAKE_THREAD
+ *   정상 처리 + thread wakeup 요청
+ */
 enum irqreturn {
     IRQ_NONE        = (0 << 0),
     IRQ_HANDLED        = (1 << 0),
diff --git a/include/linux/nospec.h b/include/linux/nospec.h
index c1e79f72cd89..6a980ca745af 100644
--- a/include/linux/nospec.h
+++ b/include/linux/nospec.h
@@ -48,6 +48,13 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
  * array_index_nospec() will clamp the index within the range of [0,
  * size).
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - 범위 검사. 주석참고
+ *   array size보다 크면 0번으로 고정시킨다.
+ *   mask는 정상값이면 ~0이므로 결과값은 결국 _i가 될것이다.
+ *   비정상일 경우 mask = 0이므로 결과는 무조건 0.
+ */
 #define array_index_nospec(index, size)                    \
 ({                                    \
     typeof(index) _i = (index);                    \
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 15a5f9974a16..9efbf626f30e 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -84,6 +84,12 @@
 #else
 # define softirq_count()    (preempt_count() & SOFTIRQ_MASK)
 #endif
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 해당 api가 interrupt context(nmi, hardirq, softirq)에서 실행됬는지
+ *   확인한다.
+ */
 #define irq_count()    (nmi_count() | hardirq_count() | softirq_count())
 
 /*
@@ -109,8 +115,24 @@
  * in_softirq()   - We have BH disabled, or are processing softirqs
  * in_interrupt() - We're in NMI,IRQ,SoftIRQ context or have BH disabled
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 해당 api가 interrupt context(hardirq)에서 실행됬는지 확인한다.
+ */
 #define in_irq()        (hardirq_count())
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 해당 api가 interrupt context(softirq)에서 실행됬는지 확인한다.
+ */
 #define in_softirq()        (softirq_count())
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 해당 api가 interrupt context(nmi, hardirq, softirq)에서 실행됬는지
+ *   확인한다.
+ */
 #define in_interrupt()        (irq_count())
 
 /*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f72cb434afd7..bb20cd246c51 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -721,6 +721,15 @@ struct kmap_ctrl {
 };
 
 struct task_struct {
+/*
+ * IAMROOT, 2022.11.05: 
+ * 아래 커널 옵션이 사용되는 경우 보안을 위해 task 구조체 내부의 가장 위에 
+ * thread_info 구조체를 가지고 있게 한다.
+ *
+ * 기존엔 스택의 가장 마지막에 thread_info 구조체를 가지고 있어서,
+ * 이를 통해 task_struct의 위치를 금방 찾는 단점이 있었다.
+ */
+
 #ifdef CONFIG_THREAD_INFO_IN_TASK
     /*
      * For reasons of header soup (see current_thread_info()), this
diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h
index 7bd7b1fbdaa0..f01f725d3758 100644
--- a/include/linux/sched/task_stack.h
+++ b/include/linux/sched/task_stack.h
@@ -22,6 +22,13 @@
  * try_get_task_stack() instead.  task_stack_page will return a pointer
  * that could get freed out from under you.
  */
+/*
+ * IAMROOT, 2022.11.08:
+ * - papago
+ *   종료될 수 있는 현재가 아닌 작업의 스택에 액세스할 때 대신
+ *   try_get_task_stack()을 사용하십시오. task_stack_page는 아래에서 해제될 수
+ *   있는 포인터를 반환합니다.
+ */
 static inline void *task_stack_page(const struct task_struct *task)
 {
     return task->stack;
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 0e1f49b216b8..ad4715d4d56c 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -498,6 +498,11 @@ void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu)
     cpumask_set_cpu(cpu, desc->percpu_enabled);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - disable이 있다면 disable. 아니면 mask.
+ * - irq disalbe한다(gic. gic_mask_irq)
+ */
 void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
 {
     if (desc->irq_data.chip->irq_disable)
@@ -618,6 +623,17 @@ void handle_nested_irq(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(handle_nested_irq);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * @return false irq가 inprogress가 아님
+ *         irq가 inprogress일때
+ *                current cpu가 irq_poll_cpu라면. (예외처리 일종)
+*                inprogress가 기다림 -> 기다리고 난후 irq가 disable이거나
+*                                       action handler가 없다면.
+*           true inprogress기다림 -> 기다리고 난 후 irq가 enable상태면서
+*                                    action handler가 존재.
+* - inprogress중이라면 기다린다.
+*/
 static bool irq_check_poll(struct irq_desc *desc)
 {
     if (!(desc->istate & IRQS_POLL_INPROGRESS))
@@ -625,6 +641,14 @@ static bool irq_check_poll(struct irq_desc *desc)
     return irq_wait_for_poll(desc);
 }
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - irq가 run 시킬수 있는지 확인한다. 필요하다면 wait까지 해본다.
+ * @return true.(running가능)
+ *          inprogress, wakeup armed상태가 아니라면, 혹은 wait후에도 irq가
+ *          enable 상태라면.
+ */
 static bool irq_may_run(struct irq_desc *desc)
 {
     unsigned int mask = IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARMED;
@@ -633,6 +657,11 @@ static bool irq_may_run(struct irq_desc *desc)
      * If the interrupt is not in progress and is not an armed
      * wakeup interrupt, proceed.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - 해당 interrupt가 진행중인지 확인한다. spi는 동시에 진입할수없다.
+ *   동시에 되는게 이상한상태.
+ */
     if (!irqd_has_set(&desc->irq_data, mask))
         return true;
 
@@ -641,6 +670,11 @@ static bool irq_may_run(struct irq_desc *desc)
      * and suspended, disable it and notify the pm core about the
      * event.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - wakeup업중인지 확인하고, wakeup이 아직 안되있으면
+ *   irq를 끄고 pending으로 한후 wakepup시킨다.
+ */
     if (irq_pm_check_wakeup(desc))
         return false;
 
@@ -782,8 +816,23 @@ void handle_level_irq(struct irq_desc *desc)
 }
 EXPORT_SYMBOL_GPL(handle_level_irq);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - irq_eoi + unmask를 상황에 따라 처리한다.
+ * - 다음과 같은 조건들을 판단한다.
+ *   IRQS_ONESHOT
+ *   desc->threads_oneshot
+ *   irqd_irq_masked
+ *   irqd_irq_disabled
+ *   IRQCHIP_EOI_THREADED
+ */
 static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
 {
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - oneshot이 아니면 irq_eoi만 처리.
+ */
     if (!(desc->istate & IRQS_ONESHOT)) {
         chip->irq_eoi(&desc->irq_data);
         return;
@@ -794,6 +843,26 @@ static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
      *   spurious interrupt or a primary handler handling it
      *   completely).
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   다음과 같은 경우 마스크를 해제해야 합니다.
+ *   - 스레드를 깨우지 않은 Oneshot irq(spurious 인터럽트 또
+ *     이를 완전히 처리하는 기본 핸들러로 인해 발생).
+ *
+ * - thread인 경우 isr이 매우 짧다(thread만 생성하고 끝나기때문에)
+ *   이런 경우 만약 isr만 처리하고 eoi를 보낼경우 level 인경우 매우많은
+ *   thread가 생길 위험이 있다. 이 경우에 대한 처리등을 진행한다. 즉
+ *   1.!irqd_irq_disabled(&desc->irq_data) => irq가 enable상태
+ *     irqd_irq_masked(&desc->irq_data)    => mask되있는 상태.
+ *     !desc->threads_oneshot              => oneshot thread가 아닌 상태
+ *     이 경우 eoi를 하고 다시 unmask를 하여 irq를 받아도 되는 상태.
+ *   2. !(chip->flags & IRQCHIP_EOI_THREADED) => thread에서 eoi처리를 
+ *     안하는 상황. 즉 flow handler에서 처리한다.
+ *   3. thread에서 처리하거나, thread가 oneshot인 경우등은 eoi를
+ *      여기서 처리 안한다.
+ *
+ */
     if (!irqd_irq_disabled(&desc->irq_data) &&
         irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot) {
         chip->irq_eoi(&desc->irq_data);
@@ -812,6 +881,12 @@ static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
  *    for modern forms of interrupt handlers, which handle the flow
  *    details in hardware, transparently.
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - 1. running 가능한지 확인한다.
+ *   2. oneshot인경우 masking.
+ */
 void handle_fasteoi_irq(struct irq_desc *desc)
 {
     struct irq_chip *chip = desc->irq_data.chip;
@@ -827,6 +902,13 @@ void handle_fasteoi_irq(struct irq_desc *desc)
      * If its disabled or no action available
      * then mask it and get out of here:
      */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - running할수있는 단계까지 왓는데 @desc가 action handler가 없거나
+ *   irq disable상태다. pending으로 표시 및 masking하고 out.
+ *   추후에 enable될때 edge trigger만 재전송한다.
+ */
     if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
         desc->istate |= IRQS_PENDING;
         mask_irq(desc);
@@ -834,11 +916,24 @@ void handle_fasteoi_irq(struct irq_desc *desc)
     }
 
     kstat_incr_irqs_this_cpu(desc);
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - oneshot이면 @desc를 masking한다.
+ */
     if (desc->istate & IRQS_ONESHOT)
         mask_irq(desc);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - action event handler 처리.
+ */
     handle_irq_event(desc);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - eoi + unmask 처리 여부 판단
+ */
     cond_unmask_eoi_irq(desc, chip);
 
     raw_spin_unlock(&desc->lock);
@@ -1035,6 +1130,20 @@ void handle_percpu_irq(struct irq_desc *desc)
  * contain the real device id for the cpu on which this handler is
  * called
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   handle_percpu_devid_irq - per cpu dev ID가 있는 per cpu local irq handler
+ *   @desc: 이 irq에 대한 인터럽트 설명 구조.
+ *
+ *   잠금 요구 사항이 없는 SMP 시스템의 CPU당 인터럽트. 위의
+ *   handle_percpu_irq()와 동일하지만 다음과 같은 추가 사항이 있습니다. 
+ *
+ *   action->percpu_dev_id는 이 핸들러가 호출되는 CPU의 실제 장치 ID를
+ *   포함하는 percpu 변수에 대한 포인터입니다.
+ *
+ * - action handler를 실행한다. 실행전후로 ack 및 irq_eoi를 수행한다.
+ */
 void handle_percpu_devid_irq(struct irq_desc *desc)
 {
     struct irq_chip *chip = irq_desc_get_chip(desc);
@@ -1048,9 +1157,18 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
      */
     __kstat_incr_irqs_this_cpu(desc);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - irq_ack가 있으면 여기서 보낸다. gic경우는 iar을 읽을시 자동으로 ack가
+ *   나가는 구조라 없다.
+ */
     if (chip->irq_ack)
         chip->irq_ack(&desc->irq_data);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - action이 없는데 들어왔다면 이상한 상황. irq disable한다.
+ */
     if (likely(action)) {
         trace_irq_handler_entry(irq, action);
         res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id));
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 8ba3b799acaa..a73144ab6ee0 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -60,6 +60,10 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action)
            "but no thread function available.", irq, action->name);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - flag를 정리하고 wake_up_process를 한다.
+ */
 void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
 {
     /*
@@ -67,6 +71,15 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
      * we handled the interrupt. The hardirq handler has disabled the
      * device interrupt, so no irq storm is lurking.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   쓰레드가 크래시를 일으키고 죽으면 우리는 인터럽트를 처리한 척합니다.
+ *   hardirq 처리기가 장치 인터럽트를 비활성화했으므로 irq 스톰이 숨어 있지
+ *   않습니다.
+ *
+ * - @desc를 사용하는 thread가 종료중. 굳이 처리 할필요없다.
+ */
     if (action->thread->flags & PF_EXITING)
         return;
 
@@ -74,6 +87,15 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
      * Wake up the handler thread for this action. If the
      * RUNTHREAD bit is already set, nothing to do.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   이 작업에 대한 핸들러 스레드를 깨우십시오. RUNTHREAD 비트가 이미
+ *   설정되어 있으면 아무 작업도 수행할 수 없습니다.
+ *
+ * - IRQTF_RUNTHREAD이게 있다면 이미 thread 깨웠다. 빠져나간다.
+ *   아니라면 set한다. (test and set)
+ */
     if (test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags))
         return;
 
@@ -122,6 +144,34 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
      * IRQTF_RUNTHREAD under desc->lock. If set it leaves
      * threads_oneshot untouched and runs the thread another time.
      */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   여기에서 마스크 잠금 장치를 사용하지 않는 것이 안전합니다.
+ *   thread_oneshot에 쓰는 곳은 두 곳뿐입니다: 이 코드와 irq 스레드.
+ *
+ *   이 코드는 하드 irq 컨텍스트이며 두 개의 CPU에서 병렬로 실행할 수
+ *   없습니다. 그렇다면 이 비트마스크보다 더 심각한 문제가 발생합니다
+ *
+ *   thread_oneshot에서 실행 비트를 지우는 이 irq의 irq 스레드는 서로에 대해
+ *   desc->lock을 통해 직렬화되고 IRQS_INPROGRESS에 의해 이 코드에 대해
+ *   직렬화됩니다.
+ *
+ *   ...
+ *
+ *   따라서 스레드는 우리가 IRQS_INPROGRESS를 지우기를 기다리거나 이 지점에
+ *   도달하기 전에 desc->lock이 해제되기 위해 flow handler에서 기다리고
+ *   있습니다. 스레드는 또한 desc->lock에서 IRQTF_RUNTHREAD를 확인합니다.
+ *   설정하면 thread_oneshot을 그대로 두고 스레드를 다시 실행합니다.
+ *
+ * - hard_irq
+ *   spin_lock은 flag제어 할때에만 사용하고, spin_lock안에서 flag로
+ *   직렬화 처리를 한다.(handle_irq_event() 참고)
+ *
+ *  - irq thread
+ *    spin_lock을 통해서 inprogress를 check한다.
+ */
     desc->threads_oneshot |= action->thread_mask;
 
     /*
@@ -133,11 +183,25 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
      * against this code (hard irq handler) via IRQS_INPROGRESS
      * like the finalize_oneshot() code. See comment above.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   irq 스레드를 깨울 경우에 대비하여 thread_active 카운터를 증가시킵니다.
+ *   irq 스레드는 핸들러에서 또는 종료 경로로 돌아올 때 카운터를 감소시키고
+ *   활성 카운트가 0이 될 때 synchronized_irq()에 갇혀 있는 웨이터를
+ *   깨웁니다. synchronize_irq()는 finalize_oneshot() 코드와 같이
+ *   IRQS_INPROGRESS를 통해 이 코드(하드 irq 핸들러)에 대해 직렬화됩니다.
+ *   위의 주석을 참조하십시오.
+ */
     atomic_inc(&desc->threads_active);
 
     wake_up_process(action->thread);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - action handler를 수행후 필요하다면 thread도 생성한다.
+ */
 irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags)
 {
     irqreturn_t retval = IRQ_NONE;
@@ -146,12 +210,23 @@ irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags
 
     record_irq_time(desc);
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - spi이므로 여러개가 있을수있다.
+ */
     for_each_action_of_desc(desc, action) {
         irqreturn_t res;
 
         /*
          * If this IRQ would be threaded under force_irqthreads, mark it so.
          */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - threaded irq 인지 확인한다.
+ *   irq_settings_can_thread(desc) : contoller에서 결정.
+ *   action->flags                 : user에서 결정.
+ */
         if (irq_settings_can_thread(desc) &&
             !(action->flags & (IRQF_NO_THREAD | IRQF_PERCPU | IRQF_ONESHOT)))
             lockdep_hardirq_threaded();
@@ -164,12 +239,21 @@ irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags
                   irq, action->handler))
             local_irq_disable();
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - result여부에 따라 thread를 wakeup한다.
+ */
         switch (res) {
         case IRQ_WAKE_THREAD:
             /*
              * Catch drivers which return WAKE_THREAD but
              * did not set up a thread function
              */
+/*
+ * IAMROOT, 2022.11.12:
+ * - thread fn이 등록이 안됬는데 thread wake 요청이 온경우 경고를 띄우고
+ *   break.
+ */
             if (unlikely(!action->thread_fn)) {
                 warn_no_thread(irq, action);
                 break;
@@ -192,6 +276,10 @@ irqreturn_t __handle_irq_event_percpu(struct irq_desc *desc, unsigned int *flags
     return retval;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - 
+ */
 irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
 {
     irqreturn_t retval;
@@ -206,6 +294,14 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
     return retval;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ *   pending flag가 여기서 지워지고, inprogress를 표시한다.
+ *                   V
+ *               handler 실행.
+ *                   V
+ *            inprogress clear.
+ */
 irqreturn_t handle_irq_event(struct irq_desc *desc)
 {
     irqreturn_t ret;
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index b4674c379965..f99e63500ca1 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -687,6 +687,10 @@ void irq_init_desc(unsigned int irq)
 
 #endif /* !CONFIG_SPARSE_IRQ */
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - @desc의 irq를 hadndle한다.
+ */
 int handle_irq_desc(struct irq_desc *desc)
 {
     struct irq_data *data;
@@ -695,6 +699,12 @@ int handle_irq_desc(struct irq_desc *desc)
         return -EINVAL;
 
     data = irq_desc_get_irq_data(desc);
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - irq진입상태인데, preempt_count가 없는 상태면(혹은 없어도
+ *   IRQD_HANDLE_ENFORCE_IRQCTX 상태가 아니라면) 이상한 상황이다.
+ */
     if (WARN_ON_ONCE(!in_irq() && handle_enforce_irqctx(data)))
         return -EPERM;
 
@@ -741,6 +751,12 @@ EXPORT_SYMBOL_GPL(generic_handle_domain_irq);
  *
  * Returns:    0 on success, or -EINVAL if conversion has failed
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - 1.stack에 backup해두었던것을 전역 pcpu 에 저장.
+ *   원래 전역 pcpu에 있던 old_regs는 handler 완료후 원복한다.
+ *   2. @domain에서 @hwirq를 검색해와서 handler를 실행한다.
+ */
 int handle_domain_irq(struct irq_domain *domain,
               unsigned int hwirq, struct pt_regs *regs)
 {
@@ -748,8 +764,16 @@ int handle_domain_irq(struct irq_domain *domain,
     struct irq_desc *desc;
     int ret = 0;
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * hardirq에 대한 preempt_count를 1 증가시킨다.
+ */
     irq_enter();
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * domain + hwirq로 irq 디스크립터를 검색해온다.
+ */
     /* The irqdomain code provides boundary checks */
     desc = irq_resolve_mapping(domain, hwirq);
     if (likely(desc))
@@ -757,6 +781,10 @@ int handle_domain_irq(struct irq_domain *domain,
     else
         ret = -EINVAL;
 
+/*
+ * IAMROOT, 2022.11.05: 
+ * hardirq에 대한 preempt_count를 1 감소시킨다.
+ */
     irq_exit();
     set_irq_regs(old_regs);
     return ret;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a581ffcf7975..f4e4cad52d6d 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1703,9 +1703,9 @@ setup_irq_thread(struct irqaction *new, unsigned int irq, bool secondary)
  *   7. /proc/에 생성된 irq번호로 자료구조 추가.
  *
  * - irq 흐름.
- *   vector
+ *   vectors(arch/arm64/kernel/entry.S)
  *     v
- *   chip handler
+ *   chip handler(handler_arch_irq, gic의 경우 gic_handle_irq)
  *     v
  *   flow handler
  *     v
@@ -3081,7 +3081,6 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act)
  *
  *   Dev_id는 전역적으로 고유해야 합니다. 이것은 CPU당 변수이며 핸들러는
  *   해당 변수의 인터럽트된 CPU 인스턴스와 함께 호출됩니다.
- *
  * - ex) ipi의 경우 ipi_handler()
  *
  * - irq 흐름.
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index d7163b503b0b..d1ed7d6e0582 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -13,8 +13,20 @@
 
 #include "internals.h"
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - wakeup 중인지 확인한다.
+ */
 bool irq_pm_check_wakeup(struct irq_desc *desc)
 {
+/*
+ * IAMROOT, 2022.11.12:
+ * - 안깨어있다면.
+ *   suspend 상태로 표시.
+ *   pending으로 표시.
+ *   irq_disable후 wakeup 시도.
+ */
     if (irqd_is_wakeup_armed(&desc->irq_data)) {
         irqd_clear(&desc->irq_data, IRQD_WAKEUP_ARMED);
         desc->istate |= IRQS_SUSPENDED | IRQS_PENDING;
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 41d3e212368a..a873d6c6e133 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -33,6 +33,23 @@ static atomic_t irq_poll_active;
  * action (about to be disabled). Only if it's still active, we return
  * true and let the handler run.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   우리는 poller가 끝날 때까지 여기서 기다립니다. 
+ *
+ *   이 CPU에서 poll이 실행되면 큰 소리로 외치고 false를 반환합니다.
+ *   그러면 최악의 경우 인터럽트 라인이 비활성화되지만 절대 발생해서는
+ *   안됩니다.
+ *
+ *   poller가 완료될 때까지 기다렸다가 비활성화 및 작업(비활성화될 예정)을
+ *   다시 확인합니다. 여전히 활성 상태인 경우에만 true를 반환하고 핸들러를
+ *   실행합니다.
+ *
+ * - poll하고 있는게 current cpu라면 false.
+ *   irq_data가 porgress끝날때가지 기다린다.
+ * - @desc가 enable상태고 action handler가 존재하면 return true;
+ */
 bool irq_wait_for_poll(struct irq_desc *desc)
     __must_hold(&desc->lock)
 {
@@ -51,6 +68,11 @@ bool irq_wait_for_poll(struct irq_desc *desc)
     /* Might have been disabled in meantime */
     return !irqd_irq_disabled(&desc->irq_data) && desc->action;
 #else
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - single core면 polling이 불가능하다.
+ */
     return false;
 #endif
 }
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index bce848e50512..4be18273af72 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -802,6 +802,10 @@ noinstr void rcu_nmi_exit(void)
  * If you add or remove a call to rcu_irq_exit(), be sure to test with
  * CONFIG_RCU_EQS_DEBUG=y.
  */
+/*
+ * IAMROOT, 2022.11.11:
+ * - TODO
+ */
 void noinstr rcu_irq_exit(void)
 {
     lockdep_assert_irqs_disabled();
@@ -1065,6 +1069,10 @@ noinstr void rcu_nmi_enter(void)
  * If you add or remove a call to rcu_irq_enter(), be sure to test with
  * CONFIG_RCU_EQS_DEBUG=y.
  */
+/*
+ * IAMROOT, 2022.11.11:
+ * - TODO
+ */
 noinstr void rcu_irq_enter(void)
 {
     lockdep_assert_irqs_disabled();
diff --git a/kernel/softirq.c b/kernel/softirq.c
index a12dbf8ca8bd..cba80841de7d 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -71,6 +71,10 @@ const char * const softirq_to_name[NR_SOFTIRQS] = {
  * to the pending events, so lets the scheduler to balance
  * the softirq load for us.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - wakeup ksoftirqd
+ */
 static void wakeup_softirqd(void)
 {
     /* Interrupts are disabled: no need to stop preemption */
@@ -131,6 +135,22 @@ EXPORT_PER_CPU_SYMBOL_GPL(hardirq_context);
  * The per CPU counter prevents pointless wakeups of ksoftirqd in case that
  * the task which is in a softirq disabled section is preempted or blocks.
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   RT는 task::softirqs_disabled_cnt 및 CPU softirq_ctrl::cnt별로 BH
+ *   비활성화 섹션을 설명합니다. 이것은 softirq 비활성화 섹션의 작업이
+ *   선점되도록 하는 데 필요합니다. 
+ *
+ *   작업당 카운터는 softirq_count(), in_softirq() 및
+ *   in_serving_softirqs()에 사용됩니다. 이러한 카운트는
+ *   softirq_ctrl::lock을 보유하는 작업이 실행 중일 때만 유효하기
+ *   때문입니다.
+ *
+ *   CPU당 카운터는 softirq 비활성화 섹션에 있는 작업이 선점되거나
+ *   차단되는 경우 ksoftirqd의 무의미한 깨우기를 방지합니다.
+ */
 struct softirq_ctrl {
     local_lock_t    lock;
     int        cnt;
@@ -266,6 +286,11 @@ EXPORT_SYMBOL(__local_bh_enable_ip);
  * Invoked from ksoftirqd_run() outside of the interrupt disabled section
  * to acquire the per CPU local lock for reentrancy protection.
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - preempt.
+ */
 static inline void ksoftirqd_run_begin(void)
 {
     __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET);
@@ -283,11 +308,20 @@ static inline void ksoftirqd_run_end(void)
 static inline void softirq_handle_begin(void) { }
 static inline void softirq_handle_end(void) { }
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - cnt가 없으면 true.
+ */
 static inline bool should_wake_ksoftirqd(void)
 {
     return !this_cpu_read(softirq_ctrl.cnt);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - softirq_ctrl::cnt == 0이면 softirq wakeup
+ */
 static inline void invoke_softirq(void)
 {
     if (should_wake_ksoftirqd())
@@ -402,6 +436,10 @@ static inline void softirq_handle_end(void)
     WARN_ON_ONCE(in_interrupt());
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - !preempt
+ */
 static inline void ksoftirqd_run_begin(void)
 {
     local_irq_disable();
@@ -417,11 +455,20 @@ static inline bool should_wake_ksoftirqd(void)
     return true;
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - !preempt
+ *   직접 처리하거나, ksoftirqd을 이용해서 처리하거나를 결정한다.
+ */
 static inline void invoke_softirq(void)
 {
     if (ksoftirqd_running(local_softirq_pending()))
         return;
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - 1. !preempt 이거나 ksoftirqd이 없으면 직접 처리한다.
+ */
     if (!force_irqthreads() || !__this_cpu_read(ksoftirqd)) {
 #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK
         /*
@@ -429,6 +476,10 @@ static inline void invoke_softirq(void)
          * it is the irq stack, because it should be near empty
          * at this stage.
          */
+/*
+ * IAMROOT, 2022.11.12:
+ * - 직접 실행한다.
+ */
         __do_softirq();
 #else
         /*
@@ -443,6 +494,10 @@ static inline void invoke_softirq(void)
     }
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - TODO
+ */
 asmlinkage __visible void do_softirq(void)
 {
     __u32 pending;
@@ -512,6 +567,10 @@ static inline bool lockdep_softirq_start(void) { return false; }
 static inline void lockdep_softirq_end(bool in_hardirq) { }
 #endif
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - TODO
+ */
 asmlinkage __visible void __softirq_entry __do_softirq(void)
 {
     unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
@@ -593,6 +652,10 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
  */
 void irq_enter_rcu(void)
 {
+/*
+ * IAMROOT, 2022.11.05: 
+ * hardirq에 대한 preempt_count를 1 증가시킨다.
+ */
     __irq_enter_raw();
 
     if (is_idle_task(current) && (irq_count() == HARDIRQ_OFFSET))
@@ -623,6 +686,14 @@ static inline void tick_irq_exit(void)
 #endif
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - preempt count감소후 필요에따라 softirq실행
+ * - softirq가 실행되는 상황.
+ *   현재 irq가 중첩이 안됬다면 preempt_count_sub로 인해
+ *   !in_interrupt() 조건이 될수있다. 이 상황에서 pending softirq가 있다면
+ *   invoke_softirq()를 수행한다.
+ */
 static inline void __irq_exit_rcu(void)
 {
 #ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
@@ -631,7 +702,16 @@ static inline void __irq_exit_rcu(void)
     lockdep_assert_irqs_disabled();
 #endif
     account_hardirq_exit(current);
+/*
+ * IAMROOT, 2022.11.05: 
+ * 인터럽트를 빠져나갈때 HARDIRQ_OFFSET에 대한 preempt count를 1 감소 시킨다.
+ */
     preempt_count_sub(HARDIRQ_OFFSET);
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - hardirq 처리후 softirq가 pending되있으면 softirq를 일으킨다.
+ */
     if (!in_interrupt() && local_softirq_pending())
         invoke_softirq();
 
@@ -655,8 +735,18 @@ void irq_exit_rcu(void)
  *
  * Also processes softirqs if needed and possible.
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - hardirq preempt count 감소.
+ * - 경우에 따라 softirq 수행.
+ */
 void irq_exit(void)
 {
+/*
+ * IAMROOT, 2022.11.05: 
+ * 아래 함수에서 hardirq에 대한 preempt_count 감소와,
+ * peinding 상태의 softirq 호출이 이루어진다.
+ */
     __irq_exit_rcu();
     rcu_irq_exit();
      /* must be last! */
@@ -666,6 +756,10 @@ void irq_exit(void)
 /*
  * This function must run with irqs disabled!
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - pending을 일단하고 현재 context가 kernel thread인 경우는 바로 깨운다.
+ */
 inline void raise_softirq_irqoff(unsigned int nr)
 {
     __raise_softirq_irqoff(nr);
@@ -679,6 +773,17 @@ inline void raise_softirq_irqoff(unsigned int nr)
      * Otherwise we wake up ksoftirqd to make sure we
      * schedule the softirq soon.
      */
+/*
+ * IAMROOT, 2022.11.12:
+ * - papago
+ *   인터럽트 또는 softirq에 있으면 작업이 완료됩니다(softirq 비활성화
+ *   코드도 포착됨). irq 또는 softirq에서 돌아오면 실제로
+ *   softirq를 실행할 것입니다. 
+ *
+ *   그렇지 않으면 ksoftirqd를 깨워 softirq를 곧 예약하도록 합니다.
+ * - !in_interrupt()
+ *   현재 함수의 call이 irq context아니라면 수행한다.
+ */
     if (!in_interrupt() && should_wake_ksoftirqd())
         wakeup_softirqd();
 }
@@ -696,6 +801,11 @@ void raise_softirq(unsigned int nr)
     local_irq_restore(flags);
 }
 
+/*
+ * IAMROOT, 2022.11.12:
+ * - softirq 요청 처리.
+ * - @nr에 해당하는 bitmask를 set한다.
+ */
 void __raise_softirq_irqoff(unsigned int nr)
 {
     lockdep_assert_irqs_disabled();
diff --git a/kernel/stackleak.c b/kernel/stackleak.c
index ce161a8e8d97..4d337c34c66f 100644
--- a/kernel/stackleak.c
+++ b/kernel/stackleak.c
@@ -48,6 +48,10 @@ int stack_erasing_sysctl(struct ctl_table *table, int write,
 #define skip_erasing()    false
 #endif /* CONFIG_STACKLEAK_RUNTIME_DISABLE */
 
+/*
+ * IAMROOT, 2022.11.09:
+ * - PASS
+ */
 asmlinkage void notrace stackleak_erase(void)
 {
     /* It would be nice not to have 'kstack_ptr' and 'boundary' on stack */
diff --git a/mm/memory.c b/mm/memory.c
index 7d1250c81605..63f4e31e9a2b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4702,6 +4702,10 @@ static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
  * The mmap_lock may have been released depending on flags and our return value.
  * See filemap_fault() and __lock_page_or_retry().
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - pte entry에 memory를 할당받아서 연결한다.
+ */
 static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
 {
     pte_t entry;
@@ -4828,6 +4832,10 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
  * The mmap_lock may have been released depending on flags and our
  * return value.  See filemap_fault() and __lock_page_or_retry().
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - table 만든후 pte fault수행.
+ */
 static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
         unsigned long address, unsigned int flags)
 {
@@ -4984,6 +4992,10 @@ static inline void mm_account_fault(struct pt_regs *regs,
  * The mmap_lock may have been released depending on flags and our
  * return value.  See filemap_fault() and __lock_page_or_retry().
  */
+/*
+ * IAMROOT, 2022.11.12:
+ * - mm fault 수행
+ */
 vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
                unsigned int flags, struct pt_regs *regs)
 {
@@ -5009,6 +5021,11 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
     if (flags & FAULT_FLAG_USER)
         mem_cgroup_enter_user_fault();
 
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - mm fault 수행
+ */
     if (unlikely(is_vm_hugetlb_page(vma)))
         ret = hugetlb_fault(vma->vm_mm, vma, address, flags);
     else
@@ -5060,6 +5077,11 @@ int __p4d_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
  * Allocate page upper directory.
  * We've already handled the fast-path in-line.
  */
+
+/*
+ * IAMROOT, 2022.11.12:
+ * - p4d에 연결(populate)한다.
+ */
 int __pud_alloc(struct mm_struct *mm, p4d_t *p4d, unsigned long address)
 {
     pud_t *new = pud_alloc_one(mm, address);
 

 

 

 

 
번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
167 [커널 18차] 80주차 kkr 2022.12.03 156
166 [커널 19차] 28 ~ 29 주차 Min 2022.12.03 35
165 [커널 19차] 27 주차 Min 2022.11.22 82
164 [커널 18차] 78주차 kkr 2022.11.19 187
163 [커널 19차] 25 ~ 26 주차 Min 2022.11.14 72
» [커널 18차] 76-77주차 kkr 2022.11.12 386
161 [커널 19차] 24주차 Min 2022.10.31 108
160 [커널 17차] 112주차 ㅇㅇㅇ 2022.10.30 81
159 [커널 18차] 75주차 kkr 2022.10.29 42
158 [커널 17차] 107 ~ 111주차 ㅇㅇㅇ 2022.10.23 77
157 [커널 19차] 22주차 Min 2022.10.17 76
156 [커널 18차] 73주차 kkr 2022.10.15 46
155 [커널 18차] 72주차 kkr 2022.10.09 183
154 [커널 18차] 71주차 kkr 2022.10.01 75
153 [커널 18차] 70주차 kkr 2022.09.24 77
152 [커널 18차] 69주차 kkr 2022.09.22 58
151 [커널 17차] 105~106주차 ㅇㅇㅇ 2022.09.18 50
150 [커널 17차] 104주차 ㅇㅇㅇ 2022.09.04 88
149 [커널 18차] 67주차 kkr 2022.09.03 138
148 [커널 17차] 103주차 ㅇㅇㅇ 2022.08.28 35
XE Login