8e4341aaa8
* Mon Apr 22 2024 Jan Stancek <jstancek@redhat.com> [6.9.0-0.rc4.2.el10] - blk-iocost: do not WARN if iocg was already offlined (Li Nan) - block: propagate partition scanning errors to the BLKRRPART ioctl (Christoph Hellwig) - MAINTAINERS: update to working email address (James Bottomley) - KVM: x86: Stop compiling vmenter.S with OBJECT_FILES_NON_STANDARD (Sean Christopherson) - KVM: SVM: Create a stack frame in __svm_sev_es_vcpu_run() (Sean Christopherson) - KVM: SVM: Save/restore args across SEV-ES VMRUN via host save area (Sean Christopherson) - KVM: SVM: Save/restore non-volatile GPRs in SEV-ES VMRUN via host save area (Sean Christopherson) - KVM: SVM: Clobber RAX instead of RBX when discarding spec_ctrl_intercepted (Sean Christopherson) - KVM: SVM: Drop 32-bit "support" from __svm_sev_es_vcpu_run() (Sean Christopherson) - KVM: SVM: Wrap __svm_sev_es_vcpu_run() with #ifdef CONFIG_KVM_AMD_SEV (Sean Christopherson) - KVM: SVM: Create a stack frame in __svm_vcpu_run() for unwinding (Sean Christopherson) - KVM: SVM: Remove a useless zeroing of allocated memory (Christophe JAILLET) - KVM: Drop unused @may_block param from gfn_to_pfn_cache_invalidate_start() (Sean Christopherson) - KVM: selftests: Add coverage of EPT-disabled to vmx_dirty_log_test (David Matlack) - KVM: x86/mmu: Fix and clarify comments about clearing D-bit vs. write-protecting (David Matlack) - KVM: x86/mmu: Remove function comments above clear_dirty_{gfn_range,pt_masked}() (David Matlack) - KVM: x86/mmu: Write-protect L2 SPTEs in TDP MMU when clearing dirty status (David Matlack) - KVM: x86/mmu: Precisely invalidate MMU root_role during CPUID update (Sean Christopherson) - KVM: VMX: Disable LBR virtualization if the CPU doesn't support LBR callstacks (Sean Christopherson) - perf/x86/intel: Expose existence of callback support to KVM (Sean Christopherson) - KVM: VMX: Snapshot LBR capabilities during module initialization (Sean Christopherson) - KVM: VMX: Ignore MKTME KeyID bits when intercepting #PF for allow_smaller_maxphyaddr (Tao Su) - KVM: selftests: fix supported_flags for riscv (Andrew Jones) - KVM: selftests: fix max_guest_memory_test with more that 256 vCPUs (Maxim Levitsky) - KVM: selftests: Verify post-RESET value of PERF_GLOBAL_CTRL in PMCs test (Sean Christopherson) - KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET" (Sean Christopherson) - KVM: x86/mmu: x86: Don't overflow lpage_info when checking attributes (Rick Edgecombe) - KVM: x86/pmu: Disable support for adaptive PEBS (Sean Christopherson) - KVM: Explicitly disallow activatating a gfn_to_pfn_cache with INVALID_GPA (Sean Christopherson) - KVM: Check validity of offset+length of gfn_to_pfn_cache prior to activation (Sean Christopherson) - KVM: Add helpers to consolidate gfn_to_pfn_cache's page split check (Sean Christopherson) - KVM: x86/pmu: Do not mask LVTPC when handling a PMI on AMD platforms (Sandipan Das) - KVM: x86: Snapshot if a vCPU's vendor model is AMD vs. Intel compatible (Sean Christopherson) - selftests/powerpc/papr-vpd: Fix missing variable initialization (Nathan Lynch) - powerpc/crypto/chacha-p10: Fix failure on non Power10 (Michael Ellerman) - powerpc/iommu: Refactor spapr_tce_platform_iommu_attach_dev() (Shivaprasad G Bhat) - clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port (Daniel Golle) - clk: mediatek: Do a runtime PM get on controllers during probe (Pin-yen Lin) - clk: Get runtime PM before walking tree for clk_summary (Stephen Boyd) - clk: Get runtime PM before walking tree during disable_unused (Stephen Boyd) - clk: Initialize struct clk_core kref earlier (Stephen Boyd) - clk: Don't hold prepare_lock when calling kref_put() (Stephen Boyd) - clk: Remove prepare_lock hold assertion in __clk_release() (Stephen Boyd) - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get() (Uwe Kleine-König) - tools/include: Sync arm64 asm/cputype.h with the kernel sources (Namhyung Kim) - tools/include: Sync asm-generic/bitops/fls.h with the kernel sources (Namhyung Kim) - tools/include: Sync x86 asm/msr-index.h with the kernel sources (Namhyung Kim) - tools/include: Sync x86 asm/irq_vectors.h with the kernel sources (Namhyung Kim) - tools/include: Sync x86 CPU feature headers with the kernel sources (Namhyung Kim) - tools/include: Sync uapi/sound/asound.h with the kernel sources (Namhyung Kim) - tools/include: Sync uapi/linux/kvm.h and asm/kvm.h with the kernel sources (Namhyung Kim) - tools/include: Sync uapi/linux/fs.h with the kernel sources (Namhyung Kim) - tools/include: Sync uapi/drm/i915_drm.h with the kernel sources (Namhyung Kim) - perf lock contention: Add a missing NULL check (Namhyung Kim) - perf annotate: Make sure to call symbol__annotate2() in TUI (Namhyung Kim) - ubsan: Add awareness of signed integer overflow traps (Kees Cook) - configs/hardening: Disable CONFIG_UBSAN_SIGNED_WRAP (Nathan Chancellor) - configs/hardening: Fix disabling UBSAN configurations (Nathan Chancellor) - iommufd: Add config needed for iommufd_fail_nth (Muhammad Usama Anjum) - iommufd: Add missing IOMMUFD_DRIVER kconfig for the selftest (Jason Gunthorpe) - RDMA/mlx5: Fix port number for counter query in multi-port configuration (Michael Guralnik) - RDMA/cm: Print the old state when cm_destroy_id gets timeout (Mark Zhang) - RDMA/rxe: Fix the problem "mutex_destroy missing" (Yanjun.Zhu) - fs/9p: drop inodes immediately on non-.L too (Joakim Sindholt) - fs/9p: Revert "fs/9p: fix dups even in uncached mode" (Eric Van Hensbergen) - fs/9p: remove erroneous nlink init from legacy stat2inode (Eric Van Hensbergen) - 9p: explicitly deny setlease attempts (Jeff Layton) - fs/9p: fix the cache always being enabled on files with qid flags (Joakim Sindholt) - fs/9p: translate O_TRUNC into OTRUNC (Joakim Sindholt) - fs/9p: only translate RWX permissions for plain 9P2000 (Joakim Sindholt) - cuse: add kernel-doc comments to cuse_process_init_reply() (Yang Li) - fuse: fix leaked ENOSYS error on first statx call (Danny Lin) - fuse: fix parallel dio write on file open in passthrough mode (Amir Goldstein) - fuse: fix wrong ff->iomode state changes from parallel dio write (Amir Goldstein) - arm64: hibernate: Fix level3 translation fault in swsusp_save() (Yaxiong Tian) - arm64/head: Disable MMU at EL2 before clearing HCR_EL2.E2H (Ard Biesheuvel) - arm64/head: Drop unnecessary pre-disable-MMU workaround (Ard Biesheuvel) - arm64/hugetlb: Fix page table walk in huge_pte_alloc() (Anshuman Khandual) - s390/mm: Fix NULL pointer dereference (Sven Schnelle) - s390/cio: log fake IRB events (Peter Oberparleiter) - s390/cio: fix race condition during online processing (Peter Oberparleiter) - s390/qdio: handle deferred cc1 (Peter Oberparleiter) - bootconfig: Fix the kerneldoc of _xbc_exit() (Masami Hiramatsu (Google)) - bootconfig: use memblock_free_late to free xbc memory to buddy (Qiang Zhang) - init/main.c: Fix potential static_command_line memory overflow (Yuntao Wang) - thermal/debugfs: Add missing count increment to thermal_debug_tz_trip_up() (Rafael J. Wysocki) - ALSA: seq: ump: Fix conversion from MIDI2 to MIDI1 UMP messages (Takashi Iwai) - ALSA: hda/realtek - Enable audio jacks of Haier Boyue G42 with ALC269VC (Ai Chao) - ALSA: hda/realtek: Add quirks for Huawei Matebook D14 NBLB-WAX9N (Mauro Carvalho Chehab) - ALSA: hda/realtek: Fix volumn control of ThinkBook 16P Gen4 (Huayu Zhang) - ALSA: hda/realtek: Fixes for Asus GU605M and GA403U sound (Vitalii Torshyn) - ALSA: hda/tas2781: Add new vendor_id and subsystem_id to support ThinkPad ICE-1 (Shenghao Ding) - ALSA: hda/tas2781: correct the register for pow calibrated data (Shenghao Ding) - ALSA: hda/realtek: Add quirk for HP SnowWhite laptops (Vitaly Rodionov) - drm/xe/vm: prevent UAF with asid based lookup (Matthew Auld) - drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init (Maarten Lankhorst) - drm/panel: novatek-nt36682e: don't unregister DSI device (Dmitry Baryshkov) - drm/panel: visionox-rm69299: don't unregister DSI device (Dmitry Baryshkov) - drm/nouveau/dp: Don't probe eDP ports twice harder (Lyude Paul) - drm/nouveau/kms/nv50-: Disable AUX bus for disconnected DP ports (Lyude Paul) - drm/v3d: Don't increment `enabled_ns` twice (Maíra Canal) - drm/vmwgfx: Sort primary plane formats by order of preference (Zack Rusin) - drm/vmwgfx: Fix crtc's atomic check conditional (Zack Rusin) - drm/vmwgfx: Fix prime import/export (Zack Rusin) - drm/ttm: stop pooling cached NUMA pages v2 (Christian König) - drm: nv04: Fix out of bounds access (Mikhail Kobuk) - nouveau: fix instmem race condition around ptr stores (Dave Airlie) - drm/radeon: silence UBSAN warning (v3) (Alex Deucher) - drm/radeon: make -fstrict-flex-arrays=3 happy (Alex Deucher) - drm/amdgpu: fix visible VRAM handling during faults (Christian König) - drm/amdgpu: validate the parameters of bo mapping operations more clearly (xinhui pan) - Revert "drm/amd/display: fix USB-C flag update after enc10 feature init" (Alex Deucher) - drm/amdkfd: Fix memory leak in create_process failure (Felix Kuehling) - drm/amdgpu: remove invalid resource->start check v2 (Christian König) - nilfs2: fix OOB in nilfs_set_de_type (Jeongjun Park) - MAINTAINERS: update Naoya Horiguchi's email address (Naoya Horiguchi) - fork: defer linking file vma until vma is fully initialized (Miaohe Lin) - mm/shmem: inline shmem_is_huge() for disabled transparent hugepages (Sumanth Korikkar) - mm,page_owner: defer enablement of static branch (Oscar Salvador) - Squashfs: check the inode number is not the invalid value of zero (Phillip Lougher) - mm,swapops: update check in is_pfn_swap_entry for hwpoison entries (Oscar Salvador) - mm/memory-failure: fix deadlock when hugetlb_optimize_vmemmap is enabled (Miaohe Lin) - mm/userfaultfd: allow hugetlb change protection upon poison entry (Peter Xu) - mm,page_owner: fix printing of stack records (Oscar Salvador) - mm,page_owner: fix accounting of pages when migrating (Oscar Salvador) - mm,page_owner: fix refcount imbalance (Oscar Salvador) - mm,page_owner: update metadata for tail pages (Oscar Salvador) - userfaultfd: change src_folio after ensuring it's unpinned in UFFDIO_MOVE (Lokesh Gidra) - mm/madvise: make MADV_POPULATE_(READ|WRITE) handle VM_FAULT_RETRY properly (David Hildenbrand) - scsi: core: Fix handling of SCMD_FAIL_IF_RECOVERING (Bart Van Assche) - scsi: ufs: qcom: Add missing interconnect bandwidth values for Gear 5 (Manivannan Sadhasivam) - net: ethernet: ti: am65-cpsw-nuss: cleanup DMA Channels before using them (Siddharth Vadapalli) - net: usb: ax88179_178a: avoid writing the mac address before first reading (Jose Ignacio Tornos Martinez) - netfilter: nf_tables: fix memleak in map from abort path (Pablo Neira Ayuso) - netfilter: nf_tables: restore set elements when delete set fails (Pablo Neira Ayuso) - netfilter: nf_tables: missing iterator type in lookup walk (Pablo Neira Ayuso) - net: ravb: Fix RX byte accounting for jumbo packets (Paul Barker) - net: ravb: Fix GbEth jumbo packet RX checksum handling (Paul Barker) - net: ravb: Allow RX loop to move past DMA mapping errors (Paul Barker) - net: ravb: Count packets instead of descriptors in R-Car RX path (Paul Barker) - net: ethernet: mtk_eth_soc: fix WED + wifi reset (Felix Fietkau) - net:usb:qmi_wwan: support Rolling modules (Vanillan Wang) - ice: Fix checking for unsupported keys on non-tunnel device (Marcin Szycik) - ice: tc: allow zero flags in parsing tc flower (Michal Swiatkowski) - ice: tc: check src_vsi in case of traffic from VF (Michal Swiatkowski) - selftests: kselftest_harness: fix Clang warning about zero-length format (Jakub Kicinski) - net/sched: Fix mirred deadlock on device recursion (Eric Dumazet) - s390/ism: Properly fix receive message buffer allocation (Gerd Bayer) - net: dsa: mt7530: fix port mirroring for MT7988 SoC switch (Arınç ÜNAL) - net: dsa: mt7530: fix mirroring frames received on local port (Arınç ÜNAL) - tun: limit printing rate when illegal packet received by tun dev (Lei Chen) - net: stmmac: Fix IP-cores specific MAC capabilities (Serge Semin) - net: stmmac: Fix max-speed being ignored on queue re-init (Serge Semin) - net: stmmac: Apply half-duplex-less constraint for DW QoS Eth only (Serge Semin) - selftests/tcp_ao: Printing fixes to confirm with format-security (Dmitry Safonov) - selftests/tcp_ao: Fix fscanf() call for format-security (Dmitry Safonov) - selftests/tcp_ao: Zero-init tcp_ao_info_opt (Dmitry Safonov) - selftests/tcp_ao: Make RST tests less flaky (Dmitry Safonov) - octeontx2-pf: fix FLOW_DIS_IS_FRAGMENT implementation (Asbjørn Sloth Tønnesen) - inet: bring NLM_DONE out to a separate recv() again (Jakub Kicinski) - net: change maximum number of UDP segments to 128 (Yuri Benditovich) - net/mlx5e: Prevent deadlock while disabling aRFS (Carolina Jubran) - net/mlx5e: Acquire RTNL lock before RQs/SQs activation/deactivation (Carolina Jubran) - net/mlx5e: Use channel mdev reference instead of global mdev instance for coalescing (Rahul Rameshbabu) - net/mlx5: Restore mistakenly dropped parts in register devlink flow (Shay Drory) - net/mlx5: SD, Handle possible devcom ERR_PTR (Tariq Toukan) - net/mlx5: Lag, restore buckets number to default after hash LAG deactivation (Shay Drory) - net: sparx5: flower: fix fragment flags handling (Asbjørn Sloth Tønnesen) - af_unix: Don't peek OOB data without MSG_OOB. (Kuniyuki Iwashima) - af_unix: Call manage_oob() for every skb in unix_stream_read_generic(). (Kuniyuki Iwashima) - netfilter: flowtable: incorrect pppoe tuple (Pablo Neira Ayuso) - netfilter: flowtable: validate pppoe header (Pablo Neira Ayuso) - netfilter: nft_set_pipapo: do not free live element (Florian Westphal) - netfilter: nft_set_pipapo: walk over current view on netlink dump (Pablo Neira Ayuso) - netfilter: br_netfilter: skip conntrack input hook for promisc packets (Pablo Neira Ayuso) - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get() (Ziyang Xuan) - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get() (Ziyang Xuan) - gpiolib: swnode: Remove wrong header inclusion (Andy Shevchenko) - gpio: lpc32xx: fix module autoloading (Krzysztof Kozlowski) - gpio: crystalcove: Use -ENOTSUPP consistently (Andy Shevchenko) - gpio: wcove: Use -ENOTSUPP consistently (Andy Shevchenko) - Revert "vmgenid: emit uevent when VMGENID updates" (Jason A. Donenfeld) - random: handle creditable entropy from atomic process context (Jason A. Donenfeld) - platform/x86/amd/pmc: Extend Framework 13 quirk to more BIOSes (Mario Limonciello) - platform/x86/intel-uncore-freq: Increase minor number support (Srinivas Pandruvada) - platform/x86: ISST: Add Granite Rapids-D to HPM CPU list (Srinivas Pandruvada) - platform/x86/amd: pmf: Add quirk for ROG Zephyrus G14 (Mario Limonciello) - platform/x86/amd: pmf: Add infrastructure for quirking supported funcs (Mario Limonciello) - platform/x86/amd: pmf: Decrease error message to debug (Mario Limonciello) - gitlab-ci: harmonize DataWarehouse tree names (Michael Hofmann) - redhat/configs: Enable CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON for rhel (Jerry Snitselaar) - spec: make sure posttrans script doesn't fail if /boot is non-POSIX (glb) - btrfs: do not wait for short bulk allocation (Qu Wenruo) - btrfs: zoned: add ASSERT and WARN for EXTENT_BUFFER_ZONED_ZEROOUT handling (Naohiro Aota) - btrfs: zoned: do not flag ZEROOUT on non-dirty extent buffer (Naohiro Aota) - dt-bindings: pwm: mediatek,pwm-disp: Document power-domains property (AngeloGioacchino Del Regno) - pwm: dwc: allow suspend/resume for 16 channels (Raag Jadav) - Turn on UBSAN for Fedora (Justin M. Forbes) - Turn on XEN_BALLOON_MEMORY_HOTPLUG for Fedora (Justin M. Forbes) - NFSD: fix endianness issue in nfsd4_encode_fattr4 (Vasily Gorbik) - SUNRPC: Fix rpcgss_context trace event acceptor field (Steven Rostedt (Google)) - bcachefs: set_btree_iter_dontneed also clears should_be_locked (Kent Overstreet) - bcachefs: fix error path of __bch2_read_super() (Chao Yu) - bcachefs: Check for backpointer bucket_offset >= bucket size (Kent Overstreet) - bcachefs: bch_member.btree_allocated_bitmap (Kent Overstreet) - bcachefs: sysfs internal/trigger_journal_flush (Kent Overstreet) - bcachefs: Fix bch2_btree_node_fill() for !path (Kent Overstreet) - bcachefs: add safety checks in bch2_btree_node_fill() (Kent Overstreet) - bcachefs: Interior known are required to have known key types (Kent Overstreet) - bcachefs: add missing bounds check in __bch2_bkey_val_invalid() (Kent Overstreet) - bcachefs: Fix btree node merging on write buffer btrees (Kent Overstreet) - bcachefs: Disable merges from interior update path (Kent Overstreet) - bcachefs: Run merges at BCH_WATERMARK_btree (Kent Overstreet) - bcachefs: Fix missing write refs in fs fio paths (Kent Overstreet) - bcachefs: Fix deadlock in journal replay (Kent Overstreet) - bcachefs: Go rw if running any explicit recovery passes (Kent Overstreet) - bcachefs: Standardize helpers for printing enum strs with bounds checks (Kent Overstreet) - bcachefs: don't queue btree nodes for rewrites during scan (Kent Overstreet) - bcachefs: fix race in bch2_btree_node_evict() (Kent Overstreet) - bcachefs: fix unsafety in bch2_stripe_to_text() (Kent Overstreet) - bcachefs: fix unsafety in bch2_extent_ptr_to_text() (Kent Overstreet) - bcachefs: btree node scan: handle encrypted nodes (Kent Overstreet) - bcachefs: Check for packed bkeys that are too big (Kent Overstreet) - bcachefs: Fix UAFs of btree_insert_entry array (Kent Overstreet) - bcachefs: Don't use bch2_btree_node_lock_write_nofail() in btree split path (Kent Overstreet) - selftests/harness: Prevent infinite loop due to Assert in FIXTURE_TEARDOWN (Shengyu Li) - selftests/ftrace: Limit length in subsystem-enable tests (Yuanhe Shu) - Linux 6.9-rc4 (Linus Torvalds) - kernfs: annotate different lockdep class for of->mutex of writable files (Amir Goldstein) - x86/cpu/amd: Move TOPOEXT enablement into the topology parser (Thomas Gleixner) - x86/cpu/amd: Make the NODEID_MSR union actually work (Thomas Gleixner) - x86/cpu/amd: Make the CPUID 0x80000008 parser correct (Thomas Gleixner) - x86/bugs: Replace CONFIG_SPECTRE_BHI_{ON,OFF} with CONFIG_MITIGATION_SPECTRE_BHI (Josh Poimboeuf) - x86/bugs: Remove CONFIG_BHI_MITIGATION_AUTO and spectre_bhi=auto (Josh Poimboeuf) - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation (Josh Poimboeuf) - x86/bugs: Fix BHI handling of RRSBA (Josh Poimboeuf) - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr' (Ingo Molnar) - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES (Josh Poimboeuf) - x86/bugs: Fix BHI documentation (Josh Poimboeuf) - x86/cpu: Actually turn off mitigations by default for SPECULATION_MITIGATIONS=n (Sean Christopherson) - x86/topology: Don't update cpu_possible_map in topo_set_cpuids() (Thomas Gleixner) - x86/bugs: Fix return type of spectre_bhi_state() (Daniel Sneddon) - x86/apic: Force native_apic_mem_read() to use the MOV instruction (Adam Dunlap) - selftests: kselftest: Fix build failure with NOLIBC (Oleg Nesterov) - selftests: timers: Fix abs() warning in posix_timers test (John Stultz) - selftests: kselftest: Mark functions that unconditionally call exit() as __noreturn (Nathan Chancellor) - selftests: timers: Fix posix_timers ksft_print_msg() warning (John Stultz) - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior (John Stultz) - bug: Fix no-return-statement warning with !CONFIG_BUG (Adrian Hunter) - timekeeping: Use READ/WRITE_ONCE() for tick_do_timer_cpu (Thomas Gleixner) - selftests/timers/posix_timers: Reimplement check_timer_distribution() (Oleg Nesterov) - irqflags: Explicitly ignore lockdep_hrtimer_exit() argument (Arnd Bergmann) - perf/x86: Fix out of range data (Namhyung Kim) - locking: Make rwsem_assert_held_write_nolockdep() build with PREEMPT_RT=y (Sebastian Andrzej Siewior) - irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1 (Nianyao Tang) - vhost: correct misleading printing information (Xianting Tian) - vhost-vdpa: change ioctl # for VDPA_GET_VRING_SIZE (Michael S. Tsirkin) - virtio: store owner from modules with register_virtio_driver() (Krzysztof Kozlowski) - vhost: Add smp_rmb() in vhost_enable_notify() (Gavin Shan) - vhost: Add smp_rmb() in vhost_vq_avail_empty() (Gavin Shan) - swiotlb: do not set total_used to 0 in swiotlb_create_debugfs_files() (Dexuan Cui) - swiotlb: fix swiotlb_bounce() to do partial sync's correctly (Michael Kelley) - swiotlb: extend buffer pre-padding to alloc_align_mask if necessary (Petr Tesarik) - ata: libata-core: Allow command duration limits detection for ACS-4 drives (Igor Pylypiv) - ata: libata-scsi: Fix ata_scsi_dev_rescan() error path (Damien Le Moal) - ata: ahci: Add mask_port_map module parameter (Damien Le Moal) - zonefs: Use str_plural() to fix Coccinelle warning (Thorsten Blum) - smb3: fix broken reconnect when password changing on the server by allowing password rotation (Steve French) - smb: client: instantiate when creating SFU files (Paulo Alcantara) - smb3: fix Open files on server counter going negative (Steve French) - smb: client: fix NULL ptr deref in cifs_mark_open_handles_for_deleted_file() (Paulo Alcantara) - arm64: tlb: Fix TLBI RANGE operand (Gavin Shan) - MAINTAINERS: Change Krzysztof Kozlowski's email address (Krzysztof Kozlowski) - cache: sifive_ccache: Partially convert to a platform driver (Samuel Holland) - firmware: arm_ffa: Fix the partition ID check in ffa_notification_info_get() (Jens Wiklander) - firmware: arm_scmi: Make raw debugfs entries non-seekable (Cristian Marussi) - firmware: arm_scmi: Fix wrong fastchannel initialization (Pierre Gondois) - arm64: dts: imx8qm-ss-dma: fix can lpcg indices (Frank Li) - arm64: dts: imx8-ss-dma: fix can lpcg indices (Frank Li) - arm64: dts: imx8-ss-dma: fix adc lpcg indices (Frank Li) - arm64: dts: imx8-ss-dma: fix pwm lpcg indices (Frank Li) - arm64: dts: imx8-ss-dma: fix spi lpcg indices (Frank Li) - arm64: dts: imx8-ss-conn: fix usb lpcg indices (Frank Li) - arm64: dts: imx8-ss-lsio: fix pwm lpcg indices (Frank Li) - ARM: dts: imx7s-warp: Pass OV2680 link-frequencies (Fabio Estevam) - ARM: dts: imx7-mba7: Use 'no-mmc' property (Fabio Estevam) - arm64: dts: imx8-ss-conn: fix usdhc wrong lpcg clock order (Frank Li) - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix USB vbus regulator (Tim Harvey) - arm64: dts: freescale: imx8mp-venice-gw72xx-2x: fix USB vbus regulator (Tim Harvey) - ARM: OMAP2+: fix USB regression on Nokia N8x0 (Aaro Koskinen) - mmc: omap: restore original power up/down steps (Aaro Koskinen) - mmc: omap: fix deferred probe (Aaro Koskinen) - mmc: omap: fix broken slot switch lookup (Aaro Koskinen) - ARM: OMAP2+: fix N810 MMC gpiod table (Aaro Koskinen) - ARM: OMAP2+: fix bogus MMC GPIO labels on Nokia N8x0 (Aaro Koskinen) - iommu/amd: Change log message severity (Vasant Hegde) - iommu/vt-d: Fix WARN_ON in iommu probe path (Lu Baolu) - iommu/vt-d: Allocate local memory for page request queue (Jacob Pan) - iommu/vt-d: Fix wrong use of pasid config (Xuchun Shang) - iommu: mtk: fix module autoloading (Krzysztof Kozlowski) - iommu/amd: Do not enable SNP when V2 page table is enabled (Vasant Hegde) - iommu/amd: Fix possible irq lock inversion dependency issue (Vasant Hegde) - Revert "PCI: Mark LSI FW643 to avoid bus reset" (Bjorn Helgaas) - MAINTAINERS: Drop Gustavo Pimentel as PCI DWC Maintainer (Manivannan Sadhasivam) - block: fix that blk_time_get_ns() doesn't update time after schedule (Yu Kuai) - raid1: fix use-after-free for original bio in raid1_write_request() (Yu Kuai) - block: allow device to have both virt_boundary_mask and max segment size (Ming Lei) - block: fix q->blkg_list corruption during disk rebind (Ming Lei) - blk-iocost: avoid out of bounds shift (Rik van Riel) - io-uring: correct typo in comment for IOU_F_TWQ_LAZY_WAKE (Haiyue Wang) - io_uring/net: restore msg_control on sendzc retry (Pavel Begunkov) - io_uring: Fix io_cqring_wait() not restoring sigmask on get_timespec64() failure (Alexey Izbyshev) - MAINTAINERS: remove myself as a Reviewer for Ceph (Jeff Layton) - ceph: switch to use cap_delay_lock for the unlink delay list (Xiubo Li) - ceph: redirty page before returning AOP_WRITEPAGE_ACTIVATE (NeilBrown) - Kconfig: add some hidden tabs on purpose (Linus Torvalds) - ring-buffer: Only update pages_touched when a new page is touched (Steven Rostedt (Google)) - tracing: hide unused ftrace_event_id_fops (Arnd Bergmann) - tracing: Fix FTRACE_RECORD_RECURSION_SIZE Kconfig entry (Prasad Pandit) - eventfs: Fix kernel-doc comments to functions (Yang Li) - MIPS: scall: Save thread_info.syscall unconditionally on entry (Jiaxun Yang) - amdkfd: use calloc instead of kzalloc to avoid integer overflow (Dave Airlie) - drm/msm/adreno: Set highest_bank_bit for A619 (Luca Weiss) - drm/msm: fix the `CRASHDUMP_READ` target of `a6xx_get_shader_block()` (Miguel Ojeda) - dt-bindings: display/msm: sm8150-mdss: add DP node (Dmitry Baryshkov) - drm/msm/dp: fix typo in dp_display_handle_port_status_changed() (Abhinav Kumar) - drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more sensible (Dmitry Baryshkov) - drm/msm/dp: assign correct DP controller ID to x1e80100 interface table (Kuogee Hsieh) - drm/msm/dpu: don't allow overriding data from catalog (Dmitry Baryshkov) - drm/msm: Add newlines to some debug prints (Stephen Boyd) - drm/msm/dp: fix runtime PM leak on connect failure (Johan Hovold) - drm/msm/dp: fix runtime PM leak on disconnect (Johan Hovold) - drm/xe: Label RING_CONTEXT_CONTROL as masked (Ashutosh Dixit) - drm/xe/xe_migrate: Cast to output precision before multiplying operands (Himal Prasad Ghimiray) - drm/xe/hwmon: Cast result to output precision on left shift of operand (Karthik Poosa) - drm/xe/display: Fix double mutex initialization (Lucas De Marchi) - drm/vmwgfx: Enable DMA mappings with SEV (Zack Rusin) - drm/client: Fully protect modes[] with dev->mode_config.mutex (Ville Syrjälä) - gpu: host1x: Do not setup DMA for virtual devices (Thierry Reding) - accel/ivpu: Fix deadlock in context_xa (Jacek Lawrynowicz) - accel/ivpu: Fix missed error message after VPU rename (Jacek Lawrynowicz) - accel/ivpu: Return max freq for DRM_IVPU_PARAM_CORE_CLOCK_RATE (Jacek Lawrynowicz) - accel/ivpu: Improve clarity of MMU error messages (Wachowski, Karol) - accel/ivpu: Put NPU back to D3hot after failed resume (Jacek Lawrynowicz) - accel/ivpu: Fix PCI D0 state entry in resume (Wachowski, Karol) - accel/ivpu: Remove d3hot_after_power_off WA (Jacek Lawrynowicz) - accel/ivpu: Check return code of ipc->lock init (Wachowski, Karol) - nouveau: fix function cast warning (Arnd Bergmann) - nouveau/gsp: Avoid addressing beyond end of rpc->entries (Kees Cook) - Revert "drm/qxl: simplify qxl_fence_wait" (Alex Constantino) - drm/ast: Fix soft lockup (Jammy Huang) - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() (Boris Brezillon) - drm/amdgpu: differentiate external rev id for gfx 11.5.0 (Yifan Zhang) - drm/amd/display: Adjust dprefclk by down spread percentage. (Zhongwei) - drm/amd/display: Set VSC SDP Colorimetry same way for MST and SST (Harry Wentland) - drm/amd/display: Program VSC SDP colorimetry for all DP sinks >= 1.4 (Harry Wentland) - drm/amd/display: fix disable otg wa logic in DCN316 (Fudongwang) - drm/amd/display: Do not recursively call manual trigger programming (Dillon Varone) - drm/amd/display: always reset ODM mode in context when adding first plane (Wenjing Liu) - drm/amdgpu: fix incorrect number of active RBs for gfx11 (Tim Huang) - drm/amd/display: Return max resolution supported by DWB (Alex Hung) - amd/amdkfd: sync all devices to wait all processes being evicted (Zhigang Luo) - drm/amdgpu: clear set_q_mode_offs when VM changed (ZhenGuo Yin) - drm/amdgpu: Fix VCN allocation in CPX partition (Lijo Lazar) - drm/amd/pm: fix the high voltage issue after unload (Kenneth Feng) - drm/amd/display: Skip on writeback when it's not applicable (Alex Hung) - drm/amdgpu: implement IRQ_STATE_ENABLE for SDMA v4.4.2 (Tao Zhou) - drm/amdgpu: add smu 14.0.1 discovery support (Yifan Zhang) - drm/amd/swsmu: Update smu v14.0.0 headers to be 14.0.1 compatible (lima1002) - drm/amdgpu : Increase the mes log buffer size as per new MES FW version (shaoyunl) - drm/amdgpu : Add mes_log_enable to control mes log feature (shaoyunl) - drm/amd/pm: fixes a random hang in S4 for SMU v13.0.4/11 (Tim Huang) - drm/amd/display: add DCN 351 version for microcode load (Li Ma) - drm/amdgpu: Reset dGPU if suspend got aborted (Lijo Lazar) - drm/amdgpu/umsch: reinitialize write pointer in hw init (Lang Yu) - drm/amdgpu: Refine IB schedule error logging (Lijo Lazar) - drm/amdgpu: always force full reset for SOC21 (Alex Deucher) - drm/amdkfd: Reset GPU on queue preemption failure (Harish Kasiviswanathan) - drm/i915/vrr: Disable VRR when using bigjoiner (Ville Syrjälä) - drm/i915: Disable live M/N updates when using bigjoiner (Ville Syrjälä) - drm/i915: Disable port sync when bigjoiner is used (Ville Syrjälä) - drm/i915/psr: Disable PSR when bigjoiner is used (Ville Syrjälä) - drm/i915/guc: Fix the fix for reset lock confusion (John Harrison) - drm/i915/hdcp: Fix get remote hdcp capability function (Suraj Kandpal) - drm/i915/cdclk: Fix voltage_level programming edge case (Ville Syrjälä) - drm/i915/cdclk: Fix CDCLK programming order when pipes are active (Ville Syrjälä) - docs: point out that python3-pyyaml is now required (Thorsten Leemhuis) - cxl: Add checks to access_coordinate calculation to fail missing data (Dave Jiang) - cxl: Consolidate dport access_coordinate ->hb_coord and ->sw_coord into ->coord (Dave Jiang) - cxl: Fix incorrect region perf data calculation (Dave Jiang) - cxl: Fix retrieving of access_coordinates in PCIe path (Dave Jiang) - cxl: Remove checking of iter in cxl_endpoint_get_perf_coordinates() (Dave Jiang) - cxl/core: Fix initialization of mbox_cmd.size_out in get event (Kwangjin Ko) - cxl/core/regs: Fix usage of map->reg_type in cxl_decode_regblock() before assigned (Dave Jiang) - cxl/mem: Fix for the index of Clear Event Record Handle (Yuquan Wang) - Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted (Michael Kelley) - uio_hv_generic: Don't free decrypted memory (Rick Edgecombe) - hv_netvsc: Don't free decrypted memory (Rick Edgecombe) - Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl (Rick Edgecombe) - Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails (Rick Edgecombe) - hv/hv_kvp_daemon: Handle IPv4 and Ipv6 combination for keyfile format (Shradha Gupta) - hv: vmbus: Convert sprintf() family to sysfs_emit() family (Li Zhijian) - mshyperv: Introduce hv_numa_node_to_pxm_info() (Nuno Das Neves) - x86/hyperv: Cosmetic changes for hv_apic.c (Erni Sri Satya Vennela) - ACPI: bus: allow _UID matching for integer zero (Raag Jadav) - ACPI: scan: Do not increase dep_unmet for already met dependencies (Hans de Goede) - PM: s2idle: Make sure CPUs will wakeup directly on resume (Anna-Maria Behnsen) - net: ena: Set tx_info->xdpf value to NULL (David Arinzon) - net: ena: Fix incorrect descriptor free behavior (David Arinzon) - net: ena: Wrong missing IO completions check order (David Arinzon) - net: ena: Fix potential sign extension issue (David Arinzon) - Bluetooth: l2cap: Don't double set the HCI_CONN_MGMT_CONNECTED bit (Archie Pusaka) - Bluetooth: hci_sock: Fix not validating setsockopt user input (Luiz Augusto von Dentz) - Bluetooth: ISO: Fix not validating setsockopt user input (Luiz Augusto von Dentz) - Bluetooth: L2CAP: Fix not validating setsockopt user input (Luiz Augusto von Dentz) - Bluetooth: RFCOMM: Fix not validating setsockopt user input (Luiz Augusto von Dentz) - Bluetooth: SCO: Fix not validating setsockopt user input (Luiz Augusto von Dentz) - Bluetooth: Fix memory leak in hci_req_sync_complete() (Dmitry Antipov) - Bluetooth: hci_sync: Fix using the same interval and window for Coded PHY (Luiz Augusto von Dentz) - Bluetooth: ISO: Don't reject BT_ISO_QOS if parameters are unset (Luiz Augusto von Dentz) - af_unix: Fix garbage collector racing against connect() (Michal Luczaj) - net: dsa: mt7530: trap link-local frames regardless of ST Port State (Arınç ÜNAL) - Revert "s390/ism: fix receive message buffer allocation" (Gerd Bayer) - net: sparx5: fix wrong config being used when reconfiguring PCS (Daniel Machon) - net/mlx5: fix possible stack overflows (Arnd Bergmann) - net/mlx5: Disallow SRIOV switchdev mode when in multi-PF netdev (Tariq Toukan) - net/mlx5e: RSS, Block XOR hash with over 128 channels (Carolina Jubran) - net/mlx5e: Do not produce metadata freelist entries in Tx port ts WQE xmit (Rahul Rameshbabu) - net/mlx5e: HTB, Fix inconsistencies with QoS SQs number (Carolina Jubran) - net/mlx5e: Fix mlx5e_priv_init() cleanup flow (Carolina Jubran) - net/mlx5e: RSS, Block changing channels number when RXFH is configured (Carolina Jubran) - net/mlx5: Correctly compare pkt reformat ids (Cosmin Ratiu) - net/mlx5: Properly link new fs rules into the tree (Cosmin Ratiu) - net/mlx5: offset comp irq index in name by one (Michael Liang) - net/mlx5: Register devlink first under devlink lock (Shay Drory) - net/mlx5: E-switch, store eswitch pointer before registering devlink_param (Shay Drory) - netfilter: complete validation of user input (Eric Dumazet) - r8169: add missing conditional compiling for call to r8169_remove_leds (Heiner Kallweit) - net: dsa: mt7530: fix enabling EEE on MT7531 switch on all boards (Arınç ÜNAL) - r8169: fix LED-related deadlock on module removal (Heiner Kallweit) - pds_core: Fix pdsc_check_pci_health function to use work thread (Brett Creeley) - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr (Jiri Benc) - nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies (Eric Dumazet) - mISDN: fix MISDN_TIME_STAMP handling (Eric Dumazet) - net: add copy_safe_from_sockptr() helper (Eric Dumazet) - ipv4/route: avoid unused-but-set-variable warning (Arnd Bergmann) - ipv6: fib: hide unused 'pn' variable (Arnd Bergmann) - octeontx2-af: Fix NIX SQ mode and BP config (Geetha sowjanya) - af_unix: Clear stale u->oob_skb. (Kuniyuki Iwashima) - net: ks8851: Handle softirqs at the end of IRQ thread to fix hang (Marek Vasut) - net: ks8851: Inline ks8851_rx_skb() (Marek Vasut) - net: stmmac: mmc_core: Add GMAC mmc tx/rx missing statistics (Minda Chen) - net: stmmac: mmc_core: Add GMAC LPI statistics (Minda Chen) - bnxt_en: Reset PTP tx_avail after possible firmware reset (Pavan Chebbi) - bnxt_en: Fix error recovery for RoCE ulp client (Vikas Gupta) - bnxt_en: Fix possible memory leak in bnxt_rdma_aux_device_init() (Vikas Gupta) - s390/ism: fix receive message buffer allocation (Gerd Bayer) - geneve: fix header validation in geneve[6]_xmit_skb (Eric Dumazet) - MAINTAINERS: Drop Li Yang as their email address stopped working (Uwe Kleine-König) - batman-adv: Avoid infinite loop trying to resize local TT (Sven Eckelmann) - lib: checksum: hide unused expected_csum_ipv6_magic[] (Arnd Bergmann) - octeontx2-pf: Fix transmit scheduler resource leak (Hariprasad Kelam) - virtio_net: Do not send RSS key if it is not supported (Breno Leitao) - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING (Eric Dumazet) - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file (Petr Tesarik) - net: openvswitch: fix unwanted error log on timeout policy probing (Ilya Maximets) - scsi: qla2xxx: Fix off by one in qla_edif_app_getstats() (Dan Carpenter) - scsi: hisi_sas: Modify the deadline for ata_wait_after_reset() (Xiang Chen) - scsi: hisi_sas: Handle the NCQ error returned by D2H frame (Xiang Chen) - scsi: target: Fix SELinux error when systemd-modules loads the target module (Maurizio Lombardi) - scsi: sg: Avoid race in error handling & drop bogus warn (Alexander Wetzel) - LoongArch: Include linux/sizes.h in addrspace.h to prevent build errors (Randy Dunlap) - LoongArch: Update dts for Loongson-2K2000 to support GMAC/GNET (Huacai Chen) - LoongArch: Update dts for Loongson-2K2000 to support PCI-MSI (Huacai Chen) - LoongArch: Update dts for Loongson-2K2000 to support ISA/LPC (Huacai Chen) - LoongArch: Update dts for Loongson-2K1000 to support ISA/LPC (Huacai Chen) - LoongArch: Make virt_addr_valid()/__virt_addr_valid() work with KFENCE (Huacai Chen) - LoongArch: Make {virt, phys, page, pfn} translation work with KFENCE (Huacai Chen) - mm: Move lowmem_page_address() a little later (Huacai Chen) - bcachefs: Fix __bch2_btree_and_journal_iter_init_node_iter() (Kent Overstreet) - bcachefs: Kill read lock dropping in bch2_btree_node_lock_write_nofail() (Kent Overstreet) - bcachefs: Fix a race in btree_update_nodes_written() (Kent Overstreet) - bcachefs: btree_node_scan: Respect member.data_allowed (Kent Overstreet) - bcachefs: Don't scan for btree nodes when we can reconstruct (Kent Overstreet) - bcachefs: Fix check_topology() when using node scan (Kent Overstreet) - bcachefs: fix eytzinger0_find_gt() (Kent Overstreet) - bcachefs: fix bch2_get_acl() transaction restart handling (Kent Overstreet) - bcachefs: fix the count of nr_freed_pcpu after changing bc->freed_nonpcpu list (Hongbo Li) - bcachefs: Fix gap buffer bug in bch2_journal_key_insert_take() (Kent Overstreet) - bcachefs: Rename struct field swap to prevent macro naming collision (Thorsten Blum) - MAINTAINERS: Add entry for bcachefs documentation (Bagas Sanjaya) - Documentation: filesystems: Add bcachefs toctree (Bagas Sanjaya) - bcachefs: JOURNAL_SPACE_LOW (Kent Overstreet) - bcachefs: Disable errors=panic for BCH_IOCTL_FSCK_OFFLINE (Kent Overstreet) - bcachefs: Fix BCH_IOCTL_FSCK_OFFLINE for encrypted filesystems (Kent Overstreet) - bcachefs: fix rand_delete unit test (Kent Overstreet) - bcachefs: fix ! vs ~ typo in __clear_bit_le64() (Dan Carpenter) - bcachefs: Fix rebalance from durability=0 device (Kent Overstreet) - bcachefs: Print shutdown journal sequence number (Kent Overstreet) - bcachefs: Further improve btree_update_to_text() (Kent Overstreet) - bcachefs: Move btree_updates to debugfs (Kent Overstreet) - bcachefs: Bump limit in btree_trans_too_many_iters() (Kent Overstreet) - bcachefs: Make snapshot_is_ancestor() safe (Kent Overstreet) - bcachefs: create debugfs dir for each btree (Thomas Bertschinger) - platform/chrome: cros_ec_uart: properly fix race condition (Noah Loomans) - Use LLVM=1 for clang_lto build (Nikita Popov) - redhat: fix def_variants.yaml check (Jan Stancek) - kprobes: Fix possible use-after-free issue on kprobe registration (Zheng Yejian) - fs/proc: Skip bootloader comment if no embedded kernel parameters (Masami Hiramatsu) - fs/proc: remove redundant comments from /proc/bootconfig (Zhenhua Huang) - media: mediatek: vcodec: support 36 bits physical address (Yunfei Dong) - media: mediatek: vcodec: adding lock to protect encoder context list (Yunfei Dong) - media: mediatek: vcodec: adding lock to protect decoder context list (Yunfei Dong) - media: mediatek: vcodec: Fix oops when HEVC init fails (Nicolas Dufresne) - media: mediatek: vcodec: Handle VP9 superframe bitstream with 8 sub-frames (Irui Wang) - randomize_kstack: Improve entropy diffusion (Kees Cook) - ubsan: fix unused variable warning in test module (Arnd Bergmann) - gcc-plugins/stackleak: Avoid .head.text section (Ard Biesheuvel) - tools/power turbostat: v2024.04.10 (Len Brown) - tools/power/turbostat: Add support for Xe sysfs knobs (Zhang Rui) - tools/power/turbostat: Add support for new i915 sysfs knobs (Zhang Rui) - tools/power/turbostat: Introduce BIC_SAM_mc6/BIC_SAMMHz/BIC_SAMACTMHz (Zhang Rui) - tools/power/turbostat: Fix uncore frequency file string (Justin Ernst) - tools/power/turbostat: Unify graphics sysfs snapshots (Zhang Rui) - tools/power/turbostat: Cache graphics sysfs path (Zhang Rui) - tools/power/turbostat: Enable MSR_CORE_C1_RES support for ICX (Zhang Rui) - tools/power turbostat: Add selftests (Patryk Wlazlyn) - tools/power turbostat: read RAPL counters via perf (Patryk Wlazlyn) - tools/power turbostat: Add proper re-initialization for perf file descriptors (Patryk Wlazlyn) - tools/power turbostat: Clear added counters when in no-msr mode (Patryk Wlazlyn) - tools/power turbostat: add early exits for permission checks (Patryk Wlazlyn) - tools/power turbostat: detect and disable unavailable BICs at runtime (Patryk Wlazlyn) - tools/power turbostat: Add reading aperf and mperf via perf API (Patryk Wlazlyn) - tools/power turbostat: Add --no-perf option (Patryk Wlazlyn) - tools/power turbostat: Add --no-msr option (Patryk Wlazlyn) - tools/power turbostat: enhance -D (debug counter dump) output (Len Brown) - tools/power turbostat: Fix warning upon failed /dev/cpu_dma_latency read (Len Brown) - tools/power turbostat: Read base_hz and bclk from CPUID.16H if available (Patryk Wlazlyn) - tools/power turbostat: Print ucode revision only if valid (Patryk Wlazlyn) - tools/power turbostat: Expand probe_intel_uncore_frequency() (Len Brown) - tools/power turbostat: Do not print negative LPI residency (Chen Yu) - tools/power turbostat: Fix Bzy_MHz documentation typo (Peng Liu) - tools/power turbostat: Increase the limit for fd opened (Wyes Karny) - tools/power turbostat: Fix added raw MSR output (Doug Smythies) - platform/x86: lg-laptop: fix %%s null argument warning (Gergo Koteles) - platform/x86: intel-vbtn: Update tablet mode switch at end of probe (Gwendal Grignou) - platform/x86: intel-vbtn: Use acpi_has_method to check for switch (Gwendal Grignou) - platform/x86: toshiba_acpi: Silence logging for some events (Hans de Goede) - platform/x86/intel/hid: Add Lunar Lake and Arrow Lake support (Sumeet Pawnikar) - platform/x86/intel/hid: Don't wake on 5-button releases (David McFarland) - platform/x86: acer-wmi: Add support for Acer PH18-71 (Bernhard Rosenkränzer) - redhat: sanity check yaml files (Jan Stancek) - spec: rework filter-mods and mod-denylist (Jan Stancek) - nouveau: fix devinit paths to only handle display on GSP. (Dave Airlie) - compiler.h: Add missing quote in macro comment (Thorsten Blum) - KVM: x86: Add BHI_NO (Daniel Sneddon) - x86/bhi: Mitigate KVM by default (Pawan Gupta) - x86/bhi: Add BHI mitigation knob (Pawan Gupta) - x86/bhi: Enumerate Branch History Injection (BHI) bug (Pawan Gupta) - x86/bhi: Define SPEC_CTRL_BHI_DIS_S (Daniel Sneddon) - x86/bhi: Add support for clearing branch history at syscall entry (Pawan Gupta) - x86/syscall: Don't force use of indirect calls for system calls (Linus Torvalds) - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file (Josh Poimboeuf) - btrfs: always clear PERTRANS metadata during commit (Boris Burkov) - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve (Boris Burkov) - btrfs: qgroup: convert PREALLOC to PERTRANS after record_root_in_trans (Boris Burkov) - btrfs: record delayed inode root in transaction (Boris Burkov) - btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations (Boris Burkov) - btrfs: qgroup: correctly model root qgroup rsv in convert (Boris Burkov) - memblock tests: fix undefined reference to `BIT' (Wei Yang) - memblock tests: fix undefined reference to `panic' (Wei Yang) - memblock tests: fix undefined reference to `early_pfn_to_nid' (Wei Yang) - Linux 6.9-rc3 (Linus Torvalds) - x86/retpoline: Add NOENDBR annotation to the SRSO dummy return thunk (Borislav Petkov (AMD)) - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank() (Borislav Petkov (AMD)) - x86/CPU/AMD: Track SNP host status with cc_platform_*() (Borislav Petkov (AMD)) - x86/cc: Add cc_platform_set/_clear() helpers (Borislav Petkov (AMD)) - x86/kvm/Kconfig: Have KVM_AMD_SEV select ARCH_HAS_CC_PLATFORM (Borislav Petkov (AMD)) - x86/coco: Require seeding RNG with RDRAND on CoCo systems (Jason A. Donenfeld) - x86/numa/32: Include missing <asm/pgtable_areas.h> (Arnd Bergmann) - x86/resctrl: Fix uninitialized memory read when last CPU of domain goes offline (Reinette Chatre) - timers/migration: Return early on deactivation (Anna-Maria Behnsen) - timers/migration: Fix ignored event due to missing CPU update (Frederic Weisbecker) - vdso: Use CONFIG_PAGE_SHIFT in vdso/datapage.h (Arnd Bergmann) - timers: Fix text inconsistencies and spelling (Randy Dunlap) - tick/sched: Fix struct tick_sched doc warnings (Randy Dunlap) - tick/sched: Fix various kernel-doc warnings (Randy Dunlap) - timers: Fix kernel-doc format and add Return values (Randy Dunlap) - time/timekeeping: Fix kernel-doc warnings and typos (Randy Dunlap) - time/timecounter: Fix inline documentation (Randy Dunlap) - perf/x86/intel/ds: Don't clear ->pebs_data_cfg for the last PEBS event (Kan Liang) - redhat: regenerate test-data (Jan Stancek) [RHEL-29722] - redhat/Makefile.variables: don't set DISTRO (Jan Stancek) [RHEL-29722] - redhat/Makefile.variables: set PATCHLIST_URL to none (Jan Stancek) [RHEL-29722] - redhat/kernel.spec.template: fix with_realtime (Jan Stancek) [RHEL-29722] - Linux v6.9.0-0.rc4 Resolves: RHEL-29722 Signed-off-by: Jan Stancek <jstancek@redhat.com>
1085 lines
38 KiB
Python
Executable File
1085 lines
38 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
filter kmods into groups for packaging, see filtermods.adoc
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import yaml
|
|
import unittest
|
|
|
|
from logging import getLogger, DEBUG, INFO, WARN, ERROR, CRITICAL, NOTSET, StreamHandler, Formatter, Logger
|
|
from typing import Optional
|
|
|
|
log = getLogger('filtermods')
|
|
|
|
|
|
def get_td(filename):
|
|
script_dir = os.path.dirname(os.path.realpath(__file__))
|
|
return os.path.join(script_dir, 'filtermods-testdata', filename)
|
|
|
|
|
|
def run_command(cmd, cwddir=None):
|
|
p = subprocess.Popen(cmd, cwd=cwddir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
out, err = p.communicate()
|
|
out_str = out.decode('utf-8')
|
|
err_str = err.decode('utf-8')
|
|
return p.returncode, out_str, err_str
|
|
|
|
|
|
def safe_run_command(cmd, cwddir=None):
|
|
log.info('%s', cmd)
|
|
retcode, out, err = run_command(cmd, cwddir)
|
|
if retcode != 0:
|
|
log.warning('Command failed: %s, ret_code: %d', cmd, retcode)
|
|
log.warning(out)
|
|
log.warning(err)
|
|
raise Exception(err)
|
|
log.info(' ^^[OK]')
|
|
return retcode, out, err
|
|
|
|
|
|
def setup_logging():
|
|
log_format = '%(asctime)s %(levelname)7.7s %(funcName)20.20s:%(lineno)4s %(message)s'
|
|
log = getLogger('filtermods')
|
|
handler = StreamHandler(sys.stdout)
|
|
formatter = Formatter(log_format, '%H:%M:%S')
|
|
handler.setFormatter(formatter)
|
|
log.addHandler(handler)
|
|
log.debug('Logging on')
|
|
return log
|
|
|
|
|
|
def canon_modname(kmod_pathname: str) -> str:
|
|
name = os.path.basename(kmod_pathname)
|
|
if name.endswith('.xz'):
|
|
name = name[:-3]
|
|
return name
|
|
|
|
|
|
class HierarchyObject:
|
|
def __init__(self):
|
|
self.depends_on = set()
|
|
|
|
|
|
def get_topo_order(obj_list: list[HierarchyObject], func_get_linked_objs=lambda x: x.depends_on) -> list[HierarchyObject]:
|
|
topo_order = []
|
|
objs_to_sort = set(obj_list)
|
|
objs_sorted = set()
|
|
|
|
while len(objs_to_sort) > 0:
|
|
no_deps = set()
|
|
for obj in objs_to_sort:
|
|
linked = func_get_linked_objs(obj)
|
|
if not linked:
|
|
no_deps.add(obj)
|
|
else:
|
|
all_deps_sorted = True
|
|
for dep in linked:
|
|
if dep not in objs_sorted:
|
|
all_deps_sorted = False
|
|
break
|
|
if all_deps_sorted:
|
|
no_deps.add(obj)
|
|
|
|
for obj in no_deps:
|
|
topo_order.append(obj)
|
|
objs_sorted.add(obj)
|
|
objs_to_sort.remove(obj)
|
|
|
|
return topo_order
|
|
|
|
|
|
class KMod(HierarchyObject):
|
|
def __init__(self, kmod_pathname: str) -> None:
|
|
super(KMod, self).__init__()
|
|
self.name: str = canon_modname(kmod_pathname)
|
|
self.kmod_pathname: str = kmod_pathname
|
|
self.is_dependency_for: set[KMod] = set()
|
|
self.assigned_to_pkg: Optional[KModPackage] = None
|
|
self.preferred_pkg: Optional[KModPackage] = None
|
|
self.rule_specifity: int = 0
|
|
self.allowed_list: Optional[set[KModPackage]] = None
|
|
self.err = 0
|
|
|
|
def __str__(self):
|
|
depends_on = ''
|
|
for kmod in self.depends_on:
|
|
depends_on = depends_on + ' ' + kmod.name
|
|
return '%s {%s}' % (self.name, depends_on)
|
|
|
|
|
|
class KModList():
|
|
def __init__(self) -> None:
|
|
self.name_to_kmod_map: dict[str, KMod] = {}
|
|
self.topo_order: Optional[list[KMod]] = None
|
|
|
|
def get(self, kmod_pathname, create_if_missing=False):
|
|
kmod_name = canon_modname(kmod_pathname)
|
|
if kmod_name in self.name_to_kmod_map:
|
|
return self.name_to_kmod_map[kmod_name]
|
|
if not create_if_missing:
|
|
return None
|
|
|
|
kmod = KMod(kmod_pathname)
|
|
# log.debug('Adding kmod %s (%s) to list', kmod.name, kmod.kmod_pathname)
|
|
if kmod.kmod_pathname != kmod_pathname:
|
|
raise Exception('Already have %s, but path changed? %s', kmod_name, kmod_pathname)
|
|
if not kmod.name:
|
|
raise Exception('Each kmod needs a name')
|
|
self.name_to_kmod_map[kmod_name] = kmod
|
|
return kmod
|
|
|
|
def process_depmod_line(self, line):
|
|
tmp = line.split(':')
|
|
if len(tmp) != 2:
|
|
raise Exception('Depmod line has unexpected format: %s', line)
|
|
kmod_pathname = tmp[0].strip()
|
|
dependencies_pathnames = tmp[1].strip()
|
|
kmod = self.get(kmod_pathname, create_if_missing=True)
|
|
|
|
if dependencies_pathnames:
|
|
for dep_pathname in dependencies_pathnames.split(' '):
|
|
dep_kmod = self.get(dep_pathname, create_if_missing=True)
|
|
kmod.depends_on.add(dep_kmod)
|
|
dep_kmod.is_dependency_for.add(kmod)
|
|
|
|
def load_depmod_file(self, filepath):
|
|
with open(filepath) as f:
|
|
lines = f.readlines()
|
|
for line in lines:
|
|
if not line or line.startswith('#'):
|
|
continue
|
|
self.process_depmod_line(line)
|
|
log.info('depmod %s loaded, number of kmods: %s', filepath, len(self.name_to_kmod_map))
|
|
|
|
def dump(self):
|
|
for kmod in self.name_to_kmod_map.values():
|
|
print(kmod)
|
|
|
|
def get_topo_order(self):
|
|
if self.topo_order is None:
|
|
self.topo_order = get_topo_order(self.name_to_kmod_map.values())
|
|
# TODO: what if we add something after?
|
|
return self.topo_order
|
|
|
|
def get_alphabetical_order(self):
|
|
kmods = list(self.name_to_kmod_map.values())
|
|
kmods.sort(key=lambda k: k.kmod_pathname)
|
|
return kmods
|
|
|
|
def load_kmods_from_dir(self, topdir):
|
|
ret = []
|
|
for root, dirs, files in os.walk(topdir):
|
|
for filename in files:
|
|
if filename.endswith('.xz'):
|
|
filename = filename[:-3]
|
|
if filename.endswith('.ko'):
|
|
kmod_pathname = os.path.join(root, filename)
|
|
ret.append(kmod_pathname)
|
|
|
|
return ret
|
|
|
|
def check_depmod_has_all_kmods(self, dirpath):
|
|
ret = self.load_kmods_from_dir(dirpath)
|
|
for kmod_pathname in ret:
|
|
kmod = self.get(kmod_pathname)
|
|
if not kmod:
|
|
raise Exception('Could not find kmod %s in depmod', kmod_pathname)
|
|
log.debug('OK: all (%s) kmods from %s are known', len(ret), dirpath)
|
|
|
|
|
|
class KModPackage(HierarchyObject):
|
|
def _get_depends_on(pkg):
|
|
return pkg.depends_on
|
|
|
|
def _get_deps_for(pkg):
|
|
return pkg.is_dependency_for
|
|
|
|
def __init__(self, name: str, depends_on=[]) -> None:
|
|
self.name: str = name
|
|
self.depends_on: set[KModPackage] = set(depends_on)
|
|
self.is_dependency_for: set[KModPackage] = set()
|
|
|
|
for pkg in self.depends_on:
|
|
pkg.is_dependency_for.add(self)
|
|
self.all_depends_on_list: list[KModPackage] = self._get_all_linked(KModPackage._get_depends_on)
|
|
self.all_depends_on: set[KModPackage] = set(self.all_depends_on_list)
|
|
self.all_deps_for: Optional[set[KModPackage]] = None
|
|
self.default = False
|
|
log.debug('KModPackage created %s, depends_on: %s', name, [pkg.name for pkg in depends_on])
|
|
|
|
def __repr__(self):
|
|
return self.name
|
|
|
|
def get_all_deps_for(self):
|
|
if self.all_deps_for is None:
|
|
self.all_deps_for = set(self._get_all_linked(KModPackage._get_deps_for))
|
|
return self.all_deps_for
|
|
|
|
def _get_all_linked(self, func_get_links):
|
|
ret = []
|
|
explore = func_get_links(self)
|
|
|
|
while len(explore) > 0:
|
|
new_explore = set()
|
|
for pkg in explore:
|
|
if pkg not in ret:
|
|
ret.append(pkg)
|
|
for dep in func_get_links(pkg):
|
|
new_explore.add(dep)
|
|
explore = new_explore
|
|
return ret
|
|
|
|
|
|
class KModPackageList(HierarchyObject):
|
|
def __init__(self) -> None:
|
|
self.name_to_obj: dict[str, KModPackage] = {}
|
|
self.kmod_pkg_list: list[KModPackage] = []
|
|
self.rules: list[tuple[str, str, str]] = []
|
|
|
|
def get(self, pkgname):
|
|
if pkgname in self.name_to_obj:
|
|
return self.name_to_obj[pkgname]
|
|
return None
|
|
|
|
def add_kmod_pkg(self, pkg):
|
|
self.name_to_obj[pkg.name] = pkg
|
|
self.kmod_pkg_list.append(pkg)
|
|
|
|
def __iter__(self):
|
|
return iter(self.kmod_pkg_list)
|
|
|
|
|
|
def get_kmods_matching_re(kmod_list: KModList, param_re: str) -> list[KMod]:
|
|
ret = []
|
|
# first subdir can be anything - this is because during build everything
|
|
# goes to kernel, but subpackages can move it (e.g. to extra)
|
|
param_re = '[^/]+/' + param_re
|
|
pattern = re.compile(param_re)
|
|
|
|
for kmod in kmod_list.get_topo_order():
|
|
m = pattern.match(kmod.kmod_pathname)
|
|
if m:
|
|
ret.append(kmod)
|
|
return ret
|
|
|
|
|
|
def walk_kmod_chain(kmod, myfunc):
|
|
visited = set()
|
|
|
|
def visit_kmod(kmod, parent_kmod, func_to_call):
|
|
func_to_call(kmod, parent_kmod)
|
|
visited.add(kmod)
|
|
for dep in kmod.depends_on:
|
|
if dep not in visited:
|
|
visit_kmod(dep, kmod, func_to_call)
|
|
|
|
visit_kmod(kmod, None, myfunc)
|
|
return visited
|
|
|
|
|
|
# is pkg a parent to any pkg from "alist"
|
|
def is_pkg_parent_to_any(pkg: KModPackage, alist: set[KModPackage]) -> bool:
|
|
if pkg in alist:
|
|
return True
|
|
|
|
for some_pkg in alist:
|
|
if some_pkg in pkg.all_depends_on:
|
|
return True
|
|
return False
|
|
|
|
|
|
# is pkg a child to any pkg from "alist"
|
|
def is_pkg_child_to_any(pkg: KModPackage, alist: set[KModPackage]) -> bool:
|
|
if pkg in alist:
|
|
return True
|
|
|
|
for some_pkg in alist:
|
|
if pkg in some_pkg.all_depends_on:
|
|
return True
|
|
return False
|
|
|
|
|
|
def update_allowed(kmod: KMod, visited: set[KMod], update_linked: bool = False) -> int:
|
|
num_updated = 0
|
|
init = False
|
|
to_remove = set()
|
|
|
|
if kmod in visited:
|
|
return num_updated
|
|
visited.add(kmod)
|
|
|
|
# if we have nothing, try to initialise based on parents and children
|
|
if kmod.allowed_list is None:
|
|
init_allowed_list: set[KModPackage] = set()
|
|
|
|
# init from children
|
|
for kmod_dep in kmod.depends_on:
|
|
if kmod_dep.allowed_list:
|
|
init_allowed_list.update(kmod_dep.allowed_list)
|
|
init = True
|
|
|
|
if init:
|
|
# also add any pkgs that pkgs from list could depend on
|
|
deps_for = set()
|
|
for pkg in init_allowed_list:
|
|
deps_for.update(pkg.get_all_deps_for())
|
|
init_allowed_list.update(deps_for)
|
|
|
|
# init from parents
|
|
if not init:
|
|
for kmod_par in kmod.is_dependency_for:
|
|
if kmod_par.allowed_list:
|
|
init_allowed_list.update(kmod_par.allowed_list)
|
|
# also add any pkgs that depend on pkgs from list
|
|
for pkg in kmod_par.allowed_list:
|
|
init_allowed_list.update(pkg.all_depends_on)
|
|
init = True
|
|
|
|
if init:
|
|
kmod.allowed_list = init_allowed_list
|
|
log.info('%s: init to %s', kmod.name, [x.name for x in kmod.allowed_list])
|
|
|
|
kmod_allowed_list = kmod.allowed_list or set()
|
|
# log.debug('%s: update to %s', kmod.name, [x.name for x in kmod_allowed_list])
|
|
|
|
# each allowed is parent to at least one child allowed [for _all_ children]
|
|
for pkg in kmod_allowed_list:
|
|
for kmod_dep in kmod.depends_on:
|
|
if kmod_dep.allowed_list is None or kmod_dep.err:
|
|
continue
|
|
if not is_pkg_parent_to_any(pkg, kmod_dep.allowed_list):
|
|
to_remove.add(pkg)
|
|
log.info('%s: remove %s from allowed, child: %s [%s]',
|
|
kmod.name, [pkg.name], kmod_dep.name, [x.name for x in kmod_dep.allowed_list])
|
|
|
|
# each allowed is child to at least one parent allowed [for _all_ parents]
|
|
for pkg in kmod_allowed_list:
|
|
for kmod_par in kmod.is_dependency_for:
|
|
if kmod_par.allowed_list is None or kmod_par.err:
|
|
continue
|
|
|
|
if not is_pkg_child_to_any(pkg, kmod_par.allowed_list):
|
|
to_remove.add(pkg)
|
|
log.info('%s: remove %s from allowed, parent: %s %s',
|
|
kmod.name, [pkg.name], kmod_par.name, [x.name for x in kmod_par.allowed_list])
|
|
|
|
for pkg in to_remove:
|
|
kmod_allowed_list.remove(pkg)
|
|
num_updated = num_updated + 1
|
|
if len(kmod_allowed_list) == 0:
|
|
log.error('%s: cleared entire allow list', kmod.name)
|
|
kmod.err = 1
|
|
|
|
if init or to_remove or update_linked:
|
|
if to_remove:
|
|
log.info('%s: updated to %s', kmod.name, [x.name for x in kmod_allowed_list])
|
|
|
|
for kmod_dep in kmod.depends_on:
|
|
num_updated = num_updated + update_allowed(kmod_dep, visited)
|
|
|
|
for kmod_dep in kmod.is_dependency_for:
|
|
num_updated = num_updated + update_allowed(kmod_dep, visited)
|
|
|
|
return num_updated
|
|
|
|
|
|
def apply_initial_labels(pkg_list: KModPackageList, kmod_list: KModList, treat_default_as_wants=False):
|
|
log.debug('')
|
|
for cur_rule in ['needs', 'wants', 'default']:
|
|
for package_name, rule_type, rule in pkg_list.rules:
|
|
pkg_obj = pkg_list.get(package_name)
|
|
|
|
if not pkg_obj:
|
|
log.error('no package with name %s', package_name)
|
|
|
|
if cur_rule != rule_type:
|
|
continue
|
|
|
|
if rule_type == 'default' and treat_default_as_wants:
|
|
rule_type = 'wants'
|
|
|
|
if 'needs' == rule_type:
|
|
# kmod_matching is already in topo_order
|
|
kmod_matching = get_kmods_matching_re(kmod_list, rule)
|
|
for kmod in kmod_matching:
|
|
if kmod.assigned_to_pkg and kmod.assigned_to_pkg != pkg_obj:
|
|
log.error('%s: can not be required by 2 pkgs %s %s', kmod.name, kmod.assigned_to_pkg, pkg_obj.name)
|
|
else:
|
|
kmod.assigned_to_pkg = pkg_obj
|
|
kmod.allowed_list = set([pkg_obj])
|
|
kmod.rule_specifity = len(kmod_matching)
|
|
log.debug('%s: needed by %s', kmod.name, [pkg_obj.name])
|
|
|
|
if 'wants' == rule_type:
|
|
# kmod_matching is already in topo_order
|
|
kmod_matching = get_kmods_matching_re(kmod_list, rule)
|
|
for kmod in kmod_matching:
|
|
if kmod.allowed_list is None:
|
|
kmod.allowed_list = set(pkg_obj.all_depends_on)
|
|
kmod.allowed_list.add(pkg_obj)
|
|
kmod.preferred_pkg = pkg_obj
|
|
kmod.rule_specifity = len(kmod_matching)
|
|
log.debug('%s: wanted by %s, init allowed to %s', kmod.name, [pkg_obj.name], [pkg.name for pkg in kmod.allowed_list])
|
|
else:
|
|
if kmod.assigned_to_pkg:
|
|
log.debug('%s: ignoring wants by %s, already assigned to %s', kmod.name, pkg_obj.name, kmod.assigned_to_pkg.name)
|
|
else:
|
|
# rule specifity may not be good idea, so just log it
|
|
# e.g. .*test.* may not be more specific than arch/x86/.*
|
|
log.debug('already have wants for %s %s, new rule: %s', kmod.name, kmod.preferred_pkg, rule)
|
|
|
|
if 'default' == rule_type:
|
|
pkg_obj.default = True
|
|
|
|
|
|
def settle(kmod_list: KModList) -> None:
|
|
kmod_topo_order = list(kmod_list.get_topo_order())
|
|
|
|
for i in range(0, 25):
|
|
log.debug('settle start %s', i)
|
|
|
|
ret = 0
|
|
for kmod in kmod_topo_order:
|
|
visited: set[KMod] = set()
|
|
ret = ret + update_allowed(kmod, visited)
|
|
log.debug('settle %s updated nodes: %s', i, ret)
|
|
|
|
if ret == 0:
|
|
break
|
|
|
|
kmod_topo_order.reverse()
|
|
|
|
|
|
# phase 1 - propagate initial labels
|
|
def propagate_labels_1(pkg_list: KModPackageList, kmod_list: KModList):
|
|
log.info('')
|
|
settle(kmod_list)
|
|
|
|
|
|
def pick_closest_to_preffered(preferred_pkg: KModPackage, allowed_set: set[KModPackage]):
|
|
for child in preferred_pkg.all_depends_on_list:
|
|
if child in allowed_set:
|
|
return child
|
|
return None
|
|
|
|
|
|
# phase 2 - if some kmods allow more than one pkg, pick wanted package
|
|
def propagate_labels_2(pkg_list: KModPackageList, kmod_list: KModList):
|
|
log.info('')
|
|
ret = 0
|
|
for kmod in kmod_list.get_topo_order():
|
|
update_linked = False
|
|
|
|
if kmod.allowed_list is None and kmod.preferred_pkg:
|
|
log.error('%s: has no allowed list but has preferred_pkg %s', kmod.name, kmod.preferred_pkg.name)
|
|
kmod.err = 1
|
|
|
|
if kmod.allowed_list and kmod.preferred_pkg:
|
|
chosen_pkg = None
|
|
if kmod.preferred_pkg in kmod.allowed_list:
|
|
chosen_pkg = kmod.preferred_pkg
|
|
else:
|
|
chosen_pkg = pick_closest_to_preffered(kmod.preferred_pkg, kmod.allowed_list)
|
|
|
|
if chosen_pkg is not None:
|
|
kmod.allowed_list = set([chosen_pkg])
|
|
log.info('%s: making to prefer %s (preffered is %s), allowed: %s', kmod.name, chosen_pkg.name,
|
|
kmod.preferred_pkg.name, [pkg.name for pkg in kmod.allowed_list])
|
|
update_linked = True
|
|
|
|
visited: set[KMod] = set()
|
|
ret = ret + update_allowed(kmod, visited, update_linked)
|
|
|
|
log.debug('updated nodes: %s', ret)
|
|
settle(kmod_list)
|
|
|
|
|
|
# Is this the best pick? ¯\_(ツ)_/¯
|
|
def pick_topmost_allowed(allowed_set: set[KModPackage]) -> KModPackage:
|
|
topmost = next(iter(allowed_set))
|
|
for pkg in allowed_set:
|
|
if len(pkg.all_depends_on) > len(topmost.all_depends_on):
|
|
topmost = pkg
|
|
|
|
return topmost
|
|
|
|
|
|
# phase 3 - assign everything else that remained
|
|
def propagate_labels_3(pkg_list: KModPackageList, kmod_list: KModList):
|
|
log.info('')
|
|
ret = 0
|
|
kmod_topo_order = list(kmod_list.get_topo_order())
|
|
# do reverse topo order to cover children faster
|
|
kmod_topo_order.reverse()
|
|
|
|
default_pkg = None
|
|
default_name = ''
|
|
for pkg_obj in pkg_list:
|
|
if pkg_obj.default:
|
|
if default_pkg:
|
|
log.error('Already have default pkg: %s / %s', default_pkg.name, pkg_obj.name)
|
|
else:
|
|
default_pkg = pkg_obj
|
|
default_name = default_pkg.name
|
|
|
|
for kmod in kmod_topo_order:
|
|
update_linked = False
|
|
chosen_pkg = None
|
|
|
|
if kmod.allowed_list is None:
|
|
if default_pkg:
|
|
chosen_pkg = default_pkg
|
|
else:
|
|
log.error('%s not assigned and there is no default', kmod.name)
|
|
elif len(kmod.allowed_list) > 1:
|
|
if default_pkg:
|
|
if default_pkg in kmod.allowed_list:
|
|
chosen_pkg = default_pkg
|
|
else:
|
|
chosen_pkg = pick_closest_to_preffered(default_pkg, kmod.allowed_list)
|
|
if chosen_pkg:
|
|
log.debug('closest is %s', chosen_pkg.name)
|
|
if not chosen_pkg:
|
|
# multiple pkgs are allowed, but none is preferred or default
|
|
chosen_pkg = pick_topmost_allowed(kmod.allowed_list)
|
|
log.debug('topmost is %s', chosen_pkg.name)
|
|
|
|
if chosen_pkg:
|
|
kmod.allowed_list = set([chosen_pkg])
|
|
log.info('%s: making to prefer %s (default: %s)', kmod.name, [chosen_pkg.name], default_name)
|
|
update_linked = True
|
|
|
|
visited: set[KMod] = set()
|
|
ret = ret + update_allowed(kmod, visited, update_linked)
|
|
|
|
log.debug('updated nodes: %s', ret)
|
|
settle(kmod_list)
|
|
|
|
|
|
def load_config(config_pathname: str, kmod_list: KModList, variants=[]):
|
|
kmod_pkg_list = KModPackageList()
|
|
|
|
with open(config_pathname, 'r') as file:
|
|
yobj = yaml.safe_load(file)
|
|
|
|
for pkg_dict in yobj['packages']:
|
|
pkg_name = pkg_dict['name']
|
|
depends_on = pkg_dict.get('depends-on', [])
|
|
if_variant_in = pkg_dict.get('if_variant_in')
|
|
|
|
if if_variant_in is not None:
|
|
if not (set(variants) & set(if_variant_in)):
|
|
log.debug('Skipping %s for variants %s', pkg_name, variants)
|
|
continue
|
|
|
|
pkg_dep_list = []
|
|
for pkg_dep_name in depends_on:
|
|
pkg_dep = kmod_pkg_list.get(pkg_dep_name)
|
|
pkg_dep_list.append(pkg_dep)
|
|
|
|
pkg_obj = kmod_pkg_list.get(pkg_name)
|
|
if not pkg_obj:
|
|
pkg_obj = KModPackage(pkg_name, pkg_dep_list)
|
|
kmod_pkg_list.add_kmod_pkg(pkg_obj)
|
|
else:
|
|
log.error('package %s already exists?', pkg_name)
|
|
|
|
rules_list = yobj.get('rules', [])
|
|
for rule_dict in rules_list:
|
|
if_variant_in = rule_dict.get('if_variant_in')
|
|
exact_pkg = rule_dict.get('exact_pkg')
|
|
|
|
for key, value in rule_dict.items():
|
|
if key in ['if_variant_in', 'exact_pkg']:
|
|
continue
|
|
|
|
if if_variant_in is not None:
|
|
if not (set(variants) & set(if_variant_in)):
|
|
continue
|
|
|
|
rule = key
|
|
package_name = value
|
|
|
|
if not kmod_pkg_list.get(package_name):
|
|
raise Exception('Unknown package ' + package_name)
|
|
|
|
rule_type = 'wants'
|
|
if exact_pkg is True:
|
|
rule_type = 'needs'
|
|
elif key == 'default':
|
|
rule_type = 'default'
|
|
rule = '.*'
|
|
|
|
log.debug('found rule: %s', (package_name, rule_type, rule))
|
|
kmod_pkg_list.rules.append((package_name, rule_type, rule))
|
|
|
|
log.info('loaded config, rules: %s', len(kmod_pkg_list.rules))
|
|
return kmod_pkg_list
|
|
|
|
|
|
def make_pictures(pkg_list: KModPackageList, kmod_list: KModList, filename: str, print_allowed=True):
|
|
f = open(filename + '.dot', 'w')
|
|
|
|
f.write('digraph {\n')
|
|
f.write('node [style=filled fillcolor="#f8f8f8"]\n')
|
|
f.write(' subgraph kmods {\n')
|
|
f.write(' "Legend" [shape=note label="kmod name\\n{desired package}\\nresulting package(s)"]\n')
|
|
|
|
for kmod in kmod_list.get_topo_order():
|
|
pkg_name = ''
|
|
attr = ''
|
|
if kmod.assigned_to_pkg:
|
|
attr = 'fillcolor="#eddad5" color="#b22800"'
|
|
pkg_name = kmod.assigned_to_pkg.name + "!"
|
|
if kmod.preferred_pkg:
|
|
attr = 'fillcolor="#ddddf5" color="#b268fe"'
|
|
pkg_name = kmod.preferred_pkg.name + "?"
|
|
allowed = ''
|
|
if kmod.allowed_list and print_allowed:
|
|
allowed = '=' + ' '.join([pkg.name for pkg in kmod.allowed_list])
|
|
f.write(' "%s" [label="%s\\n%s\\n%s" shape=box %s] \n' % (kmod.name, kmod.name, pkg_name, allowed, attr))
|
|
|
|
for kmod in kmod_list.get_topo_order():
|
|
for kmod_dep in kmod.depends_on:
|
|
f.write(' "%s" -> "%s";\n' % (kmod.name, kmod_dep.name))
|
|
f.write(' }\n')
|
|
|
|
f.write(' subgraph packages {\n')
|
|
for pkg in pkg_list:
|
|
desc = ''
|
|
if pkg.default:
|
|
desc = '/default'
|
|
f.write(' "%s" [label="%s\\n%s"] \n' % (pkg.name, pkg.name, desc))
|
|
for pkg_dep in pkg.depends_on:
|
|
f.write(' "%s" -> "%s";\n' % (pkg.name, pkg_dep.name))
|
|
f.write(' }\n')
|
|
f.write('}\n')
|
|
|
|
f.close()
|
|
|
|
# safe_run_command('dot -Tpng -Gdpi=150 %s.dot > %s.png' % (filename, filename))
|
|
safe_run_command('dot -Tsvg %s.dot > %s.svg' % (filename, filename))
|
|
|
|
|
|
def sort_kmods(depmod_pathname: str, config_str: str, variants=[], do_pictures=''):
|
|
log.info('%s %s', depmod_pathname, config_str)
|
|
kmod_list = KModList()
|
|
kmod_list.load_depmod_file(depmod_pathname)
|
|
|
|
pkg_list = load_config(config_str, kmod_list, variants)
|
|
|
|
basename = os.path.splitext(config_str)[0]
|
|
|
|
apply_initial_labels(pkg_list, kmod_list)
|
|
if '0' in do_pictures:
|
|
make_pictures(pkg_list, kmod_list, basename + "_0", print_allowed=False)
|
|
|
|
try:
|
|
|
|
propagate_labels_1(pkg_list, kmod_list)
|
|
if '1' in do_pictures:
|
|
make_pictures(pkg_list, kmod_list, basename + "_1")
|
|
propagate_labels_2(pkg_list, kmod_list)
|
|
propagate_labels_3(pkg_list, kmod_list)
|
|
finally:
|
|
if 'f' in do_pictures:
|
|
make_pictures(pkg_list, kmod_list, basename + "_f")
|
|
|
|
return pkg_list, kmod_list
|
|
|
|
|
|
def abbrev_list_for_report(alist: list[KMod]) -> str:
|
|
tmp_str = []
|
|
for kmod in alist[:2]:
|
|
if kmod.allowed_list:
|
|
tmp_str.append('%s(%s)' % (kmod.name, ' '.join([x.name for x in kmod.allowed_list])))
|
|
ret = ', '.join(tmp_str)
|
|
other_len = len(alist[2:])
|
|
if other_len > 0:
|
|
ret = ret + ' and %s other(s)' % (other_len)
|
|
return ret
|
|
|
|
|
|
def print_report(pkg_list: KModPackageList, kmod_list: KModList):
|
|
log.info('*'*26 + ' REPORT ' + '*'*26)
|
|
|
|
kmods_err = 0
|
|
kmods_moved = 0
|
|
kmods_good = 0
|
|
for kmod in kmod_list.get_topo_order():
|
|
if not kmod.allowed_list:
|
|
log.error('%s: not assigned to any package! Please check the full log for details', kmod.name)
|
|
kmods_err = kmods_err + 1
|
|
continue
|
|
|
|
if len(kmod.allowed_list) > 1:
|
|
log.error('%s: assigned to more than one package! Please check the full log for details', kmod.name)
|
|
kmods_err = kmods_err + 1
|
|
continue
|
|
|
|
if not kmod.preferred_pkg:
|
|
# config doesn't care where it ended up
|
|
kmods_good = kmods_good + 1
|
|
continue
|
|
|
|
if kmod.preferred_pkg in kmod.allowed_list:
|
|
# it ended up where it needs to be
|
|
kmods_good = kmods_good + 1
|
|
continue
|
|
|
|
bad_parent_list = []
|
|
for kmod_parent in kmod.is_dependency_for:
|
|
if not is_pkg_child_to_any(kmod.preferred_pkg, kmod_parent.allowed_list):
|
|
bad_parent_list.append(kmod_parent)
|
|
|
|
bad_child_list = []
|
|
for kmod_child in kmod.depends_on:
|
|
if not is_pkg_parent_to_any(kmod.preferred_pkg, kmod_child.allowed_list):
|
|
bad_child_list.append(kmod_parent)
|
|
|
|
log.info('%s: wanted by %s but ended up in %s', kmod.name, [kmod.preferred_pkg.name], [pkg.name for pkg in kmod.allowed_list])
|
|
if bad_parent_list:
|
|
log.info('\thas conflicting parent: %s', abbrev_list_for_report(bad_parent_list))
|
|
if bad_child_list:
|
|
log.info('\thas conflicting children: %s', abbrev_list_for_report(bad_child_list))
|
|
|
|
kmods_moved = kmods_moved + 1
|
|
|
|
log.info('No. of kmod(s) assigned to preferred package: %s', kmods_good)
|
|
log.info('No. of kmod(s) moved to a related package: %s', kmods_moved)
|
|
log.info('No. of kmod(s) which could not be assigned: %s', kmods_err)
|
|
log.info('*'*60)
|
|
|
|
return kmods_err
|
|
|
|
|
|
def write_modules_lists(path_prefix: str, pkg_list: KModPackageList, kmod_list: KModList):
|
|
kmod_list_alphabetical = sorted(kmod_list.get_topo_order(), key=lambda x: x.kmod_pathname)
|
|
for pkg in pkg_list:
|
|
output_path = os.path.join(path_prefix, pkg.name + '.list')
|
|
i = 0
|
|
with open(output_path, "w") as file:
|
|
for kmod in kmod_list_alphabetical:
|
|
if kmod.allowed_list and pkg in kmod.allowed_list:
|
|
file.write(kmod.kmod_pathname)
|
|
file.write('\n')
|
|
i = i + 1
|
|
log.info('Module list %s created with %s kmods', output_path, i)
|
|
|
|
|
|
class FiltermodTests(unittest.TestCase):
|
|
do_pictures = ''
|
|
|
|
def setUp(self):
|
|
self.pkg_list = None
|
|
self.kmod_list = None
|
|
|
|
def _is_kmod_pkg(self, kmodname, pkgnames):
|
|
self.assertIsNotNone(self.pkg_list)
|
|
self.assertIsNotNone(self.kmod_list)
|
|
|
|
if type(pkgnames) is str:
|
|
pkgnames = [pkgnames]
|
|
|
|
expected_pkgs = []
|
|
for pkgname in pkgnames:
|
|
pkg = self.pkg_list.get(pkgname)
|
|
self.assertIsNotNone(pkg)
|
|
expected_pkgs.append(pkg)
|
|
|
|
kmod = self.kmod_list.get(kmodname)
|
|
self.assertIsNotNone(kmod)
|
|
|
|
if expected_pkgs:
|
|
self.assertTrue(len(kmod.allowed_list) == 1)
|
|
self.assertIn(next(iter(kmod.allowed_list)), expected_pkgs)
|
|
else:
|
|
self.assertEqual(kmod.allowed_list, set())
|
|
|
|
def test1a(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test1.dep'), get_td('test1.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._is_kmod_pkg('kmod1', 'modules-core')
|
|
self._is_kmod_pkg('kmod2', 'modules-core')
|
|
self._is_kmod_pkg('kmod3', 'modules')
|
|
self._is_kmod_pkg('kmod4', 'modules')
|
|
|
|
def test1b(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test1.dep'), get_td('test1.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures,
|
|
variants=['rt'])
|
|
|
|
self.assertIsNotNone(self.pkg_list.get('rt-kvm'))
|
|
self._is_kmod_pkg('kmod1', 'modules-core')
|
|
self._is_kmod_pkg('kmod2', 'modules-core')
|
|
self._is_kmod_pkg('kmod3', 'modules')
|
|
self._is_kmod_pkg('kmod4', 'rt-kvm')
|
|
|
|
def test2(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test2.dep'), get_td('test2.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._is_kmod_pkg('kmod1', 'modules-extra')
|
|
self._is_kmod_pkg('kmod2', 'modules')
|
|
self._is_kmod_pkg('kmod3', 'modules-core')
|
|
self._is_kmod_pkg('kmod4', 'modules-core')
|
|
self._is_kmod_pkg('kmod5', 'modules-core')
|
|
self._is_kmod_pkg('kmod6', 'modules-extra')
|
|
self._is_kmod_pkg('kmod8', 'modules')
|
|
|
|
def test3(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test3.dep'), get_td('test3.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._is_kmod_pkg('kmod2', ['modules-core', 'modules'])
|
|
self._is_kmod_pkg('kmod4', ['modules-core', 'modules-extra'])
|
|
self._is_kmod_pkg('kmod5', 'modules-core')
|
|
self._is_kmod_pkg('kmod6', 'modules-core')
|
|
|
|
def test4(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test4.dep'), get_td('test4.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._is_kmod_pkg('kmod0', 'modules')
|
|
self._is_kmod_pkg('kmod1', 'modules')
|
|
self._is_kmod_pkg('kmod2', 'modules')
|
|
self._is_kmod_pkg('kmod3', 'modules')
|
|
self._is_kmod_pkg('kmod4', 'modules')
|
|
self._is_kmod_pkg('kmod5', 'modules')
|
|
self._is_kmod_pkg('kmod6', 'modules')
|
|
self._is_kmod_pkg('kmod7', 'modules-partner2')
|
|
self._is_kmod_pkg('kmod8', 'modules-partner')
|
|
self._is_kmod_pkg('kmod9', 'modules-partner')
|
|
|
|
def _check_preffered_pkg(self, kmodname, pkgname):
|
|
kmod = self.kmod_list.get(kmodname)
|
|
self.assertIsNotNone(kmod)
|
|
self.assertEqual(kmod.preferred_pkg.name, pkgname)
|
|
|
|
def test5(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test5.dep'), get_td('test5.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._check_preffered_pkg('kmod2', 'modules')
|
|
self._check_preffered_pkg('kmod3', 'modules-partner')
|
|
self._check_preffered_pkg('kmod4', 'modules-partner')
|
|
|
|
def test6(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test6.dep'), get_td('test6.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._is_kmod_pkg('kmod2', 'modules-core')
|
|
self._is_kmod_pkg('kmod3', 'modules')
|
|
self._is_kmod_pkg('kmod4', 'modules')
|
|
self._is_kmod_pkg('kmod1', [])
|
|
|
|
def test7(self):
|
|
self.pkg_list, self.kmod_list = sort_kmods(get_td('test7.dep'), get_td('test7.yaml'),
|
|
do_pictures=FiltermodTests.do_pictures)
|
|
|
|
self._is_kmod_pkg('kmod1', 'modules-core')
|
|
self._is_kmod_pkg('kmod2', 'modules-core')
|
|
self._is_kmod_pkg('kmod3', 'modules-other')
|
|
self._is_kmod_pkg('kmod4', 'modules')
|
|
|
|
|
|
def do_rpm_mapping_test(config_pathname, kmod_rpms):
|
|
kmod_dict = {}
|
|
|
|
def get_kmods_matching_re(pkgname, param_re):
|
|
matched = []
|
|
param_re = '^kernel/' + param_re
|
|
pattern = re.compile(param_re)
|
|
|
|
for kmod_pathname, kmod_rec in kmod_dict.items():
|
|
m = pattern.match(kmod_pathname)
|
|
if m:
|
|
matched.append(kmod_pathname)
|
|
|
|
return matched
|
|
|
|
for kmod_rpm in kmod_rpms.split():
|
|
filename = os.path.basename(kmod_rpm)
|
|
|
|
m = re.match(r'.*-modules-([^-]+)', filename)
|
|
if not m:
|
|
raise Exception('Unrecognized rpm ' + kmod_rpm + ', expected a kernel-modules* rpm')
|
|
pkgname = 'modules-' + m.group(1)
|
|
m = re.match(r'modules-([0-9.]+)', pkgname)
|
|
if m:
|
|
pkgname = 'modules'
|
|
|
|
tmpdir = os.path.join('tmp.filtermods', filename, pkgname)
|
|
if not os.path.exists(tmpdir):
|
|
log.info('creating tmp dir %s', tmpdir)
|
|
os.makedirs(tmpdir)
|
|
safe_run_command('rpm2cpio %s | cpio -id' % (os.path.abspath(kmod_rpm)), cwddir=tmpdir)
|
|
else:
|
|
log.info('using cached content of tmp dir: %s', tmpdir)
|
|
|
|
for path, subdirs, files in os.walk(tmpdir):
|
|
for name in files:
|
|
ret = re.match(r'.*/'+pkgname+'/lib/modules/[^/]+/[^/]+/(.*)', os.path.join(path, name))
|
|
if not ret:
|
|
continue
|
|
|
|
kmod_pathname = 'kernel/' + ret.group(1)
|
|
if not kmod_pathname.endswith('.xz') and not kmod_pathname.endswith('.ko'):
|
|
continue
|
|
if kmod_pathname in kmod_dict:
|
|
if pkgname not in kmod_dict[kmod_pathname]['target_pkgs']:
|
|
kmod_dict[kmod_pathname]['target_pkgs'].append(pkgname)
|
|
else:
|
|
kmod_dict[kmod_pathname] = {}
|
|
kmod_dict[kmod_pathname]['target_pkgs'] = [pkgname]
|
|
kmod_dict[kmod_pathname]['pkg'] = None
|
|
kmod_dict[kmod_pathname]['matched'] = False
|
|
|
|
kmod_pkg_list = load_config(config_pathname, None)
|
|
|
|
for package_name, rule_type, rule in kmod_pkg_list.rules:
|
|
kmod_names = get_kmods_matching_re(package_name, rule)
|
|
|
|
for kmod_pathname in kmod_names:
|
|
kmod_rec = kmod_dict[kmod_pathname]
|
|
|
|
if not kmod_rec['matched']:
|
|
kmod_rec['matched'] = True
|
|
kmod_rec['pkg'] = package_name
|
|
for kmod_pathname, kmod_rec in kmod_dict.items():
|
|
if kmod_rec['pkg'] not in kmod_rec['target_pkgs']:
|
|
log.warning('kmod %s wanted by config in %s, in tree it is: %s', kmod_pathname, [kmod_rec['pkg']], kmod_rec['target_pkgs'])
|
|
elif len(kmod_rec['target_pkgs']) > 1:
|
|
# if set(kmod_rec['target_pkgs']) != set(['modules', 'modules-core']):
|
|
log.warning('kmod %s multiple matches in tree: %s/%s', kmod_pathname, [kmod_rec['pkg']], kmod_rec['target_pkgs'])
|
|
|
|
|
|
def cmd_sort(options):
|
|
do_pictures = ''
|
|
if options.graphviz:
|
|
do_pictures = '0f'
|
|
|
|
pkg_list, kmod_list = sort_kmods(options.depmod, options.config,
|
|
options.variants, do_pictures)
|
|
ret = print_report(pkg_list, kmod_list)
|
|
if options.output:
|
|
write_modules_lists(options.output, pkg_list, kmod_list)
|
|
|
|
return ret
|
|
|
|
|
|
def cmd_print_rule_map(options):
|
|
kmod_list = KModList()
|
|
kmod_list.load_depmod_file(options.depmod)
|
|
pkg_list = load_config(options.config, kmod_list, options.variants)
|
|
apply_initial_labels(pkg_list, kmod_list, treat_default_as_wants=True)
|
|
|
|
for kmod in kmod_list.get_alphabetical_order():
|
|
print('%-20s %s' % (kmod.preferred_pkg, kmod.kmod_pathname))
|
|
|
|
|
|
def cmd_selftest(options):
|
|
if options.graphviz:
|
|
FiltermodTests.do_pictures = '0f'
|
|
|
|
for arg in ['selftest', '-g', '--graphviz']:
|
|
if arg in sys.argv:
|
|
sys.argv.remove(arg)
|
|
|
|
unittest.main()
|
|
sys.exit(0)
|
|
|
|
|
|
def cmd_cmp2rpm(options):
|
|
do_rpm_mapping_test(options.config, options.kmod_rpms)
|
|
|
|
|
|
def main():
|
|
global log
|
|
log = setup_logging()
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('-v', '--verbose', dest='verbose',
|
|
help='be more verbose', action='count', default=4)
|
|
parser.add_argument('-q', '--quiet', dest='quiet',
|
|
help='be more quiet', action='count', default=0)
|
|
subparsers = parser.add_subparsers(dest='cmd')
|
|
|
|
def add_graphviz_arg(p):
|
|
p.add_argument('-g', '--graphviz', dest='graphviz',
|
|
help='generate graphviz visualizations',
|
|
action='store_true', default=False)
|
|
|
|
def add_config_arg(p):
|
|
p.add_argument('-c', '--config', dest='config', required=True,
|
|
help='path to yaml config with rules')
|
|
|
|
def add_depmod_arg(p):
|
|
p.add_argument('-d', '--depmod', dest='depmod', required=True,
|
|
help='path to modules.dep file')
|
|
|
|
def add_output_arg(p):
|
|
p.add_argument('-o', '--output', dest='output', default=None,
|
|
help='output $module_name.list files to directory specified by this parameter')
|
|
|
|
def add_variants_arg(p):
|
|
p.add_argument('-r', '--variants', dest='variants', action='append', default=[],
|
|
help='variants to enable in config')
|
|
|
|
def add_kmod_rpms_arg(p):
|
|
p.add_argument('-k', '--kmod-rpms', dest='kmod_rpms', required=True,
|
|
help='compare content of specified rpm(s) against yaml config rules')
|
|
|
|
parser_sort = subparsers.add_parser('sort', help='assign kmods specified by modules.dep using rules from yaml config')
|
|
add_config_arg(parser_sort)
|
|
add_depmod_arg(parser_sort)
|
|
add_output_arg(parser_sort)
|
|
add_variants_arg(parser_sort)
|
|
add_graphviz_arg(parser_sort)
|
|
|
|
parser_rule_map = subparsers.add_parser('rulemap', help='print how yaml config maps to kmods')
|
|
add_config_arg(parser_rule_map)
|
|
add_depmod_arg(parser_rule_map)
|
|
add_variants_arg(parser_rule_map)
|
|
|
|
parser_test = subparsers.add_parser('selftest', help='runs a self-test')
|
|
add_graphviz_arg(parser_test)
|
|
|
|
parser_cmp2rpm = subparsers.add_parser('cmp2rpm', help='compare ruleset against RPM(s)')
|
|
add_config_arg(parser_cmp2rpm)
|
|
add_kmod_rpms_arg(parser_cmp2rpm)
|
|
|
|
options = parser.parse_args()
|
|
|
|
if options.cmd == "selftest":
|
|
options.verbose = options.verbose - 2
|
|
options.verbose = max(options.verbose - options.quiet, 0)
|
|
levels = [NOTSET, CRITICAL, ERROR, WARN, INFO, DEBUG]
|
|
log.setLevel(levels[min(options.verbose, len(levels) - 1)])
|
|
|
|
ret = 0
|
|
if options.cmd == "sort":
|
|
ret = cmd_sort(options)
|
|
elif options.cmd == "rulemap":
|
|
cmd_print_rule_map(options)
|
|
elif options.cmd == "selftest":
|
|
cmd_selftest(options)
|
|
elif options.cmd == "cmp2rpm":
|
|
cmd_cmp2rpm(options)
|
|
else:
|
|
parser.print_help()
|
|
|
|
return ret
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# import profile
|
|
# profile.run('main()', sort=1)
|
|
sys.exit(main())
|