I debug the rocky 8.7 kernel. (4.18.0-425.3.1.el8.x86_64 and 4.18.0-425.13.1.el8.x86_64) for our company module issue.
And I have a question . why pv_mmu_ops notify_page_enc_status_changed field is moved to reserved1 field on (4.18.0-425.13.1.el8.x86_64)? I think pv_mmu_ops structure reserved filed may exist for compatibility. By moving field to reserved, size reduced. (I think notify_page_enc_status_changed location dummy field needed or must not change the location)
Is there any reson I don't know ?
4.18.0-425.3.1.el8.x86_64 crash> struct pv_mmu_ops struct pv_mmu_ops { unsigned long (*read_cr2)(void); void (*notify_page_enc_status_changed)(unsigned long, int, bool); void (*write_cr2)(unsigned long); unsigned long (*read_cr3)(void); void (*write_cr3)(unsigned long); void (*activate_mm)(struct mm_struct *, struct mm_struct *); void (*dup_mmap)(struct mm_struct *, struct mm_struct *); void (*exit_mmap)(struct mm_struct *); void (*flush_tlb_user)(void); void (*flush_tlb_kernel)(void); void (*flush_tlb_one_user)(unsigned long); void (*flush_tlb_others)(const struct cpumask *, const struct flush_tlb_info *); void (*tlb_remove_table)(struct mmu_gather *, void *); int (*pgd_alloc)(struct mm_struct *); void (*pgd_free)(struct mm_struct *, pgd_t *); void (*alloc_pte)(struct mm_struct *, unsigned long); void (*alloc_pmd)(struct mm_struct *, unsigned long); void (*alloc_pud)(struct mm_struct *, unsigned long); void (*alloc_p4d)(struct mm_struct *, unsigned long); void (*release_pte)(unsigned long); void (*release_pmd)(unsigned long); void (*release_pud)(unsigned long); void (*release_p4d)(unsigned long); void (*set_pte)(pte_t *, pte_t); void (*set_pte_at)(struct mm_struct *, unsigned long, pte_t *, pte_t); void (*set_pmd)(pmd_t *, pmd_t); pte_t (*ptep_modify_prot_start)(struct vm_area_struct *, unsigned long, pte_t *); void (*ptep_modify_prot_commit)(struct vm_area_struct *, unsigned long, pte_t *, pte_t); struct paravirt_callee_save pte_val; struct paravirt_callee_save make_pte; struct paravirt_callee_save pgd_val; struct paravirt_callee_save make_pgd; void (*set_pud)(pud_t *, pud_t); struct paravirt_callee_save pmd_val; struct paravirt_callee_save make_pmd; struct paravirt_callee_save pud_val; struct paravirt_callee_save make_pud; void (*set_p4d)(p4d_t *, p4d_t); struct paravirt_callee_save p4d_val; struct paravirt_callee_save make_p4d; void (*set_pgd)(pgd_t *, pgd_t); struct pv_lazy_ops lazy_mode; void (*set_fixmap)(unsigned int, phys_addr_t, pgprot_t); unsigned long rh_reserved1; unsigned long rh_reserved2; unsigned long rh_reserved3; unsigned long rh_reserved4; } SIZE: 392
4.18.0-425.13.1.el8.x86_64 crash> struct pv_mmu_ops struct pv_mmu_ops { unsigned long (*read_cr2)(void); void (*write_cr2)(unsigned long); unsigned long (*read_cr3)(void); void (*write_cr3)(unsigned long); void (*activate_mm)(struct mm_struct *, struct mm_struct *); void (*dup_mmap)(struct mm_struct *, struct mm_struct *); void (*exit_mmap)(struct mm_struct *); void (*flush_tlb_user)(void); void (*flush_tlb_kernel)(void); void (*flush_tlb_one_user)(unsigned long); void (*flush_tlb_others)(const struct cpumask *, const struct flush_tlb_info *); void (*tlb_remove_table)(struct mmu_gather *, void *); int (*pgd_alloc)(struct mm_struct *); void (*pgd_free)(struct mm_struct *, pgd_t *); void (*alloc_pte)(struct mm_struct *, unsigned long); void (*alloc_pmd)(struct mm_struct *, unsigned long); void (*alloc_pud)(struct mm_struct *, unsigned long); void (*alloc_p4d)(struct mm_struct *, unsigned long); void (*release_pte)(unsigned long); void (*release_pmd)(unsigned long); void (*release_pud)(unsigned long); void (*release_p4d)(unsigned long); void (*set_pte)(pte_t *, pte_t); void (*set_pte_at)(struct mm_struct *, unsigned long, pte_t *, pte_t); void (*set_pmd)(pmd_t *, pmd_t); pte_t (*ptep_modify_prot_start)(struct vm_area_struct *, unsigned long, pte_t *); void (*ptep_modify_prot_commit)(struct vm_area_struct *, unsigned long, pte_t *, pte_t); struct paravirt_callee_save pte_val; struct paravirt_callee_save make_pte; struct paravirt_callee_save pgd_val; struct paravirt_callee_save make_pgd; void (*set_pud)(pud_t *, pud_t); struct paravirt_callee_save pmd_val; struct paravirt_callee_save make_pmd; struct paravirt_callee_save pud_val; struct paravirt_callee_save make_pud; void (*set_p4d)(p4d_t *, p4d_t); struct paravirt_callee_save p4d_val; struct paravirt_callee_save make_p4d; void (*set_pgd)(pgd_t *, pgd_t); struct pv_lazy_ops lazy_mode; void (*set_fixmap)(unsigned int, phys_addr_t, pgprot_t); union { void (*notify_page_enc_status_changed)(unsigned long, int, bool); struct { unsigned long rh_reserved1; } rh_kabi_hidden_308; union { <no data fields> }; }; unsigned long rh_reserved2; unsigned long rh_reserved3; unsigned long rh_reserved4; } SIZE: 384 4.18.0-425.13.1.el8.x86_64
Thanks
"안전해서 더욱 자유로운 세상 – 안랩"
youngjun park / Base Technology team / Endpoint research laboratory
T 031-722-8369 F 031-722-8277
youngjun.park@ahnlab.com www.ahnlab.comhttp://www.ahnlab.com/
(13493) 경기도 성남시 분당구 판교역로 220 (주)안랩
본 메일은 지정된 수취인만을 위해 작성되었으며, 중요한 정보나 저작권을 포함하고 있을 수 있습니다. 어떠한 권한 없이, 본 문서에 포함된 정보의 전부 또는 일부를 무단으로 제3자에게 공개, 배포, 복사 또는 사용하는 것을 엄격히 금지합니다. 만약, 본 메일이 잘못 전송된 경우, 발신인 또는 당사에 알려주시고, 본 메일을 즉시 삭제하여 주시기 바랍니다.
On Fri, Mar 24, 2023 at 8:49 PM 박영준 via rocky rocky@lists.resf.org wrote:
I debug the rocky 8.7 kernel. (4.18.0-425.3.1.el8.x86_64 and 4.18.0-425.13.1.el8.x86_64) for our company module issue.
And I have a question . why pv_mmu_ops notify_page_enc_status_changed field is moved to reserved1 field on (4.18.0-425.13.1.el8.x86_64)? I think pv_mmu_ops structure reserved filed may exist for compatibility. By moving field to reserved, size reduced. (I think notify_page_enc_status_changed location dummy field needed or must not change the location)
Is there any reson I don't know ?
Rocky kernels are rebuilt from the source code of RHEL kernels without modifications (except debranding). Therefore you need to ask Red Hat. However here is what I guess has happened.
In the GA kernel of RHEL 8.7 (4.18.0-425.3.1.el8), there was a kABI breakage. This caused failure of kmod packages built against this kernel. Turns out the breakage was in pv_mmu_ops structure and it was fixed in kernel-4.18.0-425.10.1.el8_7 [1]. That likely lead to what you have encountered.
Akemi
On Sat, Mar 25, 2023 at 3:23 AM Akemi Yagi via rocky rocky@lists.resf.org wrote:
On Fri, Mar 24, 2023 at 8:49 PM 박영준 via rocky rocky@lists.resf.org wrote:
I debug the rocky 8.7 kernel. (4.18.0-425.3.1.el8.x86_64 and 4.18.0-425.13.1.el8.x86_64) for our company module issue.
And I have a question . why pv_mmu_ops notify_page_enc_status_changed field is moved to reserved1 field on (4.18.0-425.13.1.el8.x86_64)? I think pv_mmu_ops structure reserved filed may exist for compatibility. By moving field to reserved, size reduced. (I think notify_page_enc_status_changed location dummy field needed or must not change the location)
Is there any reson I don't know ?
Rocky kernels are rebuilt from the source code of RHEL kernels without modifications (except debranding). Therefore you need to ask Red Hat. However here is what I guess has happened.
In the GA kernel of RHEL 8.7 (4.18.0-425.3.1.el8), there was a kABI breakage. This caused failure of kmod packages built against this kernel. Turns out the breakage was in pv_mmu_ops structure and it was fixed in kernel-4.18.0-425.10.1.el8_7 [1]. That likely lead to what you have encountered.
Akemi
Here's some additional info. I was curious to see how the kABI breakage was fixed. Below is a diff in the source code between kernel-425.3.1 and 425.13.1.
Akemi
===================================================== $ diff -uNpr paravirt_types.h.425.3.1 paravirt_types.h.425.13.1 --- paravirt_types.h.425.3.1 2022-09-30 07:54:26.000000000 -0700 +++ paravirt_types.h.425.13.1 2023-02-02 08:42:46.000000000 -0800 @@ -205,8 +205,6 @@ struct pv_irq_ops { struct pv_mmu_ops { unsigned long (*read_cr2)(void);
- void (*notify_page_enc_status_changed)(unsigned long pfn, int npages, bool enc); - void (*write_cr2)(unsigned long);
unsigned long (*read_cr3)(void); @@ -306,7 +304,8 @@ struct pv_mmu_ops { void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, phys_addr_t phys, pgprot_t flags);
- RH_KABI_RESERVE(1) + RH_KABI_USE(1, void (*notify_page_enc_status_changed)(unsigned long pfn, + int npages, bool enc)) RH_KABI_RESERVE(2) RH_KABI_RESERVE(3) RH_KABI_RESERVE(4)