updating to mainline 4.13
This commit is contained in:
parent
a88dbf0b2c
commit
170c948bba
184
config
184
config
|
@ -1,6 +1,6 @@
|
||||||
#
|
#
|
||||||
# Automatically generated file; DO NOT EDIT.
|
# Automatically generated file; DO NOT EDIT.
|
||||||
# Linux/x86_64 4.12.6 Kernel Configuration
|
# Linux/x86_64 4.13.0-custom Kernel Configuration
|
||||||
#
|
#
|
||||||
CONFIG_64BIT=y
|
CONFIG_64BIT=y
|
||||||
CONFIG_X86_64=y
|
CONFIG_X86_64=y
|
||||||
|
@ -87,7 +87,9 @@ CONFIG_AUDIT_TREE=y
|
||||||
#
|
#
|
||||||
CONFIG_GENERIC_IRQ_PROBE=y
|
CONFIG_GENERIC_IRQ_PROBE=y
|
||||||
CONFIG_GENERIC_IRQ_SHOW=y
|
CONFIG_GENERIC_IRQ_SHOW=y
|
||||||
|
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||||
CONFIG_GENERIC_PENDING_IRQ=y
|
CONFIG_GENERIC_PENDING_IRQ=y
|
||||||
|
CONFIG_GENERIC_IRQ_MIGRATION=y
|
||||||
CONFIG_GENERIC_IRQ_CHIP=y
|
CONFIG_GENERIC_IRQ_CHIP=y
|
||||||
CONFIG_IRQ_DOMAIN=y
|
CONFIG_IRQ_DOMAIN=y
|
||||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||||
|
@ -96,6 +98,7 @@ CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
|
||||||
# CONFIG_IRQ_DOMAIN_DEBUG is not set
|
# CONFIG_IRQ_DOMAIN_DEBUG is not set
|
||||||
CONFIG_IRQ_FORCED_THREADING=y
|
CONFIG_IRQ_FORCED_THREADING=y
|
||||||
CONFIG_SPARSE_IRQ=y
|
CONFIG_SPARSE_IRQ=y
|
||||||
|
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
|
||||||
CONFIG_CLOCKSOURCE_WATCHDOG=y
|
CONFIG_CLOCKSOURCE_WATCHDOG=y
|
||||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||||
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
|
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
|
||||||
|
@ -139,7 +142,6 @@ CONFIG_TREE_SRCU=y
|
||||||
CONFIG_TASKS_RCU=y
|
CONFIG_TASKS_RCU=y
|
||||||
CONFIG_RCU_STALL_COMMON=y
|
CONFIG_RCU_STALL_COMMON=y
|
||||||
CONFIG_RCU_NEED_SEGCBLIST=y
|
CONFIG_RCU_NEED_SEGCBLIST=y
|
||||||
# CONFIG_TREE_RCU_TRACE is not set
|
|
||||||
CONFIG_BUILD_BIN2C=y
|
CONFIG_BUILD_BIN2C=y
|
||||||
# CONFIG_IKCONFIG is not set
|
# CONFIG_IKCONFIG is not set
|
||||||
CONFIG_LOG_BUF_SHIFT=18
|
CONFIG_LOG_BUF_SHIFT=18
|
||||||
|
@ -246,6 +248,7 @@ CONFIG_SLUB_MEMCG_SYSFS_ON=y
|
||||||
# CONFIG_SLAB is not set
|
# CONFIG_SLAB is not set
|
||||||
CONFIG_SLUB=y
|
CONFIG_SLUB=y
|
||||||
# CONFIG_SLOB is not set
|
# CONFIG_SLOB is not set
|
||||||
|
CONFIG_SLAB_MERGE_DEFAULT=y
|
||||||
CONFIG_SLAB_FREELIST_RANDOM=y
|
CONFIG_SLAB_FREELIST_RANDOM=y
|
||||||
CONFIG_SLUB_CPU_PARTIAL=y
|
CONFIG_SLUB_CPU_PARTIAL=y
|
||||||
CONFIG_SYSTEM_DATA_VERIFICATION=y
|
CONFIG_SYSTEM_DATA_VERIFICATION=y
|
||||||
|
@ -277,6 +280,7 @@ CONFIG_HAVE_NMI=y
|
||||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||||
CONFIG_HAVE_DMA_CONTIGUOUS=y
|
CONFIG_HAVE_DMA_CONTIGUOUS=y
|
||||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||||
|
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
|
||||||
CONFIG_ARCH_HAS_SET_MEMORY=y
|
CONFIG_ARCH_HAS_SET_MEMORY=y
|
||||||
CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
|
CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
|
||||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||||
|
@ -286,6 +290,7 @@ CONFIG_HAVE_HW_BREAKPOINT=y
|
||||||
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
|
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
|
||||||
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
|
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
|
||||||
CONFIG_HAVE_PERF_EVENTS_NMI=y
|
CONFIG_HAVE_PERF_EVENTS_NMI=y
|
||||||
|
CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
|
||||||
CONFIG_HAVE_PERF_REGS=y
|
CONFIG_HAVE_PERF_REGS=y
|
||||||
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
|
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
|
||||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||||
|
@ -304,6 +309,7 @@ CONFIG_CC_STACKPROTECTOR=y
|
||||||
# CONFIG_CC_STACKPROTECTOR_NONE is not set
|
# CONFIG_CC_STACKPROTECTOR_NONE is not set
|
||||||
# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
|
# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
|
||||||
CONFIG_CC_STACKPROTECTOR_STRONG=y
|
CONFIG_CC_STACKPROTECTOR_STRONG=y
|
||||||
|
CONFIG_THIN_ARCHIVES=y
|
||||||
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
|
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
|
||||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||||
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
||||||
|
@ -336,6 +342,7 @@ CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
|
||||||
CONFIG_STRICT_KERNEL_RWX=y
|
CONFIG_STRICT_KERNEL_RWX=y
|
||||||
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
|
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
|
||||||
CONFIG_STRICT_MODULE_RWX=y
|
CONFIG_STRICT_MODULE_RWX=y
|
||||||
|
# CONFIG_REFCOUNT_FULL is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# GCOV-based kernel profiling
|
# GCOV-based kernel profiling
|
||||||
|
@ -569,9 +576,9 @@ CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
|
||||||
CONFIG_SPARSEMEM_VMEMMAP=y
|
CONFIG_SPARSEMEM_VMEMMAP=y
|
||||||
CONFIG_HAVE_MEMBLOCK=y
|
CONFIG_HAVE_MEMBLOCK=y
|
||||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||||
|
CONFIG_HAVE_GENERIC_GUP=y
|
||||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||||
CONFIG_MEMORY_ISOLATION=y
|
CONFIG_MEMORY_ISOLATION=y
|
||||||
CONFIG_MOVABLE_NODE=y
|
|
||||||
CONFIG_HAVE_BOOTMEM_INFO_NODE=y
|
CONFIG_HAVE_BOOTMEM_INFO_NODE=y
|
||||||
CONFIG_MEMORY_HOTPLUG=y
|
CONFIG_MEMORY_HOTPLUG=y
|
||||||
CONFIG_MEMORY_HOTPLUG_SPARSE=y
|
CONFIG_MEMORY_HOTPLUG_SPARSE=y
|
||||||
|
@ -596,6 +603,8 @@ CONFIG_HWPOISON_INJECT=m
|
||||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||||
# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set
|
# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set
|
||||||
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
|
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
|
||||||
|
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||||
|
CONFIG_THP_SWAP=y
|
||||||
CONFIG_TRANSPARENT_HUGE_PAGECACHE=y
|
CONFIG_TRANSPARENT_HUGE_PAGECACHE=y
|
||||||
CONFIG_CLEANCACHE=y
|
CONFIG_CLEANCACHE=y
|
||||||
CONFIG_FRONTSWAP=y
|
CONFIG_FRONTSWAP=y
|
||||||
|
@ -615,10 +624,12 @@ CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||||
CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y
|
CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y
|
||||||
# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
|
# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
|
||||||
CONFIG_IDLE_PAGE_TRACKING=y
|
CONFIG_IDLE_PAGE_TRACKING=y
|
||||||
|
CONFIG_ARCH_HAS_ZONE_DEVICE=y
|
||||||
CONFIG_ZONE_DEVICE=y
|
CONFIG_ZONE_DEVICE=y
|
||||||
CONFIG_FRAME_VECTOR=y
|
CONFIG_FRAME_VECTOR=y
|
||||||
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
|
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
|
||||||
CONFIG_ARCH_HAS_PKEYS=y
|
CONFIG_ARCH_HAS_PKEYS=y
|
||||||
|
# CONFIG_PERCPU_STATS is not set
|
||||||
CONFIG_X86_PMEM_LEGACY_DEVICE=y
|
CONFIG_X86_PMEM_LEGACY_DEVICE=y
|
||||||
CONFIG_X86_PMEM_LEGACY=y
|
CONFIG_X86_PMEM_LEGACY=y
|
||||||
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
|
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
|
||||||
|
@ -834,6 +845,7 @@ CONFIG_PCI_STUB=m
|
||||||
CONFIG_XEN_PCIDEV_FRONTEND=m
|
CONFIG_XEN_PCIDEV_FRONTEND=m
|
||||||
CONFIG_HT_IRQ=y
|
CONFIG_HT_IRQ=y
|
||||||
CONFIG_PCI_ATS=y
|
CONFIG_PCI_ATS=y
|
||||||
|
CONFIG_PCI_LOCKLESS_CONFIG=y
|
||||||
CONFIG_PCI_IOV=y
|
CONFIG_PCI_IOV=y
|
||||||
CONFIG_PCI_PRI=y
|
CONFIG_PCI_PRI=y
|
||||||
CONFIG_PCI_PASID=y
|
CONFIG_PCI_PASID=y
|
||||||
|
@ -941,6 +953,7 @@ CONFIG_PACKET=y
|
||||||
CONFIG_PACKET_DIAG=m
|
CONFIG_PACKET_DIAG=m
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
CONFIG_UNIX_DIAG=m
|
CONFIG_UNIX_DIAG=m
|
||||||
|
# CONFIG_TLS is not set
|
||||||
CONFIG_XFRM=y
|
CONFIG_XFRM=y
|
||||||
CONFIG_XFRM_OFFLOAD=y
|
CONFIG_XFRM_OFFLOAD=y
|
||||||
CONFIG_XFRM_ALGO=m
|
CONFIG_XFRM_ALGO=m
|
||||||
|
@ -1448,10 +1461,10 @@ CONFIG_HAVE_NET_DSA=y
|
||||||
CONFIG_NET_DSA=m
|
CONFIG_NET_DSA=m
|
||||||
CONFIG_NET_DSA_TAG_DSA=y
|
CONFIG_NET_DSA_TAG_DSA=y
|
||||||
CONFIG_NET_DSA_TAG_EDSA=y
|
CONFIG_NET_DSA_TAG_EDSA=y
|
||||||
|
CONFIG_NET_DSA_TAG_LAN9303=y
|
||||||
|
CONFIG_NET_DSA_TAG_MTK=y
|
||||||
CONFIG_NET_DSA_TAG_TRAILER=y
|
CONFIG_NET_DSA_TAG_TRAILER=y
|
||||||
CONFIG_NET_DSA_TAG_QCA=y
|
CONFIG_NET_DSA_TAG_QCA=y
|
||||||
CONFIG_NET_DSA_TAG_MTK=y
|
|
||||||
CONFIG_NET_DSA_TAG_LAN9303=y
|
|
||||||
CONFIG_VLAN_8021Q=m
|
CONFIG_VLAN_8021Q=m
|
||||||
CONFIG_VLAN_8021Q_GVRP=y
|
CONFIG_VLAN_8021Q_GVRP=y
|
||||||
CONFIG_VLAN_8021Q_MVRP=y
|
CONFIG_VLAN_8021Q_MVRP=y
|
||||||
|
@ -1954,6 +1967,10 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
|
||||||
CONFIG_MTD_CMDLINE_PARTS=m
|
CONFIG_MTD_CMDLINE_PARTS=m
|
||||||
CONFIG_MTD_AR7_PARTS=m
|
CONFIG_MTD_AR7_PARTS=m
|
||||||
|
|
||||||
|
#
|
||||||
|
# Partition parsers
|
||||||
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# User Modules And Translation Layers
|
# User Modules And Translation Layers
|
||||||
#
|
#
|
||||||
|
@ -2028,6 +2045,7 @@ CONFIG_MTD_DATAFLASH=m
|
||||||
# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
|
# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
|
||||||
CONFIG_MTD_DATAFLASH_OTP=y
|
CONFIG_MTD_DATAFLASH_OTP=y
|
||||||
CONFIG_MTD_M25P80=m
|
CONFIG_MTD_M25P80=m
|
||||||
|
# CONFIG_MTD_MCHP23K256 is not set
|
||||||
CONFIG_MTD_SST25L=m
|
CONFIG_MTD_SST25L=m
|
||||||
CONFIG_MTD_SLRAM=m
|
CONFIG_MTD_SLRAM=m
|
||||||
CONFIG_MTD_PHRAM=m
|
CONFIG_MTD_PHRAM=m
|
||||||
|
@ -2061,8 +2079,6 @@ CONFIG_MTD_NAND_DOCG4=m
|
||||||
CONFIG_MTD_NAND_CAFE=m
|
CONFIG_MTD_NAND_CAFE=m
|
||||||
CONFIG_MTD_NAND_NANDSIM=m
|
CONFIG_MTD_NAND_NANDSIM=m
|
||||||
CONFIG_MTD_NAND_PLATFORM=m
|
CONFIG_MTD_NAND_PLATFORM=m
|
||||||
CONFIG_MTD_NAND_HISI504=m
|
|
||||||
CONFIG_MTD_NAND_MTK=m
|
|
||||||
CONFIG_MTD_ONENAND=m
|
CONFIG_MTD_ONENAND=m
|
||||||
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
|
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
|
||||||
CONFIG_MTD_ONENAND_GENERIC=m
|
CONFIG_MTD_ONENAND_GENERIC=m
|
||||||
|
@ -2167,7 +2183,6 @@ CONFIG_BLK_DEV_RBD=m
|
||||||
CONFIG_BLK_DEV_RSXX=m
|
CONFIG_BLK_DEV_RSXX=m
|
||||||
CONFIG_NVME_CORE=m
|
CONFIG_NVME_CORE=m
|
||||||
CONFIG_BLK_DEV_NVME=m
|
CONFIG_BLK_DEV_NVME=m
|
||||||
CONFIG_BLK_DEV_NVME_SCSI=y
|
|
||||||
CONFIG_NVME_FABRICS=m
|
CONFIG_NVME_FABRICS=m
|
||||||
CONFIG_NVME_RDMA=m
|
CONFIG_NVME_RDMA=m
|
||||||
CONFIG_NVME_FC=m
|
CONFIG_NVME_FC=m
|
||||||
|
@ -2285,6 +2300,7 @@ CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=0
|
||||||
CONFIG_ECHO=m
|
CONFIG_ECHO=m
|
||||||
# CONFIG_CXL_BASE is not set
|
# CONFIG_CXL_BASE is not set
|
||||||
# CONFIG_CXL_AFU_DRIVER_OPS is not set
|
# CONFIG_CXL_AFU_DRIVER_OPS is not set
|
||||||
|
# CONFIG_CXL_LIB is not set
|
||||||
CONFIG_HAVE_IDE=y
|
CONFIG_HAVE_IDE=y
|
||||||
# CONFIG_IDE is not set
|
# CONFIG_IDE is not set
|
||||||
|
|
||||||
|
@ -2584,6 +2600,7 @@ CONFIG_DM_VERITY=m
|
||||||
CONFIG_DM_SWITCH=m
|
CONFIG_DM_SWITCH=m
|
||||||
CONFIG_DM_LOG_WRITES=m
|
CONFIG_DM_LOG_WRITES=m
|
||||||
CONFIG_DM_INTEGRITY=m
|
CONFIG_DM_INTEGRITY=m
|
||||||
|
# CONFIG_DM_ZONED is not set
|
||||||
CONFIG_TARGET_CORE=m
|
CONFIG_TARGET_CORE=m
|
||||||
CONFIG_TCM_IBLOCK=m
|
CONFIG_TCM_IBLOCK=m
|
||||||
CONFIG_TCM_FILEIO=m
|
CONFIG_TCM_FILEIO=m
|
||||||
|
@ -2706,17 +2723,18 @@ CONFIG_CAIF_VIRTIO=m
|
||||||
#
|
#
|
||||||
# Distributed Switch Architecture drivers
|
# Distributed Switch Architecture drivers
|
||||||
#
|
#
|
||||||
CONFIG_NET_DSA_MV88E6060=m
|
|
||||||
CONFIG_B53=m
|
CONFIG_B53=m
|
||||||
CONFIG_B53_SPI_DRIVER=m
|
CONFIG_B53_SPI_DRIVER=m
|
||||||
CONFIG_B53_MDIO_DRIVER=m
|
CONFIG_B53_MDIO_DRIVER=m
|
||||||
CONFIG_B53_MMAP_DRIVER=m
|
CONFIG_B53_MMAP_DRIVER=m
|
||||||
CONFIG_B53_SRAB_DRIVER=m
|
CONFIG_B53_SRAB_DRIVER=m
|
||||||
|
# CONFIG_NET_DSA_LOOP is not set
|
||||||
|
CONFIG_NET_DSA_MT7530=m
|
||||||
|
CONFIG_NET_DSA_MV88E6060=m
|
||||||
|
# CONFIG_MICROCHIP_KSZ is not set
|
||||||
CONFIG_NET_DSA_MV88E6XXX=m
|
CONFIG_NET_DSA_MV88E6XXX=m
|
||||||
CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y
|
CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y
|
||||||
CONFIG_NET_DSA_QCA8K=m
|
CONFIG_NET_DSA_QCA8K=m
|
||||||
# CONFIG_NET_DSA_LOOP is not set
|
|
||||||
CONFIG_NET_DSA_MT7530=m
|
|
||||||
CONFIG_NET_DSA_SMSC_LAN9303=m
|
CONFIG_NET_DSA_SMSC_LAN9303=m
|
||||||
CONFIG_NET_DSA_SMSC_LAN9303_I2C=m
|
CONFIG_NET_DSA_SMSC_LAN9303_I2C=m
|
||||||
CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m
|
CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m
|
||||||
|
@ -2759,6 +2777,7 @@ CONFIG_NET_VENDOR_AURORA=y
|
||||||
CONFIG_AURORA_NB8800=m
|
CONFIG_AURORA_NB8800=m
|
||||||
CONFIG_NET_CADENCE=y
|
CONFIG_NET_CADENCE=y
|
||||||
CONFIG_MACB=m
|
CONFIG_MACB=m
|
||||||
|
CONFIG_MACB_USE_HWSTAMP=y
|
||||||
CONFIG_MACB_PCI=m
|
CONFIG_MACB_PCI=m
|
||||||
CONFIG_NET_VENDOR_BROADCOM=y
|
CONFIG_NET_VENDOR_BROADCOM=y
|
||||||
CONFIG_B44=m
|
CONFIG_B44=m
|
||||||
|
@ -2860,6 +2879,7 @@ CONFIG_MLX4_EN_DCB=y
|
||||||
CONFIG_MLX4_CORE=m
|
CONFIG_MLX4_CORE=m
|
||||||
CONFIG_MLX4_DEBUG=y
|
CONFIG_MLX4_DEBUG=y
|
||||||
CONFIG_MLX5_CORE=m
|
CONFIG_MLX5_CORE=m
|
||||||
|
# CONFIG_MLX5_FPGA is not set
|
||||||
CONFIG_MLX5_CORE_EN=y
|
CONFIG_MLX5_CORE_EN=y
|
||||||
CONFIG_MLX5_CORE_EN_DCB=y
|
CONFIG_MLX5_CORE_EN_DCB=y
|
||||||
CONFIG_MLX5_CORE_IPOIB=y
|
CONFIG_MLX5_CORE_IPOIB=y
|
||||||
|
@ -2873,6 +2893,7 @@ CONFIG_MLXSW_SWITCHX2=m
|
||||||
CONFIG_MLXSW_SPECTRUM=m
|
CONFIG_MLXSW_SPECTRUM=m
|
||||||
CONFIG_MLXSW_SPECTRUM_DCB=y
|
CONFIG_MLXSW_SPECTRUM_DCB=y
|
||||||
CONFIG_MLXSW_MINIMAL=m
|
CONFIG_MLXSW_MINIMAL=m
|
||||||
|
CONFIG_MLXFW=m
|
||||||
CONFIG_NET_VENDOR_MICREL=y
|
CONFIG_NET_VENDOR_MICREL=y
|
||||||
CONFIG_KS8842=m
|
CONFIG_KS8842=m
|
||||||
CONFIG_KS8851=m
|
CONFIG_KS8851=m
|
||||||
|
@ -2891,6 +2912,7 @@ CONFIG_NATSEMI=m
|
||||||
CONFIG_NS83820=m
|
CONFIG_NS83820=m
|
||||||
CONFIG_NET_VENDOR_NETRONOME=y
|
CONFIG_NET_VENDOR_NETRONOME=y
|
||||||
CONFIG_NFP=m
|
CONFIG_NFP=m
|
||||||
|
# CONFIG_NFP_APP_FLOWER is not set
|
||||||
# CONFIG_NFP_DEBUG is not set
|
# CONFIG_NFP_DEBUG is not set
|
||||||
CONFIG_NET_VENDOR_8390=y
|
CONFIG_NET_VENDOR_8390=y
|
||||||
CONFIG_PCMCIA_AXNET=m
|
CONFIG_PCMCIA_AXNET=m
|
||||||
|
@ -2994,6 +3016,7 @@ CONFIG_SKFP=m
|
||||||
# CONFIG_HIPPI is not set
|
# CONFIG_HIPPI is not set
|
||||||
CONFIG_NET_SB1000=m
|
CONFIG_NET_SB1000=m
|
||||||
CONFIG_MDIO_DEVICE=y
|
CONFIG_MDIO_DEVICE=y
|
||||||
|
CONFIG_MDIO_BUS=y
|
||||||
CONFIG_MDIO_BITBANG=m
|
CONFIG_MDIO_BITBANG=m
|
||||||
CONFIG_MDIO_CAVIUM=m
|
CONFIG_MDIO_CAVIUM=m
|
||||||
CONFIG_MDIO_GPIO=m
|
CONFIG_MDIO_GPIO=m
|
||||||
|
@ -3013,6 +3036,7 @@ CONFIG_BCM87XX_PHY=m
|
||||||
CONFIG_BCM_NET_PHYLIB=m
|
CONFIG_BCM_NET_PHYLIB=m
|
||||||
CONFIG_BROADCOM_PHY=m
|
CONFIG_BROADCOM_PHY=m
|
||||||
CONFIG_CICADA_PHY=m
|
CONFIG_CICADA_PHY=m
|
||||||
|
# CONFIG_CORTINA_PHY is not set
|
||||||
CONFIG_DAVICOM_PHY=m
|
CONFIG_DAVICOM_PHY=m
|
||||||
CONFIG_DP83848_PHY=m
|
CONFIG_DP83848_PHY=m
|
||||||
CONFIG_DP83867_PHY=m
|
CONFIG_DP83867_PHY=m
|
||||||
|
@ -3022,6 +3046,7 @@ CONFIG_INTEL_XWAY_PHY=m
|
||||||
CONFIG_LSI_ET1011C_PHY=m
|
CONFIG_LSI_ET1011C_PHY=m
|
||||||
CONFIG_LXT_PHY=m
|
CONFIG_LXT_PHY=m
|
||||||
CONFIG_MARVELL_PHY=m
|
CONFIG_MARVELL_PHY=m
|
||||||
|
# CONFIG_MARVELL_10G_PHY is not set
|
||||||
CONFIG_MICREL_PHY=m
|
CONFIG_MICREL_PHY=m
|
||||||
CONFIG_MICROCHIP_PHY=m
|
CONFIG_MICROCHIP_PHY=m
|
||||||
CONFIG_MICROSEMI_PHY=m
|
CONFIG_MICROSEMI_PHY=m
|
||||||
|
@ -3140,6 +3165,7 @@ CONFIG_WIL6210_ISR_COR=y
|
||||||
CONFIG_WIL6210_TRACING=y
|
CONFIG_WIL6210_TRACING=y
|
||||||
CONFIG_ATH10K=m
|
CONFIG_ATH10K=m
|
||||||
CONFIG_ATH10K_PCI=m
|
CONFIG_ATH10K_PCI=m
|
||||||
|
# CONFIG_ATH10K_SDIO is not set
|
||||||
# CONFIG_ATH10K_DEBUG is not set
|
# CONFIG_ATH10K_DEBUG is not set
|
||||||
CONFIG_ATH10K_DEBUGFS=y
|
CONFIG_ATH10K_DEBUGFS=y
|
||||||
CONFIG_ATH10K_TRACING=y
|
CONFIG_ATH10K_TRACING=y
|
||||||
|
@ -3344,6 +3370,8 @@ CONFIG_WLAN_VENDOR_ZYDAS=y
|
||||||
CONFIG_USB_ZD1201=m
|
CONFIG_USB_ZD1201=m
|
||||||
CONFIG_ZD1211RW=m
|
CONFIG_ZD1211RW=m
|
||||||
# CONFIG_ZD1211RW_DEBUG is not set
|
# CONFIG_ZD1211RW_DEBUG is not set
|
||||||
|
CONFIG_WLAN_VENDOR_QUANTENNA=y
|
||||||
|
# CONFIG_QTNFMAC_PEARL_PCIE is not set
|
||||||
CONFIG_PCMCIA_RAYCS=m
|
CONFIG_PCMCIA_RAYCS=m
|
||||||
CONFIG_PCMCIA_WL3501=m
|
CONFIG_PCMCIA_WL3501=m
|
||||||
CONFIG_MAC80211_HWSIM=m
|
CONFIG_MAC80211_HWSIM=m
|
||||||
|
@ -3556,6 +3584,7 @@ CONFIG_KEYBOARD_ADP5589=m
|
||||||
CONFIG_KEYBOARD_ATKBD=y
|
CONFIG_KEYBOARD_ATKBD=y
|
||||||
CONFIG_KEYBOARD_QT1070=m
|
CONFIG_KEYBOARD_QT1070=m
|
||||||
CONFIG_KEYBOARD_QT2160=m
|
CONFIG_KEYBOARD_QT2160=m
|
||||||
|
# CONFIG_KEYBOARD_DLINK_DIR685 is not set
|
||||||
CONFIG_KEYBOARD_LKKBD=m
|
CONFIG_KEYBOARD_LKKBD=m
|
||||||
CONFIG_KEYBOARD_GPIO=m
|
CONFIG_KEYBOARD_GPIO=m
|
||||||
CONFIG_KEYBOARD_GPIO_POLLED=m
|
CONFIG_KEYBOARD_GPIO_POLLED=m
|
||||||
|
@ -3730,6 +3759,7 @@ CONFIG_TOUCHSCREEN_RM_TS=m
|
||||||
CONFIG_TOUCHSCREEN_SILEAD=m
|
CONFIG_TOUCHSCREEN_SILEAD=m
|
||||||
CONFIG_TOUCHSCREEN_SIS_I2C=m
|
CONFIG_TOUCHSCREEN_SIS_I2C=m
|
||||||
CONFIG_TOUCHSCREEN_ST1232=m
|
CONFIG_TOUCHSCREEN_ST1232=m
|
||||||
|
# CONFIG_TOUCHSCREEN_STMFTS is not set
|
||||||
CONFIG_TOUCHSCREEN_SUR40=m
|
CONFIG_TOUCHSCREEN_SUR40=m
|
||||||
CONFIG_TOUCHSCREEN_SURFACE3_SPI=m
|
CONFIG_TOUCHSCREEN_SURFACE3_SPI=m
|
||||||
CONFIG_TOUCHSCREEN_SX8654=m
|
CONFIG_TOUCHSCREEN_SX8654=m
|
||||||
|
@ -3930,6 +3960,7 @@ CONFIG_HVC_XEN=y
|
||||||
CONFIG_HVC_XEN_FRONTEND=y
|
CONFIG_HVC_XEN_FRONTEND=y
|
||||||
CONFIG_VIRTIO_CONSOLE=y
|
CONFIG_VIRTIO_CONSOLE=y
|
||||||
CONFIG_IPMI_HANDLER=m
|
CONFIG_IPMI_HANDLER=m
|
||||||
|
CONFIG_IPMI_DMI_DECODE=y
|
||||||
# CONFIG_IPMI_PANIC_EVENT is not set
|
# CONFIG_IPMI_PANIC_EVENT is not set
|
||||||
CONFIG_IPMI_DEVICE_INTERFACE=m
|
CONFIG_IPMI_DEVICE_INTERFACE=m
|
||||||
CONFIG_IPMI_SI=m
|
CONFIG_IPMI_SI=m
|
||||||
|
@ -4042,8 +4073,9 @@ CONFIG_I2C_SCMI=m
|
||||||
# I2C system bus drivers (mostly embedded / system-on-chip)
|
# I2C system bus drivers (mostly embedded / system-on-chip)
|
||||||
#
|
#
|
||||||
CONFIG_I2C_CBUS_GPIO=m
|
CONFIG_I2C_CBUS_GPIO=m
|
||||||
CONFIG_I2C_DESIGNWARE_CORE=m
|
CONFIG_I2C_DESIGNWARE_CORE=y
|
||||||
CONFIG_I2C_DESIGNWARE_PLATFORM=m
|
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||||
|
# CONFIG_I2C_DESIGNWARE_SLAVE is not set
|
||||||
CONFIG_I2C_DESIGNWARE_PCI=m
|
CONFIG_I2C_DESIGNWARE_PCI=m
|
||||||
CONFIG_I2C_DESIGNWARE_BAYTRAIL=y
|
CONFIG_I2C_DESIGNWARE_BAYTRAIL=y
|
||||||
# CONFIG_I2C_EMEV2 is not set
|
# CONFIG_I2C_EMEV2 is not set
|
||||||
|
@ -4111,6 +4143,7 @@ CONFIG_SPI_ZYNQMP_GQSPI=m
|
||||||
CONFIG_SPI_SPIDEV=m
|
CONFIG_SPI_SPIDEV=m
|
||||||
CONFIG_SPI_LOOPBACK_TEST=m
|
CONFIG_SPI_LOOPBACK_TEST=m
|
||||||
CONFIG_SPI_TLE62X0=m
|
CONFIG_SPI_TLE62X0=m
|
||||||
|
# CONFIG_SPI_SLAVE is not set
|
||||||
CONFIG_SPMI=m
|
CONFIG_SPMI=m
|
||||||
CONFIG_HSI=m
|
CONFIG_HSI=m
|
||||||
CONFIG_HSI_BOARDINFO=y
|
CONFIG_HSI_BOARDINFO=y
|
||||||
|
@ -4123,10 +4156,6 @@ CONFIG_HSI_BOARDINFO=y
|
||||||
# HSI clients
|
# HSI clients
|
||||||
#
|
#
|
||||||
CONFIG_HSI_CHAR=m
|
CONFIG_HSI_CHAR=m
|
||||||
|
|
||||||
#
|
|
||||||
# PPS support
|
|
||||||
#
|
|
||||||
CONFIG_PPS=m
|
CONFIG_PPS=m
|
||||||
# CONFIG_PPS_DEBUG is not set
|
# CONFIG_PPS_DEBUG is not set
|
||||||
|
|
||||||
|
@ -4161,11 +4190,13 @@ CONFIG_PINCONF=y
|
||||||
CONFIG_GENERIC_PINCONF=y
|
CONFIG_GENERIC_PINCONF=y
|
||||||
# CONFIG_DEBUG_PINCTRL is not set
|
# CONFIG_DEBUG_PINCTRL is not set
|
||||||
CONFIG_PINCTRL_AMD=y
|
CONFIG_PINCTRL_AMD=y
|
||||||
|
# CONFIG_PINCTRL_MCP23S08 is not set
|
||||||
CONFIG_PINCTRL_SX150X=y
|
CONFIG_PINCTRL_SX150X=y
|
||||||
CONFIG_PINCTRL_BAYTRAIL=y
|
CONFIG_PINCTRL_BAYTRAIL=y
|
||||||
CONFIG_PINCTRL_CHERRYVIEW=y
|
CONFIG_PINCTRL_CHERRYVIEW=y
|
||||||
CONFIG_PINCTRL_INTEL=m
|
CONFIG_PINCTRL_INTEL=m
|
||||||
CONFIG_PINCTRL_BROXTON=m
|
CONFIG_PINCTRL_BROXTON=m
|
||||||
|
# CONFIG_PINCTRL_CANNONLAKE is not set
|
||||||
CONFIG_PINCTRL_GEMINILAKE=m
|
CONFIG_PINCTRL_GEMINILAKE=m
|
||||||
CONFIG_PINCTRL_SUNRISEPOINT=m
|
CONFIG_PINCTRL_SUNRISEPOINT=m
|
||||||
CONFIG_GPIOLIB=y
|
CONFIG_GPIOLIB=y
|
||||||
|
@ -4256,10 +4287,7 @@ CONFIG_GPIO_RDC321X=m
|
||||||
CONFIG_GPIO_MAX7301=m
|
CONFIG_GPIO_MAX7301=m
|
||||||
CONFIG_GPIO_MC33880=m
|
CONFIG_GPIO_MC33880=m
|
||||||
CONFIG_GPIO_PISOSR=m
|
CONFIG_GPIO_PISOSR=m
|
||||||
|
# CONFIG_GPIO_XRA1403 is not set
|
||||||
#
|
|
||||||
# SPI or I2C GPIO expanders
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# USB GPIO expanders
|
# USB GPIO expanders
|
||||||
|
@ -4318,6 +4346,7 @@ CONFIG_BATTERY_SBS=m
|
||||||
CONFIG_CHARGER_SBS=m
|
CONFIG_CHARGER_SBS=m
|
||||||
CONFIG_BATTERY_BQ27XXX=m
|
CONFIG_BATTERY_BQ27XXX=m
|
||||||
CONFIG_BATTERY_BQ27XXX_I2C=m
|
CONFIG_BATTERY_BQ27XXX_I2C=m
|
||||||
|
# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set
|
||||||
CONFIG_BATTERY_DA9030=m
|
CONFIG_BATTERY_DA9030=m
|
||||||
CONFIG_BATTERY_DA9052=m
|
CONFIG_BATTERY_DA9052=m
|
||||||
CONFIG_CHARGER_DA9150=m
|
CONFIG_CHARGER_DA9150=m
|
||||||
|
@ -4340,6 +4369,7 @@ CONFIG_CHARGER_LP8727=m
|
||||||
CONFIG_CHARGER_LP8788=m
|
CONFIG_CHARGER_LP8788=m
|
||||||
CONFIG_CHARGER_GPIO=m
|
CONFIG_CHARGER_GPIO=m
|
||||||
CONFIG_CHARGER_MANAGER=y
|
CONFIG_CHARGER_MANAGER=y
|
||||||
|
# CONFIG_CHARGER_LTC3651 is not set
|
||||||
CONFIG_CHARGER_MAX14577=m
|
CONFIG_CHARGER_MAX14577=m
|
||||||
CONFIG_CHARGER_MAX77693=m
|
CONFIG_CHARGER_MAX77693=m
|
||||||
CONFIG_CHARGER_MAX8997=m
|
CONFIG_CHARGER_MAX8997=m
|
||||||
|
@ -4465,6 +4495,7 @@ CONFIG_SENSORS_PCF8591=m
|
||||||
CONFIG_PMBUS=m
|
CONFIG_PMBUS=m
|
||||||
CONFIG_SENSORS_PMBUS=m
|
CONFIG_SENSORS_PMBUS=m
|
||||||
CONFIG_SENSORS_ADM1275=m
|
CONFIG_SENSORS_ADM1275=m
|
||||||
|
# CONFIG_SENSORS_IR35221 is not set
|
||||||
CONFIG_SENSORS_LM25066=m
|
CONFIG_SENSORS_LM25066=m
|
||||||
CONFIG_SENSORS_LTC2978=m
|
CONFIG_SENSORS_LTC2978=m
|
||||||
CONFIG_SENSORS_LTC2978_REGULATOR=y
|
CONFIG_SENSORS_LTC2978_REGULATOR=y
|
||||||
|
@ -4563,6 +4594,7 @@ CONFIG_GENERIC_ADC_THERMAL=m
|
||||||
CONFIG_WATCHDOG=y
|
CONFIG_WATCHDOG=y
|
||||||
CONFIG_WATCHDOG_CORE=y
|
CONFIG_WATCHDOG_CORE=y
|
||||||
# CONFIG_WATCHDOG_NOWAYOUT is not set
|
# CONFIG_WATCHDOG_NOWAYOUT is not set
|
||||||
|
CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
|
||||||
CONFIG_WATCHDOG_SYSFS=y
|
CONFIG_WATCHDOG_SYSFS=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -4712,6 +4744,7 @@ CONFIG_LPC_ICH=m
|
||||||
CONFIG_LPC_SCH=m
|
CONFIG_LPC_SCH=m
|
||||||
CONFIG_INTEL_SOC_PMIC=y
|
CONFIG_INTEL_SOC_PMIC=y
|
||||||
CONFIG_INTEL_SOC_PMIC_BXTWC=m
|
CONFIG_INTEL_SOC_PMIC_BXTWC=m
|
||||||
|
# CONFIG_INTEL_SOC_PMIC_CHTWC is not set
|
||||||
CONFIG_MFD_INTEL_LPSS=m
|
CONFIG_MFD_INTEL_LPSS=m
|
||||||
CONFIG_MFD_INTEL_LPSS_ACPI=m
|
CONFIG_MFD_INTEL_LPSS_ACPI=m
|
||||||
CONFIG_MFD_INTEL_LPSS_PCI=m
|
CONFIG_MFD_INTEL_LPSS_PCI=m
|
||||||
|
@ -4903,6 +4936,7 @@ CONFIG_VIDEO_PCI_SKELETON=m
|
||||||
CONFIG_VIDEO_TUNER=m
|
CONFIG_VIDEO_TUNER=m
|
||||||
CONFIG_V4L2_MEM2MEM_DEV=m
|
CONFIG_V4L2_MEM2MEM_DEV=m
|
||||||
CONFIG_V4L2_FLASH_LED_CLASS=m
|
CONFIG_V4L2_FLASH_LED_CLASS=m
|
||||||
|
CONFIG_V4L2_FWNODE=m
|
||||||
CONFIG_VIDEOBUF_GEN=m
|
CONFIG_VIDEOBUF_GEN=m
|
||||||
CONFIG_VIDEOBUF_DMA_SG=m
|
CONFIG_VIDEOBUF_DMA_SG=m
|
||||||
CONFIG_VIDEOBUF_VMALLOC=m
|
CONFIG_VIDEOBUF_VMALLOC=m
|
||||||
|
@ -5224,6 +5258,7 @@ CONFIG_VIDEO_VIVID_MAX_DEVS=64
|
||||||
CONFIG_VIDEO_VIM2M=m
|
CONFIG_VIDEO_VIM2M=m
|
||||||
CONFIG_DVB_PLATFORM_DRIVERS=y
|
CONFIG_DVB_PLATFORM_DRIVERS=y
|
||||||
CONFIG_CEC_PLATFORM_DRIVERS=y
|
CONFIG_CEC_PLATFORM_DRIVERS=y
|
||||||
|
# CONFIG_SDR_PLATFORM_DRIVERS is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Supported MMC/SDIO adapters
|
# Supported MMC/SDIO adapters
|
||||||
|
@ -5366,6 +5401,10 @@ CONFIG_VIDEO_UPD64083=m
|
||||||
#
|
#
|
||||||
CONFIG_VIDEO_SAA6752HS=m
|
CONFIG_VIDEO_SAA6752HS=m
|
||||||
|
|
||||||
|
#
|
||||||
|
# SDR tuner chips
|
||||||
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Miscellaneous helper chips
|
# Miscellaneous helper chips
|
||||||
#
|
#
|
||||||
|
@ -5641,6 +5680,7 @@ CONFIG_DRM_I915_GVT_KVMGT=m
|
||||||
# CONFIG_DRM_I915_WERROR is not set
|
# CONFIG_DRM_I915_WERROR is not set
|
||||||
# CONFIG_DRM_I915_DEBUG is not set
|
# CONFIG_DRM_I915_DEBUG is not set
|
||||||
# CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS is not set
|
# CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS is not set
|
||||||
|
# CONFIG_DRM_I915_SW_FENCE_CHECK_DAG is not set
|
||||||
# CONFIG_DRM_I915_SELFTEST is not set
|
# CONFIG_DRM_I915_SELFTEST is not set
|
||||||
# CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS is not set
|
# CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS is not set
|
||||||
# CONFIG_DRM_I915_DEBUG_VBLANK_EVADE is not set
|
# CONFIG_DRM_I915_DEBUG_VBLANK_EVADE is not set
|
||||||
|
@ -5663,6 +5703,7 @@ CONFIG_DRM_PANEL=y
|
||||||
# Display Panels
|
# Display Panels
|
||||||
#
|
#
|
||||||
CONFIG_DRM_BRIDGE=y
|
CONFIG_DRM_BRIDGE=y
|
||||||
|
CONFIG_DRM_PANEL_BRIDGE=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Display Interface Bridges
|
# Display Interface Bridges
|
||||||
|
@ -5864,19 +5905,16 @@ CONFIG_SND_PCM_ELD=y
|
||||||
CONFIG_SND_PCM_IEC958=y
|
CONFIG_SND_PCM_IEC958=y
|
||||||
CONFIG_SND_DMAENGINE_PCM=m
|
CONFIG_SND_DMAENGINE_PCM=m
|
||||||
CONFIG_SND_HWDEP=m
|
CONFIG_SND_HWDEP=m
|
||||||
|
CONFIG_SND_SEQ_DEVICE=m
|
||||||
CONFIG_SND_RAWMIDI=m
|
CONFIG_SND_RAWMIDI=m
|
||||||
CONFIG_SND_COMPRESS_OFFLOAD=m
|
CONFIG_SND_COMPRESS_OFFLOAD=m
|
||||||
CONFIG_SND_JACK=y
|
CONFIG_SND_JACK=y
|
||||||
CONFIG_SND_JACK_INPUT_DEV=y
|
CONFIG_SND_JACK_INPUT_DEV=y
|
||||||
CONFIG_SND_SEQUENCER=m
|
|
||||||
CONFIG_SND_SEQ_DUMMY=m
|
|
||||||
CONFIG_SND_OSSEMUL=y
|
CONFIG_SND_OSSEMUL=y
|
||||||
CONFIG_SND_MIXER_OSS=m
|
CONFIG_SND_MIXER_OSS=m
|
||||||
# CONFIG_SND_PCM_OSS is not set
|
# CONFIG_SND_PCM_OSS is not set
|
||||||
CONFIG_SND_PCM_TIMER=y
|
CONFIG_SND_PCM_TIMER=y
|
||||||
# CONFIG_SND_SEQUENCER_OSS is not set
|
|
||||||
CONFIG_SND_HRTIMER=m
|
CONFIG_SND_HRTIMER=m
|
||||||
CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
|
|
||||||
CONFIG_SND_DYNAMIC_MINORS=y
|
CONFIG_SND_DYNAMIC_MINORS=y
|
||||||
CONFIG_SND_MAX_CARDS=32
|
CONFIG_SND_MAX_CARDS=32
|
||||||
CONFIG_SND_SUPPORT_OLD_API=y
|
CONFIG_SND_SUPPORT_OLD_API=y
|
||||||
|
@ -5886,13 +5924,18 @@ CONFIG_SND_VERBOSE_PROCFS=y
|
||||||
# CONFIG_SND_DEBUG is not set
|
# CONFIG_SND_DEBUG is not set
|
||||||
CONFIG_SND_VMASTER=y
|
CONFIG_SND_VMASTER=y
|
||||||
CONFIG_SND_DMA_SGBUF=y
|
CONFIG_SND_DMA_SGBUF=y
|
||||||
CONFIG_SND_RAWMIDI_SEQ=m
|
CONFIG_SND_SEQUENCER=m
|
||||||
CONFIG_SND_OPL3_LIB_SEQ=m
|
CONFIG_SND_SEQ_DUMMY=m
|
||||||
# CONFIG_SND_OPL4_LIB_SEQ is not set
|
# CONFIG_SND_SEQUENCER_OSS is not set
|
||||||
# CONFIG_SND_SBAWE_SEQ is not set
|
CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
|
||||||
CONFIG_SND_EMU10K1_SEQ=m
|
CONFIG_SND_SEQ_MIDI_EVENT=m
|
||||||
|
CONFIG_SND_SEQ_MIDI=m
|
||||||
|
CONFIG_SND_SEQ_MIDI_EMUL=m
|
||||||
|
CONFIG_SND_SEQ_VIRMIDI=m
|
||||||
CONFIG_SND_MPU401_UART=m
|
CONFIG_SND_MPU401_UART=m
|
||||||
CONFIG_SND_OPL3_LIB=m
|
CONFIG_SND_OPL3_LIB=m
|
||||||
|
CONFIG_SND_OPL3_LIB_SEQ=m
|
||||||
|
# CONFIG_SND_OPL4_LIB_SEQ is not set
|
||||||
CONFIG_SND_VX_LIB=m
|
CONFIG_SND_VX_LIB=m
|
||||||
CONFIG_SND_AC97_CODEC=m
|
CONFIG_SND_AC97_CODEC=m
|
||||||
CONFIG_SND_DRIVERS=y
|
CONFIG_SND_DRIVERS=y
|
||||||
|
@ -5946,6 +5989,7 @@ CONFIG_SND_INDIGODJ=m
|
||||||
CONFIG_SND_INDIGOIOX=m
|
CONFIG_SND_INDIGOIOX=m
|
||||||
CONFIG_SND_INDIGODJX=m
|
CONFIG_SND_INDIGODJX=m
|
||||||
CONFIG_SND_EMU10K1=m
|
CONFIG_SND_EMU10K1=m
|
||||||
|
CONFIG_SND_EMU10K1_SEQ=m
|
||||||
CONFIG_SND_EMU10K1X=m
|
CONFIG_SND_EMU10K1X=m
|
||||||
CONFIG_SND_ENS1370=m
|
CONFIG_SND_ENS1370=m
|
||||||
CONFIG_SND_ENS1371=m
|
CONFIG_SND_ENS1371=m
|
||||||
|
@ -6090,11 +6134,18 @@ CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH=m
|
||||||
CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH=m
|
CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH=m
|
||||||
CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH=m
|
CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH=m
|
||||||
CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m
|
CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH=m
|
||||||
|
# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set
|
||||||
CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=m
|
CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=m
|
||||||
|
# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set
|
||||||
|
# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set
|
||||||
CONFIG_SND_SOC_INTEL_SKYLAKE=m
|
CONFIG_SND_SOC_INTEL_SKYLAKE=m
|
||||||
CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m
|
CONFIG_SND_SOC_INTEL_SKL_RT286_MACH=m
|
||||||
CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH=m
|
CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH=m
|
||||||
CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH=m
|
CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH=m
|
||||||
|
|
||||||
|
#
|
||||||
|
# STMicroelectronics STM32 SOC audio support
|
||||||
|
#
|
||||||
CONFIG_SND_SOC_XTFPGA_I2S=m
|
CONFIG_SND_SOC_XTFPGA_I2S=m
|
||||||
CONFIG_ZX_TDM=m
|
CONFIG_ZX_TDM=m
|
||||||
CONFIG_SND_SOC_I2C_AND_SPI=m
|
CONFIG_SND_SOC_I2C_AND_SPI=m
|
||||||
|
@ -6142,6 +6193,7 @@ CONFIG_SND_SOC_DIO2125=m
|
||||||
CONFIG_SND_SOC_DMIC=m
|
CONFIG_SND_SOC_DMIC=m
|
||||||
CONFIG_SND_SOC_HDMI_CODEC=m
|
CONFIG_SND_SOC_HDMI_CODEC=m
|
||||||
CONFIG_SND_SOC_ES7134=m
|
CONFIG_SND_SOC_ES7134=m
|
||||||
|
# CONFIG_SND_SOC_ES8316 is not set
|
||||||
CONFIG_SND_SOC_ES8328=m
|
CONFIG_SND_SOC_ES8328=m
|
||||||
CONFIG_SND_SOC_ES8328_I2C=m
|
CONFIG_SND_SOC_ES8328_I2C=m
|
||||||
CONFIG_SND_SOC_ES8328_SPI=m
|
CONFIG_SND_SOC_ES8328_SPI=m
|
||||||
|
@ -6223,6 +6275,7 @@ CONFIG_SND_SOC_WM8962=m
|
||||||
CONFIG_SND_SOC_WM8974=m
|
CONFIG_SND_SOC_WM8974=m
|
||||||
CONFIG_SND_SOC_WM8978=m
|
CONFIG_SND_SOC_WM8978=m
|
||||||
CONFIG_SND_SOC_WM8985=m
|
CONFIG_SND_SOC_WM8985=m
|
||||||
|
# CONFIG_SND_SOC_ZX_AUD96P22 is not set
|
||||||
CONFIG_SND_SOC_NAU8540=m
|
CONFIG_SND_SOC_NAU8540=m
|
||||||
CONFIG_SND_SOC_NAU8810=m
|
CONFIG_SND_SOC_NAU8810=m
|
||||||
CONFIG_SND_SOC_NAU8824=m
|
CONFIG_SND_SOC_NAU8824=m
|
||||||
|
@ -6232,6 +6285,7 @@ CONFIG_SND_SIMPLE_CARD_UTILS=m
|
||||||
CONFIG_SND_SIMPLE_CARD=m
|
CONFIG_SND_SIMPLE_CARD=m
|
||||||
CONFIG_SND_X86=y
|
CONFIG_SND_X86=y
|
||||||
CONFIG_HDMI_LPE_AUDIO=m
|
CONFIG_HDMI_LPE_AUDIO=m
|
||||||
|
CONFIG_SND_SYNTH_EMUX=m
|
||||||
CONFIG_AC97_BUS=m
|
CONFIG_AC97_BUS=m
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -6280,6 +6334,7 @@ CONFIG_HID_UCLOGIC=m
|
||||||
CONFIG_HID_WALTOP=m
|
CONFIG_HID_WALTOP=m
|
||||||
CONFIG_HID_GYRATION=m
|
CONFIG_HID_GYRATION=m
|
||||||
CONFIG_HID_ICADE=m
|
CONFIG_HID_ICADE=m
|
||||||
|
# CONFIG_HID_ITE is not set
|
||||||
CONFIG_HID_TWINHAN=m
|
CONFIG_HID_TWINHAN=m
|
||||||
CONFIG_HID_KENSINGTON=m
|
CONFIG_HID_KENSINGTON=m
|
||||||
CONFIG_HID_LCPOWER=m
|
CONFIG_HID_LCPOWER=m
|
||||||
|
@ -6312,6 +6367,7 @@ CONFIG_HID_PICOLCD_LEDS=y
|
||||||
CONFIG_HID_PICOLCD_CIR=y
|
CONFIG_HID_PICOLCD_CIR=y
|
||||||
CONFIG_HID_PLANTRONICS=m
|
CONFIG_HID_PLANTRONICS=m
|
||||||
CONFIG_HID_PRIMAX=m
|
CONFIG_HID_PRIMAX=m
|
||||||
|
# CONFIG_HID_RETRODE is not set
|
||||||
CONFIG_HID_ROCCAT=m
|
CONFIG_HID_ROCCAT=m
|
||||||
CONFIG_HID_SAITEK=m
|
CONFIG_HID_SAITEK=m
|
||||||
CONFIG_HID_SAMSUNG=m
|
CONFIG_HID_SAMSUNG=m
|
||||||
|
@ -6610,7 +6666,6 @@ CONFIG_USB_HSIC_USB3503=m
|
||||||
CONFIG_USB_HSIC_USB4604=m
|
CONFIG_USB_HSIC_USB4604=m
|
||||||
CONFIG_USB_LINK_LAYER_TEST=m
|
CONFIG_USB_LINK_LAYER_TEST=m
|
||||||
CONFIG_USB_CHAOSKEY=m
|
CONFIG_USB_CHAOSKEY=m
|
||||||
CONFIG_UCSI=m
|
|
||||||
CONFIG_USB_ATM=m
|
CONFIG_USB_ATM=m
|
||||||
CONFIG_USB_SPEEDTOUCH=m
|
CONFIG_USB_SPEEDTOUCH=m
|
||||||
CONFIG_USB_CXACRU=m
|
CONFIG_USB_CXACRU=m
|
||||||
|
@ -6663,6 +6718,7 @@ CONFIG_USB_F_ACM=m
|
||||||
CONFIG_USB_F_SS_LB=m
|
CONFIG_USB_F_SS_LB=m
|
||||||
CONFIG_USB_U_SERIAL=m
|
CONFIG_USB_U_SERIAL=m
|
||||||
CONFIG_USB_U_ETHER=m
|
CONFIG_USB_U_ETHER=m
|
||||||
|
CONFIG_USB_U_AUDIO=m
|
||||||
CONFIG_USB_F_SERIAL=m
|
CONFIG_USB_F_SERIAL=m
|
||||||
CONFIG_USB_F_OBEX=m
|
CONFIG_USB_F_OBEX=m
|
||||||
CONFIG_USB_F_NCM=m
|
CONFIG_USB_F_NCM=m
|
||||||
|
@ -6694,6 +6750,7 @@ CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||||
CONFIG_USB_CONFIGFS_F_LB_SS=y
|
CONFIG_USB_CONFIGFS_F_LB_SS=y
|
||||||
CONFIG_USB_CONFIGFS_F_FS=y
|
CONFIG_USB_CONFIGFS_F_FS=y
|
||||||
CONFIG_USB_CONFIGFS_F_UAC1=y
|
CONFIG_USB_CONFIGFS_F_UAC1=y
|
||||||
|
# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
|
||||||
CONFIG_USB_CONFIGFS_F_UAC2=y
|
CONFIG_USB_CONFIGFS_F_UAC2=y
|
||||||
CONFIG_USB_CONFIGFS_F_MIDI=y
|
CONFIG_USB_CONFIGFS_F_MIDI=y
|
||||||
CONFIG_USB_CONFIGFS_F_HID=y
|
CONFIG_USB_CONFIGFS_F_HID=y
|
||||||
|
@ -6703,6 +6760,7 @@ CONFIG_USB_CONFIGFS_F_TCM=y
|
||||||
CONFIG_USB_ZERO=m
|
CONFIG_USB_ZERO=m
|
||||||
CONFIG_USB_AUDIO=m
|
CONFIG_USB_AUDIO=m
|
||||||
CONFIG_GADGET_UAC1=y
|
CONFIG_GADGET_UAC1=y
|
||||||
|
# CONFIG_GADGET_UAC1_LEGACY is not set
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_USB_ETH=m
|
||||||
CONFIG_USB_ETH_RNDIS=y
|
CONFIG_USB_ETH_RNDIS=y
|
||||||
CONFIG_USB_ETH_EEM=y
|
CONFIG_USB_ETH_EEM=y
|
||||||
|
@ -6731,6 +6789,7 @@ CONFIG_USB_G_WEBCAM=m
|
||||||
# USB Power Delivery and Type-C drivers
|
# USB Power Delivery and Type-C drivers
|
||||||
#
|
#
|
||||||
CONFIG_TYPEC=m
|
CONFIG_TYPEC=m
|
||||||
|
# CONFIG_TYPEC_UCSI is not set
|
||||||
CONFIG_USB_LED_TRIG=y
|
CONFIG_USB_LED_TRIG=y
|
||||||
CONFIG_USB_ULPI_BUS=m
|
CONFIG_USB_ULPI_BUS=m
|
||||||
CONFIG_UWB=m
|
CONFIG_UWB=m
|
||||||
|
@ -6741,7 +6800,6 @@ CONFIG_MMC=y
|
||||||
# CONFIG_MMC_DEBUG is not set
|
# CONFIG_MMC_DEBUG is not set
|
||||||
CONFIG_MMC_BLOCK=m
|
CONFIG_MMC_BLOCK=m
|
||||||
CONFIG_MMC_BLOCK_MINORS=8
|
CONFIG_MMC_BLOCK_MINORS=8
|
||||||
CONFIG_MMC_BLOCK_BOUNCE=y
|
|
||||||
CONFIG_SDIO_UART=m
|
CONFIG_SDIO_UART=m
|
||||||
# CONFIG_MMC_TEST is not set
|
# CONFIG_MMC_TEST is not set
|
||||||
|
|
||||||
|
@ -6929,6 +6987,7 @@ CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
|
||||||
CONFIG_RTC_SYSTOHC=y
|
CONFIG_RTC_SYSTOHC=y
|
||||||
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
|
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
|
||||||
# CONFIG_RTC_DEBUG is not set
|
# CONFIG_RTC_DEBUG is not set
|
||||||
|
CONFIG_RTC_NVMEM=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# RTC interfaces
|
# RTC interfaces
|
||||||
|
@ -7007,6 +7066,7 @@ CONFIG_RTC_I2C_AND_SPI=y
|
||||||
# SPI and I2C RTC drivers
|
# SPI and I2C RTC drivers
|
||||||
#
|
#
|
||||||
CONFIG_RTC_DRV_DS3232=m
|
CONFIG_RTC_DRV_DS3232=m
|
||||||
|
CONFIG_RTC_DRV_DS3232_HWMON=y
|
||||||
CONFIG_RTC_DRV_PCF2127=m
|
CONFIG_RTC_DRV_PCF2127=m
|
||||||
CONFIG_RTC_DRV_RV3029C2=m
|
CONFIG_RTC_DRV_RV3029C2=m
|
||||||
CONFIG_RTC_DRV_RV3029_HWMON=y
|
CONFIG_RTC_DRV_RV3029_HWMON=y
|
||||||
|
@ -7047,6 +7107,7 @@ CONFIG_RTC_DRV_AB3100=m
|
||||||
#
|
#
|
||||||
# on-CPU RTC drivers
|
# on-CPU RTC drivers
|
||||||
#
|
#
|
||||||
|
# CONFIG_RTC_DRV_FTRTC010 is not set
|
||||||
CONFIG_RTC_DRV_PCAP=m
|
CONFIG_RTC_DRV_PCAP=m
|
||||||
CONFIG_RTC_DRV_MC13XXX=m
|
CONFIG_RTC_DRV_MC13XXX=m
|
||||||
CONFIG_RTC_DRV_MT6397=m
|
CONFIG_RTC_DRV_MT6397=m
|
||||||
|
@ -7383,7 +7444,6 @@ CONFIG_AD5933=m
|
||||||
#
|
#
|
||||||
# Light sensors
|
# Light sensors
|
||||||
#
|
#
|
||||||
CONFIG_SENSORS_ISL29028=m
|
|
||||||
CONFIG_TSL2x7x=m
|
CONFIG_TSL2x7x=m
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -7543,6 +7603,7 @@ CONFIG_GREYBUS_USB=m
|
||||||
CONFIG_TYPEC_TCPM=m
|
CONFIG_TYPEC_TCPM=m
|
||||||
CONFIG_TYPEC_TCPCI=m
|
CONFIG_TYPEC_TCPCI=m
|
||||||
CONFIG_TYPEC_FUSB302=m
|
CONFIG_TYPEC_FUSB302=m
|
||||||
|
# CONFIG_DRM_VBOXVIDEO is not set
|
||||||
CONFIG_X86_PLATFORM_DEVICES=y
|
CONFIG_X86_PLATFORM_DEVICES=y
|
||||||
CONFIG_ACER_WMI=m
|
CONFIG_ACER_WMI=m
|
||||||
CONFIG_ACERHDF=m
|
CONFIG_ACERHDF=m
|
||||||
|
@ -7556,7 +7617,6 @@ CONFIG_DELL_WMI_LED=m
|
||||||
CONFIG_DELL_SMO8800=m
|
CONFIG_DELL_SMO8800=m
|
||||||
CONFIG_DELL_RBTN=m
|
CONFIG_DELL_RBTN=m
|
||||||
CONFIG_FUJITSU_LAPTOP=m
|
CONFIG_FUJITSU_LAPTOP=m
|
||||||
# CONFIG_FUJITSU_LAPTOP_DEBUG is not set
|
|
||||||
CONFIG_FUJITSU_TABLET=m
|
CONFIG_FUJITSU_TABLET=m
|
||||||
CONFIG_AMILO_RFKILL=m
|
CONFIG_AMILO_RFKILL=m
|
||||||
CONFIG_HP_ACCEL=m
|
CONFIG_HP_ACCEL=m
|
||||||
|
@ -7584,7 +7644,9 @@ CONFIG_ASUS_NB_WMI=m
|
||||||
CONFIG_EEEPC_WMI=m
|
CONFIG_EEEPC_WMI=m
|
||||||
CONFIG_ASUS_WIRELESS=m
|
CONFIG_ASUS_WIRELESS=m
|
||||||
CONFIG_ACPI_WMI=m
|
CONFIG_ACPI_WMI=m
|
||||||
|
CONFIG_WMI_BMOF=m
|
||||||
CONFIG_MSI_WMI=m
|
CONFIG_MSI_WMI=m
|
||||||
|
# CONFIG_PEAQ_WMI is not set
|
||||||
CONFIG_TOPSTAR_LAPTOP=m
|
CONFIG_TOPSTAR_LAPTOP=m
|
||||||
CONFIG_ACPI_TOSHIBA=m
|
CONFIG_ACPI_TOSHIBA=m
|
||||||
CONFIG_TOSHIBA_BT_RFKILL=m
|
CONFIG_TOSHIBA_BT_RFKILL=m
|
||||||
|
@ -7592,6 +7654,7 @@ CONFIG_TOSHIBA_HAPS=m
|
||||||
# CONFIG_TOSHIBA_WMI is not set
|
# CONFIG_TOSHIBA_WMI is not set
|
||||||
CONFIG_ACPI_CMPC=m
|
CONFIG_ACPI_CMPC=m
|
||||||
CONFIG_INTEL_CHT_INT33FE=m
|
CONFIG_INTEL_CHT_INT33FE=m
|
||||||
|
# CONFIG_INTEL_INT0002_VGPIO is not set
|
||||||
CONFIG_INTEL_HID_EVENT=m
|
CONFIG_INTEL_HID_EVENT=m
|
||||||
CONFIG_INTEL_VBTN=m
|
CONFIG_INTEL_VBTN=m
|
||||||
CONFIG_INTEL_IPS=m
|
CONFIG_INTEL_IPS=m
|
||||||
|
@ -7621,6 +7684,7 @@ CONFIG_CHROMEOS_LAPTOP=m
|
||||||
CONFIG_CHROMEOS_PSTORE=m
|
CONFIG_CHROMEOS_PSTORE=m
|
||||||
CONFIG_CROS_EC_CHARDEV=m
|
CONFIG_CROS_EC_CHARDEV=m
|
||||||
CONFIG_CROS_EC_LPC=m
|
CONFIG_CROS_EC_LPC=m
|
||||||
|
# CONFIG_CROS_EC_LPC_MEC is not set
|
||||||
CONFIG_CROS_EC_PROTO=y
|
CONFIG_CROS_EC_PROTO=y
|
||||||
CONFIG_CROS_KBD_LED_BACKLIGHT=m
|
CONFIG_CROS_KBD_LED_BACKLIGHT=m
|
||||||
CONFIG_CLKDEV_LOOKUP=y
|
CONFIG_CLKDEV_LOOKUP=y
|
||||||
|
@ -7641,10 +7705,7 @@ CONFIG_COMMON_CLK_PALMAS=m
|
||||||
CONFIG_COMMON_CLK_PWM=m
|
CONFIG_COMMON_CLK_PWM=m
|
||||||
# CONFIG_COMMON_CLK_PXA is not set
|
# CONFIG_COMMON_CLK_PXA is not set
|
||||||
# CONFIG_COMMON_CLK_PIC32 is not set
|
# CONFIG_COMMON_CLK_PIC32 is not set
|
||||||
|
# CONFIG_HWSPINLOCK is not set
|
||||||
#
|
|
||||||
# Hardware Spinlock drivers
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clock Source drivers
|
# Clock Source drivers
|
||||||
|
@ -7684,6 +7745,7 @@ CONFIG_REMOTEPROC=m
|
||||||
#
|
#
|
||||||
# Rpmsg drivers
|
# Rpmsg drivers
|
||||||
#
|
#
|
||||||
|
# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# SOC (System On Chip) specific Drivers
|
# SOC (System On Chip) specific Drivers
|
||||||
|
@ -7698,8 +7760,6 @@ CONFIG_REMOTEPROC=m
|
||||||
#
|
#
|
||||||
# CONFIG_SUNXI_SRAM is not set
|
# CONFIG_SUNXI_SRAM is not set
|
||||||
CONFIG_SOC_TI=y
|
CONFIG_SOC_TI=y
|
||||||
CONFIG_SOC_ZTE=y
|
|
||||||
CONFIG_ZX2967_PM_DOMAINS=y
|
|
||||||
CONFIG_PM_DEVFREQ=y
|
CONFIG_PM_DEVFREQ=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -7731,7 +7791,6 @@ CONFIG_EXTCON_MAX77693=m
|
||||||
CONFIG_EXTCON_MAX77843=m
|
CONFIG_EXTCON_MAX77843=m
|
||||||
CONFIG_EXTCON_MAX8997=m
|
CONFIG_EXTCON_MAX8997=m
|
||||||
CONFIG_EXTCON_PALMAS=m
|
CONFIG_EXTCON_PALMAS=m
|
||||||
CONFIG_EXTCON_QCOM_SPMI_MISC=m
|
|
||||||
CONFIG_EXTCON_RT8973A=m
|
CONFIG_EXTCON_RT8973A=m
|
||||||
CONFIG_EXTCON_SM5502=m
|
CONFIG_EXTCON_SM5502=m
|
||||||
CONFIG_EXTCON_USB_GPIO=m
|
CONFIG_EXTCON_USB_GPIO=m
|
||||||
|
@ -7823,7 +7882,9 @@ CONFIG_QCOM_SPMI_VADC=m
|
||||||
CONFIG_STX104=m
|
CONFIG_STX104=m
|
||||||
CONFIG_TI_ADC081C=m
|
CONFIG_TI_ADC081C=m
|
||||||
CONFIG_TI_ADC0832=m
|
CONFIG_TI_ADC0832=m
|
||||||
|
# CONFIG_TI_ADC084S021 is not set
|
||||||
CONFIG_TI_ADC12138=m
|
CONFIG_TI_ADC12138=m
|
||||||
|
# CONFIG_TI_ADC108S102 is not set
|
||||||
CONFIG_TI_ADC128S052=m
|
CONFIG_TI_ADC128S052=m
|
||||||
CONFIG_TI_ADC161S626=m
|
CONFIG_TI_ADC161S626=m
|
||||||
CONFIG_TI_ADS1015=m
|
CONFIG_TI_ADS1015=m
|
||||||
|
@ -7998,6 +8059,7 @@ CONFIG_CM36651=m
|
||||||
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
|
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
|
||||||
CONFIG_GP2AP020A00F=m
|
CONFIG_GP2AP020A00F=m
|
||||||
CONFIG_SENSORS_ISL29018=m
|
CONFIG_SENSORS_ISL29018=m
|
||||||
|
CONFIG_SENSORS_ISL29028=m
|
||||||
CONFIG_ISL29125=m
|
CONFIG_ISL29125=m
|
||||||
CONFIG_HID_SENSOR_ALS=m
|
CONFIG_HID_SENSOR_ALS=m
|
||||||
CONFIG_HID_SENSOR_PROX=m
|
CONFIG_HID_SENSOR_PROX=m
|
||||||
|
@ -8038,6 +8100,10 @@ CONFIG_SENSORS_HMC5843=m
|
||||||
CONFIG_SENSORS_HMC5843_I2C=m
|
CONFIG_SENSORS_HMC5843_I2C=m
|
||||||
CONFIG_SENSORS_HMC5843_SPI=m
|
CONFIG_SENSORS_HMC5843_SPI=m
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multiplexers
|
||||||
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Inclinometer sensors
|
# Inclinometer sensors
|
||||||
#
|
#
|
||||||
|
@ -8119,6 +8185,7 @@ CONFIG_TSYS01=m
|
||||||
CONFIG_TSYS02D=m
|
CONFIG_TSYS02D=m
|
||||||
CONFIG_NTB=m
|
CONFIG_NTB=m
|
||||||
# CONFIG_NTB_AMD is not set
|
# CONFIG_NTB_AMD is not set
|
||||||
|
# CONFIG_NTB_IDT is not set
|
||||||
CONFIG_NTB_INTEL=m
|
CONFIG_NTB_INTEL=m
|
||||||
CONFIG_NTB_PINGPONG=m
|
CONFIG_NTB_PINGPONG=m
|
||||||
CONFIG_NTB_TOOL=m
|
CONFIG_NTB_TOOL=m
|
||||||
|
@ -8161,6 +8228,7 @@ CONFIG_SERIAL_IPOCTAL=m
|
||||||
CONFIG_RESET_CONTROLLER=y
|
CONFIG_RESET_CONTROLLER=y
|
||||||
# CONFIG_RESET_ATH79 is not set
|
# CONFIG_RESET_ATH79 is not set
|
||||||
# CONFIG_RESET_BERLIN is not set
|
# CONFIG_RESET_BERLIN is not set
|
||||||
|
# CONFIG_RESET_GEMINI is not set
|
||||||
# CONFIG_RESET_IMX7 is not set
|
# CONFIG_RESET_IMX7 is not set
|
||||||
# CONFIG_RESET_LPC18XX is not set
|
# CONFIG_RESET_LPC18XX is not set
|
||||||
# CONFIG_RESET_MESON is not set
|
# CONFIG_RESET_MESON is not set
|
||||||
|
@ -8168,7 +8236,7 @@ CONFIG_RESET_CONTROLLER=y
|
||||||
# CONFIG_RESET_SOCFPGA is not set
|
# CONFIG_RESET_SOCFPGA is not set
|
||||||
# CONFIG_RESET_STM32 is not set
|
# CONFIG_RESET_STM32 is not set
|
||||||
# CONFIG_RESET_SUNXI is not set
|
# CONFIG_RESET_SUNXI is not set
|
||||||
CONFIG_TI_SYSCON_RESET=m
|
# CONFIG_RESET_TI_SYSCON is not set
|
||||||
# CONFIG_RESET_ZYNQ is not set
|
# CONFIG_RESET_ZYNQ is not set
|
||||||
# CONFIG_RESET_TEGRA_BPMP is not set
|
# CONFIG_RESET_TEGRA_BPMP is not set
|
||||||
CONFIG_FMC=m
|
CONFIG_FMC=m
|
||||||
|
@ -8181,15 +8249,16 @@ CONFIG_FMC_CHARDEV=m
|
||||||
# PHY Subsystem
|
# PHY Subsystem
|
||||||
#
|
#
|
||||||
CONFIG_GENERIC_PHY=y
|
CONFIG_GENERIC_PHY=y
|
||||||
|
CONFIG_BCM_KONA_USB2_PHY=m
|
||||||
CONFIG_PHY_PXA_28NM_HSIC=m
|
CONFIG_PHY_PXA_28NM_HSIC=m
|
||||||
CONFIG_PHY_PXA_28NM_USB2=m
|
CONFIG_PHY_PXA_28NM_USB2=m
|
||||||
CONFIG_BCM_KONA_USB2_PHY=m
|
# CONFIG_PHY_CPCAP_USB is not set
|
||||||
|
CONFIG_PHY_QCOM_USB_HS=m
|
||||||
|
CONFIG_PHY_QCOM_USB_HSIC=m
|
||||||
CONFIG_PHY_SAMSUNG_USB2=m
|
CONFIG_PHY_SAMSUNG_USB2=m
|
||||||
# CONFIG_PHY_EXYNOS4210_USB2 is not set
|
# CONFIG_PHY_EXYNOS4210_USB2 is not set
|
||||||
# CONFIG_PHY_EXYNOS4X12_USB2 is not set
|
# CONFIG_PHY_EXYNOS4X12_USB2 is not set
|
||||||
# CONFIG_PHY_EXYNOS5250_USB2 is not set
|
# CONFIG_PHY_EXYNOS5250_USB2 is not set
|
||||||
CONFIG_PHY_QCOM_USB_HS=m
|
|
||||||
CONFIG_PHY_QCOM_USB_HSIC=m
|
|
||||||
CONFIG_PHY_TUSB1210=m
|
CONFIG_PHY_TUSB1210=m
|
||||||
CONFIG_POWERCAP=y
|
CONFIG_POWERCAP=y
|
||||||
CONFIG_INTEL_RAPL=m
|
CONFIG_INTEL_RAPL=m
|
||||||
|
@ -8201,7 +8270,6 @@ CONFIG_MCB_LPC=m
|
||||||
# Performance monitor support
|
# Performance monitor support
|
||||||
#
|
#
|
||||||
CONFIG_RAS=y
|
CONFIG_RAS=y
|
||||||
CONFIG_MCE_AMD_INJ=m
|
|
||||||
CONFIG_RAS_CEC=y
|
CONFIG_RAS_CEC=y
|
||||||
CONFIG_THUNDERBOLT=m
|
CONFIG_THUNDERBOLT=m
|
||||||
|
|
||||||
|
@ -8221,7 +8289,7 @@ CONFIG_NVDIMM_DAX=y
|
||||||
CONFIG_DAX=y
|
CONFIG_DAX=y
|
||||||
CONFIG_DEV_DAX=m
|
CONFIG_DEV_DAX=m
|
||||||
CONFIG_DEV_DAX_PMEM=m
|
CONFIG_DEV_DAX_PMEM=m
|
||||||
CONFIG_NVMEM=m
|
CONFIG_NVMEM=y
|
||||||
CONFIG_STM=m
|
CONFIG_STM=m
|
||||||
CONFIG_STM_DUMMY=m
|
CONFIG_STM_DUMMY=m
|
||||||
CONFIG_STM_SOURCE_CONSOLE=m
|
CONFIG_STM_SOURCE_CONSOLE=m
|
||||||
|
@ -8246,6 +8314,9 @@ CONFIG_ALTERA_PR_IP_CORE=m
|
||||||
# FSI support
|
# FSI support
|
||||||
#
|
#
|
||||||
CONFIG_FSI=m
|
CONFIG_FSI=m
|
||||||
|
# CONFIG_FSI_MASTER_GPIO is not set
|
||||||
|
# CONFIG_FSI_MASTER_HUB is not set
|
||||||
|
# CONFIG_FSI_SCOM is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Firmware Drivers
|
# Firmware Drivers
|
||||||
|
@ -8370,6 +8441,7 @@ CONFIG_FUSE_FS=y
|
||||||
CONFIG_CUSE=m
|
CONFIG_CUSE=m
|
||||||
CONFIG_OVERLAY_FS=m
|
CONFIG_OVERLAY_FS=m
|
||||||
# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
|
# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
|
||||||
|
# CONFIG_OVERLAY_FS_INDEX is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
# Caches
|
# Caches
|
||||||
|
@ -8559,8 +8631,8 @@ CONFIG_CIFS_POSIX=y
|
||||||
CONFIG_CIFS_ACL=y
|
CONFIG_CIFS_ACL=y
|
||||||
CONFIG_CIFS_DEBUG=y
|
CONFIG_CIFS_DEBUG=y
|
||||||
# CONFIG_CIFS_DEBUG2 is not set
|
# CONFIG_CIFS_DEBUG2 is not set
|
||||||
|
# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set
|
||||||
CONFIG_CIFS_DFS_UPCALL=y
|
CONFIG_CIFS_DFS_UPCALL=y
|
||||||
CONFIG_CIFS_SMB2=y
|
|
||||||
CONFIG_CIFS_SMB311=y
|
CONFIG_CIFS_SMB311=y
|
||||||
CONFIG_CIFS_FSCACHE=y
|
CONFIG_CIFS_FSCACHE=y
|
||||||
CONFIG_NCP_FS=m
|
CONFIG_NCP_FS=m
|
||||||
|
@ -8709,6 +8781,9 @@ CONFIG_ARCH_HAS_KCOV=y
|
||||||
# Debug Lockups and Hangs
|
# Debug Lockups and Hangs
|
||||||
#
|
#
|
||||||
CONFIG_LOCKUP_DETECTOR=y
|
CONFIG_LOCKUP_DETECTOR=y
|
||||||
|
CONFIG_SOFTLOCKUP_DETECTOR=y
|
||||||
|
CONFIG_HARDLOCKUP_DETECTOR_PERF=y
|
||||||
|
CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
|
||||||
CONFIG_HARDLOCKUP_DETECTOR=y
|
CONFIG_HARDLOCKUP_DETECTOR=y
|
||||||
# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
|
# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
|
||||||
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
|
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
|
||||||
|
@ -8743,6 +8818,7 @@ CONFIG_SCHED_STACK_END_CHECK=y
|
||||||
# CONFIG_LOCK_TORTURE_TEST is not set
|
# CONFIG_LOCK_TORTURE_TEST is not set
|
||||||
# CONFIG_WW_MUTEX_SELFTEST is not set
|
# CONFIG_WW_MUTEX_SELFTEST is not set
|
||||||
CONFIG_STACKTRACE=y
|
CONFIG_STACKTRACE=y
|
||||||
|
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
|
||||||
# CONFIG_DEBUG_KOBJECT is not set
|
# CONFIG_DEBUG_KOBJECT is not set
|
||||||
CONFIG_DEBUG_BUGVERBOSE=y
|
CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
# CONFIG_DEBUG_LIST is not set
|
# CONFIG_DEBUG_LIST is not set
|
||||||
|
@ -8755,7 +8831,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
|
||||||
# RCU Debugging
|
# RCU Debugging
|
||||||
#
|
#
|
||||||
# CONFIG_PROVE_RCU is not set
|
# CONFIG_PROVE_RCU is not set
|
||||||
# CONFIG_SPARSE_RCU_POINTER is not set
|
|
||||||
CONFIG_TORTURE_TEST=m
|
CONFIG_TORTURE_TEST=m
|
||||||
CONFIG_RCU_PERF_TEST=m
|
CONFIG_RCU_PERF_TEST=m
|
||||||
# CONFIG_RCU_TORTURE_TEST is not set
|
# CONFIG_RCU_TORTURE_TEST is not set
|
||||||
|
@ -8819,7 +8894,7 @@ CONFIG_HIST_TRIGGERS=y
|
||||||
# CONFIG_TRACEPOINT_BENCHMARK is not set
|
# CONFIG_TRACEPOINT_BENCHMARK is not set
|
||||||
# CONFIG_RING_BUFFER_BENCHMARK is not set
|
# CONFIG_RING_BUFFER_BENCHMARK is not set
|
||||||
# CONFIG_RING_BUFFER_STARTUP_TEST is not set
|
# CONFIG_RING_BUFFER_STARTUP_TEST is not set
|
||||||
# CONFIG_TRACE_ENUM_MAP_FILE is not set
|
# CONFIG_TRACE_EVAL_MAP_FILE is not set
|
||||||
CONFIG_TRACING_EVENTS_GPIO=y
|
CONFIG_TRACING_EVENTS_GPIO=y
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -8850,10 +8925,12 @@ CONFIG_TEST_LKM=m
|
||||||
CONFIG_TEST_USER_COPY=m
|
CONFIG_TEST_USER_COPY=m
|
||||||
CONFIG_TEST_BPF=m
|
CONFIG_TEST_BPF=m
|
||||||
CONFIG_TEST_FIRMWARE=m
|
CONFIG_TEST_FIRMWARE=m
|
||||||
|
# CONFIG_TEST_SYSCTL is not set
|
||||||
CONFIG_TEST_UDELAY=m
|
CONFIG_TEST_UDELAY=m
|
||||||
CONFIG_MEMTEST=y
|
CONFIG_MEMTEST=y
|
||||||
CONFIG_TEST_STATIC_KEYS=m
|
CONFIG_TEST_STATIC_KEYS=m
|
||||||
# CONFIG_BUG_ON_DATA_CORRUPTION is not set
|
# CONFIG_BUG_ON_DATA_CORRUPTION is not set
|
||||||
|
# CONFIG_TEST_KMOD is not set
|
||||||
# CONFIG_SAMPLES is not set
|
# CONFIG_SAMPLES is not set
|
||||||
CONFIG_HAVE_ARCH_KGDB=y
|
CONFIG_HAVE_ARCH_KGDB=y
|
||||||
CONFIG_KGDB=y
|
CONFIG_KGDB=y
|
||||||
|
@ -8918,6 +8995,7 @@ CONFIG_SECURITY=y
|
||||||
# CONFIG_SECURITY_WRITABLE_HOOKS is not set
|
# CONFIG_SECURITY_WRITABLE_HOOKS is not set
|
||||||
CONFIG_SECURITYFS=y
|
CONFIG_SECURITYFS=y
|
||||||
CONFIG_SECURITY_NETWORK=y
|
CONFIG_SECURITY_NETWORK=y
|
||||||
|
# CONFIG_SECURITY_INFINIBAND is not set
|
||||||
CONFIG_SECURITY_NETWORK_XFRM=y
|
CONFIG_SECURITY_NETWORK_XFRM=y
|
||||||
CONFIG_SECURITY_PATH=y
|
CONFIG_SECURITY_PATH=y
|
||||||
CONFIG_INTEL_TXT=y
|
CONFIG_INTEL_TXT=y
|
||||||
|
@ -8925,6 +9003,7 @@ CONFIG_LSM_MMAP_MIN_ADDR=0
|
||||||
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
|
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
|
||||||
CONFIG_HARDENED_USERCOPY=y
|
CONFIG_HARDENED_USERCOPY=y
|
||||||
# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
|
# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
|
||||||
|
# CONFIG_FORTIFY_SOURCE is not set
|
||||||
# CONFIG_STATIC_USERMODEHELPER is not set
|
# CONFIG_STATIC_USERMODEHELPER is not set
|
||||||
CONFIG_SECURITY_SELINUX=y
|
CONFIG_SECURITY_SELINUX=y
|
||||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||||
|
@ -8965,11 +9044,11 @@ CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
|
||||||
CONFIG_IMA_DEFAULT_HASH_SHA1=y
|
CONFIG_IMA_DEFAULT_HASH_SHA1=y
|
||||||
# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set
|
# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set
|
||||||
# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
|
# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
|
||||||
# CONFIG_IMA_DEFAULT_HASH_WP512 is not set
|
|
||||||
CONFIG_IMA_DEFAULT_HASH="sha1"
|
CONFIG_IMA_DEFAULT_HASH="sha1"
|
||||||
# CONFIG_IMA_WRITE_POLICY is not set
|
# CONFIG_IMA_WRITE_POLICY is not set
|
||||||
# CONFIG_IMA_READ_POLICY is not set
|
# CONFIG_IMA_READ_POLICY is not set
|
||||||
CONFIG_IMA_APPRAISE=y
|
CONFIG_IMA_APPRAISE=y
|
||||||
|
CONFIG_IMA_APPRAISE_BOOTPARAM=y
|
||||||
CONFIG_IMA_TRUSTED_KEYRING=y
|
CONFIG_IMA_TRUSTED_KEYRING=y
|
||||||
# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set
|
# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set
|
||||||
# CONFIG_IMA_BLACKLIST_KEYRING is not set
|
# CONFIG_IMA_BLACKLIST_KEYRING is not set
|
||||||
|
@ -9175,6 +9254,7 @@ CONFIG_CRYPTO_DEV_QAT_DH895xCC=m
|
||||||
CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m
|
CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=m
|
||||||
# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
|
# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
|
||||||
# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
|
# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
|
||||||
|
# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
|
||||||
CONFIG_CRYPTO_DEV_CHELSIO=m
|
CONFIG_CRYPTO_DEV_CHELSIO=m
|
||||||
CONFIG_CRYPTO_DEV_VIRTIO=m
|
CONFIG_CRYPTO_DEV_VIRTIO=m
|
||||||
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
CONFIG_ASYMMETRIC_KEY_TYPE=y
|
||||||
|
@ -9246,6 +9326,7 @@ CONFIG_CRC32_SLICEBY8=y
|
||||||
# CONFIG_CRC32_SLICEBY4 is not set
|
# CONFIG_CRC32_SLICEBY4 is not set
|
||||||
# CONFIG_CRC32_SARWATE is not set
|
# CONFIG_CRC32_SARWATE is not set
|
||||||
# CONFIG_CRC32_BIT is not set
|
# CONFIG_CRC32_BIT is not set
|
||||||
|
CONFIG_CRC4=m
|
||||||
CONFIG_CRC7=m
|
CONFIG_CRC7=m
|
||||||
CONFIG_LIBCRC32C=m
|
CONFIG_LIBCRC32C=m
|
||||||
CONFIG_CRC8=m
|
CONFIG_CRC8=m
|
||||||
|
@ -9319,6 +9400,7 @@ CONFIG_FONT_8x16=y
|
||||||
CONFIG_SG_POOL=y
|
CONFIG_SG_POOL=y
|
||||||
CONFIG_ARCH_HAS_SG_CHAIN=y
|
CONFIG_ARCH_HAS_SG_CHAIN=y
|
||||||
CONFIG_ARCH_HAS_PMEM_API=y
|
CONFIG_ARCH_HAS_PMEM_API=y
|
||||||
|
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
|
||||||
CONFIG_ARCH_HAS_MMIO_FLUSH=y
|
CONFIG_ARCH_HAS_MMIO_FLUSH=y
|
||||||
CONFIG_SBITMAP=y
|
CONFIG_SBITMAP=y
|
||||||
CONFIG_PARMAN=m
|
CONFIG_PARMAN=m
|
||||||
|
|
|
@ -24,8 +24,6 @@ DMA-ISA-LPC.txt
|
||||||
- How to do DMA with ISA (and LPC) devices.
|
- How to do DMA with ISA (and LPC) devices.
|
||||||
DMA-attributes.txt
|
DMA-attributes.txt
|
||||||
- listing of the various possible attributes a DMA region can have
|
- listing of the various possible attributes a DMA region can have
|
||||||
DocBook/
|
|
||||||
- directory with DocBook templates etc. for kernel documentation.
|
|
||||||
EDID/
|
EDID/
|
||||||
- directory with info on customizing EDID for broken gfx/displays.
|
- directory with info on customizing EDID for broken gfx/displays.
|
||||||
IPMI.txt
|
IPMI.txt
|
||||||
|
@ -40,8 +38,6 @@ Intel-IOMMU.txt
|
||||||
- basic info on the Intel IOMMU virtualization support.
|
- basic info on the Intel IOMMU virtualization support.
|
||||||
Makefile
|
Makefile
|
||||||
- It's not of interest for those who aren't touching the build system.
|
- It's not of interest for those who aren't touching the build system.
|
||||||
Makefile.sphinx
|
|
||||||
- It's not of interest for those who aren't touching the build system.
|
|
||||||
PCI/
|
PCI/
|
||||||
- info related to PCI drivers.
|
- info related to PCI drivers.
|
||||||
RCU/
|
RCU/
|
||||||
|
@ -246,8 +242,6 @@ kprobes.txt
|
||||||
- documents the kernel probes debugging feature.
|
- documents the kernel probes debugging feature.
|
||||||
kref.txt
|
kref.txt
|
||||||
- docs on adding reference counters (krefs) to kernel objects.
|
- docs on adding reference counters (krefs) to kernel objects.
|
||||||
kselftest.txt
|
|
||||||
- small unittests for (some) individual codepaths in the kernel.
|
|
||||||
laptops/
|
laptops/
|
||||||
- directory with laptop related info and laptop driver documentation.
|
- directory with laptop related info and laptop driver documentation.
|
||||||
ldm.txt
|
ldm.txt
|
||||||
|
@ -264,6 +258,8 @@ logo.gif
|
||||||
- full colour GIF image of Linux logo (penguin - Tux).
|
- full colour GIF image of Linux logo (penguin - Tux).
|
||||||
logo.txt
|
logo.txt
|
||||||
- info on creator of above logo & site to get additional images from.
|
- info on creator of above logo & site to get additional images from.
|
||||||
|
lsm.txt
|
||||||
|
- Linux Security Modules: General Security Hooks for Linux
|
||||||
lzo.txt
|
lzo.txt
|
||||||
- kernel LZO decompressor input formats
|
- kernel LZO decompressor input formats
|
||||||
m68k/
|
m68k/
|
||||||
|
|
|
@ -55,14 +55,6 @@ Description:
|
||||||
Indicates the maximum USB speed supported by this port.
|
Indicates the maximum USB speed supported by this port.
|
||||||
Users:
|
Users:
|
||||||
|
|
||||||
What: /sys/class/udc/<udc>/maximum_speed
|
|
||||||
Date: June 2011
|
|
||||||
KernelVersion: 3.1
|
|
||||||
Contact: Felipe Balbi <balbi@kernel.org>
|
|
||||||
Description:
|
|
||||||
Indicates the maximum USB speed supported by this port.
|
|
||||||
Users:
|
|
||||||
|
|
||||||
What: /sys/class/udc/<udc>/soft_connect
|
What: /sys/class/udc/<udc>/soft_connect
|
||||||
Date: June 2011
|
Date: June 2011
|
||||||
KernelVersion: 3.1
|
KernelVersion: 3.1
|
||||||
|
@ -91,3 +83,11 @@ Description:
|
||||||
'configured', and 'suspended'; however not all USB Device
|
'configured', and 'suspended'; however not all USB Device
|
||||||
Controllers support reporting all states.
|
Controllers support reporting all states.
|
||||||
Users:
|
Users:
|
||||||
|
|
||||||
|
What: /sys/class/udc/<udc>/function
|
||||||
|
Date: June 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: Felipe Balbi <balbi@kernel.org>
|
||||||
|
Description:
|
||||||
|
Prints out name of currently running USB Gadget Driver.
|
||||||
|
Users:
|
||||||
|
|
15
kernel/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
Normal file
15
kernel/Documentation/ABI/stable/sysfs-driver-aspeed-vuart
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
What: /sys/bus/platform/drivers/aspeed-vuart/*/lpc_address
|
||||||
|
Date: April 2017
|
||||||
|
Contact: Jeremy Kerr <jk@ozlabs.org>
|
||||||
|
Description: Configures which IO port the host side of the UART
|
||||||
|
will appear on the host <-> BMC LPC bus.
|
||||||
|
Users: OpenBMC. Proposed changes should be mailed to
|
||||||
|
openbmc@lists.ozlabs.org
|
||||||
|
|
||||||
|
What: /sys/bus/platform/drivers/aspeed-vuart*/sirq
|
||||||
|
Date: April 2017
|
||||||
|
Contact: Jeremy Kerr <jk@ozlabs.org>
|
||||||
|
Description: Configures which interrupt number the host side of
|
||||||
|
the UART will appear on the host <-> BMC LPC bus.
|
||||||
|
Users: OpenBMC. Proposed changes should be mailed to
|
||||||
|
openbmc@lists.ozlabs.org
|
119
kernel/Documentation/ABI/stable/sysfs-hypervisor-xen
Normal file
119
kernel/Documentation/ABI/stable/sysfs-hypervisor-xen
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
What: /sys/hypervisor/compilation/compile_date
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Contains the build time stamp of the Xen hypervisor
|
||||||
|
Might return "<denied>" in case of special security settings
|
||||||
|
in the hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/compilation/compiled_by
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Contains information who built the Xen hypervisor
|
||||||
|
Might return "<denied>" in case of special security settings
|
||||||
|
in the hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/compilation/compiler
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Compiler which was used to build the Xen hypervisor
|
||||||
|
Might return "<denied>" in case of special security settings
|
||||||
|
in the hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/properties/capabilities
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Space separated list of supported guest system types. Each type
|
||||||
|
is in the format: <class>-<major>.<minor>-<arch>
|
||||||
|
With:
|
||||||
|
<class>: "xen" -- x86: paravirtualized, arm: standard
|
||||||
|
"hvm" -- x86 only: fully virtualized
|
||||||
|
<major>: major guest interface version
|
||||||
|
<minor>: minor guest interface version
|
||||||
|
<arch>: architecture, e.g.:
|
||||||
|
"x86_32": 32 bit x86 guest without PAE
|
||||||
|
"x86_32p": 32 bit x86 guest with PAE
|
||||||
|
"x86_64": 64 bit x86 guest
|
||||||
|
"armv7l": 32 bit arm guest
|
||||||
|
"aarch64": 64 bit arm guest
|
||||||
|
|
||||||
|
What: /sys/hypervisor/properties/changeset
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Changeset of the hypervisor (git commit)
|
||||||
|
Might return "<denied>" in case of special security settings
|
||||||
|
in the hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/properties/features
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Features the Xen hypervisor supports for the guest as defined
|
||||||
|
in include/xen/interface/features.h printed as a hex value.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/properties/pagesize
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Default page size of the hypervisor printed as a hex value.
|
||||||
|
Might return "0" in case of special security settings
|
||||||
|
in the hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/properties/virtual_start
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Virtual address of the hypervisor as a hex value.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/type
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Type of hypervisor:
|
||||||
|
"xen": Xen hypervisor
|
||||||
|
|
||||||
|
What: /sys/hypervisor/uuid
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
UUID of the guest as known to the Xen hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/version/extra
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
The Xen version is in the format <major>.<minor><extra>
|
||||||
|
This is the <extra> part of it.
|
||||||
|
Might return "<denied>" in case of special security settings
|
||||||
|
in the hypervisor.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/version/major
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
The Xen version is in the format <major>.<minor><extra>
|
||||||
|
This is the <major> part of it.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/version/minor
|
||||||
|
Date: March 2009
|
||||||
|
KernelVersion: 2.6.30
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
The Xen version is in the format <major>.<minor><extra>
|
||||||
|
This is the <minor> part of it.
|
|
@ -1,12 +1,14 @@
|
||||||
What: /config/usb-gadget/gadget/functions/uac1.name
|
What: /config/usb-gadget/gadget/functions/uac1.name
|
||||||
Date: Sep 2014
|
Date: June 2017
|
||||||
KernelVersion: 3.18
|
KernelVersion: 4.14
|
||||||
Description:
|
Description:
|
||||||
The attributes:
|
The attributes:
|
||||||
|
|
||||||
audio_buf_size - audio buffer size
|
c_chmask - capture channel mask
|
||||||
fn_cap - capture pcm device file name
|
c_srate - capture sampling rate
|
||||||
fn_cntl - control device file name
|
c_ssize - capture sample size (bytes)
|
||||||
fn_play - playback pcm device file name
|
p_chmask - playback channel mask
|
||||||
req_buf_size - ISO OUT endpoint request buffer size
|
p_srate - playback sampling rate
|
||||||
req_count - ISO OUT endpoint request count
|
p_ssize - playback sample size (bytes)
|
||||||
|
req_number - the number of pre-allocated request
|
||||||
|
for both capture and playback
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
What: /config/usb-gadget/gadget/functions/uac1_legacy.name
|
||||||
|
Date: Sep 2014
|
||||||
|
KernelVersion: 3.18
|
||||||
|
Description:
|
||||||
|
The attributes:
|
||||||
|
|
||||||
|
audio_buf_size - audio buffer size
|
||||||
|
fn_cap - capture pcm device file name
|
||||||
|
fn_cntl - control device file name
|
||||||
|
fn_play - playback pcm device file name
|
||||||
|
req_buf_size - ISO OUT endpoint request buffer size
|
||||||
|
req_count - ISO OUT endpoint request count
|
|
@ -37,6 +37,7 @@ Description:
|
||||||
fowner:= decimal value
|
fowner:= decimal value
|
||||||
lsm: are LSM specific
|
lsm: are LSM specific
|
||||||
option: appraise_type:= [imasig]
|
option: appraise_type:= [imasig]
|
||||||
|
pcr:= decimal value
|
||||||
|
|
||||||
default policy:
|
default policy:
|
||||||
# PROC_SUPER_MAGIC
|
# PROC_SUPER_MAGIC
|
||||||
|
@ -96,3 +97,8 @@ Description:
|
||||||
|
|
||||||
Smack:
|
Smack:
|
||||||
measure subj_user=_ func=FILE_CHECK mask=MAY_READ
|
measure subj_user=_ func=FILE_CHECK mask=MAY_READ
|
||||||
|
|
||||||
|
Example of measure rules using alternate PCRs:
|
||||||
|
|
||||||
|
measure func=KEXEC_KERNEL_CHECK pcr=4
|
||||||
|
measure func=KEXEC_INITRAMFS_CHECK pcr=5
|
||||||
|
|
38
kernel/Documentation/ABI/testing/sysfs-bus-fsi
Normal file
38
kernel/Documentation/ABI/testing/sysfs-bus-fsi
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
What: /sys/bus/platform/devices/fsi-master/rescan
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.12
|
||||||
|
Contact: cbostic@linux.vnet.ibm.com
|
||||||
|
Description:
|
||||||
|
Initiates a FSI master scan for all connected slave devices
|
||||||
|
on its links.
|
||||||
|
|
||||||
|
What: /sys/bus/platform/devices/fsi-master/break
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.12
|
||||||
|
Contact: cbostic@linux.vnet.ibm.com
|
||||||
|
Description:
|
||||||
|
Sends an FSI BREAK command on a master's communication
|
||||||
|
link to any connnected slaves. A BREAK resets connected
|
||||||
|
device's logic and preps it to receive further commands
|
||||||
|
from the master.
|
||||||
|
|
||||||
|
What: /sys/bus/platform/devices/fsi-master/slave@00:00/term
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.12
|
||||||
|
Contact: cbostic@linux.vnet.ibm.com
|
||||||
|
Description:
|
||||||
|
Sends an FSI terminate command from the master to its
|
||||||
|
connected slave. A terminate resets the slave's state machines
|
||||||
|
that control access to the internally connected engines. In
|
||||||
|
addition the slave freezes its internal error register for
|
||||||
|
debugging purposes. This command is also needed to abort any
|
||||||
|
ongoing operation in case of an expired 'Master Time Out'
|
||||||
|
timer.
|
||||||
|
|
||||||
|
What: /sys/bus/platform/devices/fsi-master/slave@00:00/raw
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.12
|
||||||
|
Contact: cbostic@linux.vnet.ibm.com
|
||||||
|
Description:
|
||||||
|
Provides a means of reading/writing a 32 bit value from/to a
|
||||||
|
specified FSI bus address.
|
|
@ -1425,6 +1425,17 @@ Description:
|
||||||
guarantees that the hardware fifo is flushed to the device
|
guarantees that the hardware fifo is flushed to the device
|
||||||
buffer.
|
buffer.
|
||||||
|
|
||||||
|
What: /sys/bus/iio/devices/iio:device*/buffer/hwfifo_timeout
|
||||||
|
KernelVersion: 4.12
|
||||||
|
Contact: linux-iio@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
A read/write property to provide capability to delay reporting of
|
||||||
|
samples till a timeout is reached. This allows host processors to
|
||||||
|
sleep, while the sensor is storing samples in its internal fifo.
|
||||||
|
The maximum timeout in seconds can be specified by setting
|
||||||
|
hwfifo_timeout.The current delay can be read by reading
|
||||||
|
hwfifo_timeout. A value of 0 means that there is no timeout.
|
||||||
|
|
||||||
What: /sys/bus/iio/devices/iio:deviceX/buffer/hwfifo_watermark
|
What: /sys/bus/iio/devices/iio:deviceX/buffer/hwfifo_watermark
|
||||||
KernelVersion: 4.2
|
KernelVersion: 4.2
|
||||||
Contact: linux-iio@vger.kernel.org
|
Contact: linux-iio@vger.kernel.org
|
||||||
|
|
|
@ -5,4 +5,3 @@ Description:
|
||||||
Reading returns either '1' or '0'. '1' means that the
|
Reading returns either '1' or '0'. '1' means that the
|
||||||
battery level supplied to sensor is below 2.25V.
|
battery level supplied to sensor is below 2.25V.
|
||||||
This ABI is available for tsys02d, htu21, ms8607
|
This ABI is available for tsys02d, htu21, ms8607
|
||||||
This ABI is available for htu21, ms8607
|
|
||||||
|
|
|
@ -16,6 +16,54 @@ Description:
|
||||||
- "OC2REF" : OC2REF signal is used as trigger output.
|
- "OC2REF" : OC2REF signal is used as trigger output.
|
||||||
- "OC3REF" : OC3REF signal is used as trigger output.
|
- "OC3REF" : OC3REF signal is used as trigger output.
|
||||||
- "OC4REF" : OC4REF signal is used as trigger output.
|
- "OC4REF" : OC4REF signal is used as trigger output.
|
||||||
|
Additional modes (on TRGO2 only):
|
||||||
|
- "OC5REF" : OC5REF signal is used as trigger output.
|
||||||
|
- "OC6REF" : OC6REF signal is used as trigger output.
|
||||||
|
- "compare_pulse_OC4REF":
|
||||||
|
OC4REF rising or falling edges generate pulses.
|
||||||
|
- "compare_pulse_OC6REF":
|
||||||
|
OC6REF rising or falling edges generate pulses.
|
||||||
|
- "compare_pulse_OC4REF_r_or_OC6REF_r":
|
||||||
|
OC4REF or OC6REF rising edges generate pulses.
|
||||||
|
- "compare_pulse_OC4REF_r_or_OC6REF_f":
|
||||||
|
OC4REF rising or OC6REF falling edges generate pulses.
|
||||||
|
- "compare_pulse_OC5REF_r_or_OC6REF_r":
|
||||||
|
OC5REF or OC6REF rising edges generate pulses.
|
||||||
|
- "compare_pulse_OC5REF_r_or_OC6REF_f":
|
||||||
|
OC5REF rising or OC6REF falling edges generate pulses.
|
||||||
|
|
||||||
|
+-----------+ +-------------+ +---------+
|
||||||
|
| Prescaler +-> | Counter | +-> | Master | TRGO(2)
|
||||||
|
+-----------+ +--+--------+-+ |-> | Control +-->
|
||||||
|
| | || +---------+
|
||||||
|
+--v--------+-+ OCxREF || +---------+
|
||||||
|
| Chx compare +----------> | Output | ChX
|
||||||
|
+-----------+-+ | | Control +-->
|
||||||
|
. | | +---------+
|
||||||
|
. | | .
|
||||||
|
+-----------v-+ OC6REF | .
|
||||||
|
| Ch6 compare +---------+>
|
||||||
|
+-------------+
|
||||||
|
|
||||||
|
Example with: "compare_pulse_OC4REF_r_or_OC6REF_r":
|
||||||
|
|
||||||
|
X
|
||||||
|
X X
|
||||||
|
X . . X
|
||||||
|
X . . X
|
||||||
|
X . . X
|
||||||
|
count X . . . . X
|
||||||
|
. . . .
|
||||||
|
. . . .
|
||||||
|
+---------------+
|
||||||
|
OC4REF | . . |
|
||||||
|
+-+ . . +-+
|
||||||
|
. +---+ .
|
||||||
|
OC6REF . | | .
|
||||||
|
+-------+ +-------+
|
||||||
|
+-+ +-+
|
||||||
|
TRGO2 | | | |
|
||||||
|
+-+ +---+ +---------+
|
||||||
|
|
||||||
What: /sys/bus/iio/devices/triggerX/master_mode
|
What: /sys/bus/iio/devices/triggerX/master_mode
|
||||||
KernelVersion: 4.11
|
KernelVersion: 4.11
|
||||||
|
@ -90,3 +138,18 @@ Description:
|
||||||
Counting is enabled on rising edge of the connected
|
Counting is enabled on rising edge of the connected
|
||||||
trigger, and remains enabled for the duration of this
|
trigger, and remains enabled for the duration of this
|
||||||
selected mode.
|
selected mode.
|
||||||
|
|
||||||
|
What: /sys/bus/iio/devices/iio:deviceX/in_count_trigger_mode_available
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: benjamin.gaignard@st.com
|
||||||
|
Description:
|
||||||
|
Reading returns the list possible trigger modes.
|
||||||
|
|
||||||
|
What: /sys/bus/iio/devices/iio:deviceX/in_count0_trigger_mode
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: benjamin.gaignard@st.com
|
||||||
|
Description:
|
||||||
|
Configure the device counter trigger mode
|
||||||
|
counting direction is set by in_count0_count_direction
|
||||||
|
attribute and the counter is clocked by the connected trigger
|
||||||
|
rising edges.
|
||||||
|
|
110
kernel/Documentation/ABI/testing/sysfs-bus-thunderbolt
Normal file
110
kernel/Documentation/ABI/testing/sysfs-bus-thunderbolt
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../domainX/security
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute holds current Thunderbolt security level
|
||||||
|
set by the system BIOS. Possible values are:
|
||||||
|
|
||||||
|
none: All devices are automatically authorized
|
||||||
|
user: Devices are only authorized based on writing
|
||||||
|
appropriate value to the authorized attribute
|
||||||
|
secure: Require devices that support secure connect at
|
||||||
|
minimum. User needs to authorize each device.
|
||||||
|
dponly: Automatically tunnel Display port (and USB). No
|
||||||
|
PCIe tunnels are created.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../authorized
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute is used to authorize Thunderbolt devices
|
||||||
|
after they have been connected. If the device is not
|
||||||
|
authorized, no devices such as PCIe and Display port are
|
||||||
|
available to the system.
|
||||||
|
|
||||||
|
Contents of this attribute will be 0 when the device is not
|
||||||
|
yet authorized.
|
||||||
|
|
||||||
|
Possible values are supported:
|
||||||
|
1: The device will be authorized and connected
|
||||||
|
|
||||||
|
When key attribute contains 32 byte hex string the possible
|
||||||
|
values are:
|
||||||
|
1: The 32 byte hex string is added to the device NVM and
|
||||||
|
the device is authorized.
|
||||||
|
2: Send a challenge based on the 32 byte hex string. If the
|
||||||
|
challenge response from device is valid, the device is
|
||||||
|
authorized. In case of failure errno will be ENOKEY if
|
||||||
|
the device did not contain a key at all, and
|
||||||
|
EKEYREJECTED if the challenge response did not match.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../key
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: When a devices supports Thunderbolt secure connect it will
|
||||||
|
have this attribute. Writing 32 byte hex string changes
|
||||||
|
authorization to use the secure connection method instead.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../device
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute contains id of this device extracted from
|
||||||
|
the device DROM.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../device_name
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute contains name of this device extracted from
|
||||||
|
the device DROM.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../vendor
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute contains vendor id of this device extracted
|
||||||
|
from the device DROM.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../vendor_name
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute contains vendor name of this device extracted
|
||||||
|
from the device DROM.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../unique_id
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: This attribute contains unique_id string of this device.
|
||||||
|
This is either read from hardware registers (UUID on
|
||||||
|
newer hardware) or based on UID from the device DROM.
|
||||||
|
Can be used to uniquely identify particular device.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../nvm_version
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: If the device has upgradeable firmware the version
|
||||||
|
number is available here. Format: %x.%x, major.minor.
|
||||||
|
If the device is in safe mode reading the file returns
|
||||||
|
-ENODATA instead as the NVM version is not available.
|
||||||
|
|
||||||
|
What: /sys/bus/thunderbolt/devices/.../nvm_authenticate
|
||||||
|
Date: Sep 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: thunderbolt-software@lists.01.org
|
||||||
|
Description: When new NVM image is written to the non-active NVM
|
||||||
|
area (through non_activeX NVMem device), the
|
||||||
|
authentication procedure is started by writing 1 to
|
||||||
|
this file. If everything goes well, the device is
|
||||||
|
restarted with the new NVM firmware. If the image
|
||||||
|
verification fails an error code is returned instead.
|
||||||
|
|
||||||
|
When read holds status of the last authentication
|
||||||
|
operation if an error occurred during the process. This
|
||||||
|
is directly the status value from the DMA configuration
|
||||||
|
based mailbox before the device is power cycled. Writing
|
||||||
|
0 here clears the status.
|
|
@ -229,6 +229,6 @@ KernelVersion: 4.1
|
||||||
Contact: linux-mtd@lists.infradead.org
|
Contact: linux-mtd@lists.infradead.org
|
||||||
Description:
|
Description:
|
||||||
For a partition, the offset of that partition from the start
|
For a partition, the offset of that partition from the start
|
||||||
of the master device in bytes. This attribute is absent on
|
of the parent (another partition or a flash device) in bytes.
|
||||||
main devices, so it can be used to distinguish between
|
This attribute is absent on flash devices, so it can be used
|
||||||
partitions and devices that aren't partitions.
|
to distinguish them from partitions.
|
||||||
|
|
16
kernel/Documentation/ABI/testing/sysfs-class-mux
Normal file
16
kernel/Documentation/ABI/testing/sysfs-class-mux
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
What: /sys/class/mux/
|
||||||
|
Date: April 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: Peter Rosin <peda@axentia.se>
|
||||||
|
Description:
|
||||||
|
The mux/ class sub-directory belongs to the Generic MUX
|
||||||
|
Framework and provides a sysfs interface for using MUX
|
||||||
|
controllers.
|
||||||
|
|
||||||
|
What: /sys/class/mux/muxchipN/
|
||||||
|
Date: April 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: Peter Rosin <peda@axentia.se>
|
||||||
|
Description:
|
||||||
|
A /sys/class/mux/muxchipN directory is created for each
|
||||||
|
probed MUX chip where N is a simple enumeration.
|
|
@ -251,3 +251,11 @@ Contact: netdev@vger.kernel.org
|
||||||
Description:
|
Description:
|
||||||
Indicates the unique physical switch identifier of a switch this
|
Indicates the unique physical switch identifier of a switch this
|
||||||
port belongs to, as a string.
|
port belongs to, as a string.
|
||||||
|
|
||||||
|
What: /sys/class/net/<iface>/phydev
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: netdev@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
Symbolic link to the PHY device this network device is attached
|
||||||
|
to.
|
||||||
|
|
36
kernel/Documentation/ABI/testing/sysfs-class-net-phydev
Normal file
36
kernel/Documentation/ABI/testing/sysfs-class-net-phydev
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
What: /sys/class/mdio_bus/<bus>/<device>/attached_dev
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: netdev@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
Symbolic link to the network device this PHY device is
|
||||||
|
attached to.
|
||||||
|
|
||||||
|
What: /sys/class/mdio_bus/<bus>/<device>/phy_has_fixups
|
||||||
|
Date: February 2014
|
||||||
|
KernelVersion: 3.15
|
||||||
|
Contact: netdev@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
Boolean value indicating whether the PHY device has
|
||||||
|
any fixups registered against it (phy_register_fixup)
|
||||||
|
|
||||||
|
What: /sys/class/mdio_bus/<bus>/<device>/phy_id
|
||||||
|
Date: November 2012
|
||||||
|
KernelVersion: 3.8
|
||||||
|
Contact: netdev@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
32-bit hexadecimal value corresponding to the PHY device's OUI,
|
||||||
|
model and revision number.
|
||||||
|
|
||||||
|
What: /sys/class/mdio_bus/<bus>/<device>/phy_interface
|
||||||
|
Date: February 2014
|
||||||
|
KernelVersion: 3.15
|
||||||
|
Contact: netdev@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
String value indicating the PHY interface, possible
|
||||||
|
values are:.
|
||||||
|
<empty> (not available), mii, gmii, sgmii, tbi, rev-mii,
|
||||||
|
rmii, rgmii, rgmii-id, rgmii-rxid, rgmii-txid, rtbi, smii
|
||||||
|
xgmii, moca, qsgmii, trgmii, 1000base-x, 2500base-x, rxaui,
|
||||||
|
xaui, 10gbase-kr, unknown
|
||||||
|
|
|
@ -1,20 +1,3 @@
|
||||||
What: /sys/class/power_supply/twl4030_ac/max_current
|
|
||||||
/sys/class/power_supply/twl4030_usb/max_current
|
|
||||||
Description:
|
|
||||||
Read/Write limit on current which may
|
|
||||||
be drawn from the ac (Accessory Charger) or
|
|
||||||
USB port.
|
|
||||||
|
|
||||||
Value is in micro-Amps.
|
|
||||||
|
|
||||||
Value is set automatically to an appropriate
|
|
||||||
value when a cable is plugged or unplugged.
|
|
||||||
|
|
||||||
Value can the set by writing to the attribute.
|
|
||||||
The change will only persist until the next
|
|
||||||
plug event. These event are reported via udev.
|
|
||||||
|
|
||||||
|
|
||||||
What: /sys/class/power_supply/twl4030_usb/mode
|
What: /sys/class/power_supply/twl4030_usb/mode
|
||||||
Description:
|
Description:
|
||||||
Changing mode for USB port.
|
Changing mode for USB port.
|
||||||
|
|
|
@ -30,6 +30,21 @@ Description:
|
||||||
|
|
||||||
Valid values: source, sink
|
Valid values: source, sink
|
||||||
|
|
||||||
|
What: /sys/class/typec/<port>/port_type
|
||||||
|
Date: May 2017
|
||||||
|
Contact: Badhri Jagan Sridharan <Badhri@google.com>
|
||||||
|
Description:
|
||||||
|
Indicates the type of the port. This attribute can be used for
|
||||||
|
requesting a change in the port type. Port type change is
|
||||||
|
supported as a synchronous operation, so write(2) to the
|
||||||
|
attribute will not return until the operation has finished.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
- source (The port will behave as source only DFP port)
|
||||||
|
- sink (The port will behave as sink only UFP port)
|
||||||
|
- dual (The port will behave as dual-role-data and
|
||||||
|
dual-role-power port)
|
||||||
|
|
||||||
What: /sys/class/typec/<port>/vconn_source
|
What: /sys/class/typec/<port>/vconn_source
|
||||||
Date: April 2017
|
Date: April 2017
|
||||||
Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
What: /sys/firmware/devicetree/*
|
What: /sys/firmware/devicetree/*
|
||||||
Date: November 2013
|
Date: November 2013
|
||||||
Contact: Grant Likely <grant.likely@linaro.org>
|
Contact: Grant Likely <grant.likely@arm.com>, devicetree@vger.kernel.org
|
||||||
Description:
|
Description:
|
||||||
When using OpenFirmware or a Flattened Device Tree to enumerate
|
When using OpenFirmware or a Flattened Device Tree to enumerate
|
||||||
hardware, the device tree structure will be exposed in this
|
hardware, the device tree structure will be exposed in this
|
||||||
|
@ -26,3 +26,27 @@ Description:
|
||||||
name plus address). Properties are represented as files
|
name plus address). Properties are represented as files
|
||||||
in the directory. The contents of each file is the exact
|
in the directory. The contents of each file is the exact
|
||||||
binary data from the device tree.
|
binary data from the device tree.
|
||||||
|
|
||||||
|
What: /sys/firmware/fdt
|
||||||
|
Date: February 2015
|
||||||
|
KernelVersion: 3.19
|
||||||
|
Contact: Frank Rowand <frowand.list@gmail.com>, devicetree@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
Exports the FDT blob that was passed to the kernel by
|
||||||
|
the bootloader. This allows userland applications such
|
||||||
|
as kexec to access the raw binary. This blob is also
|
||||||
|
useful when debugging since it contains any changes
|
||||||
|
made to the blob by the bootloader.
|
||||||
|
|
||||||
|
The fact that this node does not reside under
|
||||||
|
/sys/firmware/device-tree is deliberate: FDT is also used
|
||||||
|
on arm64 UEFI/ACPI systems to communicate just the UEFI
|
||||||
|
and ACPI entry points, but the FDT is never unflattened
|
||||||
|
and used to configure the system.
|
||||||
|
|
||||||
|
A CRC32 checksum is calculated over the entire FDT
|
||||||
|
blob, and verified at late_initcall time. The sysfs
|
||||||
|
entry is instantiated only if the checksum is valid,
|
||||||
|
i.e., if the FDT blob has not been modified in the mean
|
||||||
|
time. Otherwise, a warning is printed.
|
||||||
|
Users: kexec, debugging
|
||||||
|
|
|
@ -75,7 +75,7 @@ Contact: "Jaegeuk Kim" <jaegeuk.kim@samsung.com>
|
||||||
Description:
|
Description:
|
||||||
Controls the memory footprint used by f2fs.
|
Controls the memory footprint used by f2fs.
|
||||||
|
|
||||||
What: /sys/fs/f2fs/<disk>/trim_sections
|
What: /sys/fs/f2fs/<disk>/batched_trim_sections
|
||||||
Date: February 2015
|
Date: February 2015
|
||||||
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
Contact: "Jaegeuk Kim" <jaegeuk@kernel.org>
|
||||||
Description:
|
Description:
|
||||||
|
@ -112,3 +112,21 @@ Date: January 2016
|
||||||
Contact: "Shuoran Liu" <liushuoran@huawei.com>
|
Contact: "Shuoran Liu" <liushuoran@huawei.com>
|
||||||
Description:
|
Description:
|
||||||
Shows total written kbytes issued to disk.
|
Shows total written kbytes issued to disk.
|
||||||
|
|
||||||
|
What: /sys/fs/f2fs/<disk>/inject_rate
|
||||||
|
Date: May 2016
|
||||||
|
Contact: "Sheng Yong" <shengyong1@huawei.com>
|
||||||
|
Description:
|
||||||
|
Controls the injection rate.
|
||||||
|
|
||||||
|
What: /sys/fs/f2fs/<disk>/inject_type
|
||||||
|
Date: May 2016
|
||||||
|
Contact: "Sheng Yong" <shengyong1@huawei.com>
|
||||||
|
Description:
|
||||||
|
Controls the injection type.
|
||||||
|
|
||||||
|
What: /sys/fs/f2fs/<disk>/reserved_blocks
|
||||||
|
Date: June 2017
|
||||||
|
Contact: "Chao Yu" <yuchao0@huawei.com>
|
||||||
|
Description:
|
||||||
|
Controls current reserved blocks in system.
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
What: /sys/hypervisor/pmu/pmu_mode
|
|
||||||
Date: August 2015
|
|
||||||
KernelVersion: 4.3
|
|
||||||
Contact: Boris Ostrovsky <boris.ostrovsky@oracle.com>
|
|
||||||
Description:
|
|
||||||
Describes mode that Xen's performance-monitoring unit (PMU)
|
|
||||||
uses. Accepted values are
|
|
||||||
"off" -- PMU is disabled
|
|
||||||
"self" -- The guest can profile itself
|
|
||||||
"hv" -- The guest can profile itself and, if it is
|
|
||||||
privileged (e.g. dom0), the hypervisor
|
|
||||||
"all" -- The guest can profile itself, the hypervisor
|
|
||||||
and all other guests. Only available to
|
|
||||||
privileged guests.
|
|
||||||
|
|
||||||
What: /sys/hypervisor/pmu/pmu_features
|
|
||||||
Date: August 2015
|
|
||||||
KernelVersion: 4.3
|
|
||||||
Contact: Boris Ostrovsky <boris.ostrovsky@oracle.com>
|
|
||||||
Description:
|
|
||||||
Describes Xen PMU features (as an integer). A set bit indicates
|
|
||||||
that the corresponding feature is enabled. See
|
|
||||||
include/xen/interface/xenpmu.h for available features
|
|
43
kernel/Documentation/ABI/testing/sysfs-hypervisor-xen
Normal file
43
kernel/Documentation/ABI/testing/sysfs-hypervisor-xen
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
What: /sys/hypervisor/guest_type
|
||||||
|
Date: June 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Type of guest:
|
||||||
|
"Xen": standard guest type on arm
|
||||||
|
"HVM": fully virtualized guest (x86)
|
||||||
|
"PV": paravirtualized guest (x86)
|
||||||
|
"PVH": fully virtualized guest without legacy emulation (x86)
|
||||||
|
|
||||||
|
What: /sys/hypervisor/pmu/pmu_mode
|
||||||
|
Date: August 2015
|
||||||
|
KernelVersion: 4.3
|
||||||
|
Contact: Boris Ostrovsky <boris.ostrovsky@oracle.com>
|
||||||
|
Description: If running under Xen:
|
||||||
|
Describes mode that Xen's performance-monitoring unit (PMU)
|
||||||
|
uses. Accepted values are
|
||||||
|
"off" -- PMU is disabled
|
||||||
|
"self" -- The guest can profile itself
|
||||||
|
"hv" -- The guest can profile itself and, if it is
|
||||||
|
privileged (e.g. dom0), the hypervisor
|
||||||
|
"all" -- The guest can profile itself, the hypervisor
|
||||||
|
and all other guests. Only available to
|
||||||
|
privileged guests.
|
||||||
|
|
||||||
|
What: /sys/hypervisor/pmu/pmu_features
|
||||||
|
Date: August 2015
|
||||||
|
KernelVersion: 4.3
|
||||||
|
Contact: Boris Ostrovsky <boris.ostrovsky@oracle.com>
|
||||||
|
Description: If running under Xen:
|
||||||
|
Describes Xen PMU features (as an integer). A set bit indicates
|
||||||
|
that the corresponding feature is enabled. See
|
||||||
|
include/xen/interface/xenpmu.h for available features
|
||||||
|
|
||||||
|
What: /sys/hypervisor/properties/buildid
|
||||||
|
Date: June 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: xen-devel@lists.xenproject.org
|
||||||
|
Description: If running under Xen:
|
||||||
|
Build id of the hypervisor, needed for hypervisor live patching.
|
||||||
|
Might return "<denied>" in case of special security settings
|
||||||
|
in the hypervisor.
|
|
@ -17,3 +17,11 @@ Description:
|
||||||
* 2 -> Dust Cleaning
|
* 2 -> Dust Cleaning
|
||||||
* 4 -> Efficient Thermal Dissipation Mode
|
* 4 -> Efficient Thermal Dissipation Mode
|
||||||
|
|
||||||
|
What: /sys/devices/platform/ideapad/touchpad
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: "Ritesh Raj Sarraf <rrs@debian.org>"
|
||||||
|
Description:
|
||||||
|
Control touchpad mode.
|
||||||
|
* 1 -> Switched On
|
||||||
|
* 0 -> Switched Off
|
||||||
|
|
47
kernel/Documentation/ABI/testing/sysfs-uevent
Normal file
47
kernel/Documentation/ABI/testing/sysfs-uevent
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
What: /sys/.../uevent
|
||||||
|
Date: May 2017
|
||||||
|
KernelVersion: 4.13
|
||||||
|
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
||||||
|
Description:
|
||||||
|
Enable passing additional variables for synthetic uevents that
|
||||||
|
are generated by writing /sys/.../uevent file.
|
||||||
|
|
||||||
|
Recognized extended format is ACTION [UUID [KEY=VALUE ...].
|
||||||
|
|
||||||
|
The ACTION is compulsory - it is the name of the uevent action
|
||||||
|
("add", "change", "remove"). There is no change compared to
|
||||||
|
previous functionality here. The rest of the extended format
|
||||||
|
is optional.
|
||||||
|
|
||||||
|
You need to pass UUID first before any KEY=VALUE pairs.
|
||||||
|
The UUID must be in "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
format where 'x' is a hex digit. The UUID is considered to be
|
||||||
|
a transaction identifier so it's possible to use the same UUID
|
||||||
|
value for one or more synthetic uevents in which case we
|
||||||
|
logically group these uevents together for any userspace
|
||||||
|
listeners. The UUID value appears in uevent as
|
||||||
|
"SYNTH_UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" environment
|
||||||
|
variable.
|
||||||
|
|
||||||
|
If UUID is not passed in, the generated synthetic uevent gains
|
||||||
|
"SYNTH_UUID=0" environment variable automatically.
|
||||||
|
|
||||||
|
The KEY=VALUE pairs can contain alphanumeric characters only.
|
||||||
|
It's possible to define zero or more pairs - each pair is then
|
||||||
|
delimited by a space character ' '. Each pair appears in
|
||||||
|
synthetic uevent as "SYNTH_ARG_KEY=VALUE". That means the KEY
|
||||||
|
name gains "SYNTH_ARG_" prefix to avoid possible collisions
|
||||||
|
with existing variables.
|
||||||
|
|
||||||
|
Example of valid sequence written to the uevent file:
|
||||||
|
|
||||||
|
add fe4d7c9d-b8c6-4a70-9ef1-3d8a58d18eed A=1 B=abc
|
||||||
|
|
||||||
|
This generates synthetic uevent including these variables:
|
||||||
|
|
||||||
|
ACTION=add
|
||||||
|
SYNTH_ARG_A=1
|
||||||
|
SYNTH_ARG_B=abc
|
||||||
|
SYNTH_UUID=fe4d7c9d-b8c6-4a70-9ef1-3d8a58d18eed
|
||||||
|
Users:
|
||||||
|
udev, userspace tools generating synthetic uevents
|
72
kernel/Documentation/Changes.rej
Normal file
72
kernel/Documentation/Changes.rej
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
--- Documentation/Changes 2017-08-30 04:32:30.000000000 -0400
|
||||||
|
+++ Documentation/Changes 2017-09-03 16:56:17.000000000 -0400
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
====================== =============== ========================================
|
||||||
|
GNU C 3.2 gcc --version
|
||||||
|
GNU make 3.81 make --version
|
||||||
|
-binutils 2.12 ld -v
|
||||||
|
+binutils 2.20 ld -v
|
||||||
|
util-linux 2.10o fdformat --version
|
||||||
|
module-init-tools 0.9.10 depmod -V
|
||||||
|
e2fsprogs 1.41.4 e2fsck -V
|
||||||
|
@@ -75,10 +75,9 @@
|
||||||
|
Binutils
|
||||||
|
--------
|
||||||
|
|
||||||
|
-Linux on IA-32 has recently switched from using ``as86`` to using ``gas`` for
|
||||||
|
-assembling the 16-bit boot code, removing the need for ``as86`` to compile
|
||||||
|
-your kernel. This change does, however, mean that you need a recent
|
||||||
|
-release of binutils.
|
||||||
|
+The build system has, as of 4.13, switched to using thin archives (`ar T`)
|
||||||
|
+rather than incremental linking (`ld -r`) for built-in.o intermediate steps.
|
||||||
|
+This requires binutils 2.20 or newer.
|
||||||
|
|
||||||
|
Perl
|
||||||
|
----
|
||||||
|
@@ -116,12 +115,11 @@
|
||||||
|
|
||||||
|
Linux documentation for functions is transitioning to inline
|
||||||
|
documentation via specially-formatted comments near their
|
||||||
|
-definitions in the source. These comments can be combined with the
|
||||||
|
-SGML templates in the Documentation/DocBook directory to make DocBook
|
||||||
|
-files, which can then be converted by DocBook stylesheets to PostScript,
|
||||||
|
-HTML, PDF files, and several other formats. In order to convert from
|
||||||
|
-DocBook format to a format of your choice, you'll need to install Jade as
|
||||||
|
-well as the desired DocBook stylesheets.
|
||||||
|
+definitions in the source. These comments can be combined with ReST
|
||||||
|
+files the Documentation/ directory to make enriched documentation, which can
|
||||||
|
+then be converted to PostScript, HTML, LaTex, ePUB and PDF files.
|
||||||
|
+In order to convert from ReST format to a format of your choice, you'll need
|
||||||
|
+Sphinx.
|
||||||
|
|
||||||
|
Util-linux
|
||||||
|
----------
|
||||||
|
@@ -323,12 +321,6 @@
|
||||||
|
functionalities required for ``XeLaTex`` to work. For PDF output you'll also
|
||||||
|
need ``convert(1)`` from ImageMagick (https://www.imagemagick.org).
|
||||||
|
|
||||||
|
-Other tools
|
||||||
|
------------
|
||||||
|
-
|
||||||
|
-In order to produce documentation from DocBook, you'll also need ``xmlto``.
|
||||||
|
-Please notice, however, that we're currently migrating all documents to use
|
||||||
|
-``Sphinx``.
|
||||||
|
|
||||||
|
Getting updated software
|
||||||
|
========================
|
||||||
|
@@ -409,15 +401,6 @@
|
||||||
|
|
||||||
|
- <http://sourceforge.net/projects/linuxquota/>
|
||||||
|
|
||||||
|
-DocBook Stylesheets
|
||||||
|
--------------------
|
||||||
|
-
|
||||||
|
-- <http://sourceforge.net/projects/docbook/files/docbook-dsssl/>
|
||||||
|
-
|
||||||
|
-XMLTO XSLT Frontend
|
||||||
|
--------------------
|
||||||
|
-
|
||||||
|
-- <http://cyberelk.net/tim/xmlto/>
|
||||||
|
|
||||||
|
Intel P6 microcode
|
||||||
|
------------------
|
|
@ -1,22 +1,24 @@
|
||||||
|
=========================
|
||||||
Dynamic DMA mapping Guide
|
Dynamic DMA mapping Guide
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
David S. Miller <davem@redhat.com>
|
:Author: David S. Miller <davem@redhat.com>
|
||||||
Richard Henderson <rth@cygnus.com>
|
:Author: Richard Henderson <rth@cygnus.com>
|
||||||
Jakub Jelinek <jakub@redhat.com>
|
:Author: Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
This is a guide to device driver writers on how to use the DMA API
|
This is a guide to device driver writers on how to use the DMA API
|
||||||
with example pseudo-code. For a concise description of the API, see
|
with example pseudo-code. For a concise description of the API, see
|
||||||
DMA-API.txt.
|
DMA-API.txt.
|
||||||
|
|
||||||
CPU and DMA addresses
|
CPU and DMA addresses
|
||||||
|
=====================
|
||||||
|
|
||||||
There are several kinds of addresses involved in the DMA API, and it's
|
There are several kinds of addresses involved in the DMA API, and it's
|
||||||
important to understand the differences.
|
important to understand the differences.
|
||||||
|
|
||||||
The kernel normally uses virtual addresses. Any address returned by
|
The kernel normally uses virtual addresses. Any address returned by
|
||||||
kmalloc(), vmalloc(), and similar interfaces is a virtual address and can
|
kmalloc(), vmalloc(), and similar interfaces is a virtual address and can
|
||||||
be stored in a "void *".
|
be stored in a ``void *``.
|
||||||
|
|
||||||
The virtual memory system (TLB, page tables, etc.) translates virtual
|
The virtual memory system (TLB, page tables, etc.) translates virtual
|
||||||
addresses to CPU physical addresses, which are stored as "phys_addr_t" or
|
addresses to CPU physical addresses, which are stored as "phys_addr_t" or
|
||||||
|
@ -37,7 +39,7 @@ be restricted to a subset of that space. For example, even if a system
|
||||||
supports 64-bit addresses for main memory and PCI BARs, it may use an IOMMU
|
supports 64-bit addresses for main memory and PCI BARs, it may use an IOMMU
|
||||||
so devices only need to use 32-bit DMA addresses.
|
so devices only need to use 32-bit DMA addresses.
|
||||||
|
|
||||||
Here's a picture and some examples:
|
Here's a picture and some examples::
|
||||||
|
|
||||||
CPU CPU Bus
|
CPU CPU Bus
|
||||||
Virtual Physical Address
|
Virtual Physical Address
|
||||||
|
@ -98,7 +100,7 @@ microprocessor architecture. You should use the DMA API rather than the
|
||||||
bus-specific DMA API, i.e., use the dma_map_*() interfaces rather than the
|
bus-specific DMA API, i.e., use the dma_map_*() interfaces rather than the
|
||||||
pci_map_*() interfaces.
|
pci_map_*() interfaces.
|
||||||
|
|
||||||
First of all, you should make sure
|
First of all, you should make sure::
|
||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
|
||||||
|
@ -107,6 +109,7 @@ can hold any valid DMA address for the platform and should be used
|
||||||
everywhere you hold a DMA address returned from the DMA mapping functions.
|
everywhere you hold a DMA address returned from the DMA mapping functions.
|
||||||
|
|
||||||
What memory is DMA'able?
|
What memory is DMA'able?
|
||||||
|
========================
|
||||||
|
|
||||||
The first piece of information you must know is what kernel memory can
|
The first piece of information you must know is what kernel memory can
|
||||||
be used with the DMA mapping facilities. There has been an unwritten
|
be used with the DMA mapping facilities. There has been an unwritten
|
||||||
|
@ -144,6 +147,7 @@ networking subsystems make sure that the buffers they use are valid
|
||||||
for you to DMA from/to.
|
for you to DMA from/to.
|
||||||
|
|
||||||
DMA addressing limitations
|
DMA addressing limitations
|
||||||
|
==========================
|
||||||
|
|
||||||
Does your device have any DMA addressing limitations? For example, is
|
Does your device have any DMA addressing limitations? For example, is
|
||||||
your device only capable of driving the low order 24-bits of address?
|
your device only capable of driving the low order 24-bits of address?
|
||||||
|
@ -166,7 +170,7 @@ style to do this even if your device holds the default setting,
|
||||||
because this shows that you did think about these issues wrt. your
|
because this shows that you did think about these issues wrt. your
|
||||||
device.
|
device.
|
||||||
|
|
||||||
The query is performed via a call to dma_set_mask_and_coherent():
|
The query is performed via a call to dma_set_mask_and_coherent()::
|
||||||
|
|
||||||
int dma_set_mask_and_coherent(struct device *dev, u64 mask);
|
int dma_set_mask_and_coherent(struct device *dev, u64 mask);
|
||||||
|
|
||||||
|
@ -175,12 +179,12 @@ If you have some special requirements, then the following two separate
|
||||||
queries can be used instead:
|
queries can be used instead:
|
||||||
|
|
||||||
The query for streaming mappings is performed via a call to
|
The query for streaming mappings is performed via a call to
|
||||||
dma_set_mask():
|
dma_set_mask()::
|
||||||
|
|
||||||
int dma_set_mask(struct device *dev, u64 mask);
|
int dma_set_mask(struct device *dev, u64 mask);
|
||||||
|
|
||||||
The query for consistent allocations is performed via a call
|
The query for consistent allocations is performed via a call
|
||||||
to dma_set_coherent_mask():
|
to dma_set_coherent_mask()::
|
||||||
|
|
||||||
int dma_set_coherent_mask(struct device *dev, u64 mask);
|
int dma_set_coherent_mask(struct device *dev, u64 mask);
|
||||||
|
|
||||||
|
@ -209,7 +213,7 @@ of your driver reports that performance is bad or that the device is not
|
||||||
even detected, you can ask them for the kernel messages to find out
|
even detected, you can ask them for the kernel messages to find out
|
||||||
exactly why.
|
exactly why.
|
||||||
|
|
||||||
The standard 32-bit addressing device would do something like this:
|
The standard 32-bit addressing device would do something like this::
|
||||||
|
|
||||||
if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
|
if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
|
||||||
dev_warn(dev, "mydev: No suitable DMA available\n");
|
dev_warn(dev, "mydev: No suitable DMA available\n");
|
||||||
|
@ -225,7 +229,7 @@ than 64-bit addressing. For example, Sparc64 PCI SAC addressing is
|
||||||
more efficient than DAC addressing.
|
more efficient than DAC addressing.
|
||||||
|
|
||||||
Here is how you would handle a 64-bit capable device which can drive
|
Here is how you would handle a 64-bit capable device which can drive
|
||||||
all 64-bits when accessing streaming DMA:
|
all 64-bits when accessing streaming DMA::
|
||||||
|
|
||||||
int using_dac;
|
int using_dac;
|
||||||
|
|
||||||
|
@ -239,7 +243,7 @@ all 64-bits when accessing streaming DMA:
|
||||||
}
|
}
|
||||||
|
|
||||||
If a card is capable of using 64-bit consistent allocations as well,
|
If a card is capable of using 64-bit consistent allocations as well,
|
||||||
the case would look like this:
|
the case would look like this::
|
||||||
|
|
||||||
int using_dac, consistent_using_dac;
|
int using_dac, consistent_using_dac;
|
||||||
|
|
||||||
|
@ -260,7 +264,7 @@ uses consistent allocations, one would have to check the return value from
|
||||||
dma_set_coherent_mask().
|
dma_set_coherent_mask().
|
||||||
|
|
||||||
Finally, if your device can only drive the low 24-bits of
|
Finally, if your device can only drive the low 24-bits of
|
||||||
address you might do something like:
|
address you might do something like::
|
||||||
|
|
||||||
if (dma_set_mask(dev, DMA_BIT_MASK(24))) {
|
if (dma_set_mask(dev, DMA_BIT_MASK(24))) {
|
||||||
dev_warn(dev, "mydev: 24-bit DMA addressing not available\n");
|
dev_warn(dev, "mydev: 24-bit DMA addressing not available\n");
|
||||||
|
@ -280,7 +284,7 @@ only provide the functionality which the machine can handle. It
|
||||||
is important that the last call to dma_set_mask() be for the
|
is important that the last call to dma_set_mask() be for the
|
||||||
most specific mask.
|
most specific mask.
|
||||||
|
|
||||||
Here is pseudo-code showing how this might be done:
|
Here is pseudo-code showing how this might be done::
|
||||||
|
|
||||||
#define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
|
#define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32)
|
||||||
#define RECORD_ADDRESS_BITS DMA_BIT_MASK(24)
|
#define RECORD_ADDRESS_BITS DMA_BIT_MASK(24)
|
||||||
|
@ -309,6 +313,7 @@ devices seems to be littered with ISA chips given a PCI front end,
|
||||||
and thus retaining the 16MB DMA addressing limitations of ISA.
|
and thus retaining the 16MB DMA addressing limitations of ISA.
|
||||||
|
|
||||||
Types of DMA mappings
|
Types of DMA mappings
|
||||||
|
=====================
|
||||||
|
|
||||||
There are two types of DMA mappings:
|
There are two types of DMA mappings:
|
||||||
|
|
||||||
|
@ -336,12 +341,14 @@ There are two types of DMA mappings:
|
||||||
to memory is immediately visible to the device, and vice
|
to memory is immediately visible to the device, and vice
|
||||||
versa. Consistent mappings guarantee this.
|
versa. Consistent mappings guarantee this.
|
||||||
|
|
||||||
IMPORTANT: Consistent DMA memory does not preclude the usage of
|
.. important::
|
||||||
|
|
||||||
|
Consistent DMA memory does not preclude the usage of
|
||||||
proper memory barriers. The CPU may reorder stores to
|
proper memory barriers. The CPU may reorder stores to
|
||||||
consistent memory just as it may normal memory. Example:
|
consistent memory just as it may normal memory. Example:
|
||||||
if it is important for the device to see the first word
|
if it is important for the device to see the first word
|
||||||
of a descriptor updated before the second, you must do
|
of a descriptor updated before the second, you must do
|
||||||
something like:
|
something like::
|
||||||
|
|
||||||
desc->word0 = address;
|
desc->word0 = address;
|
||||||
wmb();
|
wmb();
|
||||||
|
@ -377,16 +384,17 @@ Also, systems with caches that aren't DMA-coherent will work better
|
||||||
when the underlying buffers don't share cache lines with other data.
|
when the underlying buffers don't share cache lines with other data.
|
||||||
|
|
||||||
|
|
||||||
Using Consistent DMA mappings.
|
Using Consistent DMA mappings
|
||||||
|
=============================
|
||||||
|
|
||||||
To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
|
To allocate and map large (PAGE_SIZE or so) consistent DMA regions,
|
||||||
you should do:
|
you should do::
|
||||||
|
|
||||||
dma_addr_t dma_handle;
|
dma_addr_t dma_handle;
|
||||||
|
|
||||||
cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp);
|
cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp);
|
||||||
|
|
||||||
where device is a struct device *. This may be called in interrupt
|
where device is a ``struct device *``. This may be called in interrupt
|
||||||
context with the GFP_ATOMIC flag.
|
context with the GFP_ATOMIC flag.
|
||||||
|
|
||||||
Size is the length of the region you want to allocate, in bytes.
|
Size is the length of the region you want to allocate, in bytes.
|
||||||
|
@ -415,7 +423,7 @@ exists (for example) to guarantee that if you allocate a chunk
|
||||||
which is smaller than or equal to 64 kilobytes, the extent of the
|
which is smaller than or equal to 64 kilobytes, the extent of the
|
||||||
buffer you receive will not cross a 64K boundary.
|
buffer you receive will not cross a 64K boundary.
|
||||||
|
|
||||||
To unmap and free such a DMA region, you call:
|
To unmap and free such a DMA region, you call::
|
||||||
|
|
||||||
dma_free_coherent(dev, size, cpu_addr, dma_handle);
|
dma_free_coherent(dev, size, cpu_addr, dma_handle);
|
||||||
|
|
||||||
|
@ -430,7 +438,7 @@ a kmem_cache, but it uses dma_alloc_coherent(), not __get_free_pages().
|
||||||
Also, it understands common hardware constraints for alignment,
|
Also, it understands common hardware constraints for alignment,
|
||||||
like queue heads needing to be aligned on N byte boundaries.
|
like queue heads needing to be aligned on N byte boundaries.
|
||||||
|
|
||||||
Create a dma_pool like this:
|
Create a dma_pool like this::
|
||||||
|
|
||||||
struct dma_pool *pool;
|
struct dma_pool *pool;
|
||||||
|
|
||||||
|
@ -444,7 +452,7 @@ pass 0 for boundary; passing 4096 says memory allocated from this pool
|
||||||
must not cross 4KByte boundaries (but at that time it may be better to
|
must not cross 4KByte boundaries (but at that time it may be better to
|
||||||
use dma_alloc_coherent() directly instead).
|
use dma_alloc_coherent() directly instead).
|
||||||
|
|
||||||
Allocate memory from a DMA pool like this:
|
Allocate memory from a DMA pool like this::
|
||||||
|
|
||||||
cpu_addr = dma_pool_alloc(pool, flags, &dma_handle);
|
cpu_addr = dma_pool_alloc(pool, flags, &dma_handle);
|
||||||
|
|
||||||
|
@ -452,7 +460,7 @@ flags are GFP_KERNEL if blocking is permitted (not in_interrupt nor
|
||||||
holding SMP locks), GFP_ATOMIC otherwise. Like dma_alloc_coherent(),
|
holding SMP locks), GFP_ATOMIC otherwise. Like dma_alloc_coherent(),
|
||||||
this returns two values, cpu_addr and dma_handle.
|
this returns two values, cpu_addr and dma_handle.
|
||||||
|
|
||||||
Free memory that was allocated from a dma_pool like this:
|
Free memory that was allocated from a dma_pool like this::
|
||||||
|
|
||||||
dma_pool_free(pool, cpu_addr, dma_handle);
|
dma_pool_free(pool, cpu_addr, dma_handle);
|
||||||
|
|
||||||
|
@ -460,7 +468,7 @@ where pool is what you passed to dma_pool_alloc(), and cpu_addr and
|
||||||
dma_handle are the values dma_pool_alloc() returned. This function
|
dma_handle are the values dma_pool_alloc() returned. This function
|
||||||
may be called in interrupt context.
|
may be called in interrupt context.
|
||||||
|
|
||||||
Destroy a dma_pool by calling:
|
Destroy a dma_pool by calling::
|
||||||
|
|
||||||
dma_pool_destroy(pool);
|
dma_pool_destroy(pool);
|
||||||
|
|
||||||
|
@ -469,10 +477,11 @@ from a pool before you destroy the pool. This function may not
|
||||||
be called in interrupt context.
|
be called in interrupt context.
|
||||||
|
|
||||||
DMA Direction
|
DMA Direction
|
||||||
|
=============
|
||||||
|
|
||||||
The interfaces described in subsequent portions of this document
|
The interfaces described in subsequent portions of this document
|
||||||
take a DMA direction argument, which is an integer and takes on
|
take a DMA direction argument, which is an integer and takes on
|
||||||
one of the following values:
|
one of the following values::
|
||||||
|
|
||||||
DMA_BIDIRECTIONAL
|
DMA_BIDIRECTIONAL
|
||||||
DMA_TO_DEVICE
|
DMA_TO_DEVICE
|
||||||
|
@ -522,13 +531,14 @@ specifier. For receive packets, just the opposite, map/unmap them
|
||||||
with the DMA_FROM_DEVICE direction specifier.
|
with the DMA_FROM_DEVICE direction specifier.
|
||||||
|
|
||||||
Using Streaming DMA mappings
|
Using Streaming DMA mappings
|
||||||
|
============================
|
||||||
|
|
||||||
The streaming DMA mapping routines can be called from interrupt
|
The streaming DMA mapping routines can be called from interrupt
|
||||||
context. There are two versions of each map/unmap, one which will
|
context. There are two versions of each map/unmap, one which will
|
||||||
map/unmap a single memory region, and one which will map/unmap a
|
map/unmap a single memory region, and one which will map/unmap a
|
||||||
scatterlist.
|
scatterlist.
|
||||||
|
|
||||||
To map a single region, you do:
|
To map a single region, you do::
|
||||||
|
|
||||||
struct device *dev = &my_dev->dev;
|
struct device *dev = &my_dev->dev;
|
||||||
dma_addr_t dma_handle;
|
dma_addr_t dma_handle;
|
||||||
|
@ -545,37 +555,16 @@ To map a single region, you do:
|
||||||
goto map_error_handling;
|
goto map_error_handling;
|
||||||
}
|
}
|
||||||
|
|
||||||
and to unmap it:
|
and to unmap it::
|
||||||
|
|
||||||
dma_unmap_single(dev, dma_handle, size, direction);
|
dma_unmap_single(dev, dma_handle, size, direction);
|
||||||
|
|
||||||
You should call dma_mapping_error() as dma_map_single() could fail and return
|
You should call dma_mapping_error() as dma_map_single() could fail and return
|
||||||
error. Not all DMA implementations support the dma_mapping_error() interface.
|
error. Doing so will ensure that the mapping code will work correctly on all
|
||||||
However, it is a good practice to call dma_mapping_error() interface, which
|
DMA implementations without any dependency on the specifics of the underlying
|
||||||
will invoke the generic mapping error check interface. Doing so will ensure
|
implementation. Using the returned address without checking for errors could
|
||||||
that the mapping code will work correctly on all DMA implementations without
|
result in failures ranging from panics to silent data corruption. The same
|
||||||
any dependency on the specifics of the underlying implementation. Using the
|
applies to dma_map_page() as well.
|
||||||
returned address without checking for errors could result in failures ranging
|
|
||||||
from panics to silent data corruption. A couple of examples of incorrect ways
|
|
||||||
to check for errors that make assumptions about the underlying DMA
|
|
||||||
implementation are as follows and these are applicable to dma_map_page() as
|
|
||||||
well.
|
|
||||||
|
|
||||||
Incorrect example 1:
|
|
||||||
dma_addr_t dma_handle;
|
|
||||||
|
|
||||||
dma_handle = dma_map_single(dev, addr, size, direction);
|
|
||||||
if ((dma_handle & 0xffff != 0) || (dma_handle >= 0x1000000)) {
|
|
||||||
goto map_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
Incorrect example 2:
|
|
||||||
dma_addr_t dma_handle;
|
|
||||||
|
|
||||||
dma_handle = dma_map_single(dev, addr, size, direction);
|
|
||||||
if (dma_handle == DMA_ERROR_CODE) {
|
|
||||||
goto map_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
You should call dma_unmap_single() when the DMA activity is finished, e.g.,
|
You should call dma_unmap_single() when the DMA activity is finished, e.g.,
|
||||||
from the interrupt which told you that the DMA transfer is done.
|
from the interrupt which told you that the DMA transfer is done.
|
||||||
|
@ -584,7 +573,7 @@ Using CPU pointers like this for single mappings has a disadvantage:
|
||||||
you cannot reference HIGHMEM memory in this way. Thus, there is a
|
you cannot reference HIGHMEM memory in this way. Thus, there is a
|
||||||
map/unmap interface pair akin to dma_{map,unmap}_single(). These
|
map/unmap interface pair akin to dma_{map,unmap}_single(). These
|
||||||
interfaces deal with page/offset pairs instead of CPU pointers.
|
interfaces deal with page/offset pairs instead of CPU pointers.
|
||||||
Specifically:
|
Specifically::
|
||||||
|
|
||||||
struct device *dev = &my_dev->dev;
|
struct device *dev = &my_dev->dev;
|
||||||
dma_addr_t dma_handle;
|
dma_addr_t dma_handle;
|
||||||
|
@ -614,7 +603,7 @@ error as outlined under the dma_map_single() discussion.
|
||||||
You should call dma_unmap_page() when the DMA activity is finished, e.g.,
|
You should call dma_unmap_page() when the DMA activity is finished, e.g.,
|
||||||
from the interrupt which told you that the DMA transfer is done.
|
from the interrupt which told you that the DMA transfer is done.
|
||||||
|
|
||||||
With scatterlists, you map a region gathered from several regions by:
|
With scatterlists, you map a region gathered from several regions by::
|
||||||
|
|
||||||
int i, count = dma_map_sg(dev, sglist, nents, direction);
|
int i, count = dma_map_sg(dev, sglist, nents, direction);
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
@ -638,13 +627,15 @@ Then you should loop count times (note: this can be less than nents times)
|
||||||
and use sg_dma_address() and sg_dma_len() macros where you previously
|
and use sg_dma_address() and sg_dma_len() macros where you previously
|
||||||
accessed sg->address and sg->length as shown above.
|
accessed sg->address and sg->length as shown above.
|
||||||
|
|
||||||
To unmap a scatterlist, just call:
|
To unmap a scatterlist, just call::
|
||||||
|
|
||||||
dma_unmap_sg(dev, sglist, nents, direction);
|
dma_unmap_sg(dev, sglist, nents, direction);
|
||||||
|
|
||||||
Again, make sure DMA activity has already finished.
|
Again, make sure DMA activity has already finished.
|
||||||
|
|
||||||
PLEASE NOTE: The 'nents' argument to the dma_unmap_sg call must be
|
.. note::
|
||||||
|
|
||||||
|
The 'nents' argument to the dma_unmap_sg call must be
|
||||||
the _same_ one you passed into the dma_map_sg call,
|
the _same_ one you passed into the dma_map_sg call,
|
||||||
it should _NOT_ be the 'count' value _returned_ from the
|
it should _NOT_ be the 'count' value _returned_ from the
|
||||||
dma_map_sg call.
|
dma_map_sg call.
|
||||||
|
@ -659,11 +650,11 @@ properly in order for the CPU and device to see the most up-to-date and
|
||||||
correct copy of the DMA buffer.
|
correct copy of the DMA buffer.
|
||||||
|
|
||||||
So, firstly, just map it with dma_map_{single,sg}(), and after each DMA
|
So, firstly, just map it with dma_map_{single,sg}(), and after each DMA
|
||||||
transfer call either:
|
transfer call either::
|
||||||
|
|
||||||
dma_sync_single_for_cpu(dev, dma_handle, size, direction);
|
dma_sync_single_for_cpu(dev, dma_handle, size, direction);
|
||||||
|
|
||||||
or:
|
or::
|
||||||
|
|
||||||
dma_sync_sg_for_cpu(dev, sglist, nents, direction);
|
dma_sync_sg_for_cpu(dev, sglist, nents, direction);
|
||||||
|
|
||||||
|
@ -671,17 +662,19 @@ as appropriate.
|
||||||
|
|
||||||
Then, if you wish to let the device get at the DMA area again,
|
Then, if you wish to let the device get at the DMA area again,
|
||||||
finish accessing the data with the CPU, and then before actually
|
finish accessing the data with the CPU, and then before actually
|
||||||
giving the buffer to the hardware call either:
|
giving the buffer to the hardware call either::
|
||||||
|
|
||||||
dma_sync_single_for_device(dev, dma_handle, size, direction);
|
dma_sync_single_for_device(dev, dma_handle, size, direction);
|
||||||
|
|
||||||
or:
|
or::
|
||||||
|
|
||||||
dma_sync_sg_for_device(dev, sglist, nents, direction);
|
dma_sync_sg_for_device(dev, sglist, nents, direction);
|
||||||
|
|
||||||
as appropriate.
|
as appropriate.
|
||||||
|
|
||||||
PLEASE NOTE: The 'nents' argument to dma_sync_sg_for_cpu() and
|
.. note::
|
||||||
|
|
||||||
|
The 'nents' argument to dma_sync_sg_for_cpu() and
|
||||||
dma_sync_sg_for_device() must be the same passed to
|
dma_sync_sg_for_device() must be the same passed to
|
||||||
dma_map_sg(). It is _NOT_ the count returned by
|
dma_map_sg(). It is _NOT_ the count returned by
|
||||||
dma_map_sg().
|
dma_map_sg().
|
||||||
|
@ -692,7 +685,7 @@ dma_map_*() call till dma_unmap_*(), then you don't have to call the
|
||||||
dma_sync_*() routines at all.
|
dma_sync_*() routines at all.
|
||||||
|
|
||||||
Here is pseudo code which shows a situation in which you would need
|
Here is pseudo code which shows a situation in which you would need
|
||||||
to use the dma_sync_*() interfaces.
|
to use the dma_sync_*() interfaces::
|
||||||
|
|
||||||
my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
|
my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len)
|
||||||
{
|
{
|
||||||
|
@ -769,6 +762,7 @@ they are entirely deprecated. Some ports already do not provide these
|
||||||
as it is impossible to correctly support them.
|
as it is impossible to correctly support them.
|
||||||
|
|
||||||
Handling Errors
|
Handling Errors
|
||||||
|
===============
|
||||||
|
|
||||||
DMA address space is limited on some architectures and an allocation
|
DMA address space is limited on some architectures and an allocation
|
||||||
failure can be determined by:
|
failure can be determined by:
|
||||||
|
@ -776,7 +770,7 @@ failure can be determined by:
|
||||||
- checking if dma_alloc_coherent() returns NULL or dma_map_sg returns 0
|
- checking if dma_alloc_coherent() returns NULL or dma_map_sg returns 0
|
||||||
|
|
||||||
- checking the dma_addr_t returned from dma_map_single() and dma_map_page()
|
- checking the dma_addr_t returned from dma_map_single() and dma_map_page()
|
||||||
by using dma_mapping_error():
|
by using dma_mapping_error()::
|
||||||
|
|
||||||
dma_addr_t dma_handle;
|
dma_addr_t dma_handle;
|
||||||
|
|
||||||
|
@ -794,7 +788,8 @@ failure can be determined by:
|
||||||
of a multiple page mapping attempt. These example are applicable to
|
of a multiple page mapping attempt. These example are applicable to
|
||||||
dma_map_page() as well.
|
dma_map_page() as well.
|
||||||
|
|
||||||
Example 1:
|
Example 1::
|
||||||
|
|
||||||
dma_addr_t dma_handle1;
|
dma_addr_t dma_handle1;
|
||||||
dma_addr_t dma_handle2;
|
dma_addr_t dma_handle2;
|
||||||
|
|
||||||
|
@ -823,8 +818,12 @@ Example 1:
|
||||||
dma_unmap_single(dma_handle1);
|
dma_unmap_single(dma_handle1);
|
||||||
map_error_handling1:
|
map_error_handling1:
|
||||||
|
|
||||||
Example 2: (if buffers are allocated in a loop, unmap all mapped buffers when
|
Example 2::
|
||||||
mapping error is detected in the middle)
|
|
||||||
|
/*
|
||||||
|
* if buffers are allocated in a loop, unmap all mapped buffers when
|
||||||
|
* mapping error is detected in the middle
|
||||||
|
*/
|
||||||
|
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
dma_addr_t array[DMA_BUFFERS];
|
dma_addr_t array[DMA_BUFFERS];
|
||||||
|
@ -868,6 +867,7 @@ fails in the queuecommand hook. This means that the SCSI subsystem
|
||||||
passes the command to the driver again later.
|
passes the command to the driver again later.
|
||||||
|
|
||||||
Optimizing Unmap State Space Consumption
|
Optimizing Unmap State Space Consumption
|
||||||
|
========================================
|
||||||
|
|
||||||
On many platforms, dma_unmap_{single,page}() is simply a nop.
|
On many platforms, dma_unmap_{single,page}() is simply a nop.
|
||||||
Therefore, keeping track of the mapping address and length is a waste
|
Therefore, keeping track of the mapping address and length is a waste
|
||||||
|
@ -879,7 +879,7 @@ Actually, instead of describing the macros one by one, we'll
|
||||||
transform some example code.
|
transform some example code.
|
||||||
|
|
||||||
1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
|
1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
|
||||||
Example, before:
|
Example, before::
|
||||||
|
|
||||||
struct ring_state {
|
struct ring_state {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -887,7 +887,7 @@ transform some example code.
|
||||||
__u32 len;
|
__u32 len;
|
||||||
};
|
};
|
||||||
|
|
||||||
after:
|
after::
|
||||||
|
|
||||||
struct ring_state {
|
struct ring_state {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -896,23 +896,23 @@ transform some example code.
|
||||||
};
|
};
|
||||||
|
|
||||||
2) Use dma_unmap_{addr,len}_set() to set these values.
|
2) Use dma_unmap_{addr,len}_set() to set these values.
|
||||||
Example, before:
|
Example, before::
|
||||||
|
|
||||||
ringp->mapping = FOO;
|
ringp->mapping = FOO;
|
||||||
ringp->len = BAR;
|
ringp->len = BAR;
|
||||||
|
|
||||||
after:
|
after::
|
||||||
|
|
||||||
dma_unmap_addr_set(ringp, mapping, FOO);
|
dma_unmap_addr_set(ringp, mapping, FOO);
|
||||||
dma_unmap_len_set(ringp, len, BAR);
|
dma_unmap_len_set(ringp, len, BAR);
|
||||||
|
|
||||||
3) Use dma_unmap_{addr,len}() to access these values.
|
3) Use dma_unmap_{addr,len}() to access these values.
|
||||||
Example, before:
|
Example, before::
|
||||||
|
|
||||||
dma_unmap_single(dev, ringp->mapping, ringp->len,
|
dma_unmap_single(dev, ringp->mapping, ringp->len,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
|
|
||||||
after:
|
after::
|
||||||
|
|
||||||
dma_unmap_single(dev,
|
dma_unmap_single(dev,
|
||||||
dma_unmap_addr(ringp, mapping),
|
dma_unmap_addr(ringp, mapping),
|
||||||
|
@ -924,6 +924,7 @@ separately, because it is possible for an implementation to only
|
||||||
need the address in order to perform the unmap operation.
|
need the address in order to perform the unmap operation.
|
||||||
|
|
||||||
Platform Issues
|
Platform Issues
|
||||||
|
===============
|
||||||
|
|
||||||
If you are just writing drivers for Linux and do not maintain
|
If you are just writing drivers for Linux and do not maintain
|
||||||
an architecture port for the kernel, you can safely skip down
|
an architecture port for the kernel, you can safely skip down
|
||||||
|
@ -950,11 +951,12 @@ to "Closing".
|
||||||
objects).
|
objects).
|
||||||
|
|
||||||
Closing
|
Closing
|
||||||
|
=======
|
||||||
|
|
||||||
This document, and the API itself, would not be in its current
|
This document, and the API itself, would not be in its current
|
||||||
form without the feedback and suggestions from numerous individuals.
|
form without the feedback and suggestions from numerous individuals.
|
||||||
We would like to specifically mention, in no particular order, the
|
We would like to specifically mention, in no particular order, the
|
||||||
following people:
|
following people::
|
||||||
|
|
||||||
Russell King <rmk@arm.linux.org.uk>
|
Russell King <rmk@arm.linux.org.uk>
|
||||||
Leo Dagum <dagum@barrel.engr.sgi.com>
|
Leo Dagum <dagum@barrel.engr.sgi.com>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
============================================
|
||||||
Dynamic DMA mapping using the generic device
|
Dynamic DMA mapping using the generic device
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
|
:Author: James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
|
||||||
|
|
||||||
This document describes the DMA API. For a more gentle introduction
|
This document describes the DMA API. For a more gentle introduction
|
||||||
of the API (and actual examples), see Documentation/DMA-API-HOWTO.txt.
|
of the API (and actual examples), see Documentation/DMA-API-HOWTO.txt.
|
||||||
|
@ -13,7 +14,7 @@ non-consistent platforms (this is usually only legacy platforms) you
|
||||||
should only use the API described in part I.
|
should only use the API described in part I.
|
||||||
|
|
||||||
Part I - dma_API
|
Part I - dma_API
|
||||||
-------------------------------------
|
----------------
|
||||||
|
|
||||||
To get the dma_API, you must #include <linux/dma-mapping.h>. This
|
To get the dma_API, you must #include <linux/dma-mapping.h>. This
|
||||||
provides dma_addr_t and the interfaces described below.
|
provides dma_addr_t and the interfaces described below.
|
||||||
|
@ -26,6 +27,8 @@ address space and the DMA address space.
|
||||||
Part Ia - Using large DMA-coherent buffers
|
Part Ia - Using large DMA-coherent buffers
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void *
|
void *
|
||||||
dma_alloc_coherent(struct device *dev, size_t size,
|
dma_alloc_coherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_handle, gfp_t flag)
|
dma_addr_t *dma_handle, gfp_t flag)
|
||||||
|
@ -51,10 +54,12 @@ consolidate your requests for consistent memory as much as possible.
|
||||||
The simplest way to do that is to use the dma_pool calls (see below).
|
The simplest way to do that is to use the dma_pool calls (see below).
|
||||||
|
|
||||||
The flag parameter (dma_alloc_coherent() only) allows the caller to
|
The flag parameter (dma_alloc_coherent() only) allows the caller to
|
||||||
specify the GFP_ flags (see kmalloc()) for the allocation (the
|
specify the ``GFP_`` flags (see kmalloc()) for the allocation (the
|
||||||
implementation may choose to ignore flags that affect the location of
|
implementation may choose to ignore flags that affect the location of
|
||||||
the returned memory, like GFP_DMA).
|
the returned memory, like GFP_DMA).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void *
|
void *
|
||||||
dma_zalloc_coherent(struct device *dev, size_t size,
|
dma_zalloc_coherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_handle, gfp_t flag)
|
dma_addr_t *dma_handle, gfp_t flag)
|
||||||
|
@ -62,6 +67,8 @@ dma_zalloc_coherent(struct device *dev, size_t size,
|
||||||
Wraps dma_alloc_coherent() and also zeroes the returned memory if the
|
Wraps dma_alloc_coherent() and also zeroes the returned memory if the
|
||||||
allocation attempt succeeded.
|
allocation attempt succeeded.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
||||||
dma_addr_t dma_handle)
|
dma_addr_t dma_handle)
|
||||||
|
@ -88,6 +95,8 @@ not __get_free_pages(). Also, they understand common hardware constraints
|
||||||
for alignment, like queue heads needing to be aligned on N-byte boundaries.
|
for alignment, like queue heads needing to be aligned on N-byte boundaries.
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
struct dma_pool *
|
struct dma_pool *
|
||||||
dma_pool_create(const char *name, struct device *dev,
|
dma_pool_create(const char *name, struct device *dev,
|
||||||
size_t size, size_t align, size_t alloc);
|
size_t size, size_t align, size_t alloc);
|
||||||
|
@ -103,15 +112,20 @@ in bytes, and must be a power of two). If your device has no boundary
|
||||||
crossing restrictions, pass 0 for alloc; passing 4096 says memory allocated
|
crossing restrictions, pass 0 for alloc; passing 4096 says memory allocated
|
||||||
from this pool must not cross 4KByte boundaries.
|
from this pool must not cross 4KByte boundaries.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void *dma_pool_zalloc(struct dma_pool *pool, gfp_t mem_flags,
|
void *
|
||||||
|
dma_pool_zalloc(struct dma_pool *pool, gfp_t mem_flags,
|
||||||
dma_addr_t *handle)
|
dma_addr_t *handle)
|
||||||
|
|
||||||
Wraps dma_pool_alloc() and also zeroes the returned memory if the
|
Wraps dma_pool_alloc() and also zeroes the returned memory if the
|
||||||
allocation attempt succeeded.
|
allocation attempt succeeded.
|
||||||
|
|
||||||
|
|
||||||
void *dma_pool_alloc(struct dma_pool *pool, gfp_t gfp_flags,
|
::
|
||||||
|
|
||||||
|
void *
|
||||||
|
dma_pool_alloc(struct dma_pool *pool, gfp_t gfp_flags,
|
||||||
dma_addr_t *dma_handle);
|
dma_addr_t *dma_handle);
|
||||||
|
|
||||||
This allocates memory from the pool; the returned memory will meet the
|
This allocates memory from the pool; the returned memory will meet the
|
||||||
|
@ -122,16 +136,20 @@ blocking. Like dma_alloc_coherent(), this returns two values: an
|
||||||
address usable by the CPU, and the DMA address usable by the pool's
|
address usable by the CPU, and the DMA address usable by the pool's
|
||||||
device.
|
device.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void dma_pool_free(struct dma_pool *pool, void *vaddr,
|
void
|
||||||
|
dma_pool_free(struct dma_pool *pool, void *vaddr,
|
||||||
dma_addr_t addr);
|
dma_addr_t addr);
|
||||||
|
|
||||||
This puts memory back into the pool. The pool is what was passed to
|
This puts memory back into the pool. The pool is what was passed to
|
||||||
dma_pool_alloc(); the CPU (vaddr) and DMA addresses are what
|
dma_pool_alloc(); the CPU (vaddr) and DMA addresses are what
|
||||||
were returned when that routine allocated the memory being freed.
|
were returned when that routine allocated the memory being freed.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void dma_pool_destroy(struct dma_pool *pool);
|
void
|
||||||
|
dma_pool_destroy(struct dma_pool *pool);
|
||||||
|
|
||||||
dma_pool_destroy() frees the resources of the pool. It must be
|
dma_pool_destroy() frees the resources of the pool. It must be
|
||||||
called in a context which can sleep. Make sure you've freed all allocated
|
called in a context which can sleep. Make sure you've freed all allocated
|
||||||
|
@ -141,6 +159,8 @@ memory back to the pool before you destroy it.
|
||||||
Part Ic - DMA addressing limitations
|
Part Ic - DMA addressing limitations
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_set_mask_and_coherent(struct device *dev, u64 mask)
|
dma_set_mask_and_coherent(struct device *dev, u64 mask)
|
||||||
|
|
||||||
|
@ -149,6 +169,8 @@ streaming and coherent DMA mask parameters if it is.
|
||||||
|
|
||||||
Returns: 0 if successful and a negative error if not.
|
Returns: 0 if successful and a negative error if not.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_set_mask(struct device *dev, u64 mask)
|
dma_set_mask(struct device *dev, u64 mask)
|
||||||
|
|
||||||
|
@ -157,6 +179,8 @@ parameters if it is.
|
||||||
|
|
||||||
Returns: 0 if successful and a negative error if not.
|
Returns: 0 if successful and a negative error if not.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_set_coherent_mask(struct device *dev, u64 mask)
|
dma_set_coherent_mask(struct device *dev, u64 mask)
|
||||||
|
|
||||||
|
@ -165,6 +189,8 @@ parameters if it is.
|
||||||
|
|
||||||
Returns: 0 if successful and a negative error if not.
|
Returns: 0 if successful and a negative error if not.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
u64
|
u64
|
||||||
dma_get_required_mask(struct device *dev)
|
dma_get_required_mask(struct device *dev)
|
||||||
|
|
||||||
|
@ -182,6 +208,8 @@ call to set the mask to the value returned.
|
||||||
Part Id - Streaming DMA mappings
|
Part Id - Streaming DMA mappings
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
dma_addr_t
|
dma_addr_t
|
||||||
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
|
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
@ -193,12 +221,16 @@ The direction for both APIs may be converted freely by casting.
|
||||||
However the dma_API uses a strongly typed enumerator for its
|
However the dma_API uses a strongly typed enumerator for its
|
||||||
direction:
|
direction:
|
||||||
|
|
||||||
|
======================= =============================================
|
||||||
DMA_NONE no direction (used for debugging)
|
DMA_NONE no direction (used for debugging)
|
||||||
DMA_TO_DEVICE data is going from the memory to the device
|
DMA_TO_DEVICE data is going from the memory to the device
|
||||||
DMA_FROM_DEVICE data is coming from the device to the memory
|
DMA_FROM_DEVICE data is coming from the device to the memory
|
||||||
DMA_BIDIRECTIONAL direction isn't known
|
DMA_BIDIRECTIONAL direction isn't known
|
||||||
|
======================= =============================================
|
||||||
|
|
||||||
Notes: Not all memory regions in a machine can be mapped by this API.
|
.. note::
|
||||||
|
|
||||||
|
Not all memory regions in a machine can be mapped by this API.
|
||||||
Further, contiguous kernel virtual space may not be contiguous as
|
Further, contiguous kernel virtual space may not be contiguous as
|
||||||
physical memory. Since this API does not provide any scatter/gather
|
physical memory. Since this API does not provide any scatter/gather
|
||||||
capability, it will fail if the user tries to map a non-physically
|
capability, it will fail if the user tries to map a non-physically
|
||||||
|
@ -223,7 +255,9 @@ maps an I/O DMA address to a physical memory address). However, to be
|
||||||
portable, device driver writers may *not* assume that such an IOMMU
|
portable, device driver writers may *not* assume that such an IOMMU
|
||||||
exists.
|
exists.
|
||||||
|
|
||||||
Warnings: Memory coherency operates at a granularity called the cache
|
.. warning::
|
||||||
|
|
||||||
|
Memory coherency operates at a granularity called the cache
|
||||||
line width. In order for memory mapped by this API to operate
|
line width. In order for memory mapped by this API to operate
|
||||||
correctly, the mapped region must begin exactly on a cache line
|
correctly, the mapped region must begin exactly on a cache line
|
||||||
boundary and end exactly on one (to prevent two separately mapped
|
boundary and end exactly on one (to prevent two separately mapped
|
||||||
|
@ -255,6 +289,8 @@ are flushed from the processor) and once before the data may be
|
||||||
accessed after being used by the device (to make sure any processor
|
accessed after being used by the device (to make sure any processor
|
||||||
cache lines are updated with data that the device may have changed).
|
cache lines are updated with data that the device may have changed).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
@ -263,10 +299,13 @@ Unmaps the region previously mapped. All the parameters passed in
|
||||||
must be identical to those passed in (and returned) by the mapping
|
must be identical to those passed in (and returned) by the mapping
|
||||||
API.
|
API.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
dma_addr_t
|
dma_addr_t
|
||||||
dma_map_page(struct device *dev, struct page *page,
|
dma_map_page(struct device *dev, struct page *page,
|
||||||
unsigned long offset, size_t size,
|
unsigned long offset, size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
@ -277,6 +316,8 @@ and <size> parameters are provided to do partial page mapping, it is
|
||||||
recommended that you never use these unless you really know what the
|
recommended that you never use these unless you really know what the
|
||||||
cache width is.
|
cache width is.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
dma_addr_t
|
dma_addr_t
|
||||||
dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
|
dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
|
||||||
enum dma_data_direction dir, unsigned long attrs)
|
enum dma_data_direction dir, unsigned long attrs)
|
||||||
|
@ -289,6 +330,8 @@ API for mapping and unmapping for MMIO resources. All the notes and
|
||||||
warnings for the other mapping APIs apply here. The API should only be
|
warnings for the other mapping APIs apply here. The API should only be
|
||||||
used to map device MMIO resources, mapping of RAM is not permitted.
|
used to map device MMIO resources, mapping of RAM is not permitted.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||||
|
|
||||||
|
@ -298,6 +341,8 @@ the returned DMA address with dma_mapping_error(). A non-zero return value
|
||||||
means the mapping could not be created and the driver should take appropriate
|
means the mapping could not be created and the driver should take appropriate
|
||||||
action (e.g. reduce current DMA mapping usage or delay and try again later).
|
action (e.g. reduce current DMA mapping usage or delay and try again later).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_map_sg(struct device *dev, struct scatterlist *sg,
|
dma_map_sg(struct device *dev, struct scatterlist *sg,
|
||||||
int nents, enum dma_data_direction direction)
|
int nents, enum dma_data_direction direction)
|
||||||
|
@ -316,7 +361,7 @@ critical that the driver do something, in the case of a block driver
|
||||||
aborting the request or even oopsing is better than doing nothing and
|
aborting the request or even oopsing is better than doing nothing and
|
||||||
corrupting the filesystem.
|
corrupting the filesystem.
|
||||||
|
|
||||||
With scatterlists, you use the resulting mapping like this:
|
With scatterlists, you use the resulting mapping like this::
|
||||||
|
|
||||||
int i, count = dma_map_sg(dev, sglist, nents, direction);
|
int i, count = dma_map_sg(dev, sglist, nents, direction);
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
|
@ -337,6 +382,8 @@ Then you should loop count times (note: this can be less than nents times)
|
||||||
and use sg_dma_address() and sg_dma_len() macros where you previously
|
and use sg_dma_address() and sg_dma_len() macros where you previously
|
||||||
accessed sg->address and sg->length as shown above.
|
accessed sg->address and sg->length as shown above.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
dma_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||||
int nents, enum dma_data_direction direction)
|
int nents, enum dma_data_direction direction)
|
||||||
|
@ -348,17 +395,26 @@ API.
|
||||||
Note: <nents> must be the number you passed in, *not* the number of
|
Note: <nents> must be the number you passed in, *not* the number of
|
||||||
DMA address entries returned.
|
DMA address entries returned.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
|
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
|
||||||
|
size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
|
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
|
||||||
|
size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
|
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
|
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
|
||||||
|
int nents,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
|
||||||
Synchronise a single contiguous or scatter/gather mapping for the CPU
|
Synchronise a single contiguous or scatter/gather mapping for the CPU
|
||||||
|
@ -367,7 +423,10 @@ as those passed into the single mapping API. With the sync_single API,
|
||||||
you can use dma_handle and size parameters that aren't identical to
|
you can use dma_handle and size parameters that aren't identical to
|
||||||
those passed into the single mapping API to do a partial sync.
|
those passed into the single mapping API to do a partial sync.
|
||||||
|
|
||||||
Notes: You must do this:
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You must do this:
|
||||||
|
|
||||||
- Before reading values that have been written by DMA from the device
|
- Before reading values that have been written by DMA from the device
|
||||||
(use the DMA_FROM_DEVICE direction)
|
(use the DMA_FROM_DEVICE direction)
|
||||||
|
@ -378,6 +437,8 @@ Notes: You must do this:
|
||||||
|
|
||||||
See also dma_map_single().
|
See also dma_map_single().
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
dma_addr_t
|
dma_addr_t
|
||||||
dma_map_single_attrs(struct device *dev, void *cpu_addr, size_t size,
|
dma_map_single_attrs(struct device *dev, void *cpu_addr, size_t size,
|
||||||
enum dma_data_direction dir,
|
enum dma_data_direction dir,
|
||||||
|
@ -410,9 +471,9 @@ is identical to those of the corresponding function
|
||||||
without the _attrs suffix. As a result dma_map_single_attrs()
|
without the _attrs suffix. As a result dma_map_single_attrs()
|
||||||
can generally replace dma_map_single(), etc.
|
can generally replace dma_map_single(), etc.
|
||||||
|
|
||||||
As an example of the use of the *_attrs functions, here's how
|
As an example of the use of the ``*_attrs`` functions, here's how
|
||||||
you could pass an attribute DMA_ATTR_FOO when mapping memory
|
you could pass an attribute DMA_ATTR_FOO when mapping memory
|
||||||
for DMA:
|
for DMA::
|
||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
/* DMA_ATTR_FOO should be defined in linux/dma-mapping.h and
|
/* DMA_ATTR_FOO should be defined in linux/dma-mapping.h and
|
||||||
|
@ -427,7 +488,7 @@ for DMA:
|
||||||
|
|
||||||
Architectures that care about DMA_ATTR_FOO would check for its
|
Architectures that care about DMA_ATTR_FOO would check for its
|
||||||
presence in their implementations of the mapping and unmapping
|
presence in their implementations of the mapping and unmapping
|
||||||
routines, e.g.:
|
routines, e.g.:::
|
||||||
|
|
||||||
void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
|
void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
|
||||||
size_t size, enum dma_data_direction dir,
|
size_t size, enum dma_data_direction dir,
|
||||||
|
@ -437,10 +498,11 @@ void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
|
||||||
if (attrs & DMA_ATTR_FOO)
|
if (attrs & DMA_ATTR_FOO)
|
||||||
/* twizzle the frobnozzle */
|
/* twizzle the frobnozzle */
|
||||||
....
|
....
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Part II - Advanced dma_ usage
|
Part II - Advanced dma usage
|
||||||
-----------------------------
|
----------------------------
|
||||||
|
|
||||||
Warning: These pieces of the DMA API should not be used in the
|
Warning: These pieces of the DMA API should not be used in the
|
||||||
majority of cases, since they cater for unlikely corner cases that
|
majority of cases, since they cater for unlikely corner cases that
|
||||||
|
@ -450,6 +512,8 @@ If you don't understand how cache line coherency works between a
|
||||||
processor and an I/O device, you should not be using this part of the
|
processor and an I/O device, you should not be using this part of the
|
||||||
API at all.
|
API at all.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void *
|
void *
|
||||||
dma_alloc_noncoherent(struct device *dev, size_t size,
|
dma_alloc_noncoherent(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_handle, gfp_t flag)
|
dma_addr_t *dma_handle, gfp_t flag)
|
||||||
|
@ -468,6 +532,8 @@ only use this API if you positively know your driver will be
|
||||||
required to work on one of the rare (usually non-PCI) architectures
|
required to work on one of the rare (usually non-PCI) architectures
|
||||||
that simply cannot make consistent memory.
|
that simply cannot make consistent memory.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
|
dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
|
||||||
dma_addr_t dma_handle)
|
dma_addr_t dma_handle)
|
||||||
|
@ -476,6 +542,8 @@ Free memory allocated by the nonconsistent API. All parameters must
|
||||||
be identical to those passed in (and returned by
|
be identical to those passed in (and returned by
|
||||||
dma_alloc_noncoherent()).
|
dma_alloc_noncoherent()).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_get_cache_alignment(void)
|
dma_get_cache_alignment(void)
|
||||||
|
|
||||||
|
@ -483,11 +551,15 @@ Returns the processor cache alignment. This is the absolute minimum
|
||||||
alignment *and* width that you must observe when either mapping
|
alignment *and* width that you must observe when either mapping
|
||||||
memory or doing partial flushes.
|
memory or doing partial flushes.
|
||||||
|
|
||||||
Notes: This API may return a number *larger* than the actual cache
|
.. note::
|
||||||
|
|
||||||
|
This API may return a number *larger* than the actual cache
|
||||||
line, but it will guarantee that one or more cache lines fit exactly
|
line, but it will guarantee that one or more cache lines fit exactly
|
||||||
into the width returned by this call. It will also always be a power
|
into the width returned by this call. It will also always be a power
|
||||||
of two for easy alignment.
|
of two for easy alignment.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||||
enum dma_data_direction direction)
|
enum dma_data_direction direction)
|
||||||
|
@ -497,6 +569,8 @@ dma_alloc_noncoherent(), starting at virtual address vaddr and
|
||||||
continuing on for size. Again, you *must* observe the cache line
|
continuing on for size. Again, you *must* observe the cache line
|
||||||
boundaries when doing this.
|
boundaries when doing this.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
int
|
int
|
||||||
dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
|
dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
|
||||||
dma_addr_t device_addr, size_t size, int
|
dma_addr_t device_addr, size_t size, int
|
||||||
|
@ -516,19 +590,19 @@ size is the size of the area (must be multiples of PAGE_SIZE).
|
||||||
|
|
||||||
flags can be ORed together and are:
|
flags can be ORed together and are:
|
||||||
|
|
||||||
DMA_MEMORY_MAP - request that the memory returned from
|
- DMA_MEMORY_MAP - request that the memory returned from
|
||||||
dma_alloc_coherent() be directly writable.
|
dma_alloc_coherent() be directly writable.
|
||||||
|
|
||||||
DMA_MEMORY_IO - request that the memory returned from
|
- DMA_MEMORY_IO - request that the memory returned from
|
||||||
dma_alloc_coherent() be addressable using read()/write()/memcpy_toio() etc.
|
dma_alloc_coherent() be addressable using read()/write()/memcpy_toio() etc.
|
||||||
|
|
||||||
One or both of these flags must be present.
|
One or both of these flags must be present.
|
||||||
|
|
||||||
DMA_MEMORY_INCLUDES_CHILDREN - make the declared memory be allocated by
|
- DMA_MEMORY_INCLUDES_CHILDREN - make the declared memory be allocated by
|
||||||
dma_alloc_coherent of any child devices of this one (for memory residing
|
dma_alloc_coherent of any child devices of this one (for memory residing
|
||||||
on a bridge).
|
on a bridge).
|
||||||
|
|
||||||
DMA_MEMORY_EXCLUSIVE - only allocate memory from the declared regions.
|
- DMA_MEMORY_EXCLUSIVE - only allocate memory from the declared regions.
|
||||||
Do not allow dma_alloc_coherent() to fall back to system memory when
|
Do not allow dma_alloc_coherent() to fall back to system memory when
|
||||||
it's out of memory in the declared region.
|
it's out of memory in the declared region.
|
||||||
|
|
||||||
|
@ -543,13 +617,15 @@ must be accessed using the correct bus functions. If your driver
|
||||||
isn't prepared to handle this contingency, it should not specify
|
isn't prepared to handle this contingency, it should not specify
|
||||||
DMA_MEMORY_IO in the input flags.
|
DMA_MEMORY_IO in the input flags.
|
||||||
|
|
||||||
As a simplification for the platforms, only *one* such region of
|
As a simplification for the platforms, only **one** such region of
|
||||||
memory may be declared per device.
|
memory may be declared per device.
|
||||||
|
|
||||||
For reasons of efficiency, most platforms choose to track the declared
|
For reasons of efficiency, most platforms choose to track the declared
|
||||||
region only at the granularity of a page. For smaller allocations,
|
region only at the granularity of a page. For smaller allocations,
|
||||||
you should use the dma_pool() API.
|
you should use the dma_pool() API.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void
|
void
|
||||||
dma_release_declared_memory(struct device *dev)
|
dma_release_declared_memory(struct device *dev)
|
||||||
|
|
||||||
|
@ -559,6 +635,8 @@ unconditionally having removed all the required structures. It is the
|
||||||
driver's job to ensure that no parts of this memory region are
|
driver's job to ensure that no parts of this memory region are
|
||||||
currently in use.
|
currently in use.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
void *
|
void *
|
||||||
dma_mark_declared_memory_occupied(struct device *dev,
|
dma_mark_declared_memory_occupied(struct device *dev,
|
||||||
dma_addr_t device_addr, size_t size)
|
dma_addr_t device_addr, size_t size)
|
||||||
|
@ -592,9 +670,8 @@ option has a performance impact. Do not enable it in production kernels.
|
||||||
If you boot the resulting kernel will contain code which does some bookkeeping
|
If you boot the resulting kernel will contain code which does some bookkeeping
|
||||||
about what DMA memory was allocated for which device. If this code detects an
|
about what DMA memory was allocated for which device. If this code detects an
|
||||||
error it prints a warning message with some details into your kernel log. An
|
error it prints a warning message with some details into your kernel log. An
|
||||||
example warning message may look like this:
|
example warning message may look like this::
|
||||||
|
|
||||||
------------[ cut here ]------------
|
|
||||||
WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448
|
WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448
|
||||||
check_unmap+0x203/0x490()
|
check_unmap+0x203/0x490()
|
||||||
Hardware name:
|
Hardware name:
|
||||||
|
@ -637,6 +714,7 @@ details.
|
||||||
The debugfs directory for the DMA-API debugging code is called dma-api/. In
|
The debugfs directory for the DMA-API debugging code is called dma-api/. In
|
||||||
this directory the following files can currently be found:
|
this directory the following files can currently be found:
|
||||||
|
|
||||||
|
=============================== ===============================================
|
||||||
dma-api/all_errors This file contains a numeric value. If this
|
dma-api/all_errors This file contains a numeric value. If this
|
||||||
value is not equal to zero the debugging code
|
value is not equal to zero the debugging code
|
||||||
will print a warning for every error it finds
|
will print a warning for every error it finds
|
||||||
|
@ -657,23 +735,21 @@ this directory the following files can currently be found:
|
||||||
one at system boot and be set by writing into
|
one at system boot and be set by writing into
|
||||||
this file
|
this file
|
||||||
|
|
||||||
dma-api/min_free_entries
|
dma-api/min_free_entries This read-only file can be read to get the
|
||||||
This read-only file can be read to get the
|
|
||||||
minimum number of free dma_debug_entries the
|
minimum number of free dma_debug_entries the
|
||||||
allocator has ever seen. If this value goes
|
allocator has ever seen. If this value goes
|
||||||
down to zero the code will disable itself
|
down to zero the code will disable itself
|
||||||
because it is not longer reliable.
|
because it is not longer reliable.
|
||||||
|
|
||||||
dma-api/num_free_entries
|
dma-api/num_free_entries The current number of free dma_debug_entries
|
||||||
The current number of free dma_debug_entries
|
|
||||||
in the allocator.
|
in the allocator.
|
||||||
|
|
||||||
dma-api/driver-filter
|
dma-api/driver-filter You can write a name of a driver into this file
|
||||||
You can write a name of a driver into this file
|
|
||||||
to limit the debug output to requests from that
|
to limit the debug output to requests from that
|
||||||
particular driver. Write an empty string to
|
particular driver. Write an empty string to
|
||||||
that file to disable the filter and see
|
that file to disable the filter and see
|
||||||
all errors again.
|
all errors again.
|
||||||
|
=============================== ===============================================
|
||||||
|
|
||||||
If you have this code compiled into your kernel it will be enabled by default.
|
If you have this code compiled into your kernel it will be enabled by default.
|
||||||
If you want to boot without the bookkeeping anyway you can provide
|
If you want to boot without the bookkeeping anyway you can provide
|
||||||
|
@ -692,7 +768,10 @@ of preallocated entries is defined per architecture. If it is too low for you
|
||||||
boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
|
boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
|
||||||
architectural default.
|
architectural default.
|
||||||
|
|
||||||
void debug_dmap_mapping_error(struct device *dev, dma_addr_t dma_addr);
|
::
|
||||||
|
|
||||||
|
void
|
||||||
|
debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
|
||||||
|
|
||||||
dma-debug interface debug_dma_mapping_error() to debug drivers that fail
|
dma-debug interface debug_dma_mapping_error() to debug drivers that fail
|
||||||
to check DMA mapping errors on addresses returned by dma_map_single() and
|
to check DMA mapping errors on addresses returned by dma_map_single() and
|
||||||
|
@ -702,4 +781,3 @@ the driver. When driver does unmap, debug_dma_unmap() checks the flag and if
|
||||||
this flag is still set, prints warning message that includes call trace that
|
this flag is still set, prints warning message that includes call trace that
|
||||||
leads up to the unmap. This interface can be called from dma_mapping_error()
|
leads up to the unmap. This interface can be called from dma_mapping_error()
|
||||||
routines to enable DMA mapping error check debugging.
|
routines to enable DMA mapping error check debugging.
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
|
============================
|
||||||
DMA with ISA and LPC devices
|
DMA with ISA and LPC devices
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Pierre Ossman <drzeus@drzeus.cx>
|
:Author: Pierre Ossman <drzeus@drzeus.cx>
|
||||||
|
|
||||||
This document describes how to do DMA transfers using the old ISA DMA
|
This document describes how to do DMA transfers using the old ISA DMA
|
||||||
controller. Even though ISA is more or less dead today the LPC bus
|
controller. Even though ISA is more or less dead today the LPC bus
|
||||||
uses the same DMA system so it will be around for quite some time.
|
uses the same DMA system so it will be around for quite some time.
|
||||||
|
|
||||||
Part I - Headers and dependencies
|
Headers and dependencies
|
||||||
---------------------------------
|
------------------------
|
||||||
|
|
||||||
To do ISA style DMA you need to include two headers:
|
To do ISA style DMA you need to include two headers::
|
||||||
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
|
@ -23,8 +24,8 @@ this is not present on all platforms make sure you construct your
|
||||||
Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries
|
Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries
|
||||||
to build your driver on unsupported platforms.
|
to build your driver on unsupported platforms.
|
||||||
|
|
||||||
Part II - Buffer allocation
|
Buffer allocation
|
||||||
---------------------------
|
-----------------
|
||||||
|
|
||||||
The ISA DMA controller has some very strict requirements on which
|
The ISA DMA controller has some very strict requirements on which
|
||||||
memory it can access so extra care must be taken when allocating
|
memory it can access so extra care must be taken when allocating
|
||||||
|
@ -42,13 +43,13 @@ requirements you pass the flag GFP_DMA to kmalloc.
|
||||||
|
|
||||||
Unfortunately the memory available for ISA DMA is scarce so unless you
|
Unfortunately the memory available for ISA DMA is scarce so unless you
|
||||||
allocate the memory during boot-up it's a good idea to also pass
|
allocate the memory during boot-up it's a good idea to also pass
|
||||||
__GFP_REPEAT and __GFP_NOWARN to make the allocator try a bit harder.
|
__GFP_RETRY_MAYFAIL and __GFP_NOWARN to make the allocator try a bit harder.
|
||||||
|
|
||||||
(This scarcity also means that you should allocate the buffer as
|
(This scarcity also means that you should allocate the buffer as
|
||||||
early as possible and not release it until the driver is unloaded.)
|
early as possible and not release it until the driver is unloaded.)
|
||||||
|
|
||||||
Part III - Address translation
|
Address translation
|
||||||
------------------------------
|
-------------------
|
||||||
|
|
||||||
To translate the virtual address to a bus address, use the normal DMA
|
To translate the virtual address to a bus address, use the normal DMA
|
||||||
API. Do _not_ use isa_virt_to_phys() even though it does the same
|
API. Do _not_ use isa_virt_to_phys() even though it does the same
|
||||||
|
@ -61,8 +62,8 @@ Note: x86_64 had a broken DMA API when it came to ISA but has since
|
||||||
been fixed. If your arch has problems then fix the DMA API instead of
|
been fixed. If your arch has problems then fix the DMA API instead of
|
||||||
reverting to the ISA functions.
|
reverting to the ISA functions.
|
||||||
|
|
||||||
Part IV - Channels
|
Channels
|
||||||
------------------
|
--------
|
||||||
|
|
||||||
A normal ISA DMA controller has 8 channels. The lower four are for
|
A normal ISA DMA controller has 8 channels. The lower four are for
|
||||||
8-bit transfers and the upper four are for 16-bit transfers.
|
8-bit transfers and the upper four are for 16-bit transfers.
|
||||||
|
@ -80,8 +81,8 @@ The ability to use 16-bit or 8-bit transfers is _not_ up to you as a
|
||||||
driver author but depends on what the hardware supports. Check your
|
driver author but depends on what the hardware supports. Check your
|
||||||
specs or test different channels.
|
specs or test different channels.
|
||||||
|
|
||||||
Part V - Transfer data
|
Transfer data
|
||||||
----------------------
|
-------------
|
||||||
|
|
||||||
Now for the good stuff, the actual DMA transfer. :)
|
Now for the good stuff, the actual DMA transfer. :)
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ Once the DMA transfer is finished (or timed out) you should disable
|
||||||
the channel again. You should also check get_dma_residue() to make
|
the channel again. You should also check get_dma_residue() to make
|
||||||
sure that all data has been transferred.
|
sure that all data has been transferred.
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
int flags, residue;
|
int flags, residue;
|
||||||
|
|
||||||
|
@ -141,8 +142,8 @@ if (residue != 0)
|
||||||
|
|
||||||
release_dma_lock(flags);
|
release_dma_lock(flags);
|
||||||
|
|
||||||
Part VI - Suspend/resume
|
Suspend/resume
|
||||||
------------------------
|
--------------
|
||||||
|
|
||||||
It is the driver's responsibility to make sure that the machine isn't
|
It is the driver's responsibility to make sure that the machine isn't
|
||||||
suspended while a DMA transfer is in progress. Also, all DMA settings
|
suspended while a DMA transfer is in progress. Also, all DMA settings
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
==============
|
||||||
DMA attributes
|
DMA attributes
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
@ -108,6 +109,7 @@ This is a hint to the DMA-mapping subsystem that it's probably not worth
|
||||||
the time to try to allocate memory to in a way that gives better TLB
|
the time to try to allocate memory to in a way that gives better TLB
|
||||||
efficiency (AKA it's not worth trying to build the mapping out of larger
|
efficiency (AKA it's not worth trying to build the mapping out of larger
|
||||||
pages). You might want to specify this if:
|
pages). You might want to specify this if:
|
||||||
|
|
||||||
- You know that the accesses to this memory won't thrash the TLB.
|
- You know that the accesses to this memory won't thrash the TLB.
|
||||||
You might know that the accesses are likely to be sequential or
|
You might know that the accesses are likely to be sequential or
|
||||||
that they aren't sequential but it's unlikely you'll ping-pong
|
that they aren't sequential but it's unlikely you'll ping-pong
|
||||||
|
@ -121,10 +123,11 @@ pages). You might want to specify this if:
|
||||||
the mapping to have a short lifetime then it may be worth it to
|
the mapping to have a short lifetime then it may be worth it to
|
||||||
optimize allocation (avoid coming up with large pages) instead of
|
optimize allocation (avoid coming up with large pages) instead of
|
||||||
getting the slight performance win of larger pages.
|
getting the slight performance win of larger pages.
|
||||||
|
|
||||||
Setting this hint doesn't guarantee that you won't get huge pages, but it
|
Setting this hint doesn't guarantee that you won't get huge pages, but it
|
||||||
means that we won't try quite as hard to get them.
|
means that we won't try quite as hard to get them.
|
||||||
|
|
||||||
NOTE: At the moment DMA_ATTR_ALLOC_SINGLE_PAGES is only implemented on ARM,
|
.. note:: At the moment DMA_ATTR_ALLOC_SINGLE_PAGES is only implemented on ARM,
|
||||||
though ARM64 patches will likely be posted soon.
|
though ARM64 patches will likely be posted soon.
|
||||||
|
|
||||||
DMA_ATTR_NO_WARN
|
DMA_ATTR_NO_WARN
|
||||||
|
@ -142,10 +145,10 @@ problem at all, depending on the implementation of the retry mechanism.
|
||||||
So, this provides a way for drivers to avoid those error messages on calls
|
So, this provides a way for drivers to avoid those error messages on calls
|
||||||
where allocation failures are not a problem, and shouldn't bother the logs.
|
where allocation failures are not a problem, and shouldn't bother the logs.
|
||||||
|
|
||||||
NOTE: At the moment DMA_ATTR_NO_WARN is only implemented on PowerPC.
|
.. note:: At the moment DMA_ATTR_NO_WARN is only implemented on PowerPC.
|
||||||
|
|
||||||
DMA_ATTR_PRIVILEGED
|
DMA_ATTR_PRIVILEGED
|
||||||
------------------------------
|
-------------------
|
||||||
|
|
||||||
Some advanced peripherals such as remote processors and GPUs perform
|
Some advanced peripherals such as remote processors and GPUs perform
|
||||||
accesses to DMA buffers in both privileged "supervisor" and unprivileged
|
accesses to DMA buffers in both privileged "supervisor" and unprivileged
|
||||||
|
|
17
kernel/Documentation/DocBook/.gitignore
vendored
17
kernel/Documentation/DocBook/.gitignore
vendored
|
@ -1,17 +0,0 @@
|
||||||
*.xml
|
|
||||||
*.ps
|
|
||||||
*.pdf
|
|
||||||
*.html
|
|
||||||
*.9.gz
|
|
||||||
*.9
|
|
||||||
*.aux
|
|
||||||
*.dvi
|
|
||||||
*.log
|
|
||||||
*.out
|
|
||||||
*.png
|
|
||||||
*.gif
|
|
||||||
*.svg
|
|
||||||
*.proc
|
|
||||||
*.db
|
|
||||||
media-indices.tmpl
|
|
||||||
media-entities.tmpl
|
|
|
@ -1,282 +0,0 @@
|
||||||
###
|
|
||||||
# This makefile is used to generate the kernel documentation,
|
|
||||||
# primarily based on in-line comments in various source files.
|
|
||||||
# See Documentation/kernel-doc-nano-HOWTO.txt for instruction in how
|
|
||||||
# to document the SRC - and how to read it.
|
|
||||||
# To add a new book the only step required is to add the book to the
|
|
||||||
# list of DOCBOOKS.
|
|
||||||
|
|
||||||
DOCBOOKS := z8530book.xml \
|
|
||||||
kernel-hacking.xml kernel-locking.xml \
|
|
||||||
networking.xml \
|
|
||||||
filesystems.xml lsm.xml kgdb.xml \
|
|
||||||
libata.xml mtdnand.xml librs.xml rapidio.xml \
|
|
||||||
s390-drivers.xml scsi.xml \
|
|
||||||
sh.xml w1.xml
|
|
||||||
|
|
||||||
ifeq ($(DOCBOOKS),)
|
|
||||||
|
|
||||||
# Skip DocBook build if the user explicitly requested no DOCBOOKS.
|
|
||||||
.DEFAULT:
|
|
||||||
@echo " SKIP DocBook $@ target (DOCBOOKS=\"\" specified)."
|
|
||||||
else
|
|
||||||
ifneq ($(SPHINXDIRS),)
|
|
||||||
|
|
||||||
# Skip DocBook build if the user explicitly requested a sphinx dir
|
|
||||||
.DEFAULT:
|
|
||||||
@echo " SKIP DocBook $@ target (SPHINXDIRS specified)."
|
|
||||||
else
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
# The build process is as follows (targets):
|
|
||||||
# (xmldocs) [by docproc]
|
|
||||||
# file.tmpl --> file.xml +--> file.ps (psdocs) [by db2ps or xmlto]
|
|
||||||
# +--> file.pdf (pdfdocs) [by db2pdf or xmlto]
|
|
||||||
# +--> DIR=file (htmldocs) [by xmlto]
|
|
||||||
# +--> man/ (mandocs) [by xmlto]
|
|
||||||
|
|
||||||
|
|
||||||
# for PDF and PS output you can choose between xmlto and docbook-utils tools
|
|
||||||
PDF_METHOD = $(prefer-db2x)
|
|
||||||
PS_METHOD = $(prefer-db2x)
|
|
||||||
|
|
||||||
|
|
||||||
targets += $(DOCBOOKS)
|
|
||||||
BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
|
|
||||||
xmldocs: $(BOOKS)
|
|
||||||
sgmldocs: xmldocs
|
|
||||||
|
|
||||||
PS := $(patsubst %.xml, %.ps, $(BOOKS))
|
|
||||||
psdocs: $(PS)
|
|
||||||
|
|
||||||
PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
|
|
||||||
pdfdocs: $(PDF)
|
|
||||||
|
|
||||||
HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
|
|
||||||
htmldocs: $(HTML)
|
|
||||||
$(call cmd,build_main_index)
|
|
||||||
|
|
||||||
MAN := $(patsubst %.xml, %.9, $(BOOKS))
|
|
||||||
mandocs: $(MAN)
|
|
||||||
find $(obj)/man -name '*.9' | xargs gzip -nf
|
|
||||||
|
|
||||||
# Default location for installed man pages
|
|
||||||
export INSTALL_MAN_PATH = $(objtree)/usr
|
|
||||||
|
|
||||||
installmandocs: mandocs
|
|
||||||
mkdir -p $(INSTALL_MAN_PATH)/man/man9/
|
|
||||||
find $(obj)/man -name '*.9.gz' -printf '%h %f\n' | \
|
|
||||||
sort -k 2 -k 1 | uniq -f 1 | sed -e 's: :/:' | \
|
|
||||||
xargs install -m 644 -t $(INSTALL_MAN_PATH)/man/man9/
|
|
||||||
|
|
||||||
# no-op for the DocBook toolchain
|
|
||||||
epubdocs:
|
|
||||||
latexdocs:
|
|
||||||
linkcheckdocs:
|
|
||||||
|
|
||||||
###
|
|
||||||
#External programs used
|
|
||||||
KERNELDOCXMLREF = $(srctree)/scripts/kernel-doc-xml-ref
|
|
||||||
KERNELDOC = $(srctree)/scripts/kernel-doc
|
|
||||||
DOCPROC = $(objtree)/scripts/docproc
|
|
||||||
CHECK_LC_CTYPE = $(objtree)/scripts/check-lc_ctype
|
|
||||||
|
|
||||||
# Use a fixed encoding - UTF-8 if the C library has support built-in
|
|
||||||
# or ASCII if not
|
|
||||||
LC_CTYPE := $(call try-run, LC_CTYPE=C.UTF-8 $(CHECK_LC_CTYPE),C.UTF-8,C)
|
|
||||||
export LC_CTYPE
|
|
||||||
|
|
||||||
XMLTOFLAGS = -m $(srctree)/$(src)/stylesheet.xsl
|
|
||||||
XMLTOFLAGS += --skip-validation
|
|
||||||
|
|
||||||
###
|
|
||||||
# DOCPROC is used for two purposes:
|
|
||||||
# 1) To generate a dependency list for a .tmpl file
|
|
||||||
# 2) To preprocess a .tmpl file and call kernel-doc with
|
|
||||||
# appropriate parameters.
|
|
||||||
# The following rules are used to generate the .xml documentation
|
|
||||||
# required to generate the final targets. (ps, pdf, html).
|
|
||||||
quiet_cmd_docproc = DOCPROC $@
|
|
||||||
cmd_docproc = SRCTREE=$(srctree)/ $(DOCPROC) doc $< >$@
|
|
||||||
define rule_docproc
|
|
||||||
set -e; \
|
|
||||||
$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))';) \
|
|
||||||
$(cmd_$(1)); \
|
|
||||||
( \
|
|
||||||
echo 'cmd_$@ := $(cmd_$(1))'; \
|
|
||||||
echo $@: `SRCTREE=$(srctree) $(DOCPROC) depend $<`; \
|
|
||||||
) > $(dir $@).$(notdir $@).cmd
|
|
||||||
endef
|
|
||||||
|
|
||||||
%.xml: %.tmpl $(KERNELDOC) $(DOCPROC) $(KERNELDOCXMLREF) FORCE
|
|
||||||
$(call if_changed_rule,docproc)
|
|
||||||
|
|
||||||
# Tell kbuild to always build the programs
|
|
||||||
always := $(hostprogs-y)
|
|
||||||
|
|
||||||
notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
|
|
||||||
exit 1
|
|
||||||
db2xtemplate = db2TYPE -o $(dir $@) $<
|
|
||||||
xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
|
|
||||||
|
|
||||||
# determine which methods are available
|
|
||||||
ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found)
|
|
||||||
use-db2x = db2x
|
|
||||||
prefer-db2x = db2x
|
|
||||||
else
|
|
||||||
use-db2x = notfound
|
|
||||||
prefer-db2x = $(use-xmlto)
|
|
||||||
endif
|
|
||||||
ifeq ($(shell which xmlto >/dev/null 2>&1 && echo found),found)
|
|
||||||
use-xmlto = xmlto
|
|
||||||
prefer-xmlto = xmlto
|
|
||||||
else
|
|
||||||
use-xmlto = notfound
|
|
||||||
prefer-xmlto = $(use-db2x)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# the commands, generated from the chosen template
|
|
||||||
quiet_cmd_db2ps = PS $@
|
|
||||||
cmd_db2ps = $(subst TYPE,ps, $($(PS_METHOD)template))
|
|
||||||
%.ps : %.xml
|
|
||||||
$(call cmd,db2ps)
|
|
||||||
|
|
||||||
quiet_cmd_db2pdf = PDF $@
|
|
||||||
cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template))
|
|
||||||
%.pdf : %.xml
|
|
||||||
$(call cmd,db2pdf)
|
|
||||||
|
|
||||||
|
|
||||||
index = index.html
|
|
||||||
main_idx = $(obj)/$(index)
|
|
||||||
quiet_cmd_build_main_index = HTML $(main_idx)
|
|
||||||
cmd_build_main_index = rm -rf $(main_idx); \
|
|
||||||
echo '<h1>Linux Kernel HTML Documentation</h1>' >> $(main_idx) && \
|
|
||||||
echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \
|
|
||||||
cat $(HTML) >> $(main_idx)
|
|
||||||
|
|
||||||
quiet_cmd_db2html = HTML $@
|
|
||||||
cmd_db2html = xmlto html $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
|
|
||||||
echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
|
|
||||||
$(patsubst %.html,%,$(notdir $@))</a><p>' > $@
|
|
||||||
|
|
||||||
###
|
|
||||||
# Rules to create an aux XML and .db, and use them to re-process the DocBook XML
|
|
||||||
# to fill internal hyperlinks
|
|
||||||
gen_aux_xml = :
|
|
||||||
quiet_gen_aux_xml = echo ' XMLREF $@'
|
|
||||||
silent_gen_aux_xml = :
|
|
||||||
%.aux.xml: %.xml
|
|
||||||
@$($(quiet)gen_aux_xml)
|
|
||||||
@rm -rf $@
|
|
||||||
@(cat $< | egrep "^<refentry id" | egrep -o "\".*\"" | cut -f 2 -d \" > $<.db)
|
|
||||||
@$(KERNELDOCXMLREF) -db $<.db $< > $@
|
|
||||||
.PRECIOUS: %.aux.xml
|
|
||||||
|
|
||||||
%.html: %.aux.xml
|
|
||||||
@(which xmlto > /dev/null 2>&1) || \
|
|
||||||
(echo "*** You need to install xmlto ***"; \
|
|
||||||
exit 1)
|
|
||||||
@rm -rf $@ $(patsubst %.html,%,$@)
|
|
||||||
$(call cmd,db2html)
|
|
||||||
@if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
|
|
||||||
cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
|
|
||||||
|
|
||||||
quiet_cmd_db2man = MAN $@
|
|
||||||
cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man/$(*F) $< ; fi
|
|
||||||
%.9 : %.xml
|
|
||||||
@(which xmlto > /dev/null 2>&1) || \
|
|
||||||
(echo "*** You need to install xmlto ***"; \
|
|
||||||
exit 1)
|
|
||||||
$(Q)mkdir -p $(obj)/man/$(*F)
|
|
||||||
$(call cmd,db2man)
|
|
||||||
@touch $@
|
|
||||||
|
|
||||||
###
|
|
||||||
# Rules to generate postscripts and PNG images from .fig format files
|
|
||||||
quiet_cmd_fig2eps = FIG2EPS $@
|
|
||||||
cmd_fig2eps = fig2dev -Leps $< $@
|
|
||||||
|
|
||||||
%.eps: %.fig
|
|
||||||
@(which fig2dev > /dev/null 2>&1) || \
|
|
||||||
(echo "*** You need to install transfig ***"; \
|
|
||||||
exit 1)
|
|
||||||
$(call cmd,fig2eps)
|
|
||||||
|
|
||||||
quiet_cmd_fig2png = FIG2PNG $@
|
|
||||||
cmd_fig2png = fig2dev -Lpng $< $@
|
|
||||||
|
|
||||||
%.png: %.fig
|
|
||||||
@(which fig2dev > /dev/null 2>&1) || \
|
|
||||||
(echo "*** You need to install transfig ***"; \
|
|
||||||
exit 1)
|
|
||||||
$(call cmd,fig2png)
|
|
||||||
|
|
||||||
###
|
|
||||||
# Rule to convert a .c file to inline XML documentation
|
|
||||||
gen_xml = :
|
|
||||||
quiet_gen_xml = echo ' GEN $@'
|
|
||||||
silent_gen_xml = :
|
|
||||||
%.xml: %.c
|
|
||||||
@$($(quiet)gen_xml)
|
|
||||||
@( \
|
|
||||||
echo "<programlisting>"; \
|
|
||||||
expand --tabs=8 < $< | \
|
|
||||||
sed -e "s/&/\\&/g" \
|
|
||||||
-e "s/</\\</g" \
|
|
||||||
-e "s/>/\\>/g"; \
|
|
||||||
echo "</programlisting>") > $@
|
|
||||||
|
|
||||||
endif # DOCBOOKS=""
|
|
||||||
endif # SPHINDIR=...
|
|
||||||
|
|
||||||
###
|
|
||||||
# Help targets as used by the top-level makefile
|
|
||||||
dochelp:
|
|
||||||
@echo ' Linux kernel internal documentation in different formats (DocBook):'
|
|
||||||
@echo ' htmldocs - HTML'
|
|
||||||
@echo ' pdfdocs - PDF'
|
|
||||||
@echo ' psdocs - Postscript'
|
|
||||||
@echo ' xmldocs - XML DocBook'
|
|
||||||
@echo ' mandocs - man pages'
|
|
||||||
@echo ' installmandocs - install man pages generated by mandocs to INSTALL_MAN_PATH'; \
|
|
||||||
echo ' (default: $(INSTALL_MAN_PATH))'; \
|
|
||||||
echo ''
|
|
||||||
@echo ' cleandocs - clean all generated DocBook files'
|
|
||||||
@echo
|
|
||||||
@echo ' make DOCBOOKS="s1.xml s2.xml" [target] Generate only docs s1.xml s2.xml'
|
|
||||||
@echo ' valid values for DOCBOOKS are: $(DOCBOOKS)'
|
|
||||||
@echo
|
|
||||||
@echo " make DOCBOOKS=\"\" [target] Don't generate docs from Docbook"
|
|
||||||
@echo ' This is useful to generate only the ReST docs (Sphinx)'
|
|
||||||
|
|
||||||
|
|
||||||
###
|
|
||||||
# Temporary files left by various tools
|
|
||||||
clean-files := $(DOCBOOKS) \
|
|
||||||
$(patsubst %.xml, %.dvi, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.aux, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.tex, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.log, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.out, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.ps, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.pdf, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.html, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.aux.xml, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.xml.db, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, %.xml, $(DOCBOOKS)) \
|
|
||||||
$(patsubst %.xml, .%.xml.cmd, $(DOCBOOKS)) \
|
|
||||||
$(index)
|
|
||||||
|
|
||||||
clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
|
|
||||||
|
|
||||||
cleandocs:
|
|
||||||
$(Q)rm -f $(call objectify, $(clean-files))
|
|
||||||
$(Q)rm -rf $(call objectify, $(clean-dirs))
|
|
||||||
|
|
||||||
# Declare the contents of the .PHONY variable as phony. We keep that
|
|
||||||
# information in a variable so we can use it in if_changed and friends.
|
|
||||||
|
|
||||||
.PHONY: $(PHONY)
|
|
|
@ -1,381 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="Linux-filesystems-API">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Linux Filesystems API</title>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later
|
|
||||||
version.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="vfs">
|
|
||||||
<title>The Linux VFS</title>
|
|
||||||
<sect1 id="the_filesystem_types"><title>The Filesystem types</title>
|
|
||||||
!Iinclude/linux/fs.h
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="the_directory_cache"><title>The Directory Cache</title>
|
|
||||||
!Efs/dcache.c
|
|
||||||
!Iinclude/linux/dcache.h
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="inode_handling"><title>Inode Handling</title>
|
|
||||||
!Efs/inode.c
|
|
||||||
!Efs/bad_inode.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="registration_and_superblocks"><title>Registration and Superblocks</title>
|
|
||||||
!Efs/super.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="file_locks"><title>File Locks</title>
|
|
||||||
!Efs/locks.c
|
|
||||||
!Ifs/locks.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="other_functions"><title>Other Functions</title>
|
|
||||||
!Efs/mpage.c
|
|
||||||
!Efs/namei.c
|
|
||||||
!Efs/buffer.c
|
|
||||||
!Eblock/bio.c
|
|
||||||
!Efs/seq_file.c
|
|
||||||
!Efs/filesystems.c
|
|
||||||
!Efs/fs-writeback.c
|
|
||||||
!Efs/block_dev.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="proc">
|
|
||||||
<title>The proc filesystem</title>
|
|
||||||
|
|
||||||
<sect1 id="sysctl_interface"><title>sysctl interface</title>
|
|
||||||
!Ekernel/sysctl.c
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="proc_filesystem_interface"><title>proc filesystem interface</title>
|
|
||||||
!Ifs/proc/base.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="fs_events">
|
|
||||||
<title>Events based on file descriptors</title>
|
|
||||||
!Efs/eventfd.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="sysfs">
|
|
||||||
<title>The Filesystem for Exporting Kernel Objects</title>
|
|
||||||
!Efs/sysfs/file.c
|
|
||||||
!Efs/sysfs/symlink.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="debugfs">
|
|
||||||
<title>The debugfs filesystem</title>
|
|
||||||
|
|
||||||
<sect1 id="debugfs_interface"><title>debugfs interface</title>
|
|
||||||
!Efs/debugfs/inode.c
|
|
||||||
!Efs/debugfs/file.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="LinuxJDBAPI">
|
|
||||||
<chapterinfo>
|
|
||||||
<title>The Linux Journalling API</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Roger</firstname>
|
|
||||||
<surname>Gammans</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>rgammans@computer-surgery.co.uk</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Stephen</firstname>
|
|
||||||
<surname>Tweedie</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>sct@redhat.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2002</year>
|
|
||||||
<holder>Roger Gammans</holder>
|
|
||||||
</copyright>
|
|
||||||
</chapterinfo>
|
|
||||||
|
|
||||||
<title>The Linux Journalling API</title>
|
|
||||||
|
|
||||||
<sect1 id="journaling_overview">
|
|
||||||
<title>Overview</title>
|
|
||||||
<sect2 id="journaling_details">
|
|
||||||
<title>Details</title>
|
|
||||||
<para>
|
|
||||||
The journalling layer is easy to use. You need to
|
|
||||||
first of all create a journal_t data structure. There are
|
|
||||||
two calls to do this dependent on how you decide to allocate the physical
|
|
||||||
media on which the journal resides. The jbd2_journal_init_inode() call
|
|
||||||
is for journals stored in filesystem inodes, or the jbd2_journal_init_dev()
|
|
||||||
call can be used for journal stored on a raw device (in a continuous range
|
|
||||||
of blocks). A journal_t is a typedef for a struct pointer, so when
|
|
||||||
you are finally finished make sure you call jbd2_journal_destroy() on it
|
|
||||||
to free up any used kernel memory.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Once you have got your journal_t object you need to 'mount' or load the journal
|
|
||||||
file. The journalling layer expects the space for the journal was already
|
|
||||||
allocated and initialized properly by the userspace tools. When loading the
|
|
||||||
journal you must call jbd2_journal_load() to process journal contents. If the
|
|
||||||
client file system detects the journal contents does not need to be processed
|
|
||||||
(or even need not have valid contents), it may call jbd2_journal_wipe() to
|
|
||||||
clear the journal contents before calling jbd2_journal_load().
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Note that jbd2_journal_wipe(..,0) calls jbd2_journal_skip_recovery() for you if
|
|
||||||
it detects any outstanding transactions in the journal and similarly
|
|
||||||
jbd2_journal_load() will call jbd2_journal_recover() if necessary. I would
|
|
||||||
advise reading ext4_load_journal() in fs/ext4/super.c for examples on this
|
|
||||||
stage.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Now you can go ahead and start modifying the underlying
|
|
||||||
filesystem. Almost.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
|
|
||||||
You still need to actually journal your filesystem changes, this
|
|
||||||
is done by wrapping them into transactions. Additionally you
|
|
||||||
also need to wrap the modification of each of the buffers
|
|
||||||
with calls to the journal layer, so it knows what the modifications
|
|
||||||
you are actually making are. To do this use jbd2_journal_start() which
|
|
||||||
returns a transaction handle.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
jbd2_journal_start()
|
|
||||||
and its counterpart jbd2_journal_stop(), which indicates the end of a
|
|
||||||
transaction are nestable calls, so you can reenter a transaction if necessary,
|
|
||||||
but remember you must call jbd2_journal_stop() the same number of times as
|
|
||||||
jbd2_journal_start() before the transaction is completed (or more accurately
|
|
||||||
leaves the update phase). Ext4/VFS makes use of this feature to simplify
|
|
||||||
handling of inode dirtying, quota support, etc.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Inside each transaction you need to wrap the modifications to the
|
|
||||||
individual buffers (blocks). Before you start to modify a buffer you
|
|
||||||
need to call jbd2_journal_get_{create,write,undo}_access() as appropriate,
|
|
||||||
this allows the journalling layer to copy the unmodified data if it
|
|
||||||
needs to. After all the buffer may be part of a previously uncommitted
|
|
||||||
transaction.
|
|
||||||
At this point you are at last ready to modify a buffer, and once
|
|
||||||
you are have done so you need to call jbd2_journal_dirty_{meta,}data().
|
|
||||||
Or if you've asked for access to a buffer you now know is now longer
|
|
||||||
required to be pushed back on the device you can call jbd2_journal_forget()
|
|
||||||
in much the same way as you might have used bforget() in the past.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
A jbd2_journal_flush() may be called at any time to commit and checkpoint
|
|
||||||
all your transactions.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Then at umount time , in your put_super() you can then call jbd2_journal_destroy()
|
|
||||||
to clean up your in-core journal object.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Unfortunately there a couple of ways the journal layer can cause a deadlock.
|
|
||||||
The first thing to note is that each task can only have
|
|
||||||
a single outstanding transaction at any one time, remember nothing
|
|
||||||
commits until the outermost jbd2_journal_stop(). This means
|
|
||||||
you must complete the transaction at the end of each file/inode/address
|
|
||||||
etc. operation you perform, so that the journalling system isn't re-entered
|
|
||||||
on another journal. Since transactions can't be nested/batched
|
|
||||||
across differing journals, and another filesystem other than
|
|
||||||
yours (say ext4) may be modified in a later syscall.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The second case to bear in mind is that jbd2_journal_start() can
|
|
||||||
block if there isn't enough space in the journal for your transaction
|
|
||||||
(based on the passed nblocks param) - when it blocks it merely(!) needs to
|
|
||||||
wait for transactions to complete and be committed from other tasks,
|
|
||||||
so essentially we are waiting for jbd2_journal_stop(). So to avoid
|
|
||||||
deadlocks you must treat jbd2_journal_start/stop() as if they
|
|
||||||
were semaphores and include them in your semaphore ordering rules to prevent
|
|
||||||
deadlocks. Note that jbd2_journal_extend() has similar blocking behaviour to
|
|
||||||
jbd2_journal_start() so you can deadlock here just as easily as on
|
|
||||||
jbd2_journal_start().
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Try to reserve the right number of blocks the first time. ;-). This will
|
|
||||||
be the maximum number of blocks you are going to touch in this transaction.
|
|
||||||
I advise having a look at at least ext4_jbd.h to see the basis on which
|
|
||||||
ext4 uses to make these decisions.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Another wriggle to watch out for is your on-disk block allocation strategy.
|
|
||||||
Why? Because, if you do a delete, you need to ensure you haven't reused any
|
|
||||||
of the freed blocks until the transaction freeing these blocks commits. If you
|
|
||||||
reused these blocks and crash happens, there is no way to restore the contents
|
|
||||||
of the reallocated blocks at the end of the last fully committed transaction.
|
|
||||||
|
|
||||||
One simple way of doing this is to mark blocks as free in internal in-memory
|
|
||||||
block allocation structures only after the transaction freeing them commits.
|
|
||||||
Ext4 uses journal commit callback for this purpose.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
With journal commit callbacks you can ask the journalling layer to call a
|
|
||||||
callback function when the transaction is finally committed to disk, so that
|
|
||||||
you can do some of your own management. You ask the journalling layer for
|
|
||||||
calling the callback by simply setting journal->j_commit_callback function
|
|
||||||
pointer and that function is called after each transaction commit. You can also
|
|
||||||
use transaction->t_private_list for attaching entries to a transaction that
|
|
||||||
need processing when the transaction commits.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
JBD2 also provides a way to block all transaction updates via
|
|
||||||
jbd2_journal_{un,}lock_updates(). Ext4 uses this when it wants a window with a
|
|
||||||
clean and stable fs for a moment. E.g.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting>
|
|
||||||
|
|
||||||
jbd2_journal_lock_updates() //stop new stuff happening..
|
|
||||||
jbd2_journal_flush() // checkpoint everything.
|
|
||||||
..do stuff on stable fs
|
|
||||||
jbd2_journal_unlock_updates() // carry on with filesystem use.
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The opportunities for abuse and DOS attacks with this should be obvious,
|
|
||||||
if you allow unprivileged userspace to trigger codepaths containing these
|
|
||||||
calls.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="jbd_summary">
|
|
||||||
<title>Summary</title>
|
|
||||||
<para>
|
|
||||||
Using the journal is a matter of wrapping the different context changes,
|
|
||||||
being each mount, each modification (transaction) and each changed buffer
|
|
||||||
to tell the journalling layer about them.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="data_types">
|
|
||||||
<title>Data Types</title>
|
|
||||||
<para>
|
|
||||||
The journalling layer uses typedefs to 'hide' the concrete definitions
|
|
||||||
of the structures used. As a client of the JBD2 layer you can
|
|
||||||
just rely on the using the pointer as a magic cookie of some sort.
|
|
||||||
|
|
||||||
Obviously the hiding is not enforced as this is 'C'.
|
|
||||||
</para>
|
|
||||||
<sect2 id="structures"><title>Structures</title>
|
|
||||||
!Iinclude/linux/jbd2.h
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="functions">
|
|
||||||
<title>Functions</title>
|
|
||||||
<para>
|
|
||||||
The functions here are split into two groups those that
|
|
||||||
affect a journal as a whole, and those which are used to
|
|
||||||
manage transactions
|
|
||||||
</para>
|
|
||||||
<sect2 id="journal_level"><title>Journal Level</title>
|
|
||||||
!Efs/jbd2/journal.c
|
|
||||||
!Ifs/jbd2/recovery.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="transaction_level"><title>Transasction Level</title>
|
|
||||||
!Efs/jbd2/transaction.c
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="see_also">
|
|
||||||
<title>See also</title>
|
|
||||||
<para>
|
|
||||||
<citation>
|
|
||||||
<ulink url="http://kernel.org/pub/linux/kernel/people/sct/ext3/journal-design.ps.gz">
|
|
||||||
Journaling the Linux ext2fs Filesystem, LinuxExpo 98, Stephen Tweedie
|
|
||||||
</ulink>
|
|
||||||
</citation>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<citation>
|
|
||||||
<ulink url="http://olstrans.sourceforge.net/release/OLS2000-ext3/OLS2000-ext3.html">
|
|
||||||
Ext3 Journalling FileSystem, OLS 2000, Dr. Stephen Tweedie
|
|
||||||
</ulink>
|
|
||||||
</citation>
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="splice">
|
|
||||||
<title>splice API</title>
|
|
||||||
<para>
|
|
||||||
splice is a method for moving blocks of data around inside the
|
|
||||||
kernel, without continually transferring them between the kernel
|
|
||||||
and user space.
|
|
||||||
</para>
|
|
||||||
!Ffs/splice.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="pipes">
|
|
||||||
<title>pipes API</title>
|
|
||||||
<para>
|
|
||||||
Pipe interfaces are all for in-kernel (builtin image) use.
|
|
||||||
They are not exported for use by modules.
|
|
||||||
</para>
|
|
||||||
!Iinclude/linux/pipe_fs_i.h
|
|
||||||
!Ffs/pipe.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
</book>
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,918 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="kgdbOnLinux">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Using kgdb, kdb and the kernel debugger internals</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Jason</firstname>
|
|
||||||
<surname>Wessel</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>jason.wessel@windriver.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
<copyright>
|
|
||||||
<year>2008,2010</year>
|
|
||||||
<holder>Wind River Systems, Inc.</holder>
|
|
||||||
</copyright>
|
|
||||||
<copyright>
|
|
||||||
<year>2004-2005</year>
|
|
||||||
<holder>MontaVista Software, Inc.</holder>
|
|
||||||
</copyright>
|
|
||||||
<copyright>
|
|
||||||
<year>2004</year>
|
|
||||||
<holder>Amit S. Kale</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This file is licensed under the terms of the GNU General Public License
|
|
||||||
version 2. This program is licensed "as is" without any warranty of any
|
|
||||||
kind, whether express or implied.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
<chapter id="Introduction">
|
|
||||||
<title>Introduction</title>
|
|
||||||
<para>
|
|
||||||
The kernel has two different debugger front ends (kdb and kgdb)
|
|
||||||
which interface to the debug core. It is possible to use either
|
|
||||||
of the debugger front ends and dynamically transition between them
|
|
||||||
if you configure the kernel properly at compile and runtime.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Kdb is simplistic shell-style interface which you can use on a
|
|
||||||
system console with a keyboard or serial console. You can use it
|
|
||||||
to inspect memory, registers, process lists, dmesg, and even set
|
|
||||||
breakpoints to stop in a certain location. Kdb is not a source
|
|
||||||
level debugger, although you can set breakpoints and execute some
|
|
||||||
basic kernel run control. Kdb is mainly aimed at doing some
|
|
||||||
analysis to aid in development or diagnosing kernel problems. You
|
|
||||||
can access some symbols by name in kernel built-ins or in kernel
|
|
||||||
modules if the code was built
|
|
||||||
with <symbol>CONFIG_KALLSYMS</symbol>.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Kgdb is intended to be used as a source level debugger for the
|
|
||||||
Linux kernel. It is used along with gdb to debug a Linux kernel.
|
|
||||||
The expectation is that gdb can be used to "break in" to the
|
|
||||||
kernel to inspect memory, variables and look through call stack
|
|
||||||
information similar to the way an application developer would use
|
|
||||||
gdb to debug an application. It is possible to place breakpoints
|
|
||||||
in kernel code and perform some limited execution stepping.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Two machines are required for using kgdb. One of these machines is
|
|
||||||
a development machine and the other is the target machine. The
|
|
||||||
kernel to be debugged runs on the target machine. The development
|
|
||||||
machine runs an instance of gdb against the vmlinux file which
|
|
||||||
contains the symbols (not a boot image such as bzImage, zImage,
|
|
||||||
uImage...). In gdb the developer specifies the connection
|
|
||||||
parameters and connects to kgdb. The type of connection a
|
|
||||||
developer makes with gdb depends on the availability of kgdb I/O
|
|
||||||
modules compiled as built-ins or loadable kernel modules in the test
|
|
||||||
machine's kernel.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="CompilingAKernel">
|
|
||||||
<title>Compiling a kernel</title>
|
|
||||||
<para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>In order to enable compilation of kdb, you must first enable kgdb.</para></listitem>
|
|
||||||
<listitem><para>The kgdb test compile options are described in the kgdb test suite chapter.</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
<sect1 id="CompileKGDB">
|
|
||||||
<title>Kernel config options for kgdb</title>
|
|
||||||
<para>
|
|
||||||
To enable <symbol>CONFIG_KGDB</symbol> you should look under
|
|
||||||
"Kernel hacking" / "Kernel debugging" and select "KGDB: kernel debugger".
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
While it is not a hard requirement that you have symbols in your
|
|
||||||
vmlinux file, gdb tends not to be very useful without the symbolic
|
|
||||||
data, so you will want to turn
|
|
||||||
on <symbol>CONFIG_DEBUG_INFO</symbol> which is called "Compile the
|
|
||||||
kernel with debug info" in the config menu.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
It is advised, but not required, that you turn on the
|
|
||||||
<symbol>CONFIG_FRAME_POINTER</symbol> kernel option which is called "Compile the
|
|
||||||
kernel with frame pointers" in the config menu. This option
|
|
||||||
inserts code to into the compiled executable which saves the frame
|
|
||||||
information in registers or on the stack at different points which
|
|
||||||
allows a debugger such as gdb to more accurately construct
|
|
||||||
stack back traces while debugging the kernel.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If the architecture that you are using supports the kernel option
|
|
||||||
CONFIG_STRICT_KERNEL_RWX, you should consider turning it off. This
|
|
||||||
option will prevent the use of software breakpoints because it
|
|
||||||
marks certain regions of the kernel's memory space as read-only.
|
|
||||||
If kgdb supports it for the architecture you are using, you can
|
|
||||||
use hardware breakpoints if you desire to run with the
|
|
||||||
CONFIG_STRICT_KERNEL_RWX option turned on, else you need to turn off
|
|
||||||
this option.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Next you should choose one of more I/O drivers to interconnect
|
|
||||||
debugging host and debugged target. Early boot debugging requires
|
|
||||||
a KGDB I/O driver that supports early debugging and the driver
|
|
||||||
must be built into the kernel directly. Kgdb I/O driver
|
|
||||||
configuration takes place via kernel or module parameters which
|
|
||||||
you can learn more about in the in the section that describes the
|
|
||||||
parameter "kgdboc".
|
|
||||||
</para>
|
|
||||||
<para>Here is an example set of .config symbols to enable or
|
|
||||||
disable for kgdb:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para># CONFIG_STRICT_KERNEL_RWX is not set</para></listitem>
|
|
||||||
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
|
|
||||||
<listitem><para>CONFIG_KGDB=y</para></listitem>
|
|
||||||
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="CompileKDB">
|
|
||||||
<title>Kernel config options for kdb</title>
|
|
||||||
<para>Kdb is quite a bit more complex than the simple gdbstub
|
|
||||||
sitting on top of the kernel's debug core. Kdb must implement a
|
|
||||||
shell, and also adds some helper functions in other parts of the
|
|
||||||
kernel, responsible for printing out interesting data such as what
|
|
||||||
you would see if you ran "lsmod", or "ps". In order to build kdb
|
|
||||||
into the kernel you follow the same steps as you would for kgdb.
|
|
||||||
</para>
|
|
||||||
<para>The main config option for kdb
|
|
||||||
is <symbol>CONFIG_KGDB_KDB</symbol> which is called "KGDB_KDB:
|
|
||||||
include kdb frontend for kgdb" in the config menu. In theory you
|
|
||||||
would have already also selected an I/O driver such as the
|
|
||||||
CONFIG_KGDB_SERIAL_CONSOLE interface if you plan on using kdb on a
|
|
||||||
serial port, when you were configuring kgdb.
|
|
||||||
</para>
|
|
||||||
<para>If you want to use a PS/2-style keyboard with kdb, you would
|
|
||||||
select CONFIG_KDB_KEYBOARD which is called "KGDB_KDB: keyboard as
|
|
||||||
input device" in the config menu. The CONFIG_KDB_KEYBOARD option
|
|
||||||
is not used for anything in the gdb interface to kgdb. The
|
|
||||||
CONFIG_KDB_KEYBOARD option only works with kdb.
|
|
||||||
</para>
|
|
||||||
<para>Here is an example set of .config symbols to enable/disable kdb:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para># CONFIG_STRICT_KERNEL_RWX is not set</para></listitem>
|
|
||||||
<listitem><para>CONFIG_FRAME_POINTER=y</para></listitem>
|
|
||||||
<listitem><para>CONFIG_KGDB=y</para></listitem>
|
|
||||||
<listitem><para>CONFIG_KGDB_SERIAL_CONSOLE=y</para></listitem>
|
|
||||||
<listitem><para>CONFIG_KGDB_KDB=y</para></listitem>
|
|
||||||
<listitem><para>CONFIG_KDB_KEYBOARD=y</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="kgdbKernelArgs">
|
|
||||||
<title>Kernel Debugger Boot Arguments</title>
|
|
||||||
<para>This section describes the various runtime kernel
|
|
||||||
parameters that affect the configuration of the kernel debugger.
|
|
||||||
The following chapter covers using kdb and kgdb as well as
|
|
||||||
providing some examples of the configuration parameters.</para>
|
|
||||||
<sect1 id="kgdboc">
|
|
||||||
<title>Kernel parameter: kgdboc</title>
|
|
||||||
<para>The kgdboc driver was originally an abbreviation meant to
|
|
||||||
stand for "kgdb over console". Today it is the primary mechanism
|
|
||||||
to configure how to communicate from gdb to kgdb as well as the
|
|
||||||
devices you want to use to interact with the kdb shell.
|
|
||||||
</para>
|
|
||||||
<para>For kgdb/gdb, kgdboc is designed to work with a single serial
|
|
||||||
port. It is intended to cover the circumstance where you want to
|
|
||||||
use a serial console as your primary console as well as using it to
|
|
||||||
perform kernel debugging. It is also possible to use kgdb on a
|
|
||||||
serial port which is not designated as a system console. Kgdboc
|
|
||||||
may be configured as a kernel built-in or a kernel loadable module.
|
|
||||||
You can only make use of <constant>kgdbwait</constant> and early
|
|
||||||
debugging if you build kgdboc into the kernel as a built-in.
|
|
||||||
</para>
|
|
||||||
<para>Optionally you can elect to activate kms (Kernel Mode
|
|
||||||
Setting) integration. When you use kms with kgdboc and you have a
|
|
||||||
video driver that has atomic mode setting hooks, it is possible to
|
|
||||||
enter the debugger on the graphics console. When the kernel
|
|
||||||
execution is resumed, the previous graphics mode will be restored.
|
|
||||||
This integration can serve as a useful tool to aid in diagnosing
|
|
||||||
crashes or doing analysis of memory with kdb while allowing the
|
|
||||||
full graphics console applications to run.
|
|
||||||
</para>
|
|
||||||
<sect2 id="kgdbocArgs">
|
|
||||||
<title>kgdboc arguments</title>
|
|
||||||
<para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
|
|
||||||
<para>The order listed above must be observed if you use any of the
|
|
||||||
optional configurations together.
|
|
||||||
</para>
|
|
||||||
<para>Abbreviations:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>kms = Kernel Mode Setting</para></listitem>
|
|
||||||
<listitem><para>kbd = Keyboard</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
<para>You can configure kgdboc to use the keyboard, and/or a serial
|
|
||||||
device depending on if you are using kdb and/or kgdb, in one of the
|
|
||||||
following scenarios. The order listed above must be observed if
|
|
||||||
you use any of the optional configurations together. Using kms +
|
|
||||||
only gdb is generally not a useful combination.</para>
|
|
||||||
<sect3 id="kgdbocArgs1">
|
|
||||||
<title>Using loadable module or built-in</title>
|
|
||||||
<para>
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>As a kernel built-in:</para>
|
|
||||||
<para>Use the kernel boot argument: <constant>kgdboc=<tty-device>,[baud]</constant></para></listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>As a kernel loadable module:</para>
|
|
||||||
<para>Use the command: <constant>modprobe kgdboc kgdboc=<tty-device>,[baud]</constant></para>
|
|
||||||
<para>Here are two examples of how you might format the kgdboc
|
|
||||||
string. The first is for an x86 target using the first serial port.
|
|
||||||
The second example is for the ARM Versatile AB using the second
|
|
||||||
serial port.
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para><constant>kgdboc=ttyS0,115200</constant></para></listitem>
|
|
||||||
<listitem><para><constant>kgdboc=ttyAMA1,115200</constant></para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist></para>
|
|
||||||
</sect3>
|
|
||||||
<sect3 id="kgdbocArgs2">
|
|
||||||
<title>Configure kgdboc at runtime with sysfs</title>
|
|
||||||
<para>At run time you can enable or disable kgdboc by echoing a
|
|
||||||
parameters into the sysfs. Here are two examples:</para>
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Enable kgdboc on ttyS0</para>
|
|
||||||
<para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
|
||||||
<listitem><para>Disable kgdboc</para>
|
|
||||||
<para><constant>echo "" > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
<para>NOTE: You do not need to specify the baud if you are
|
|
||||||
configuring the console on tty which is already configured or
|
|
||||||
open.</para>
|
|
||||||
</sect3>
|
|
||||||
<sect3 id="kgdbocArgs3">
|
|
||||||
<title>More examples</title>
|
|
||||||
<para>You can configure kgdboc to use the keyboard, and/or a serial device
|
|
||||||
depending on if you are using kdb and/or kgdb, in one of the
|
|
||||||
following scenarios.
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>kdb and kgdb over only a serial port</para>
|
|
||||||
<para><constant>kgdboc=<serial_device>[,baud]</constant></para>
|
|
||||||
<para>Example: <constant>kgdboc=ttyS0,115200</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kdb and kgdb with keyboard and a serial port</para>
|
|
||||||
<para><constant>kgdboc=kbd,<serial_device>[,baud]</constant></para>
|
|
||||||
<para>Example: <constant>kgdboc=kbd,ttyS0,115200</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kdb with a keyboard</para>
|
|
||||||
<para><constant>kgdboc=kbd</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kdb with kernel mode setting</para>
|
|
||||||
<para><constant>kgdboc=kms,kbd</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kdb with kernel mode setting and kgdb over a serial port</para>
|
|
||||||
<para><constant>kgdboc=kms,kbd,ttyS0,115200</constant></para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
<para>NOTE: Kgdboc does not support interrupting the target via the
|
|
||||||
gdb remote protocol. You must manually send a sysrq-g unless you
|
|
||||||
have a proxy that splits console output to a terminal program.
|
|
||||||
A console proxy has a separate TCP port for the debugger and a separate
|
|
||||||
TCP port for the "human" console. The proxy can take care of sending
|
|
||||||
the sysrq-g for you.
|
|
||||||
</para>
|
|
||||||
<para>When using kgdboc with no debugger proxy, you can end up
|
|
||||||
connecting the debugger at one of two entry points. If an
|
|
||||||
exception occurs after you have loaded kgdboc, a message should
|
|
||||||
print on the console stating it is waiting for the debugger. In
|
|
||||||
this case you disconnect your terminal program and then connect the
|
|
||||||
debugger in its place. If you want to interrupt the target system
|
|
||||||
and forcibly enter a debug session you have to issue a Sysrq
|
|
||||||
sequence and then type the letter <constant>g</constant>. Then
|
|
||||||
you disconnect the terminal session and connect gdb. Your options
|
|
||||||
if you don't like this are to hack gdb to send the sysrq-g for you
|
|
||||||
as well as on the initial connect, or to use a debugger proxy that
|
|
||||||
allows an unmodified gdb to do the debugging.
|
|
||||||
</para>
|
|
||||||
</sect3>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="kgdbwait">
|
|
||||||
<title>Kernel parameter: kgdbwait</title>
|
|
||||||
<para>
|
|
||||||
The Kernel command line option <constant>kgdbwait</constant> makes
|
|
||||||
kgdb wait for a debugger connection during booting of a kernel. You
|
|
||||||
can only use this option if you compiled a kgdb I/O driver into the
|
|
||||||
kernel and you specified the I/O driver configuration as a kernel
|
|
||||||
command line option. The kgdbwait parameter should always follow the
|
|
||||||
configuration parameter for the kgdb I/O driver in the kernel
|
|
||||||
command line else the I/O driver will not be configured prior to
|
|
||||||
asking the kernel to use it to wait.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The kernel will stop and wait as early as the I/O driver and
|
|
||||||
architecture allows when you use this option. If you build the
|
|
||||||
kgdb I/O driver as a loadable kernel module kgdbwait will not do
|
|
||||||
anything.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="kgdbcon">
|
|
||||||
<title>Kernel parameter: kgdbcon</title>
|
|
||||||
<para> The kgdbcon feature allows you to see printk() messages
|
|
||||||
inside gdb while gdb is connected to the kernel. Kdb does not make
|
|
||||||
use of the kgdbcon feature.
|
|
||||||
</para>
|
|
||||||
<para>Kgdb supports using the gdb serial protocol to send console
|
|
||||||
messages to the debugger when the debugger is connected and running.
|
|
||||||
There are two ways to activate this feature.
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Activate with the kernel command line option:</para>
|
|
||||||
<para><constant>kgdbcon</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>Use sysfs before configuring an I/O driver</para>
|
|
||||||
<para>
|
|
||||||
<constant>echo 1 > /sys/module/kgdb/parameters/kgdb_use_con</constant>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
NOTE: If you do this after you configure the kgdb I/O driver, the
|
|
||||||
setting will not take effect until the next point the I/O is
|
|
||||||
reconfigured.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
<para>IMPORTANT NOTE: You cannot use kgdboc + kgdbcon on a tty that is an
|
|
||||||
active system console. An example of incorrect usage is <constant>console=ttyS0,115200 kgdboc=ttyS0 kgdbcon</constant>
|
|
||||||
</para>
|
|
||||||
<para>It is possible to use this option with kgdboc on a tty that is not a system console.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="kgdbreboot">
|
|
||||||
<title>Run time parameter: kgdbreboot</title>
|
|
||||||
<para> The kgdbreboot feature allows you to change how the debugger
|
|
||||||
deals with the reboot notification. You have 3 choices for the
|
|
||||||
behavior. The default behavior is always set to 0.</para>
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>echo -1 > /sys/module/debug_core/parameters/kgdbreboot</para>
|
|
||||||
<para>Ignore the reboot notification entirely.</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>echo 0 > /sys/module/debug_core/parameters/kgdbreboot</para>
|
|
||||||
<para>Send the detach message to any attached debugger client.</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>echo 1 > /sys/module/debug_core/parameters/kgdbreboot</para>
|
|
||||||
<para>Enter the debugger on reboot notify.</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="usingKDB">
|
|
||||||
<title>Using kdb</title>
|
|
||||||
<para>
|
|
||||||
</para>
|
|
||||||
<sect1 id="quickKDBserial">
|
|
||||||
<title>Quick start for kdb on a serial port</title>
|
|
||||||
<para>This is a quick example of how to use kdb.</para>
|
|
||||||
<para><orderedlist>
|
|
||||||
<listitem><para>Configure kgdboc at boot using kernel parameters:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><constant>console=ttyS0,115200 kgdboc=ttyS0,115200</constant></para></listitem>
|
|
||||||
</itemizedlist></para>
|
|
||||||
<para>OR</para>
|
|
||||||
<para>Configure kgdboc after the kernel has booted; assuming you are using a serial port console:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>Enter the kernel debugger manually or by waiting for an oops or fault. There are several ways you can enter the kernel debugger manually; all involve using the sysrq-g, which means you must have enabled CONFIG_MAGIC_SYSRQ=y in your kernel config.</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>When logged in as root or with a super user session you can run:</para>
|
|
||||||
<para><constant>echo g > /proc/sysrq-trigger</constant></para></listitem>
|
|
||||||
<listitem><para>Example using minicom 2.2</para>
|
|
||||||
<para>Press: <constant>Control-a</constant></para>
|
|
||||||
<para>Press: <constant>f</constant></para>
|
|
||||||
<para>Press: <constant>g</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>When you have telneted to a terminal server that supports sending a remote break</para>
|
|
||||||
<para>Press: <constant>Control-]</constant></para>
|
|
||||||
<para>Type in:<constant>send break</constant></para>
|
|
||||||
<para>Press: <constant>Enter</constant></para>
|
|
||||||
<para>Press: <constant>g</constant></para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>From the kdb prompt you can run the "help" command to see a complete list of the commands that are available.</para>
|
|
||||||
<para>Some useful commands in kdb include:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>lsmod -- Shows where kernel modules are loaded</para></listitem>
|
|
||||||
<listitem><para>ps -- Displays only the active processes</para></listitem>
|
|
||||||
<listitem><para>ps A -- Shows all the processes</para></listitem>
|
|
||||||
<listitem><para>summary -- Shows kernel version info and memory usage</para></listitem>
|
|
||||||
<listitem><para>bt -- Get a backtrace of the current process using dump_stack()</para></listitem>
|
|
||||||
<listitem><para>dmesg -- View the kernel syslog buffer</para></listitem>
|
|
||||||
<listitem><para>go -- Continue the system</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>When you are done using kdb you need to consider rebooting the
|
|
||||||
system or using the "go" command to resuming normal kernel
|
|
||||||
execution. If you have paused the kernel for a lengthy period of
|
|
||||||
time, applications that rely on timely networking or anything to do
|
|
||||||
with real wall clock time could be adversely affected, so you
|
|
||||||
should take this into consideration when using the kernel
|
|
||||||
debugger.</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist></para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="quickKDBkeyboard">
|
|
||||||
<title>Quick start for kdb using a keyboard connected console</title>
|
|
||||||
<para>This is a quick example of how to use kdb with a keyboard.</para>
|
|
||||||
<para><orderedlist>
|
|
||||||
<listitem><para>Configure kgdboc at boot using kernel parameters:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><constant>kgdboc=kbd</constant></para></listitem>
|
|
||||||
</itemizedlist></para>
|
|
||||||
<para>OR</para>
|
|
||||||
<para>Configure kgdboc after the kernel has booted:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><constant>echo kbd > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>Enter the kernel debugger manually or by waiting for an oops or fault. There are several ways you can enter the kernel debugger manually; all involve using the sysrq-g, which means you must have enabled CONFIG_MAGIC_SYSRQ=y in your kernel config.</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>When logged in as root or with a super user session you can run:</para>
|
|
||||||
<para><constant>echo g > /proc/sysrq-trigger</constant></para></listitem>
|
|
||||||
<listitem><para>Example using a laptop keyboard</para>
|
|
||||||
<para>Press and hold down: <constant>Alt</constant></para>
|
|
||||||
<para>Press and hold down: <constant>Fn</constant></para>
|
|
||||||
<para>Press and release the key with the label: <constant>SysRq</constant></para>
|
|
||||||
<para>Release: <constant>Fn</constant></para>
|
|
||||||
<para>Press and release: <constant>g</constant></para>
|
|
||||||
<para>Release: <constant>Alt</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>Example using a PS/2 101-key keyboard</para>
|
|
||||||
<para>Press and hold down: <constant>Alt</constant></para>
|
|
||||||
<para>Press and release the key with the label: <constant>SysRq</constant></para>
|
|
||||||
<para>Press and release: <constant>g</constant></para>
|
|
||||||
<para>Release: <constant>Alt</constant></para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>Now type in a kdb command such as "help", "dmesg", "bt" or "go" to continue kernel execution.</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist></para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="EnableKGDB">
|
|
||||||
<title>Using kgdb / gdb</title>
|
|
||||||
<para>In order to use kgdb you must activate it by passing
|
|
||||||
configuration information to one of the kgdb I/O drivers. If you
|
|
||||||
do not pass any configuration information kgdb will not do anything
|
|
||||||
at all. Kgdb will only actively hook up to the kernel trap hooks
|
|
||||||
if a kgdb I/O driver is loaded and configured. If you unconfigure
|
|
||||||
a kgdb I/O driver, kgdb will unregister all the kernel hook points.
|
|
||||||
</para>
|
|
||||||
<para> All kgdb I/O drivers can be reconfigured at run time, if
|
|
||||||
<symbol>CONFIG_SYSFS</symbol> and <symbol>CONFIG_MODULES</symbol>
|
|
||||||
are enabled, by echo'ing a new config string to
|
|
||||||
<constant>/sys/module/<driver>/parameter/<option></constant>.
|
|
||||||
The driver can be unconfigured by passing an empty string. You cannot
|
|
||||||
change the configuration while the debugger is attached. Make sure
|
|
||||||
to detach the debugger with the <constant>detach</constant> command
|
|
||||||
prior to trying to unconfigure a kgdb I/O driver.
|
|
||||||
</para>
|
|
||||||
<sect1 id="ConnectingGDB">
|
|
||||||
<title>Connecting with gdb to a serial port</title>
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Configure kgdboc</para>
|
|
||||||
<para>Configure kgdboc at boot using kernel parameters:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><constant>kgdboc=ttyS0,115200</constant></para></listitem>
|
|
||||||
</itemizedlist></para>
|
|
||||||
<para>OR</para>
|
|
||||||
<para>Configure kgdboc after the kernel has booted:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><constant>echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc</constant></para></listitem>
|
|
||||||
</itemizedlist></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>Stop kernel execution (break into the debugger)</para>
|
|
||||||
<para>In order to connect to gdb via kgdboc, the kernel must
|
|
||||||
first be stopped. There are several ways to stop the kernel which
|
|
||||||
include using kgdbwait as a boot argument, via a sysrq-g, or running
|
|
||||||
the kernel until it takes an exception where it waits for the
|
|
||||||
debugger to attach.
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>When logged in as root or with a super user session you can run:</para>
|
|
||||||
<para><constant>echo g > /proc/sysrq-trigger</constant></para></listitem>
|
|
||||||
<listitem><para>Example using minicom 2.2</para>
|
|
||||||
<para>Press: <constant>Control-a</constant></para>
|
|
||||||
<para>Press: <constant>f</constant></para>
|
|
||||||
<para>Press: <constant>g</constant></para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>When you have telneted to a terminal server that supports sending a remote break</para>
|
|
||||||
<para>Press: <constant>Control-]</constant></para>
|
|
||||||
<para>Type in:<constant>send break</constant></para>
|
|
||||||
<para>Press: <constant>Enter</constant></para>
|
|
||||||
<para>Press: <constant>g</constant></para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>Connect from gdb</para>
|
|
||||||
<para>
|
|
||||||
Example (using a directly connected port):
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
% gdb ./vmlinux
|
|
||||||
(gdb) set remotebaud 115200
|
|
||||||
(gdb) target remote /dev/ttyS0
|
|
||||||
</programlisting>
|
|
||||||
<para>
|
|
||||||
Example (kgdb to a terminal server on TCP port 2012):
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
% gdb ./vmlinux
|
|
||||||
(gdb) target remote 192.168.2.2:2012
|
|
||||||
</programlisting>
|
|
||||||
<para>
|
|
||||||
Once connected, you can debug a kernel the way you would debug an
|
|
||||||
application program.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you are having problems connecting or something is going
|
|
||||||
seriously wrong while debugging, it will most often be the case
|
|
||||||
that you want to enable gdb to be verbose about its target
|
|
||||||
communications. You do this prior to issuing the <constant>target
|
|
||||||
remote</constant> command by typing in: <constant>set debug remote 1</constant>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
<para>Remember if you continue in gdb, and need to "break in" again,
|
|
||||||
you need to issue an other sysrq-g. It is easy to create a simple
|
|
||||||
entry point by putting a breakpoint at <constant>sys_sync</constant>
|
|
||||||
and then you can run "sync" from a shell or script to break into the
|
|
||||||
debugger.</para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="switchKdbKgdb">
|
|
||||||
<title>kgdb and kdb interoperability</title>
|
|
||||||
<para>It is possible to transition between kdb and kgdb dynamically.
|
|
||||||
The debug core will remember which you used the last time and
|
|
||||||
automatically start in the same mode.</para>
|
|
||||||
<sect1>
|
|
||||||
<title>Switching between kdb and kgdb</title>
|
|
||||||
<sect2>
|
|
||||||
<title>Switching from kgdb to kdb</title>
|
|
||||||
<para>
|
|
||||||
There are two ways to switch from kgdb to kdb: you can use gdb to
|
|
||||||
issue a maintenance packet, or you can blindly type the command $3#33.
|
|
||||||
Whenever the kernel debugger stops in kgdb mode it will print the
|
|
||||||
message <constant>KGDB or $3#33 for KDB</constant>. It is important
|
|
||||||
to note that you have to type the sequence correctly in one pass.
|
|
||||||
You cannot type a backspace or delete because kgdb will interpret
|
|
||||||
that as part of the debug stream.
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Change from kgdb to kdb by blindly typing:</para>
|
|
||||||
<para><constant>$3#33</constant></para></listitem>
|
|
||||||
<listitem><para>Change from kgdb to kdb with gdb</para>
|
|
||||||
<para><constant>maintenance packet 3</constant></para>
|
|
||||||
<para>NOTE: Now you must kill gdb. Typically you press control-z and
|
|
||||||
issue the command: kill -9 %</para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2>
|
|
||||||
<title>Change from kdb to kgdb</title>
|
|
||||||
<para>There are two ways you can change from kdb to kgdb. You can
|
|
||||||
manually enter kgdb mode by issuing the kgdb command from the kdb
|
|
||||||
shell prompt, or you can connect gdb while the kdb shell prompt is
|
|
||||||
active. The kdb shell looks for the typical first commands that gdb
|
|
||||||
would issue with the gdb remote protocol and if it sees one of those
|
|
||||||
commands it automatically changes into kgdb mode.</para>
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>From kdb issue the command:</para>
|
|
||||||
<para><constant>kgdb</constant></para>
|
|
||||||
<para>Now disconnect your terminal program and connect gdb in its place</para></listitem>
|
|
||||||
<listitem><para>At the kdb prompt, disconnect the terminal program and connect gdb in its place.</para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
<sect1>
|
|
||||||
<title>Running kdb commands from gdb</title>
|
|
||||||
<para>It is possible to run a limited set of kdb commands from gdb,
|
|
||||||
using the gdb monitor command. You don't want to execute any of the
|
|
||||||
run control or breakpoint operations, because it can disrupt the
|
|
||||||
state of the kernel debugger. You should be using gdb for
|
|
||||||
breakpoints and run control operations if you have gdb connected.
|
|
||||||
The more useful commands to run are things like lsmod, dmesg, ps or
|
|
||||||
possibly some of the memory information commands. To see all the kdb
|
|
||||||
commands you can run <constant>monitor help</constant>.</para>
|
|
||||||
<para>Example:
|
|
||||||
<informalexample><programlisting>
|
|
||||||
(gdb) monitor ps
|
|
||||||
1 idle process (state I) and
|
|
||||||
27 sleeping system daemon (state M) processes suppressed,
|
|
||||||
use 'ps A' to see all.
|
|
||||||
Task Addr Pid Parent [*] cpu State Thread Command
|
|
||||||
|
|
||||||
0xc78291d0 1 0 0 0 S 0xc7829404 init
|
|
||||||
0xc7954150 942 1 0 0 S 0xc7954384 dropbear
|
|
||||||
0xc78789c0 944 1 0 0 S 0xc7878bf4 sh
|
|
||||||
(gdb)
|
|
||||||
</programlisting></informalexample>
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="KGDBTestSuite">
|
|
||||||
<title>kgdb Test Suite</title>
|
|
||||||
<para>
|
|
||||||
When kgdb is enabled in the kernel config you can also elect to
|
|
||||||
enable the config parameter KGDB_TESTS. Turning this on will
|
|
||||||
enable a special kgdb I/O module which is designed to test the
|
|
||||||
kgdb internal functions.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The kgdb tests are mainly intended for developers to test the kgdb
|
|
||||||
internals as well as a tool for developing a new kgdb architecture
|
|
||||||
specific implementation. These tests are not really for end users
|
|
||||||
of the Linux kernel. The primary source of documentation would be
|
|
||||||
to look in the drivers/misc/kgdbts.c file.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The kgdb test suite can also be configured at compile time to run
|
|
||||||
the core set of tests by setting the kernel config parameter
|
|
||||||
KGDB_TESTS_ON_BOOT. This particular option is aimed at automated
|
|
||||||
regression testing and does not require modifying the kernel boot
|
|
||||||
config arguments. If this is turned on, the kgdb test suite can
|
|
||||||
be disabled by specifying "kgdbts=" as a kernel boot argument.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="CommonBackEndReq">
|
|
||||||
<title>Kernel Debugger Internals</title>
|
|
||||||
<sect1 id="kgdbArchitecture">
|
|
||||||
<title>Architecture Specifics</title>
|
|
||||||
<para>
|
|
||||||
The kernel debugger is organized into a number of components:
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>The debug core</para>
|
|
||||||
<para>
|
|
||||||
The debug core is found in kernel/debugger/debug_core.c. It contains:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>A generic OS exception handler which includes
|
|
||||||
sync'ing the processors into a stopped state on an multi-CPU
|
|
||||||
system.</para></listitem>
|
|
||||||
<listitem><para>The API to talk to the kgdb I/O drivers</para></listitem>
|
|
||||||
<listitem><para>The API to make calls to the arch-specific kgdb implementation</para></listitem>
|
|
||||||
<listitem><para>The logic to perform safe memory reads and writes to memory while using the debugger</para></listitem>
|
|
||||||
<listitem><para>A full implementation for software breakpoints unless overridden by the arch</para></listitem>
|
|
||||||
<listitem><para>The API to invoke either the kdb or kgdb frontend to the debug core.</para></listitem>
|
|
||||||
<listitem><para>The structures and callback API for atomic kernel mode setting.</para>
|
|
||||||
<para>NOTE: kgdboc is where the kms callbacks are invoked.</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kgdb arch-specific implementation</para>
|
|
||||||
<para>
|
|
||||||
This implementation is generally found in arch/*/kernel/kgdb.c.
|
|
||||||
As an example, arch/x86/kernel/kgdb.c contains the specifics to
|
|
||||||
implement HW breakpoint as well as the initialization to
|
|
||||||
dynamically register and unregister for the trap handlers on
|
|
||||||
this architecture. The arch-specific portion implements:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>contains an arch-specific trap catcher which
|
|
||||||
invokes kgdb_handle_exception() to start kgdb about doing its
|
|
||||||
work</para></listitem>
|
|
||||||
<listitem><para>translation to and from gdb specific packet format to pt_regs</para></listitem>
|
|
||||||
<listitem><para>Registration and unregistration of architecture specific trap hooks</para></listitem>
|
|
||||||
<listitem><para>Any special exception handling and cleanup</para></listitem>
|
|
||||||
<listitem><para>NMI exception handling and cleanup</para></listitem>
|
|
||||||
<listitem><para>(optional) HW breakpoints</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>gdbstub frontend (aka kgdb)</para>
|
|
||||||
<para>The gdbstub is located in kernel/debug/gdbstub.c. It contains:</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>All the logic to implement the gdb serial protocol</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kdb frontend</para>
|
|
||||||
<para>The kdb debugger shell is broken down into a number of
|
|
||||||
components. The kdb core is located in kernel/debug/kdb. There
|
|
||||||
are a number of helper functions in some of the other kernel
|
|
||||||
components to make it possible for kdb to examine and report
|
|
||||||
information about the kernel without taking locks that could
|
|
||||||
cause a kernel deadlock. The kdb core contains implements the following functionality.</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>A simple shell</para></listitem>
|
|
||||||
<listitem><para>The kdb core command set</para></listitem>
|
|
||||||
<listitem><para>A registration API to register additional kdb shell commands.</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>A good example of a self-contained kdb module
|
|
||||||
is the "ftdump" command for dumping the ftrace buffer. See:
|
|
||||||
kernel/trace/trace_kdb.c</para></listitem>
|
|
||||||
<listitem><para>For an example of how to dynamically register
|
|
||||||
a new kdb command you can build the kdb_hello.ko kernel module
|
|
||||||
from samples/kdb/kdb_hello.c. To build this example you can
|
|
||||||
set CONFIG_SAMPLES=y and CONFIG_SAMPLE_KDB=m in your kernel
|
|
||||||
config. Later run "modprobe kdb_hello" and the next time you
|
|
||||||
enter the kdb shell, you can run the "hello"
|
|
||||||
command.</para></listitem>
|
|
||||||
</itemizedlist></listitem>
|
|
||||||
<listitem><para>The implementation for kdb_printf() which
|
|
||||||
emits messages directly to I/O drivers, bypassing the kernel
|
|
||||||
log.</para></listitem>
|
|
||||||
<listitem><para>SW / HW breakpoint management for the kdb shell</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</listitem>
|
|
||||||
<listitem><para>kgdb I/O driver</para>
|
|
||||||
<para>
|
|
||||||
Each kgdb I/O driver has to provide an implementation for the following:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>configuration via built-in or module</para></listitem>
|
|
||||||
<listitem><para>dynamic configuration and kgdb hook registration calls</para></listitem>
|
|
||||||
<listitem><para>read and write character interface</para></listitem>
|
|
||||||
<listitem><para>A cleanup handler for unconfiguring from the kgdb core</para></listitem>
|
|
||||||
<listitem><para>(optional) Early debug methodology</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
Any given kgdb I/O driver has to operate very closely with the
|
|
||||||
hardware and must do it in such a way that does not enable
|
|
||||||
interrupts or change other parts of the system context without
|
|
||||||
completely restoring them. The kgdb core will repeatedly "poll"
|
|
||||||
a kgdb I/O driver for characters when it needs input. The I/O
|
|
||||||
driver is expected to return immediately if there is no data
|
|
||||||
available. Doing so allows for the future possibility to touch
|
|
||||||
watchdog hardware in such a way as to have a target system not
|
|
||||||
reset when these are enabled.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you are intent on adding kgdb architecture specific support
|
|
||||||
for a new architecture, the architecture should define
|
|
||||||
<constant>HAVE_ARCH_KGDB</constant> in the architecture specific
|
|
||||||
Kconfig file. This will enable kgdb for the architecture, and
|
|
||||||
at that point you must create an architecture specific kgdb
|
|
||||||
implementation.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
There are a few flags which must be set on every architecture in
|
|
||||||
their <asm/kgdb.h> file. These are:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
NUMREGBYTES: The size in bytes of all of the registers, so
|
|
||||||
that we can ensure they will all fit into a packet.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
BUFMAX: The size in bytes of the buffer GDB will read into.
|
|
||||||
This must be larger than NUMREGBYTES.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
CACHE_FLUSH_IS_SAFE: Set to 1 if it is always safe to call
|
|
||||||
flush_cache_range or flush_icache_range. On some architectures,
|
|
||||||
these functions may not be safe to call on SMP since we keep other
|
|
||||||
CPUs in a holding pattern.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
There are also the following functions for the common backend,
|
|
||||||
found in kernel/kgdb.c, that must be supplied by the
|
|
||||||
architecture-specific backend unless marked as (optional), in
|
|
||||||
which case a default function maybe used if the architecture
|
|
||||||
does not need to provide a specific implementation.
|
|
||||||
</para>
|
|
||||||
!Iinclude/linux/kgdb.h
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="kgdbocDesign">
|
|
||||||
<title>kgdboc internals</title>
|
|
||||||
<sect2>
|
|
||||||
<title>kgdboc and uarts</title>
|
|
||||||
<para>
|
|
||||||
The kgdboc driver is actually a very thin driver that relies on the
|
|
||||||
underlying low level to the hardware driver having "polling hooks"
|
|
||||||
to which the tty driver is attached. In the initial
|
|
||||||
implementation of kgdboc the serial_core was changed to expose a
|
|
||||||
low level UART hook for doing polled mode reading and writing of a
|
|
||||||
single character while in an atomic context. When kgdb makes an I/O
|
|
||||||
request to the debugger, kgdboc invokes a callback in the serial
|
|
||||||
core which in turn uses the callback in the UART driver.</para>
|
|
||||||
<para>
|
|
||||||
When using kgdboc with a UART, the UART driver must implement two callbacks in the <constant>struct uart_ops</constant>. Example from drivers/8250.c:<programlisting>
|
|
||||||
#ifdef CONFIG_CONSOLE_POLL
|
|
||||||
.poll_get_char = serial8250_get_poll_char,
|
|
||||||
.poll_put_char = serial8250_put_poll_char,
|
|
||||||
#endif
|
|
||||||
</programlisting>
|
|
||||||
Any implementation specifics around creating a polling driver use the
|
|
||||||
<constant>#ifdef CONFIG_CONSOLE_POLL</constant>, as shown above.
|
|
||||||
Keep in mind that polling hooks have to be implemented in such a way
|
|
||||||
that they can be called from an atomic context and have to restore
|
|
||||||
the state of the UART chip on return such that the system can return
|
|
||||||
to normal when the debugger detaches. You need to be very careful
|
|
||||||
with any kind of lock you consider, because failing here is most likely
|
|
||||||
going to mean pressing the reset button.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="kgdbocKbd">
|
|
||||||
<title>kgdboc and keyboards</title>
|
|
||||||
<para>The kgdboc driver contains logic to configure communications
|
|
||||||
with an attached keyboard. The keyboard infrastructure is only
|
|
||||||
compiled into the kernel when CONFIG_KDB_KEYBOARD=y is set in the
|
|
||||||
kernel configuration.</para>
|
|
||||||
<para>The core polled keyboard driver driver for PS/2 type keyboards
|
|
||||||
is in drivers/char/kdb_keyboard.c. This driver is hooked into the
|
|
||||||
debug core when kgdboc populates the callback in the array
|
|
||||||
called <constant>kdb_poll_funcs[]</constant>. The
|
|
||||||
kdb_get_kbd_char() is the top-level function which polls hardware
|
|
||||||
for single character input.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="kgdbocKms">
|
|
||||||
<title>kgdboc and kms</title>
|
|
||||||
<para>The kgdboc driver contains logic to request the graphics
|
|
||||||
display to switch to a text context when you are using
|
|
||||||
"kgdboc=kms,kbd", provided that you have a video driver which has a
|
|
||||||
frame buffer console and atomic kernel mode setting support.</para>
|
|
||||||
<para>
|
|
||||||
Every time the kernel
|
|
||||||
debugger is entered it calls kgdboc_pre_exp_handler() which in turn
|
|
||||||
calls con_debug_enter() in the virtual console layer. On resuming kernel
|
|
||||||
execution, the kernel debugger calls kgdboc_post_exp_handler() which
|
|
||||||
in turn calls con_debug_leave().</para>
|
|
||||||
<para>Any video driver that wants to be compatible with the kernel
|
|
||||||
debugger and the atomic kms callbacks must implement the
|
|
||||||
mode_set_base_atomic, fb_debug_enter and fb_debug_leave operations.
|
|
||||||
For the fb_debug_enter and fb_debug_leave the option exists to use
|
|
||||||
the generic drm fb helper functions or implement something custom for
|
|
||||||
the hardware. The following example shows the initialization of the
|
|
||||||
.mode_set_base_atomic operation in
|
|
||||||
drivers/gpu/drm/i915/intel_display.c:
|
|
||||||
<informalexample>
|
|
||||||
<programlisting>
|
|
||||||
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
|
|
||||||
[...]
|
|
||||||
.mode_set_base_atomic = intel_pipe_set_base_atomic,
|
|
||||||
[...]
|
|
||||||
};
|
|
||||||
</programlisting>
|
|
||||||
</informalexample>
|
|
||||||
</para>
|
|
||||||
<para>Here is an example of how the i915 driver initializes the fb_debug_enter and fb_debug_leave functions to use the generic drm helpers in
|
|
||||||
drivers/gpu/drm/i915/intel_fb.c:
|
|
||||||
<informalexample>
|
|
||||||
<programlisting>
|
|
||||||
static struct fb_ops intelfb_ops = {
|
|
||||||
[...]
|
|
||||||
.fb_debug_enter = drm_fb_helper_debug_enter,
|
|
||||||
.fb_debug_leave = drm_fb_helper_debug_leave,
|
|
||||||
[...]
|
|
||||||
};
|
|
||||||
</programlisting>
|
|
||||||
</informalexample>
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="credits">
|
|
||||||
<title>Credits</title>
|
|
||||||
<para>
|
|
||||||
The following people have contributed to this document:
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Amit Kale<email>amitkale@linsyssoft.com</email></para></listitem>
|
|
||||||
<listitem><para>Tom Rini<email>trini@kernel.crashing.org</email></para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
In March 2008 this document was completely rewritten by:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>Jason Wessel<email>jason.wessel@windriver.com</email></para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
In Jan 2010 this document was updated to include kdb.
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>Jason Wessel<email>jason.wessel@windriver.com</email></para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
</book>
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,289 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="Reed-Solomon-Library-Guide">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Reed-Solomon Library Programming Interface</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Thomas</firstname>
|
|
||||||
<surname>Gleixner</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>tglx@linutronix.de</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2004</year>
|
|
||||||
<holder>Thomas Gleixner</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License version 2 as published by the Free Software Foundation.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="intro">
|
|
||||||
<title>Introduction</title>
|
|
||||||
<para>
|
|
||||||
The generic Reed-Solomon Library provides encoding, decoding
|
|
||||||
and error correction functions.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Reed-Solomon codes are used in communication and storage
|
|
||||||
applications to ensure data integrity.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
This documentation is provided for developers who want to utilize
|
|
||||||
the functions provided by the library.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="bugs">
|
|
||||||
<title>Known Bugs And Assumptions</title>
|
|
||||||
<para>
|
|
||||||
None.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="usage">
|
|
||||||
<title>Usage</title>
|
|
||||||
<para>
|
|
||||||
This chapter provides examples of how to use the library.
|
|
||||||
</para>
|
|
||||||
<sect1>
|
|
||||||
<title>Initializing</title>
|
|
||||||
<para>
|
|
||||||
The init function init_rs returns a pointer to an
|
|
||||||
rs decoder structure, which holds the necessary
|
|
||||||
information for encoding, decoding and error correction
|
|
||||||
with the given polynomial. It either uses an existing
|
|
||||||
matching decoder or creates a new one. On creation all
|
|
||||||
the lookup tables for fast en/decoding are created.
|
|
||||||
The function may take a while, so make sure not to
|
|
||||||
call it in critical code paths.
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
/* the Reed Solomon control structure */
|
|
||||||
static struct rs_control *rs_decoder;
|
|
||||||
|
|
||||||
/* Symbolsize is 10 (bits)
|
|
||||||
* Primitive polynomial is x^10+x^3+1
|
|
||||||
* first consecutive root is 0
|
|
||||||
* primitive element to generate roots = 1
|
|
||||||
* generator polynomial degree (number of roots) = 6
|
|
||||||
*/
|
|
||||||
rs_decoder = init_rs (10, 0x409, 0, 1, 6);
|
|
||||||
</programlisting>
|
|
||||||
</sect1>
|
|
||||||
<sect1>
|
|
||||||
<title>Encoding</title>
|
|
||||||
<para>
|
|
||||||
The encoder calculates the Reed-Solomon code over
|
|
||||||
the given data length and stores the result in
|
|
||||||
the parity buffer. Note that the parity buffer must
|
|
||||||
be initialized before calling the encoder.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The expanded data can be inverted on the fly by
|
|
||||||
providing a non-zero inversion mask. The expanded data is
|
|
||||||
XOR'ed with the mask. This is used e.g. for FLASH
|
|
||||||
ECC, where the all 0xFF is inverted to an all 0x00.
|
|
||||||
The Reed-Solomon code for all 0x00 is all 0x00. The
|
|
||||||
code is inverted before storing to FLASH so it is 0xFF
|
|
||||||
too. This prevents that reading from an erased FLASH
|
|
||||||
results in ECC errors.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The databytes are expanded to the given symbol size
|
|
||||||
on the fly. There is no support for encoding continuous
|
|
||||||
bitstreams with a symbol size != 8 at the moment. If
|
|
||||||
it is necessary it should be not a big deal to implement
|
|
||||||
such functionality.
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
/* Parity buffer. Size = number of roots */
|
|
||||||
uint16_t par[6];
|
|
||||||
/* Initialize the parity buffer */
|
|
||||||
memset(par, 0, sizeof(par));
|
|
||||||
/* Encode 512 byte in data8. Store parity in buffer par */
|
|
||||||
encode_rs8 (rs_decoder, data8, 512, par, 0);
|
|
||||||
</programlisting>
|
|
||||||
</sect1>
|
|
||||||
<sect1>
|
|
||||||
<title>Decoding</title>
|
|
||||||
<para>
|
|
||||||
The decoder calculates the syndrome over
|
|
||||||
the given data length and the received parity symbols
|
|
||||||
and corrects errors in the data.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If a syndrome is available from a hardware decoder
|
|
||||||
then the syndrome calculation is skipped.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The correction of the data buffer can be suppressed
|
|
||||||
by providing a correction pattern buffer and an error
|
|
||||||
location buffer to the decoder. The decoder stores the
|
|
||||||
calculated error location and the correction bitmask
|
|
||||||
in the given buffers. This is useful for hardware
|
|
||||||
decoders which use a weird bit ordering scheme.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The databytes are expanded to the given symbol size
|
|
||||||
on the fly. There is no support for decoding continuous
|
|
||||||
bitstreams with a symbolsize != 8 at the moment. If
|
|
||||||
it is necessary it should be not a big deal to implement
|
|
||||||
such functionality.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>
|
|
||||||
Decoding with syndrome calculation, direct data correction
|
|
||||||
</title>
|
|
||||||
<programlisting>
|
|
||||||
/* Parity buffer. Size = number of roots */
|
|
||||||
uint16_t par[6];
|
|
||||||
uint8_t data[512];
|
|
||||||
int numerr;
|
|
||||||
/* Receive data */
|
|
||||||
.....
|
|
||||||
/* Receive parity */
|
|
||||||
.....
|
|
||||||
/* Decode 512 byte in data8.*/
|
|
||||||
numerr = decode_rs8 (rs_decoder, data8, par, 512, NULL, 0, NULL, 0, NULL);
|
|
||||||
</programlisting>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>
|
|
||||||
Decoding with syndrome given by hardware decoder, direct data correction
|
|
||||||
</title>
|
|
||||||
<programlisting>
|
|
||||||
/* Parity buffer. Size = number of roots */
|
|
||||||
uint16_t par[6], syn[6];
|
|
||||||
uint8_t data[512];
|
|
||||||
int numerr;
|
|
||||||
/* Receive data */
|
|
||||||
.....
|
|
||||||
/* Receive parity */
|
|
||||||
.....
|
|
||||||
/* Get syndrome from hardware decoder */
|
|
||||||
.....
|
|
||||||
/* Decode 512 byte in data8.*/
|
|
||||||
numerr = decode_rs8 (rs_decoder, data8, par, 512, syn, 0, NULL, 0, NULL);
|
|
||||||
</programlisting>
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2>
|
|
||||||
<title>
|
|
||||||
Decoding with syndrome given by hardware decoder, no direct data correction.
|
|
||||||
</title>
|
|
||||||
<para>
|
|
||||||
Note: It's not necessary to give data and received parity to the decoder.
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
/* Parity buffer. Size = number of roots */
|
|
||||||
uint16_t par[6], syn[6], corr[8];
|
|
||||||
uint8_t data[512];
|
|
||||||
int numerr, errpos[8];
|
|
||||||
/* Receive data */
|
|
||||||
.....
|
|
||||||
/* Receive parity */
|
|
||||||
.....
|
|
||||||
/* Get syndrome from hardware decoder */
|
|
||||||
.....
|
|
||||||
/* Decode 512 byte in data8.*/
|
|
||||||
numerr = decode_rs8 (rs_decoder, NULL, NULL, 512, syn, 0, errpos, 0, corr);
|
|
||||||
for (i = 0; i < numerr; i++) {
|
|
||||||
do_error_correction_in_your_buffer(errpos[i], corr[i]);
|
|
||||||
}
|
|
||||||
</programlisting>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
<sect1>
|
|
||||||
<title>Cleanup</title>
|
|
||||||
<para>
|
|
||||||
The function free_rs frees the allocated resources,
|
|
||||||
if the caller is the last user of the decoder.
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
/* Release resources */
|
|
||||||
free_rs(rs_decoder);
|
|
||||||
</programlisting>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="structs">
|
|
||||||
<title>Structures</title>
|
|
||||||
<para>
|
|
||||||
This chapter contains the autogenerated documentation of the structures which are
|
|
||||||
used in the Reed-Solomon Library and are relevant for a developer.
|
|
||||||
</para>
|
|
||||||
!Iinclude/linux/rslib.h
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="pubfunctions">
|
|
||||||
<title>Public Functions Provided</title>
|
|
||||||
<para>
|
|
||||||
This chapter contains the autogenerated documentation of the Reed-Solomon functions
|
|
||||||
which are exported.
|
|
||||||
</para>
|
|
||||||
!Elib/reed_solomon/reed_solomon.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="credits">
|
|
||||||
<title>Credits</title>
|
|
||||||
<para>
|
|
||||||
The library code for encoding and decoding was written by Phil Karn.
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
Copyright 2002, Phil Karn, KA9Q
|
|
||||||
May be used under the terms of the GNU General Public License (GPL)
|
|
||||||
</programlisting>
|
|
||||||
<para>
|
|
||||||
The wrapper functions and interfaces are written by Thomas Gleixner.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Many users have provided bugfixes, improvements and helping hands for testing.
|
|
||||||
Thanks a lot.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The following people have contributed to this document:
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Thomas Gleixner<email>tglx@linutronix.de</email>
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
</book>
|
|
|
@ -1,265 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<article class="whitepaper" id="LinuxSecurityModule" lang="en">
|
|
||||||
<articleinfo>
|
|
||||||
<title>Linux Security Modules: General Security Hooks for Linux</title>
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Stephen</firstname>
|
|
||||||
<surname>Smalley</surname>
|
|
||||||
<affiliation>
|
|
||||||
<orgname>NAI Labs</orgname>
|
|
||||||
<address><email>ssmalley@nai.com</email></address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
<author>
|
|
||||||
<firstname>Timothy</firstname>
|
|
||||||
<surname>Fraser</surname>
|
|
||||||
<affiliation>
|
|
||||||
<orgname>NAI Labs</orgname>
|
|
||||||
<address><email>tfraser@nai.com</email></address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
<author>
|
|
||||||
<firstname>Chris</firstname>
|
|
||||||
<surname>Vance</surname>
|
|
||||||
<affiliation>
|
|
||||||
<orgname>NAI Labs</orgname>
|
|
||||||
<address><email>cvance@nai.com</email></address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
</articleinfo>
|
|
||||||
|
|
||||||
<sect1 id="Introduction"><title>Introduction</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In March 2001, the National Security Agency (NSA) gave a presentation
|
|
||||||
about Security-Enhanced Linux (SELinux) at the 2.5 Linux Kernel
|
|
||||||
Summit. SELinux is an implementation of flexible and fine-grained
|
|
||||||
nondiscretionary access controls in the Linux kernel, originally
|
|
||||||
implemented as its own particular kernel patch. Several other
|
|
||||||
security projects (e.g. RSBAC, Medusa) have also developed flexible
|
|
||||||
access control architectures for the Linux kernel, and various
|
|
||||||
projects have developed particular access control models for Linux
|
|
||||||
(e.g. LIDS, DTE, SubDomain). Each project has developed and
|
|
||||||
maintained its own kernel patch to support its security needs.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In response to the NSA presentation, Linus Torvalds made a set of
|
|
||||||
remarks that described a security framework he would be willing to
|
|
||||||
consider for inclusion in the mainstream Linux kernel. He described a
|
|
||||||
general framework that would provide a set of security hooks to
|
|
||||||
control operations on kernel objects and a set of opaque security
|
|
||||||
fields in kernel data structures for maintaining security attributes.
|
|
||||||
This framework could then be used by loadable kernel modules to
|
|
||||||
implement any desired model of security. Linus also suggested the
|
|
||||||
possibility of migrating the Linux capabilities code into such a
|
|
||||||
module.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The Linux Security Modules (LSM) project was started by WireX to
|
|
||||||
develop such a framework. LSM is a joint development effort by
|
|
||||||
several security projects, including Immunix, SELinux, SGI and Janus,
|
|
||||||
and several individuals, including Greg Kroah-Hartman and James
|
|
||||||
Morris, to develop a Linux kernel patch that implements this
|
|
||||||
framework. The patch is currently tracking the 2.4 series and is
|
|
||||||
targeted for integration into the 2.5 development series. This
|
|
||||||
technical report provides an overview of the framework and the example
|
|
||||||
capabilities security module provided by the LSM kernel patch.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="framework"><title>LSM Framework</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The LSM kernel patch provides a general kernel framework to support
|
|
||||||
security modules. In particular, the LSM framework is primarily
|
|
||||||
focused on supporting access control modules, although future
|
|
||||||
development is likely to address other security needs such as
|
|
||||||
auditing. By itself, the framework does not provide any additional
|
|
||||||
security; it merely provides the infrastructure to support security
|
|
||||||
modules. The LSM kernel patch also moves most of the capabilities
|
|
||||||
logic into an optional security module, with the system defaulting
|
|
||||||
to the traditional superuser logic. This capabilities module
|
|
||||||
is discussed further in <xref linkend="cap"/>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The LSM kernel patch adds security fields to kernel data structures
|
|
||||||
and inserts calls to hook functions at critical points in the kernel
|
|
||||||
code to manage the security fields and to perform access control. It
|
|
||||||
also adds functions for registering and unregistering security
|
|
||||||
modules, and adds a general <function>security</function> system call
|
|
||||||
to support new system calls for security-aware applications.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The LSM security fields are simply <type>void*</type> pointers. For
|
|
||||||
process and program execution security information, security fields
|
|
||||||
were added to <structname>struct task_struct</structname> and
|
|
||||||
<structname>struct linux_binprm</structname>. For filesystem security
|
|
||||||
information, a security field was added to
|
|
||||||
<structname>struct super_block</structname>. For pipe, file, and socket
|
|
||||||
security information, security fields were added to
|
|
||||||
<structname>struct inode</structname> and
|
|
||||||
<structname>struct file</structname>. For packet and network device security
|
|
||||||
information, security fields were added to
|
|
||||||
<structname>struct sk_buff</structname> and
|
|
||||||
<structname>struct net_device</structname>. For System V IPC security
|
|
||||||
information, security fields were added to
|
|
||||||
<structname>struct kern_ipc_perm</structname> and
|
|
||||||
<structname>struct msg_msg</structname>; additionally, the definitions
|
|
||||||
for <structname>struct msg_msg</structname>, <structname>struct
|
|
||||||
msg_queue</structname>, and <structname>struct
|
|
||||||
shmid_kernel</structname> were moved to header files
|
|
||||||
(<filename>include/linux/msg.h</filename> and
|
|
||||||
<filename>include/linux/shm.h</filename> as appropriate) to allow
|
|
||||||
the security modules to use these definitions.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Each LSM hook is a function pointer in a global table,
|
|
||||||
security_ops. This table is a
|
|
||||||
<structname>security_operations</structname> structure as defined by
|
|
||||||
<filename>include/linux/security.h</filename>. Detailed documentation
|
|
||||||
for each hook is included in this header file. At present, this
|
|
||||||
structure consists of a collection of substructures that group related
|
|
||||||
hooks based on the kernel object (e.g. task, inode, file, sk_buff,
|
|
||||||
etc) as well as some top-level hook function pointers for system
|
|
||||||
operations. This structure is likely to be flattened in the future
|
|
||||||
for performance. The placement of the hook calls in the kernel code
|
|
||||||
is described by the "called:" lines in the per-hook documentation in
|
|
||||||
the header file. The hook calls can also be easily found in the
|
|
||||||
kernel code by looking for the string "security_ops->".
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Linus mentioned per-process security hooks in his original remarks as a
|
|
||||||
possible alternative to global security hooks. However, if LSM were
|
|
||||||
to start from the perspective of per-process hooks, then the base
|
|
||||||
framework would have to deal with how to handle operations that
|
|
||||||
involve multiple processes (e.g. kill), since each process might have
|
|
||||||
its own hook for controlling the operation. This would require a
|
|
||||||
general mechanism for composing hooks in the base framework.
|
|
||||||
Additionally, LSM would still need global hooks for operations that
|
|
||||||
have no process context (e.g. network input operations).
|
|
||||||
Consequently, LSM provides global security hooks, but a security
|
|
||||||
module is free to implement per-process hooks (where that makes sense)
|
|
||||||
by storing a security_ops table in each process' security field and
|
|
||||||
then invoking these per-process hooks from the global hooks.
|
|
||||||
The problem of composition is thus deferred to the module.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The global security_ops table is initialized to a set of hook
|
|
||||||
functions provided by a dummy security module that provides
|
|
||||||
traditional superuser logic. A <function>register_security</function>
|
|
||||||
function (in <filename>security/security.c</filename>) is provided to
|
|
||||||
allow a security module to set security_ops to refer to its own hook
|
|
||||||
functions, and an <function>unregister_security</function> function is
|
|
||||||
provided to revert security_ops to the dummy module hooks. This
|
|
||||||
mechanism is used to set the primary security module, which is
|
|
||||||
responsible for making the final decision for each hook.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
LSM also provides a simple mechanism for stacking additional security
|
|
||||||
modules with the primary security module. It defines
|
|
||||||
<function>register_security</function> and
|
|
||||||
<function>unregister_security</function> hooks in the
|
|
||||||
<structname>security_operations</structname> structure and provides
|
|
||||||
<function>mod_reg_security</function> and
|
|
||||||
<function>mod_unreg_security</function> functions that invoke these
|
|
||||||
hooks after performing some sanity checking. A security module can
|
|
||||||
call these functions in order to stack with other modules. However,
|
|
||||||
the actual details of how this stacking is handled are deferred to the
|
|
||||||
module, which can implement these hooks in any way it wishes
|
|
||||||
(including always returning an error if it does not wish to support
|
|
||||||
stacking). In this manner, LSM again defers the problem of
|
|
||||||
composition to the module.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Although the LSM hooks are organized into substructures based on
|
|
||||||
kernel object, all of the hooks can be viewed as falling into two
|
|
||||||
major categories: hooks that are used to manage the security fields
|
|
||||||
and hooks that are used to perform access control. Examples of the
|
|
||||||
first category of hooks include the
|
|
||||||
<function>alloc_security</function> and
|
|
||||||
<function>free_security</function> hooks defined for each kernel data
|
|
||||||
structure that has a security field. These hooks are used to allocate
|
|
||||||
and free security structures for kernel objects. The first category
|
|
||||||
of hooks also includes hooks that set information in the security
|
|
||||||
field after allocation, such as the <function>post_lookup</function>
|
|
||||||
hook in <structname>struct inode_security_ops</structname>. This hook
|
|
||||||
is used to set security information for inodes after successful lookup
|
|
||||||
operations. An example of the second category of hooks is the
|
|
||||||
<function>permission</function> hook in
|
|
||||||
<structname>struct inode_security_ops</structname>. This hook checks
|
|
||||||
permission when accessing an inode.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="cap"><title>LSM Capabilities Module</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
The LSM kernel patch moves most of the existing POSIX.1e capabilities
|
|
||||||
logic into an optional security module stored in the file
|
|
||||||
<filename>security/capability.c</filename>. This change allows
|
|
||||||
users who do not want to use capabilities to omit this code entirely
|
|
||||||
from their kernel, instead using the dummy module for traditional
|
|
||||||
superuser logic or any other module that they desire. This change
|
|
||||||
also allows the developers of the capabilities logic to maintain and
|
|
||||||
enhance their code more freely, without needing to integrate patches
|
|
||||||
back into the base kernel.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In addition to moving the capabilities logic, the LSM kernel patch
|
|
||||||
could move the capability-related fields from the kernel data
|
|
||||||
structures into the new security fields managed by the security
|
|
||||||
modules. However, at present, the LSM kernel patch leaves the
|
|
||||||
capability fields in the kernel data structures. In his original
|
|
||||||
remarks, Linus suggested that this might be preferable so that other
|
|
||||||
security modules can be easily stacked with the capabilities module
|
|
||||||
without needing to chain multiple security structures on the security field.
|
|
||||||
It also avoids imposing extra overhead on the capabilities module
|
|
||||||
to manage the security fields. However, the LSM framework could
|
|
||||||
certainly support such a move if it is determined to be desirable,
|
|
||||||
with only a few additional changes described below.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
At present, the capabilities logic for computing process capabilities
|
|
||||||
on <function>execve</function> and <function>set*uid</function>,
|
|
||||||
checking capabilities for a particular process, saving and checking
|
|
||||||
capabilities for netlink messages, and handling the
|
|
||||||
<function>capget</function> and <function>capset</function> system
|
|
||||||
calls have been moved into the capabilities module. There are still a
|
|
||||||
few locations in the base kernel where capability-related fields are
|
|
||||||
directly examined or modified, but the current version of the LSM
|
|
||||||
patch does allow a security module to completely replace the
|
|
||||||
assignment and testing of capabilities. These few locations would
|
|
||||||
need to be changed if the capability-related fields were moved into
|
|
||||||
the security field. The following is a list of known locations that
|
|
||||||
still perform such direct examination or modification of
|
|
||||||
capability-related fields:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para><filename>fs/open.c</filename>:<function>sys_access</function></para></listitem>
|
|
||||||
<listitem><para><filename>fs/lockd/host.c</filename>:<function>nlm_bind_host</function></para></listitem>
|
|
||||||
<listitem><para><filename>fs/nfsd/auth.c</filename>:<function>nfsd_setuser</function></para></listitem>
|
|
||||||
<listitem><para><filename>fs/proc/array.c</filename>:<function>task_cap</function></para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
</article>
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,111 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="LinuxNetworking">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Linux Networking and Network Devices APIs</title>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later
|
|
||||||
version.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="netcore">
|
|
||||||
<title>Linux Networking</title>
|
|
||||||
<sect1><title>Networking Base Types</title>
|
|
||||||
!Iinclude/linux/net.h
|
|
||||||
</sect1>
|
|
||||||
<sect1><title>Socket Buffer Functions</title>
|
|
||||||
!Iinclude/linux/skbuff.h
|
|
||||||
!Iinclude/net/sock.h
|
|
||||||
!Enet/socket.c
|
|
||||||
!Enet/core/skbuff.c
|
|
||||||
!Enet/core/sock.c
|
|
||||||
!Enet/core/datagram.c
|
|
||||||
!Enet/core/stream.c
|
|
||||||
</sect1>
|
|
||||||
<sect1><title>Socket Filter</title>
|
|
||||||
!Enet/core/filter.c
|
|
||||||
</sect1>
|
|
||||||
<sect1><title>Generic Network Statistics</title>
|
|
||||||
!Iinclude/uapi/linux/gen_stats.h
|
|
||||||
!Enet/core/gen_stats.c
|
|
||||||
!Enet/core/gen_estimator.c
|
|
||||||
</sect1>
|
|
||||||
<sect1><title>SUN RPC subsystem</title>
|
|
||||||
<!-- The !D functionality is not perfect, garbage has to be protected by comments
|
|
||||||
!Dnet/sunrpc/sunrpc_syms.c
|
|
||||||
-->
|
|
||||||
!Enet/sunrpc/xdr.c
|
|
||||||
!Enet/sunrpc/svc_xprt.c
|
|
||||||
!Enet/sunrpc/xprt.c
|
|
||||||
!Enet/sunrpc/sched.c
|
|
||||||
!Enet/sunrpc/socklib.c
|
|
||||||
!Enet/sunrpc/stats.c
|
|
||||||
!Enet/sunrpc/rpc_pipe.c
|
|
||||||
!Enet/sunrpc/rpcb_clnt.c
|
|
||||||
!Enet/sunrpc/clnt.c
|
|
||||||
</sect1>
|
|
||||||
<sect1><title>WiMAX</title>
|
|
||||||
!Enet/wimax/op-msg.c
|
|
||||||
!Enet/wimax/op-reset.c
|
|
||||||
!Enet/wimax/op-rfkill.c
|
|
||||||
!Enet/wimax/stack.c
|
|
||||||
!Iinclude/net/wimax.h
|
|
||||||
!Iinclude/uapi/linux/wimax.h
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="netdev">
|
|
||||||
<title>Network device support</title>
|
|
||||||
<sect1><title>Driver Support</title>
|
|
||||||
!Enet/core/dev.c
|
|
||||||
!Enet/ethernet/eth.c
|
|
||||||
!Enet/sched/sch_generic.c
|
|
||||||
!Iinclude/linux/etherdevice.h
|
|
||||||
!Iinclude/linux/netdevice.h
|
|
||||||
</sect1>
|
|
||||||
<sect1><title>PHY Support</title>
|
|
||||||
!Edrivers/net/phy/phy.c
|
|
||||||
!Idrivers/net/phy/phy.c
|
|
||||||
!Edrivers/net/phy/phy_device.c
|
|
||||||
!Idrivers/net/phy/phy_device.c
|
|
||||||
!Edrivers/net/phy/mdio_bus.c
|
|
||||||
!Idrivers/net/phy/mdio_bus.c
|
|
||||||
</sect1>
|
|
||||||
<!-- FIXME: Removed for now since no structured comments in source
|
|
||||||
<sect1><title>Wireless</title>
|
|
||||||
X!Enet/core/wireless.c
|
|
||||||
</sect1>
|
|
||||||
-->
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
</book>
|
|
|
@ -1,155 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
|
|
||||||
<!ENTITY rapidio SYSTEM "rapidio.xml">
|
|
||||||
]>
|
|
||||||
|
|
||||||
<book id="RapidIO-Guide">
|
|
||||||
<bookinfo>
|
|
||||||
<title>RapidIO Subsystem Guide</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Matt</firstname>
|
|
||||||
<surname>Porter</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>mporter@kernel.crashing.org</email>
|
|
||||||
<email>mporter@mvista.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2005</year>
|
|
||||||
<holder>MontaVista Software, Inc.</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License version 2 as published by the Free Software Foundation.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="intro">
|
|
||||||
<title>Introduction</title>
|
|
||||||
<para>
|
|
||||||
RapidIO is a high speed switched fabric interconnect with
|
|
||||||
features aimed at the embedded market. RapidIO provides
|
|
||||||
support for memory-mapped I/O as well as message-based
|
|
||||||
transactions over the switched fabric network. RapidIO has
|
|
||||||
a standardized discovery mechanism not unlike the PCI bus
|
|
||||||
standard that allows simple detection of devices in a
|
|
||||||
network.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
This documentation is provided for developers intending
|
|
||||||
to support RapidIO on new architectures, write new drivers,
|
|
||||||
or to understand the subsystem internals.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="bugs">
|
|
||||||
<title>Known Bugs and Limitations</title>
|
|
||||||
|
|
||||||
<sect1 id="known_bugs">
|
|
||||||
<title>Bugs</title>
|
|
||||||
<para>None. ;)</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="Limitations">
|
|
||||||
<title>Limitations</title>
|
|
||||||
<para>
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Access/management of RapidIO memory regions is not supported</para></listitem>
|
|
||||||
<listitem><para>Multiple host enumeration is not supported</para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="drivers">
|
|
||||||
<title>RapidIO driver interface</title>
|
|
||||||
<para>
|
|
||||||
Drivers are provided a set of calls in order
|
|
||||||
to interface with the subsystem to gather info
|
|
||||||
on devices, request/map memory region resources,
|
|
||||||
and manage mailboxes/doorbells.
|
|
||||||
</para>
|
|
||||||
<sect1 id="Functions">
|
|
||||||
<title>Functions</title>
|
|
||||||
!Iinclude/linux/rio_drv.h
|
|
||||||
!Edrivers/rapidio/rio-driver.c
|
|
||||||
!Edrivers/rapidio/rio.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="internals">
|
|
||||||
<title>Internals</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This chapter contains the autogenerated documentation of the RapidIO
|
|
||||||
subsystem.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<sect1 id="Structures"><title>Structures</title>
|
|
||||||
!Iinclude/linux/rio.h
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="Enumeration_and_Discovery"><title>Enumeration and Discovery</title>
|
|
||||||
!Idrivers/rapidio/rio-scan.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="Driver_functionality"><title>Driver functionality</title>
|
|
||||||
!Idrivers/rapidio/rio.c
|
|
||||||
!Idrivers/rapidio/rio-access.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="Device_model_support"><title>Device model support</title>
|
|
||||||
!Idrivers/rapidio/rio-driver.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="PPC32_support"><title>PPC32 support</title>
|
|
||||||
!Iarch/powerpc/sysdev/fsl_rio.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="credits">
|
|
||||||
<title>Credits</title>
|
|
||||||
<para>
|
|
||||||
The following people have contributed to the RapidIO
|
|
||||||
subsystem directly or indirectly:
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
|
|
||||||
<listitem><para>Randy Vinson<email>rvinson@mvista.com</email></para></listitem>
|
|
||||||
<listitem><para>Dan Malek<email>dan@embeddedalley.com</email></para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The following people have contributed to this document:
|
|
||||||
<orderedlist>
|
|
||||||
<listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
|
|
||||||
</orderedlist>
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
</book>
|
|
|
@ -1,161 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="s390drivers">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Writing s390 channel device drivers</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Cornelia</firstname>
|
|
||||||
<surname>Huck</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>cornelia.huck@de.ibm.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2007</year>
|
|
||||||
<holder>IBM Corp.</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later
|
|
||||||
version.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="intro">
|
|
||||||
<title>Introduction</title>
|
|
||||||
<para>
|
|
||||||
This document describes the interfaces available for device drivers that
|
|
||||||
drive s390 based channel attached I/O devices. This includes interfaces for
|
|
||||||
interaction with the hardware and interfaces for interacting with the
|
|
||||||
common driver core. Those interfaces are provided by the s390 common I/O
|
|
||||||
layer.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The document assumes a familarity with the technical terms associated
|
|
||||||
with the s390 channel I/O architecture. For a description of this
|
|
||||||
architecture, please refer to the "z/Architecture: Principles of
|
|
||||||
Operation", IBM publication no. SA22-7832.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
While most I/O devices on a s390 system are typically driven through the
|
|
||||||
channel I/O mechanism described here, there are various other methods
|
|
||||||
(like the diag interface). These are out of the scope of this document.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Some additional information can also be found in the kernel source
|
|
||||||
under Documentation/s390/driver-model.txt.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="ccw">
|
|
||||||
<title>The ccw bus</title>
|
|
||||||
<para>
|
|
||||||
The ccw bus typically contains the majority of devices available to
|
|
||||||
a s390 system. Named after the channel command word (ccw), the basic
|
|
||||||
command structure used to address its devices, the ccw bus contains
|
|
||||||
so-called channel attached devices. They are addressed via I/O
|
|
||||||
subchannels, visible on the css bus. A device driver for
|
|
||||||
channel-attached devices, however, will never interact with the
|
|
||||||
subchannel directly, but only via the I/O device on the ccw bus,
|
|
||||||
the ccw device.
|
|
||||||
</para>
|
|
||||||
<sect1 id="channelIO">
|
|
||||||
<title>I/O functions for channel-attached devices</title>
|
|
||||||
<para>
|
|
||||||
Some hardware structures have been translated into C structures for use
|
|
||||||
by the common I/O layer and device drivers. For more information on
|
|
||||||
the hardware structures represented here, please consult the Principles
|
|
||||||
of Operation.
|
|
||||||
</para>
|
|
||||||
!Iarch/s390/include/asm/cio.h
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="ccwdev">
|
|
||||||
<title>ccw devices</title>
|
|
||||||
<para>
|
|
||||||
Devices that want to initiate channel I/O need to attach to the ccw bus.
|
|
||||||
Interaction with the driver core is done via the common I/O layer, which
|
|
||||||
provides the abstractions of ccw devices and ccw device drivers.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The functions that initiate or terminate channel I/O all act upon a
|
|
||||||
ccw device structure. Device drivers must not bypass those functions
|
|
||||||
or strange side effects may happen.
|
|
||||||
</para>
|
|
||||||
!Iarch/s390/include/asm/ccwdev.h
|
|
||||||
!Edrivers/s390/cio/device.c
|
|
||||||
!Edrivers/s390/cio/device_ops.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="cmf">
|
|
||||||
<title>The channel-measurement facility</title>
|
|
||||||
<para>
|
|
||||||
The channel-measurement facility provides a means to collect
|
|
||||||
measurement data which is made available by the channel subsystem
|
|
||||||
for each channel attached device.
|
|
||||||
</para>
|
|
||||||
!Iarch/s390/include/asm/cmb.h
|
|
||||||
!Edrivers/s390/cio/cmf.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="ccwgroup">
|
|
||||||
<title>The ccwgroup bus</title>
|
|
||||||
<para>
|
|
||||||
The ccwgroup bus only contains artificial devices, created by the user.
|
|
||||||
Many networking devices (e.g. qeth) are in fact composed of several
|
|
||||||
ccw devices (like read, write and data channel for qeth). The
|
|
||||||
ccwgroup bus provides a mechanism to create a meta-device which
|
|
||||||
contains those ccw devices as slave devices and can be associated
|
|
||||||
with the netdevice.
|
|
||||||
</para>
|
|
||||||
<sect1 id="ccwgroupdevices">
|
|
||||||
<title>ccw group devices</title>
|
|
||||||
!Iarch/s390/include/asm/ccwgroup.h
|
|
||||||
!Edrivers/s390/cio/ccwgroup.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="genericinterfaces">
|
|
||||||
<title>Generic interfaces</title>
|
|
||||||
<para>
|
|
||||||
Some interfaces are available to other drivers that do not necessarily
|
|
||||||
have anything to do with the busses described above, but still are
|
|
||||||
indirectly using basic infrastructure in the common I/O layer.
|
|
||||||
One example is the support for adapter interrupts.
|
|
||||||
</para>
|
|
||||||
!Edrivers/s390/cio/airq.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
</book>
|
|
|
@ -1,409 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="scsimid">
|
|
||||||
<bookinfo>
|
|
||||||
<title>SCSI Interfaces Guide</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>James</firstname>
|
|
||||||
<surname>Bottomley</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>James.Bottomley@hansenpartnership.com</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
|
|
||||||
<author>
|
|
||||||
<firstname>Rob</firstname>
|
|
||||||
<surname>Landley</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>rob@landley.net</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2007</year>
|
|
||||||
<holder>Linux Foundation</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License version 2.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="intro">
|
|
||||||
<title>Introduction</title>
|
|
||||||
<sect1 id="protocol_vs_bus">
|
|
||||||
<title>Protocol vs bus</title>
|
|
||||||
<para>
|
|
||||||
Once upon a time, the Small Computer Systems Interface defined both
|
|
||||||
a parallel I/O bus and a data protocol to connect a wide variety of
|
|
||||||
peripherals (disk drives, tape drives, modems, printers, scanners,
|
|
||||||
optical drives, test equipment, and medical devices) to a host
|
|
||||||
computer.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Although the old parallel (fast/wide/ultra) SCSI bus has largely
|
|
||||||
fallen out of use, the SCSI command set is more widely used than ever
|
|
||||||
to communicate with devices over a number of different busses.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The <ulink url='http://www.t10.org/scsi-3.htm'>SCSI protocol</ulink>
|
|
||||||
is a big-endian peer-to-peer packet based protocol. SCSI commands
|
|
||||||
are 6, 10, 12, or 16 bytes long, often followed by an associated data
|
|
||||||
payload.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
SCSI commands can be transported over just about any kind of bus, and
|
|
||||||
are the default protocol for storage devices attached to USB, SATA,
|
|
||||||
SAS, Fibre Channel, FireWire, and ATAPI devices. SCSI packets are
|
|
||||||
also commonly exchanged over Infiniband,
|
|
||||||
<ulink url='http://i2o.shadowconnect.com/faq.php'>I20</ulink>, TCP/IP
|
|
||||||
(<ulink url='https://en.wikipedia.org/wiki/ISCSI'>iSCSI</ulink>), even
|
|
||||||
<ulink url='http://cyberelk.net/tim/parport/parscsi.html'>Parallel
|
|
||||||
ports</ulink>.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="subsystem_design">
|
|
||||||
<title>Design of the Linux SCSI subsystem</title>
|
|
||||||
<para>
|
|
||||||
The SCSI subsystem uses a three layer design, with upper, mid, and low
|
|
||||||
layers. Every operation involving the SCSI subsystem (such as reading
|
|
||||||
a sector from a disk) uses one driver at each of the 3 levels: one
|
|
||||||
upper layer driver, one lower layer driver, and the SCSI midlayer.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The SCSI upper layer provides the interface between userspace and the
|
|
||||||
kernel, in the form of block and char device nodes for I/O and
|
|
||||||
ioctl(). The SCSI lower layer contains drivers for specific hardware
|
|
||||||
devices.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
In between is the SCSI mid-layer, analogous to a network routing
|
|
||||||
layer such as the IPv4 stack. The SCSI mid-layer routes a packet
|
|
||||||
based data protocol between the upper layer's /dev nodes and the
|
|
||||||
corresponding devices in the lower layer. It manages command queues,
|
|
||||||
provides error handling and power management functions, and responds
|
|
||||||
to ioctl() requests.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="upper_layer">
|
|
||||||
<title>SCSI upper layer</title>
|
|
||||||
<para>
|
|
||||||
The upper layer supports the user-kernel interface by providing
|
|
||||||
device nodes.
|
|
||||||
</para>
|
|
||||||
<sect1 id="sd">
|
|
||||||
<title>sd (SCSI Disk)</title>
|
|
||||||
<para>sd (sd_mod.o)</para>
|
|
||||||
<!-- !Idrivers/scsi/sd.c -->
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="sr">
|
|
||||||
<title>sr (SCSI CD-ROM)</title>
|
|
||||||
<para>sr (sr_mod.o)</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="st">
|
|
||||||
<title>st (SCSI Tape)</title>
|
|
||||||
<para>st (st.o)</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="sg">
|
|
||||||
<title>sg (SCSI Generic)</title>
|
|
||||||
<para>sg (sg.o)</para>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="ch">
|
|
||||||
<title>ch (SCSI Media Changer)</title>
|
|
||||||
<para>ch (ch.c)</para>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="mid_layer">
|
|
||||||
<title>SCSI mid layer</title>
|
|
||||||
|
|
||||||
<sect1 id="midlayer_implementation">
|
|
||||||
<title>SCSI midlayer implementation</title>
|
|
||||||
<sect2 id="scsi_device.h">
|
|
||||||
<title>include/scsi/scsi_device.h</title>
|
|
||||||
<para>
|
|
||||||
</para>
|
|
||||||
!Iinclude/scsi/scsi_device.h
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="scsi.c">
|
|
||||||
<title>drivers/scsi/scsi.c</title>
|
|
||||||
<para>Main file for the SCSI midlayer.</para>
|
|
||||||
!Edrivers/scsi/scsi.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsicam.c">
|
|
||||||
<title>drivers/scsi/scsicam.c</title>
|
|
||||||
<para>
|
|
||||||
<ulink url='http://www.t10.org/ftp/t10/drafts/cam/cam-r12b.pdf'>SCSI
|
|
||||||
Common Access Method</ulink> support functions, for use with
|
|
||||||
HDIO_GETGEO, etc.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsicam.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_error.c">
|
|
||||||
<title>drivers/scsi/scsi_error.c</title>
|
|
||||||
<para>Common SCSI error/timeout handling routines.</para>
|
|
||||||
!Edrivers/scsi/scsi_error.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_devinfo.c">
|
|
||||||
<title>drivers/scsi/scsi_devinfo.c</title>
|
|
||||||
<para>
|
|
||||||
Manage scsi_dev_info_list, which tracks blacklisted and whitelisted
|
|
||||||
devices.
|
|
||||||
</para>
|
|
||||||
!Idrivers/scsi/scsi_devinfo.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_ioctl.c">
|
|
||||||
<title>drivers/scsi/scsi_ioctl.c</title>
|
|
||||||
<para>
|
|
||||||
Handle ioctl() calls for SCSI devices.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_ioctl.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_lib.c">
|
|
||||||
<title>drivers/scsi/scsi_lib.c</title>
|
|
||||||
<para>
|
|
||||||
SCSI queuing library.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_lib.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_lib_dma.c">
|
|
||||||
<title>drivers/scsi/scsi_lib_dma.c</title>
|
|
||||||
<para>
|
|
||||||
SCSI library functions depending on DMA
|
|
||||||
(map and unmap scatter-gather lists).
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_lib_dma.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_module.c">
|
|
||||||
<title>drivers/scsi/scsi_module.c</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_module.c contains legacy support for
|
|
||||||
old-style host templates. It should never be used by any new driver.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_proc.c">
|
|
||||||
<title>drivers/scsi/scsi_proc.c</title>
|
|
||||||
<para>
|
|
||||||
The functions in this file provide an interface between
|
|
||||||
the PROC file system and the SCSI device drivers
|
|
||||||
It is mainly used for debugging, statistics and to pass
|
|
||||||
information directly to the lowlevel driver.
|
|
||||||
|
|
||||||
I.E. plumbing to manage /proc/scsi/*
|
|
||||||
</para>
|
|
||||||
!Idrivers/scsi/scsi_proc.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_netlink.c">
|
|
||||||
<title>drivers/scsi/scsi_netlink.c</title>
|
|
||||||
<para>
|
|
||||||
Infrastructure to provide async events from transports to userspace
|
|
||||||
via netlink, using a single NETLINK_SCSITRANSPORT protocol for all
|
|
||||||
transports.
|
|
||||||
|
|
||||||
See <ulink url='http://marc.info/?l=linux-scsi&m=115507374832500&w=2'>the
|
|
||||||
original patch submission</ulink> for more details.
|
|
||||||
</para>
|
|
||||||
!Idrivers/scsi/scsi_netlink.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_scan.c">
|
|
||||||
<title>drivers/scsi/scsi_scan.c</title>
|
|
||||||
<para>
|
|
||||||
Scan a host to determine which (if any) devices are attached.
|
|
||||||
|
|
||||||
The general scanning/probing algorithm is as follows, exceptions are
|
|
||||||
made to it depending on device specific flags, compilation options,
|
|
||||||
and global variable (boot or module load time) settings.
|
|
||||||
|
|
||||||
A specific LUN is scanned via an INQUIRY command; if the LUN has a
|
|
||||||
device attached, a scsi_device is allocated and setup for it.
|
|
||||||
|
|
||||||
For every id of every channel on the given host, start by scanning
|
|
||||||
LUN 0. Skip hosts that don't respond at all to a scan of LUN 0.
|
|
||||||
Otherwise, if LUN 0 has a device attached, allocate and setup a
|
|
||||||
scsi_device for it. If target is SCSI-3 or up, issue a REPORT LUN,
|
|
||||||
and scan all of the LUNs returned by the REPORT LUN; else,
|
|
||||||
sequentially scan LUNs up until some maximum is reached, or a LUN is
|
|
||||||
seen that cannot have a device attached to it.
|
|
||||||
</para>
|
|
||||||
!Idrivers/scsi/scsi_scan.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_sysctl.c">
|
|
||||||
<title>drivers/scsi/scsi_sysctl.c</title>
|
|
||||||
<para>
|
|
||||||
Set up the sysctl entry: "/dev/scsi/logging_level"
|
|
||||||
(DEV_SCSI_LOGGING_LEVEL) which sets/returns scsi_logging_level.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="scsi_sysfs.c">
|
|
||||||
<title>drivers/scsi/scsi_sysfs.c</title>
|
|
||||||
<para>
|
|
||||||
SCSI sysfs interface routines.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_sysfs.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="hosts.c">
|
|
||||||
<title>drivers/scsi/hosts.c</title>
|
|
||||||
<para>
|
|
||||||
mid to lowlevel SCSI driver interface
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/hosts.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="constants.c">
|
|
||||||
<title>drivers/scsi/constants.c</title>
|
|
||||||
<para>
|
|
||||||
mid to lowlevel SCSI driver interface
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/constants.c
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="Transport_classes">
|
|
||||||
<title>Transport classes</title>
|
|
||||||
<para>
|
|
||||||
Transport classes are service libraries for drivers in the SCSI
|
|
||||||
lower layer, which expose transport attributes in sysfs.
|
|
||||||
</para>
|
|
||||||
<sect2 id="Fibre_Channel_transport">
|
|
||||||
<title>Fibre Channel transport</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_transport_fc.c defines transport attributes
|
|
||||||
for Fibre Channel.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_transport_fc.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="iSCSI_transport">
|
|
||||||
<title>iSCSI transport class</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_transport_iscsi.c defines transport
|
|
||||||
attributes for the iSCSI class, which sends SCSI packets over TCP/IP
|
|
||||||
connections.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_transport_iscsi.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="SAS_transport">
|
|
||||||
<title>Serial Attached SCSI (SAS) transport class</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_transport_sas.c defines transport
|
|
||||||
attributes for Serial Attached SCSI, a variant of SATA aimed at
|
|
||||||
large high-end systems.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The SAS transport class contains common code to deal with SAS HBAs,
|
|
||||||
an aproximated representation of SAS topologies in the driver model,
|
|
||||||
and various sysfs attributes to expose these topologies and management
|
|
||||||
interfaces to userspace.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
In addition to the basic SCSI core objects this transport class
|
|
||||||
introduces two additional intermediate objects: The SAS PHY
|
|
||||||
as represented by struct sas_phy defines an "outgoing" PHY on
|
|
||||||
a SAS HBA or Expander, and the SAS remote PHY represented by
|
|
||||||
struct sas_rphy defines an "incoming" PHY on a SAS Expander or
|
|
||||||
end device. Note that this is purely a software concept, the
|
|
||||||
underlying hardware for a PHY and a remote PHY is the exactly
|
|
||||||
the same.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
There is no concept of a SAS port in this code, users can see
|
|
||||||
what PHYs form a wide port based on the port_identifier attribute,
|
|
||||||
which is the same for all PHYs in a port.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_transport_sas.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="SATA_transport">
|
|
||||||
<title>SATA transport class</title>
|
|
||||||
<para>
|
|
||||||
The SATA transport is handled by libata, which has its own book of
|
|
||||||
documentation in this directory.
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="SPI_transport">
|
|
||||||
<title>Parallel SCSI (SPI) transport class</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_transport_spi.c defines transport
|
|
||||||
attributes for traditional (fast/wide/ultra) SCSI busses.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_transport_spi.c
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="SRP_transport">
|
|
||||||
<title>SCSI RDMA (SRP) transport class</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_transport_srp.c defines transport
|
|
||||||
attributes for SCSI over Remote Direct Memory Access.
|
|
||||||
</para>
|
|
||||||
!Edrivers/scsi/scsi_transport_srp.c
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="lower_layer">
|
|
||||||
<title>SCSI lower layer</title>
|
|
||||||
<sect1 id="hba_drivers">
|
|
||||||
<title>Host Bus Adapter transport types</title>
|
|
||||||
<para>
|
|
||||||
Many modern device controllers use the SCSI command set as a protocol to
|
|
||||||
communicate with their devices through many different types of physical
|
|
||||||
connections.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
In SCSI language a bus capable of carrying SCSI commands is
|
|
||||||
called a "transport", and a controller connecting to such a bus is
|
|
||||||
called a "host bus adapter" (HBA).
|
|
||||||
</para>
|
|
||||||
<sect2 id="scsi_debug.c">
|
|
||||||
<title>Debug transport</title>
|
|
||||||
<para>
|
|
||||||
The file drivers/scsi/scsi_debug.c simulates a host adapter with a
|
|
||||||
variable number of disks (or disk like devices) attached, sharing a
|
|
||||||
common amount of RAM. Does a lot of checking to make sure that we are
|
|
||||||
not getting blocks mixed up, and panics the kernel if anything out of
|
|
||||||
the ordinary is seen.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
To be more realistic, the simulated devices have the transport
|
|
||||||
attributes of SAS disks.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
For documentation see
|
|
||||||
<ulink url='http://sg.danny.cz/sg/sdebug26.html'>http://sg.danny.cz/sg/sdebug26.html</ulink>
|
|
||||||
</para>
|
|
||||||
<!-- !Edrivers/scsi/scsi_debug.c -->
|
|
||||||
</sect2>
|
|
||||||
<sect2 id="todo">
|
|
||||||
<title>todo</title>
|
|
||||||
<para>Parallel (fast/wide/ultra) SCSI, USB, SATA,
|
|
||||||
SAS, Fibre Channel, FireWire, ATAPI devices, Infiniband,
|
|
||||||
I20, iSCSI, Parallel ports, netlink...
|
|
||||||
</para>
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
</book>
|
|
|
@ -1,105 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="sh-drivers">
|
|
||||||
<bookinfo>
|
|
||||||
<title>SuperH Interfaces Guide</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Paul</firstname>
|
|
||||||
<surname>Mundt</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>lethal@linux-sh.org</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2008-2010</year>
|
|
||||||
<holder>Paul Mundt</holder>
|
|
||||||
</copyright>
|
|
||||||
<copyright>
|
|
||||||
<year>2008-2010</year>
|
|
||||||
<holder>Renesas Technology Corp.</holder>
|
|
||||||
</copyright>
|
|
||||||
<copyright>
|
|
||||||
<year>2010</year>
|
|
||||||
<holder>Renesas Electronics Corp.</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License version 2 as published by the Free Software Foundation.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="mm">
|
|
||||||
<title>Memory Management</title>
|
|
||||||
<sect1 id="sh4">
|
|
||||||
<title>SH-4</title>
|
|
||||||
<sect2 id="sq">
|
|
||||||
<title>Store Queue API</title>
|
|
||||||
!Earch/sh/kernel/cpu/sh4/sq.c
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="sh5">
|
|
||||||
<title>SH-5</title>
|
|
||||||
<sect2 id="tlb">
|
|
||||||
<title>TLB Interfaces</title>
|
|
||||||
!Iarch/sh/mm/tlb-sh5.c
|
|
||||||
!Iarch/sh/include/asm/tlb_64.h
|
|
||||||
</sect2>
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="mach">
|
|
||||||
<title>Machine Specific Interfaces</title>
|
|
||||||
<sect1 id="dreamcast">
|
|
||||||
<title>mach-dreamcast</title>
|
|
||||||
!Iarch/sh/boards/mach-dreamcast/rtc.c
|
|
||||||
</sect1>
|
|
||||||
<sect1 id="x3proto">
|
|
||||||
<title>mach-x3proto</title>
|
|
||||||
!Earch/sh/boards/mach-x3proto/ilsel.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
<chapter id="busses">
|
|
||||||
<title>Busses</title>
|
|
||||||
<sect1 id="superhyway">
|
|
||||||
<title>SuperHyway</title>
|
|
||||||
!Edrivers/sh/superhyway/superhyway.c
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="maple">
|
|
||||||
<title>Maple</title>
|
|
||||||
!Edrivers/sh/maple/maple.c
|
|
||||||
</sect1>
|
|
||||||
</chapter>
|
|
||||||
</book>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
|
||||||
<param name="chunk.quietly">1</param>
|
|
||||||
<param name="funcsynopsis.style">ansi</param>
|
|
||||||
<param name="funcsynopsis.tabular.threshold">80</param>
|
|
||||||
<param name="callout.graphics">0</param>
|
|
||||||
<!-- <param name="paper.type">A4</param> -->
|
|
||||||
<param name="generate.consistent.ids">1</param>
|
|
||||||
<param name="generate.section.toc.level">2</param>
|
|
||||||
<param name="use.id.as.filename">1</param>
|
|
||||||
</stylesheet>
|
|
|
@ -1,101 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="w1id">
|
|
||||||
<bookinfo>
|
|
||||||
<title>W1: Dallas' 1-wire bus</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>David</firstname>
|
|
||||||
<surname>Fries</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>David@Fries.net</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2013</year>
|
|
||||||
<!--
|
|
||||||
<holder></holder>
|
|
||||||
-->
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License version 2.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="w1_internal">
|
|
||||||
<title>W1 API internal to the kernel</title>
|
|
||||||
|
|
||||||
<sect1 id="w1_internal_api">
|
|
||||||
<title>W1 API internal to the kernel</title>
|
|
||||||
<sect2 id="w1.h">
|
|
||||||
<title>drivers/w1/w1.h</title>
|
|
||||||
<para>W1 core functions.</para>
|
|
||||||
!Idrivers/w1/w1.h
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="w1.c">
|
|
||||||
<title>drivers/w1/w1.c</title>
|
|
||||||
<para>W1 core functions.</para>
|
|
||||||
!Idrivers/w1/w1.c
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="w1_family.h">
|
|
||||||
<title>drivers/w1/w1_family.h</title>
|
|
||||||
<para>Allows registering device family operations.</para>
|
|
||||||
!Idrivers/w1/w1_family.h
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="w1_family.c">
|
|
||||||
<title>drivers/w1/w1_family.c</title>
|
|
||||||
<para>Allows registering device family operations.</para>
|
|
||||||
!Edrivers/w1/w1_family.c
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="w1_int.c">
|
|
||||||
<title>drivers/w1/w1_int.c</title>
|
|
||||||
<para>W1 internal initialization for master devices.</para>
|
|
||||||
!Edrivers/w1/w1_int.c
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="w1_netlink.h">
|
|
||||||
<title>drivers/w1/w1_netlink.h</title>
|
|
||||||
<para>W1 external netlink API structures and commands.</para>
|
|
||||||
!Idrivers/w1/w1_netlink.h
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
<sect2 id="w1_io.c">
|
|
||||||
<title>drivers/w1/w1_io.c</title>
|
|
||||||
<para>W1 input/output.</para>
|
|
||||||
!Edrivers/w1/w1_io.c
|
|
||||||
!Idrivers/w1/w1_io.c
|
|
||||||
</sect2>
|
|
||||||
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
</book>
|
|
|
@ -1,371 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
||||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
|
|
||||||
|
|
||||||
<book id="Z85230Guide">
|
|
||||||
<bookinfo>
|
|
||||||
<title>Z8530 Programming Guide</title>
|
|
||||||
|
|
||||||
<authorgroup>
|
|
||||||
<author>
|
|
||||||
<firstname>Alan</firstname>
|
|
||||||
<surname>Cox</surname>
|
|
||||||
<affiliation>
|
|
||||||
<address>
|
|
||||||
<email>alan@lxorguk.ukuu.org.uk</email>
|
|
||||||
</address>
|
|
||||||
</affiliation>
|
|
||||||
</author>
|
|
||||||
</authorgroup>
|
|
||||||
|
|
||||||
<copyright>
|
|
||||||
<year>2000</year>
|
|
||||||
<holder>Alan Cox</holder>
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<legalnotice>
|
|
||||||
<para>
|
|
||||||
This documentation is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later
|
|
||||||
version.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This program is distributed in the hope that it will be
|
|
||||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
||||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
You should have received a copy of the GNU General Public
|
|
||||||
License along with this program; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
MA 02111-1307 USA
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
For more details see the file COPYING in the source
|
|
||||||
distribution of Linux.
|
|
||||||
</para>
|
|
||||||
</legalnotice>
|
|
||||||
</bookinfo>
|
|
||||||
|
|
||||||
<toc></toc>
|
|
||||||
|
|
||||||
<chapter id="intro">
|
|
||||||
<title>Introduction</title>
|
|
||||||
<para>
|
|
||||||
The Z85x30 family synchronous/asynchronous controller chips are
|
|
||||||
used on a large number of cheap network interface cards. The
|
|
||||||
kernel provides a core interface layer that is designed to make
|
|
||||||
it easy to provide WAN services using this chip.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The current driver only support synchronous operation. Merging the
|
|
||||||
asynchronous driver support into this code to allow any Z85x30
|
|
||||||
device to be used as both a tty interface and as a synchronous
|
|
||||||
controller is a project for Linux post the 2.4 release
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="Driver_Modes">
|
|
||||||
<title>Driver Modes</title>
|
|
||||||
<para>
|
|
||||||
The Z85230 driver layer can drive Z8530, Z85C30 and Z85230 devices
|
|
||||||
in three different modes. Each mode can be applied to an individual
|
|
||||||
channel on the chip (each chip has two channels).
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The PIO synchronous mode supports the most common Z8530 wiring. Here
|
|
||||||
the chip is interface to the I/O and interrupt facilities of the
|
|
||||||
host machine but not to the DMA subsystem. When running PIO the
|
|
||||||
Z8530 has extremely tight timing requirements. Doing high speeds,
|
|
||||||
even with a Z85230 will be tricky. Typically you should expect to
|
|
||||||
achieve at best 9600 baud with a Z8C530 and 64Kbits with a Z85230.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The DMA mode supports the chip when it is configured to use dual DMA
|
|
||||||
channels on an ISA bus. The better cards tend to support this mode
|
|
||||||
of operation for a single channel. With DMA running the Z85230 tops
|
|
||||||
out when it starts to hit ISA DMA constraints at about 512Kbits. It
|
|
||||||
is worth noting here that many PC machines hang or crash when the
|
|
||||||
chip is driven fast enough to hold the ISA bus solid.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Transmit DMA mode uses a single DMA channel. The DMA channel is used
|
|
||||||
for transmission as the transmit FIFO is smaller than the receive
|
|
||||||
FIFO. it gives better performance than pure PIO mode but is nowhere
|
|
||||||
near as ideal as pure DMA mode.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="Using_the_Z85230_driver">
|
|
||||||
<title>Using the Z85230 driver</title>
|
|
||||||
<para>
|
|
||||||
The Z85230 driver provides the back end interface to your board. To
|
|
||||||
configure a Z8530 interface you need to detect the board and to
|
|
||||||
identify its ports and interrupt resources. It is also your problem
|
|
||||||
to verify the resources are available.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Having identified the chip you need to fill in a struct z8530_dev,
|
|
||||||
which describes each chip. This object must exist until you finally
|
|
||||||
shutdown the board. Firstly zero the active field. This ensures
|
|
||||||
nothing goes off without you intending it. The irq field should
|
|
||||||
be set to the interrupt number of the chip. (Each chip has a single
|
|
||||||
interrupt source rather than each channel). You are responsible
|
|
||||||
for allocating the interrupt line. The interrupt handler should be
|
|
||||||
set to <function>z8530_interrupt</function>. The device id should
|
|
||||||
be set to the z8530_dev structure pointer. Whether the interrupt can
|
|
||||||
be shared or not is board dependent, and up to you to initialise.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The structure holds two channel structures.
|
|
||||||
Initialise chanA.ctrlio and chanA.dataio with the address of the
|
|
||||||
control and data ports. You can or this with Z8530_PORT_SLEEP to
|
|
||||||
indicate your interface needs the 5uS delay for chip settling done
|
|
||||||
in software. The PORT_SLEEP option is architecture specific. Other
|
|
||||||
flags may become available on future platforms, eg for MMIO.
|
|
||||||
Initialise the chanA.irqs to &z8530_nop to start the chip up
|
|
||||||
as disabled and discarding interrupt events. This ensures that
|
|
||||||
stray interrupts will be mopped up and not hang the bus. Set
|
|
||||||
chanA.dev to point to the device structure itself. The
|
|
||||||
private and name field you may use as you wish. The private field
|
|
||||||
is unused by the Z85230 layer. The name is used for error reporting
|
|
||||||
and it may thus make sense to make it match the network name.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Repeat the same operation with the B channel if your chip has
|
|
||||||
both channels wired to something useful. This isn't always the
|
|
||||||
case. If it is not wired then the I/O values do not matter, but
|
|
||||||
you must initialise chanB.dev.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If your board has DMA facilities then initialise the txdma and
|
|
||||||
rxdma fields for the relevant channels. You must also allocate the
|
|
||||||
ISA DMA channels and do any necessary board level initialisation
|
|
||||||
to configure them. The low level driver will do the Z8530 and
|
|
||||||
DMA controller programming but not board specific magic.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Having initialised the device you can then call
|
|
||||||
<function>z8530_init</function>. This will probe the chip and
|
|
||||||
reset it into a known state. An identification sequence is then
|
|
||||||
run to identify the chip type. If the checks fail to pass the
|
|
||||||
function returns a non zero error code. Typically this indicates
|
|
||||||
that the port given is not valid. After this call the
|
|
||||||
type field of the z8530_dev structure is initialised to either
|
|
||||||
Z8530, Z85C30 or Z85230 according to the chip found.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Once you have called z8530_init you can also make use of the utility
|
|
||||||
function <function>z8530_describe</function>. This provides a
|
|
||||||
consistent reporting format for the Z8530 devices, and allows all
|
|
||||||
the drivers to provide consistent reporting.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="Attaching_Network_Interfaces">
|
|
||||||
<title>Attaching Network Interfaces</title>
|
|
||||||
<para>
|
|
||||||
If you wish to use the network interface facilities of the driver,
|
|
||||||
then you need to attach a network device to each channel that is
|
|
||||||
present and in use. In addition to use the generic HDLC
|
|
||||||
you need to follow some additional plumbing rules. They may seem
|
|
||||||
complex but a look at the example hostess_sv11 driver should
|
|
||||||
reassure you.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The network device used for each channel should be pointed to by
|
|
||||||
the netdevice field of each channel. The hdlc-> priv field of the
|
|
||||||
network device points to your private data - you will need to be
|
|
||||||
able to find your private data from this.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The way most drivers approach this particular problem is to
|
|
||||||
create a structure holding the Z8530 device definition and
|
|
||||||
put that into the private field of the network device. The
|
|
||||||
network device fields of the channels then point back to the
|
|
||||||
network devices.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you wish to use the generic HDLC then you need to register
|
|
||||||
the HDLC device.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Before you register your network device you will also need to
|
|
||||||
provide suitable handlers for most of the network device callbacks.
|
|
||||||
See the network device documentation for more details on this.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="Configuring_And_Activating_The_Port">
|
|
||||||
<title>Configuring And Activating The Port</title>
|
|
||||||
<para>
|
|
||||||
The Z85230 driver provides helper functions and tables to load the
|
|
||||||
port registers on the Z8530 chips. When programming the register
|
|
||||||
settings for a channel be aware that the documentation recommends
|
|
||||||
initialisation orders. Strange things happen when these are not
|
|
||||||
followed.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<function>z8530_channel_load</function> takes an array of
|
|
||||||
pairs of initialisation values in an array of u8 type. The first
|
|
||||||
value is the Z8530 register number. Add 16 to indicate the alternate
|
|
||||||
register bank on the later chips. The array is terminated by a 255.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The driver provides a pair of public tables. The
|
|
||||||
z8530_hdlc_kilostream table is for the UK 'Kilostream' service and
|
|
||||||
also happens to cover most other end host configurations. The
|
|
||||||
z8530_hdlc_kilostream_85230 table is the same configuration using
|
|
||||||
the enhancements of the 85230 chip. The configuration loaded is
|
|
||||||
standard NRZ encoded synchronous data with HDLC bitstuffing. All
|
|
||||||
of the timing is taken from the other end of the link.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
When writing your own tables be aware that the driver internally
|
|
||||||
tracks register values. It may need to reload values. You should
|
|
||||||
therefore be sure to set registers 1-7, 9-11, 14 and 15 in all
|
|
||||||
configurations. Where the register settings depend on DMA selection
|
|
||||||
the driver will update the bits itself when you open or close.
|
|
||||||
Loading a new table with the interface open is not recommended.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
There are three standard configurations supported by the core
|
|
||||||
code. In PIO mode the interface is programmed up to use
|
|
||||||
interrupt driven PIO. This places high demands on the host processor
|
|
||||||
to avoid latency. The driver is written to take account of latency
|
|
||||||
issues but it cannot avoid latencies caused by other drivers,
|
|
||||||
notably IDE in PIO mode. Because the drivers allocate buffers you
|
|
||||||
must also prevent MTU changes while the port is open.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Once the port is open it will call the rx_function of each channel
|
|
||||||
whenever a completed packet arrived. This is invoked from
|
|
||||||
interrupt context and passes you the channel and a network
|
|
||||||
buffer (struct sk_buff) holding the data. The data includes
|
|
||||||
the CRC bytes so most users will want to trim the last two
|
|
||||||
bytes before processing the data. This function is very timing
|
|
||||||
critical. When you wish to simply discard data the support
|
|
||||||
code provides the function <function>z8530_null_rx</function>
|
|
||||||
to discard the data.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
To active PIO mode sending and receiving the <function>
|
|
||||||
z8530_sync_open</function> is called. This expects to be passed
|
|
||||||
the network device and the channel. Typically this is called from
|
|
||||||
your network device open callback. On a failure a non zero error
|
|
||||||
status is returned. The <function>z8530_sync_close</function>
|
|
||||||
function shuts down a PIO channel. This must be done before the
|
|
||||||
channel is opened again and before the driver shuts down
|
|
||||||
and unloads.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The ideal mode of operation is dual channel DMA mode. Here the
|
|
||||||
kernel driver will configure the board for DMA in both directions.
|
|
||||||
The driver also handles ISA DMA issues such as controller
|
|
||||||
programming and the memory range limit for you. This mode is
|
|
||||||
activated by calling the <function>z8530_sync_dma_open</function>
|
|
||||||
function. On failure a non zero error value is returned.
|
|
||||||
Once this mode is activated it can be shut down by calling the
|
|
||||||
<function>z8530_sync_dma_close</function>. You must call the close
|
|
||||||
function matching the open mode you used.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The final supported mode uses a single DMA channel to drive the
|
|
||||||
transmit side. As the Z85C30 has a larger FIFO on the receive
|
|
||||||
channel this tends to increase the maximum speed a little.
|
|
||||||
This is activated by calling the <function>z8530_sync_txdma_open
|
|
||||||
</function>. This returns a non zero error code on failure. The
|
|
||||||
<function>z8530_sync_txdma_close</function> function closes down
|
|
||||||
the Z8530 interface from this mode.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="Network_Layer_Functions">
|
|
||||||
<title>Network Layer Functions</title>
|
|
||||||
<para>
|
|
||||||
The Z8530 layer provides functions to queue packets for
|
|
||||||
transmission. The driver internally buffers the frame currently
|
|
||||||
being transmitted and one further frame (in order to keep back
|
|
||||||
to back transmission running). Any further buffering is up to
|
|
||||||
the caller.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The function <function>z8530_queue_xmit</function> takes a network
|
|
||||||
buffer in sk_buff format and queues it for transmission. The
|
|
||||||
caller must provide the entire packet with the exception of the
|
|
||||||
bitstuffing and CRC. This is normally done by the caller via
|
|
||||||
the generic HDLC interface layer. It returns 0 if the buffer has been
|
|
||||||
queued and non zero values for queue full. If the function accepts
|
|
||||||
the buffer it becomes property of the Z8530 layer and the caller
|
|
||||||
should not free it.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The function <function>z8530_get_stats</function> returns a pointer
|
|
||||||
to an internally maintained per interface statistics block. This
|
|
||||||
provides most of the interface code needed to implement the network
|
|
||||||
layer get_stats callback.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="Porting_The_Z8530_Driver">
|
|
||||||
<title>Porting The Z8530 Driver</title>
|
|
||||||
<para>
|
|
||||||
The Z8530 driver is written to be portable. In DMA mode it makes
|
|
||||||
assumptions about the use of ISA DMA. These are probably warranted
|
|
||||||
in most cases as the Z85230 in particular was designed to glue to PC
|
|
||||||
type machines. The PIO mode makes no real assumptions.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Should you need to retarget the Z8530 driver to another architecture
|
|
||||||
the only code that should need changing are the port I/O functions.
|
|
||||||
At the moment these assume PC I/O port accesses. This may not be
|
|
||||||
appropriate for all platforms. Replacing
|
|
||||||
<function>z8530_read_port</function> and <function>z8530_write_port
|
|
||||||
</function> is intended to be all that is required to port this
|
|
||||||
driver layer.
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="bugs">
|
|
||||||
<title>Known Bugs And Assumptions</title>
|
|
||||||
<para>
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry><term>Interrupt Locking</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The locking in the driver is done via the global cli/sti lock. This
|
|
||||||
makes for relatively poor SMP performance. Switching this to use a
|
|
||||||
per device spin lock would probably materially improve performance.
|
|
||||||
</para>
|
|
||||||
</listitem></varlistentry>
|
|
||||||
|
|
||||||
<varlistentry><term>Occasional Failures</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
We have reports of occasional failures when run for very long
|
|
||||||
periods of time and the driver starts to receive junk frames. At
|
|
||||||
the moment the cause of this is not clear.
|
|
||||||
</para>
|
|
||||||
</listitem></varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="pubfunctions">
|
|
||||||
<title>Public Functions Provided</title>
|
|
||||||
!Edrivers/net/wan/z85230.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
<chapter id="intfunctions">
|
|
||||||
<title>Internal Functions</title>
|
|
||||||
!Idrivers/net/wan/z85230.c
|
|
||||||
</chapter>
|
|
||||||
|
|
||||||
</book>
|
|
|
@ -1,9 +1,8 @@
|
||||||
|
=====================
|
||||||
The Linux IPMI Driver
|
The Linux IPMI Driver
|
||||||
---------------------
|
=====================
|
||||||
Corey Minyard
|
|
||||||
<minyard@mvista.com>
|
:Author: Corey Minyard <minyard@mvista.com> / <minyard@acm.org>
|
||||||
<minyard@acm.org>
|
|
||||||
|
|
||||||
The Intelligent Platform Management Interface, or IPMI, is a
|
The Intelligent Platform Management Interface, or IPMI, is a
|
||||||
standard for controlling intelligent devices that monitor a system.
|
standard for controlling intelligent devices that monitor a system.
|
||||||
|
@ -141,7 +140,7 @@ Addressing
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The IPMI addressing works much like IP addresses, you have an overlay
|
The IPMI addressing works much like IP addresses, you have an overlay
|
||||||
to handle the different address types. The overlay is:
|
to handle the different address types. The overlay is::
|
||||||
|
|
||||||
struct ipmi_addr
|
struct ipmi_addr
|
||||||
{
|
{
|
||||||
|
@ -153,7 +152,7 @@ to handle the different address types. The overlay is:
|
||||||
The addr_type determines what the address really is. The driver
|
The addr_type determines what the address really is. The driver
|
||||||
currently understands two different types of addresses.
|
currently understands two different types of addresses.
|
||||||
|
|
||||||
"System Interface" addresses are defined as:
|
"System Interface" addresses are defined as::
|
||||||
|
|
||||||
struct ipmi_system_interface_addr
|
struct ipmi_system_interface_addr
|
||||||
{
|
{
|
||||||
|
@ -166,7 +165,7 @@ straight to the BMC on the current card. The channel must be
|
||||||
IPMI_BMC_CHANNEL.
|
IPMI_BMC_CHANNEL.
|
||||||
|
|
||||||
Messages that are destined to go out on the IPMB bus use the
|
Messages that are destined to go out on the IPMB bus use the
|
||||||
IPMI_IPMB_ADDR_TYPE address type. The format is
|
IPMI_IPMB_ADDR_TYPE address type. The format is::
|
||||||
|
|
||||||
struct ipmi_ipmb_addr
|
struct ipmi_ipmb_addr
|
||||||
{
|
{
|
||||||
|
@ -184,7 +183,7 @@ spec.
|
||||||
Messages
|
Messages
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Messages are defined as:
|
Messages are defined as::
|
||||||
|
|
||||||
struct ipmi_msg
|
struct ipmi_msg
|
||||||
{
|
{
|
||||||
|
@ -208,7 +207,7 @@ block of data, even when receiving messages. Otherwise the driver
|
||||||
will have no place to put the message.
|
will have no place to put the message.
|
||||||
|
|
||||||
Messages coming up from the message handler in kernelland will come in
|
Messages coming up from the message handler in kernelland will come in
|
||||||
as:
|
as::
|
||||||
|
|
||||||
struct ipmi_recv_msg
|
struct ipmi_recv_msg
|
||||||
{
|
{
|
||||||
|
@ -246,6 +245,7 @@ and the user should not have to care what type of SMI is below them.
|
||||||
|
|
||||||
|
|
||||||
Watching For Interfaces
|
Watching For Interfaces
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
When your code comes up, the IPMI driver may or may not have detected
|
When your code comes up, the IPMI driver may or may not have detected
|
||||||
if IPMI devices exist. So you might have to defer your setup until
|
if IPMI devices exist. So you might have to defer your setup until
|
||||||
|
@ -256,6 +256,7 @@ and tell you when they come and go.
|
||||||
|
|
||||||
|
|
||||||
Creating the User
|
Creating the User
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
To use the message handler, you must first create a user using
|
To use the message handler, you must first create a user using
|
||||||
ipmi_create_user. The interface number specifies which SMI you want
|
ipmi_create_user. The interface number specifies which SMI you want
|
||||||
|
@ -272,6 +273,7 @@ closing the device automatically destroys the user.
|
||||||
|
|
||||||
|
|
||||||
Messaging
|
Messaging
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
To send a message from kernel-land, the ipmi_request_settime() call does
|
To send a message from kernel-land, the ipmi_request_settime() call does
|
||||||
pretty much all message handling. Most of the parameter are
|
pretty much all message handling. Most of the parameter are
|
||||||
|
@ -321,6 +323,7 @@ though, since it is tricky to manage your own buffers.
|
||||||
|
|
||||||
|
|
||||||
Events and Incoming Commands
|
Events and Incoming Commands
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The driver takes care of polling for IPMI events and receiving
|
The driver takes care of polling for IPMI events and receiving
|
||||||
commands (commands are messages that are not responses, they are
|
commands (commands are messages that are not responses, they are
|
||||||
|
@ -367,7 +370,7 @@ in the system. It discovers interfaces through a host of different
|
||||||
methods, depending on the system.
|
methods, depending on the system.
|
||||||
|
|
||||||
You can specify up to four interfaces on the module load line and
|
You can specify up to four interfaces on the module load line and
|
||||||
control some module parameters:
|
control some module parameters::
|
||||||
|
|
||||||
modprobe ipmi_si.o type=<type1>,<type2>....
|
modprobe ipmi_si.o type=<type1>,<type2>....
|
||||||
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
|
ports=<port1>,<port2>... addrs=<addr1>,<addr2>...
|
||||||
|
@ -437,7 +440,7 @@ default is one. Setting to 0 is useful with the hotmod, but is
|
||||||
obviously only useful for modules.
|
obviously only useful for modules.
|
||||||
|
|
||||||
When compiled into the kernel, the parameters can be specified on the
|
When compiled into the kernel, the parameters can be specified on the
|
||||||
kernel command line as:
|
kernel command line as::
|
||||||
|
|
||||||
ipmi_si.type=<type1>,<type2>...
|
ipmi_si.type=<type1>,<type2>...
|
||||||
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
|
ipmi_si.ports=<port1>,<port2>... ipmi_si.addrs=<addr1>,<addr2>...
|
||||||
|
@ -474,16 +477,22 @@ The driver supports a hot add and remove of interfaces. This way,
|
||||||
interfaces can be added or removed after the kernel is up and running.
|
interfaces can be added or removed after the kernel is up and running.
|
||||||
This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
|
This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
|
||||||
write-only parameter. You write a string to this interface. The string
|
write-only parameter. You write a string to this interface. The string
|
||||||
has the format:
|
has the format::
|
||||||
|
|
||||||
<op1>[:op2[:op3...]]
|
<op1>[:op2[:op3...]]
|
||||||
The "op"s are:
|
|
||||||
|
The "op"s are::
|
||||||
|
|
||||||
add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
|
add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
|
||||||
You can specify more than one interface on the line. The "opt"s are:
|
|
||||||
|
You can specify more than one interface on the line. The "opt"s are::
|
||||||
|
|
||||||
rsp=<regspacing>
|
rsp=<regspacing>
|
||||||
rsi=<regsize>
|
rsi=<regsize>
|
||||||
rsh=<regshift>
|
rsh=<regshift>
|
||||||
irq=<irq>
|
irq=<irq>
|
||||||
ipmb=<ipmb slave addr>
|
ipmb=<ipmb slave addr>
|
||||||
|
|
||||||
and these have the same meanings as discussed above. Note that you
|
and these have the same meanings as discussed above. Note that you
|
||||||
can also use this on the kernel command line for a more compact format
|
can also use this on the kernel command line for a more compact format
|
||||||
for specifying an interface. Note that when removing an interface,
|
for specifying an interface. Note that when removing an interface,
|
||||||
|
@ -496,7 +505,7 @@ The SMBus Driver (SSIF)
|
||||||
The SMBus driver allows up to 4 SMBus devices to be configured in the
|
The SMBus driver allows up to 4 SMBus devices to be configured in the
|
||||||
system. By default, the driver will only register with something it
|
system. By default, the driver will only register with something it
|
||||||
finds in DMI or ACPI tables. You can change this
|
finds in DMI or ACPI tables. You can change this
|
||||||
at module load time (for a module) with:
|
at module load time (for a module) with::
|
||||||
|
|
||||||
modprobe ipmi_ssif.o
|
modprobe ipmi_ssif.o
|
||||||
addr=<i2caddr1>[,<i2caddr2>[,...]]
|
addr=<i2caddr1>[,<i2caddr2>[,...]]
|
||||||
|
@ -535,7 +544,7 @@ the smb_addr parameter unless you have DMI or ACPI data to tell the
|
||||||
driver what to use.
|
driver what to use.
|
||||||
|
|
||||||
When compiled into the kernel, the addresses can be specified on the
|
When compiled into the kernel, the addresses can be specified on the
|
||||||
kernel command line as:
|
kernel command line as::
|
||||||
|
|
||||||
ipmb_ssif.addr=<i2caddr1>[,<i2caddr2>[...]]
|
ipmb_ssif.addr=<i2caddr1>[,<i2caddr2>[...]]
|
||||||
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
|
ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]]
|
||||||
|
@ -565,7 +574,7 @@ Some users need more detailed information about a device, like where
|
||||||
the address came from or the raw base device for the IPMI interface.
|
the address came from or the raw base device for the IPMI interface.
|
||||||
You can use the IPMI smi_watcher to catch the IPMI interfaces as they
|
You can use the IPMI smi_watcher to catch the IPMI interfaces as they
|
||||||
come or go, and to grab the information, you can use the function
|
come or go, and to grab the information, you can use the function
|
||||||
ipmi_get_smi_info(), which returns the following structure:
|
ipmi_get_smi_info(), which returns the following structure::
|
||||||
|
|
||||||
struct ipmi_smi_info {
|
struct ipmi_smi_info {
|
||||||
enum ipmi_addr_src addr_src;
|
enum ipmi_addr_src addr_src;
|
||||||
|
@ -590,7 +599,7 @@ Watchdog
|
||||||
|
|
||||||
A watchdog timer is provided that implements the Linux-standard
|
A watchdog timer is provided that implements the Linux-standard
|
||||||
watchdog timer interface. It has three module parameters that can be
|
watchdog timer interface. It has three module parameters that can be
|
||||||
used to control it:
|
used to control it::
|
||||||
|
|
||||||
modprobe ipmi_watchdog timeout=<t> pretimeout=<t> action=<action type>
|
modprobe ipmi_watchdog timeout=<t> pretimeout=<t> action=<action type>
|
||||||
preaction=<preaction type> preop=<preop type> start_now=x
|
preaction=<preaction type> preop=<preop type> start_now=x
|
||||||
|
@ -635,7 +644,7 @@ watchdog device is closed. The default value of nowayout is true
|
||||||
if the CONFIG_WATCHDOG_NOWAYOUT option is enabled, or false if not.
|
if the CONFIG_WATCHDOG_NOWAYOUT option is enabled, or false if not.
|
||||||
|
|
||||||
When compiled into the kernel, the kernel command line is available
|
When compiled into the kernel, the kernel command line is available
|
||||||
for configuring the watchdog:
|
for configuring the watchdog::
|
||||||
|
|
||||||
ipmi_watchdog.timeout=<t> ipmi_watchdog.pretimeout=<t>
|
ipmi_watchdog.timeout=<t> ipmi_watchdog.pretimeout=<t>
|
||||||
ipmi_watchdog.action=<action type>
|
ipmi_watchdog.action=<action type>
|
||||||
|
@ -675,6 +684,7 @@ also get a bunch of OEM events holding the panic string.
|
||||||
|
|
||||||
|
|
||||||
The field settings of the events are:
|
The field settings of the events are:
|
||||||
|
|
||||||
* Generator ID: 0x21 (kernel)
|
* Generator ID: 0x21 (kernel)
|
||||||
* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
|
* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
|
||||||
* Sensor Type: 0x20 (OS critical stop sensor)
|
* Sensor Type: 0x20 (OS critical stop sensor)
|
||||||
|
@ -683,15 +693,17 @@ The field settings of the events are:
|
||||||
* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
|
* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
|
||||||
* Event data 2: second byte of panic string
|
* Event data 2: second byte of panic string
|
||||||
* Event data 3: third byte of panic string
|
* Event data 3: third byte of panic string
|
||||||
|
|
||||||
See the IPMI spec for the details of the event layout. This event is
|
See the IPMI spec for the details of the event layout. This event is
|
||||||
always sent to the local management controller. It will handle routing
|
always sent to the local management controller. It will handle routing
|
||||||
the message to the right place
|
the message to the right place
|
||||||
|
|
||||||
Other OEM events have the following format:
|
Other OEM events have the following format:
|
||||||
Record ID (bytes 0-1): Set by the SEL.
|
|
||||||
Record type (byte 2): 0xf0 (OEM non-timestamped)
|
* Record ID (bytes 0-1): Set by the SEL.
|
||||||
byte 3: The slave address of the card saving the panic
|
* Record type (byte 2): 0xf0 (OEM non-timestamped)
|
||||||
byte 4: A sequence number (starting at zero)
|
* byte 3: The slave address of the card saving the panic
|
||||||
|
* byte 4: A sequence number (starting at zero)
|
||||||
The rest of the bytes (11 bytes) are the panic string. If the panic string
|
The rest of the bytes (11 bytes) are the panic string. If the panic string
|
||||||
is longer than 11 bytes, multiple messages will be sent with increasing
|
is longer than 11 bytes, multiple messages will be sent with increasing
|
||||||
sequence numbers.
|
sequence numbers.
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
ChangeLog:
|
================
|
||||||
Started by Ingo Molnar <mingo@redhat.com>
|
|
||||||
Update by Max Krasnyansky <maxk@qualcomm.com>
|
|
||||||
|
|
||||||
SMP IRQ affinity
|
SMP IRQ affinity
|
||||||
|
================
|
||||||
|
|
||||||
|
ChangeLog:
|
||||||
|
- Started by Ingo Molnar <mingo@redhat.com>
|
||||||
|
- Update by Max Krasnyansky <maxk@qualcomm.com>
|
||||||
|
|
||||||
|
|
||||||
/proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify
|
/proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify
|
||||||
which target CPUs are permitted for a given IRQ source. It's a bitmask
|
which target CPUs are permitted for a given IRQ source. It's a bitmask
|
||||||
|
@ -16,7 +19,7 @@ will be set to the default mask. It can then be changed as described above.
|
||||||
Default mask is 0xffffffff.
|
Default mask is 0xffffffff.
|
||||||
|
|
||||||
Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting
|
Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting
|
||||||
it to CPU4-7 (this is an 8-CPU SMP box):
|
it to CPU4-7 (this is an 8-CPU SMP box)::
|
||||||
|
|
||||||
[root@moon 44]# cd /proc/irq/44
|
[root@moon 44]# cd /proc/irq/44
|
||||||
[root@moon 44]# cat smp_affinity
|
[root@moon 44]# cat smp_affinity
|
||||||
|
@ -39,6 +42,8 @@ As can be seen from the line above IRQ44 was delivered only to the first four
|
||||||
processors (0-3).
|
processors (0-3).
|
||||||
Now lets restrict that IRQ to CPU(4-7).
|
Now lets restrict that IRQ to CPU(4-7).
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
[root@moon 44]# echo f0 > smp_affinity
|
[root@moon 44]# echo f0 > smp_affinity
|
||||||
[root@moon 44]# cat smp_affinity
|
[root@moon 44]# cat smp_affinity
|
||||||
000000f0
|
000000f0
|
||||||
|
@ -55,7 +60,7 @@ round-trip min/avg/max = 0.1/0.5/585.4 ms
|
||||||
This time around IRQ44 was delivered only to the last four processors.
|
This time around IRQ44 was delivered only to the last four processors.
|
||||||
i.e counters for the CPU0-3 did not change.
|
i.e counters for the CPU0-3 did not change.
|
||||||
|
|
||||||
Here is an example of limiting that same irq (44) to cpus 1024 to 1031:
|
Here is an example of limiting that same irq (44) to cpus 1024 to 1031::
|
||||||
|
|
||||||
[root@moon 44]# echo 1024-1031 > smp_affinity_list
|
[root@moon 44]# echo 1024-1031 > smp_affinity_list
|
||||||
[root@moon 44]# cat smp_affinity_list
|
[root@moon 44]# cat smp_affinity_list
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
irq_domain interrupt number mapping library
|
===============================================
|
||||||
|
The irq_domain interrupt number mapping library
|
||||||
|
===============================================
|
||||||
|
|
||||||
The current design of the Linux kernel uses a single large number
|
The current design of the Linux kernel uses a single large number
|
||||||
space where each separate IRQ source is assigned a different number.
|
space where each separate IRQ source is assigned a different number.
|
||||||
|
@ -36,7 +38,9 @@ irq_domain also implements translation from an abstract irq_fwspec
|
||||||
structure to hwirq numbers (Device Tree and ACPI GSI so far), and can
|
structure to hwirq numbers (Device Tree and ACPI GSI so far), and can
|
||||||
be easily extended to support other IRQ topology data sources.
|
be easily extended to support other IRQ topology data sources.
|
||||||
|
|
||||||
=== irq_domain usage ===
|
irq_domain usage
|
||||||
|
================
|
||||||
|
|
||||||
An interrupt controller driver creates and registers an irq_domain by
|
An interrupt controller driver creates and registers an irq_domain by
|
||||||
calling one of the irq_domain_add_*() functions (each mapping method
|
calling one of the irq_domain_add_*() functions (each mapping method
|
||||||
has a different allocator function, more on that later). The function
|
has a different allocator function, more on that later). The function
|
||||||
|
@ -62,13 +66,19 @@ If the driver has the Linux IRQ number or the irq_data pointer, and
|
||||||
needs to know the associated hwirq number (such as in the irq_chip
|
needs to know the associated hwirq number (such as in the irq_chip
|
||||||
callbacks) then it can be directly obtained from irq_data->hwirq.
|
callbacks) then it can be directly obtained from irq_data->hwirq.
|
||||||
|
|
||||||
=== Types of irq_domain mappings ===
|
Types of irq_domain mappings
|
||||||
|
============================
|
||||||
|
|
||||||
There are several mechanisms available for reverse mapping from hwirq
|
There are several mechanisms available for reverse mapping from hwirq
|
||||||
to Linux irq, and each mechanism uses a different allocation function.
|
to Linux irq, and each mechanism uses a different allocation function.
|
||||||
Which reverse map type should be used depends on the use case. Each
|
Which reverse map type should be used depends on the use case. Each
|
||||||
of the reverse map types are described below:
|
of the reverse map types are described below:
|
||||||
|
|
||||||
==== Linear ====
|
Linear
|
||||||
|
------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
irq_domain_add_linear()
|
irq_domain_add_linear()
|
||||||
irq_domain_create_linear()
|
irq_domain_create_linear()
|
||||||
|
|
||||||
|
@ -89,7 +99,11 @@ accepts a more general abstraction 'struct fwnode_handle'.
|
||||||
|
|
||||||
The majority of drivers should use the linear map.
|
The majority of drivers should use the linear map.
|
||||||
|
|
||||||
==== Tree ====
|
Tree
|
||||||
|
----
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
irq_domain_add_tree()
|
irq_domain_add_tree()
|
||||||
irq_domain_create_tree()
|
irq_domain_create_tree()
|
||||||
|
|
||||||
|
@ -109,7 +123,11 @@ accepts a more general abstraction 'struct fwnode_handle'.
|
||||||
|
|
||||||
Very few drivers should need this mapping.
|
Very few drivers should need this mapping.
|
||||||
|
|
||||||
==== No Map ===-
|
No Map
|
||||||
|
------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
irq_domain_add_nomap()
|
irq_domain_add_nomap()
|
||||||
|
|
||||||
The No Map mapping is to be used when the hwirq number is
|
The No Map mapping is to be used when the hwirq number is
|
||||||
|
@ -121,7 +139,11 @@ Linux IRQ number into the hardware.
|
||||||
|
|
||||||
Most drivers cannot use this mapping.
|
Most drivers cannot use this mapping.
|
||||||
|
|
||||||
==== Legacy ====
|
Legacy
|
||||||
|
------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
irq_domain_add_simple()
|
irq_domain_add_simple()
|
||||||
irq_domain_add_legacy()
|
irq_domain_add_legacy()
|
||||||
irq_domain_add_legacy_isa()
|
irq_domain_add_legacy_isa()
|
||||||
|
@ -163,14 +185,17 @@ that the driver using the simple domain call irq_create_mapping()
|
||||||
before any irq_find_mapping() since the latter will actually work
|
before any irq_find_mapping() since the latter will actually work
|
||||||
for the static IRQ assignment case.
|
for the static IRQ assignment case.
|
||||||
|
|
||||||
==== Hierarchy IRQ domain ====
|
Hierarchy IRQ domain
|
||||||
|
--------------------
|
||||||
|
|
||||||
On some architectures, there may be multiple interrupt controllers
|
On some architectures, there may be multiple interrupt controllers
|
||||||
involved in delivering an interrupt from the device to the target CPU.
|
involved in delivering an interrupt from the device to the target CPU.
|
||||||
Let's look at a typical interrupt delivering path on x86 platforms:
|
Let's look at a typical interrupt delivering path on x86 platforms::
|
||||||
|
|
||||||
Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
|
Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
|
||||||
|
|
||||||
There are three interrupt controllers involved:
|
There are three interrupt controllers involved:
|
||||||
|
|
||||||
1) IOAPIC controller
|
1) IOAPIC controller
|
||||||
2) Interrupt remapping controller
|
2) Interrupt remapping controller
|
||||||
3) Local APIC controller
|
3) Local APIC controller
|
||||||
|
@ -180,7 +205,8 @@ hardware architecture, an irq_domain data structure is built for each
|
||||||
interrupt controller and those irq_domains are organized into hierarchy.
|
interrupt controller and those irq_domains are organized into hierarchy.
|
||||||
When building irq_domain hierarchy, the irq_domain near to the device is
|
When building irq_domain hierarchy, the irq_domain near to the device is
|
||||||
child and the irq_domain near to CPU is parent. So a hierarchy structure
|
child and the irq_domain near to CPU is parent. So a hierarchy structure
|
||||||
as below will be built for the example above.
|
as below will be built for the example above::
|
||||||
|
|
||||||
CPU Vector irq_domain (root irq_domain to manage CPU vectors)
|
CPU Vector irq_domain (root irq_domain to manage CPU vectors)
|
||||||
^
|
^
|
||||||
|
|
|
|
||||||
|
@ -190,6 +216,7 @@ as below will be built for the example above.
|
||||||
IOAPIC irq_domain (manage IOAPIC delivery entries/pins)
|
IOAPIC irq_domain (manage IOAPIC delivery entries/pins)
|
||||||
|
|
||||||
There are four major interfaces to use hierarchy irq_domain:
|
There are four major interfaces to use hierarchy irq_domain:
|
||||||
|
|
||||||
1) irq_domain_alloc_irqs(): allocate IRQ descriptors and interrupt
|
1) irq_domain_alloc_irqs(): allocate IRQ descriptors and interrupt
|
||||||
controller related resources to deliver these interrupts.
|
controller related resources to deliver these interrupts.
|
||||||
2) irq_domain_free_irqs(): free IRQ descriptors and interrupt controller
|
2) irq_domain_free_irqs(): free IRQ descriptors and interrupt controller
|
||||||
|
@ -199,7 +226,8 @@ There are four major interfaces to use hierarchy irq_domain:
|
||||||
4) irq_domain_deactivate_irq(): deactivate interrupt controller hardware
|
4) irq_domain_deactivate_irq(): deactivate interrupt controller hardware
|
||||||
to stop delivering the interrupt.
|
to stop delivering the interrupt.
|
||||||
|
|
||||||
Following changes are needed to support hierarchy irq_domain.
|
Following changes are needed to support hierarchy irq_domain:
|
||||||
|
|
||||||
1) a new field 'parent' is added to struct irq_domain; it's used to
|
1) a new field 'parent' is added to struct irq_domain; it's used to
|
||||||
maintain irq_domain hierarchy information.
|
maintain irq_domain hierarchy information.
|
||||||
2) a new field 'parent_data' is added to struct irq_data; it's used to
|
2) a new field 'parent_data' is added to struct irq_data; it's used to
|
||||||
|
@ -223,6 +251,7 @@ software architecture.
|
||||||
|
|
||||||
For an interrupt controller driver to support hierarchy irq_domain, it
|
For an interrupt controller driver to support hierarchy irq_domain, it
|
||||||
needs to:
|
needs to:
|
||||||
|
|
||||||
1) Implement irq_domain_ops.alloc and irq_domain_ops.free
|
1) Implement irq_domain_ops.alloc and irq_domain_ops.free
|
||||||
2) Optionally implement irq_domain_ops.activate and
|
2) Optionally implement irq_domain_ops.activate and
|
||||||
irq_domain_ops.deactivate.
|
irq_domain_ops.deactivate.
|
||||||
|
@ -231,5 +260,42 @@ needs to:
|
||||||
4) No need to implement irq_domain_ops.map and irq_domain_ops.unmap,
|
4) No need to implement irq_domain_ops.map and irq_domain_ops.unmap,
|
||||||
they are unused with hierarchy irq_domain.
|
they are unused with hierarchy irq_domain.
|
||||||
|
|
||||||
Hierarchy irq_domain may also be used to support other architectures,
|
Hierarchy irq_domain is in no way x86 specific, and is heavily used to
|
||||||
such as ARM, ARM64 etc.
|
support other architectures, such as ARM, ARM64 etc.
|
||||||
|
|
||||||
|
=== Debugging ===
|
||||||
|
|
||||||
|
If you switch on CONFIG_IRQ_DOMAIN_DEBUG (which depends on
|
||||||
|
CONFIG_IRQ_DOMAIN and CONFIG_DEBUG_FS), you will find a new file in
|
||||||
|
your debugfs mount point, called irq_domain_mapping. This file
|
||||||
|
contains a live snapshot of all the IRQ domains in the system:
|
||||||
|
|
||||||
|
name mapped linear-max direct-max devtree-node
|
||||||
|
pl061 8 8 0 /smb/gpio@e0080000
|
||||||
|
pl061 8 8 0 /smb/gpio@e1050000
|
||||||
|
pMSI 0 0 0 /interrupt-controller@e1101000/v2m@e0080000
|
||||||
|
MSI 37 0 0 /interrupt-controller@e1101000/v2m@e0080000
|
||||||
|
GICv2m 37 0 0 /interrupt-controller@e1101000/v2m@e0080000
|
||||||
|
GICv2 448 448 0 /interrupt-controller@e1101000
|
||||||
|
|
||||||
|
it also iterates over the interrupts to display their mapping in the
|
||||||
|
domains, and makes the domain stacking visible:
|
||||||
|
|
||||||
|
|
||||||
|
irq hwirq chip name chip data active type domain
|
||||||
|
1 0x00019 GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
||||||
|
2 0x0001d GICv2 0xffff00000916bfd8 LINEAR GICv2
|
||||||
|
3 0x0001e GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
||||||
|
4 0x0001b GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
||||||
|
5 0x0001a GICv2 0xffff00000916bfd8 LINEAR GICv2
|
||||||
|
[...]
|
||||||
|
96 0x81808 MSI 0x (null) RADIX MSI
|
||||||
|
96+ 0x00063 GICv2m 0xffff8003ee116980 RADIX GICv2m
|
||||||
|
96+ 0x00063 GICv2 0xffff00000916bfd8 LINEAR GICv2
|
||||||
|
97 0x08800 MSI 0x (null) * RADIX MSI
|
||||||
|
97+ 0x00064 GICv2m 0xffff8003ee116980 * RADIX GICv2m
|
||||||
|
97+ 0x00064 GICv2 0xffff00000916bfd8 * LINEAR GICv2
|
||||||
|
|
||||||
|
Here, interrupts 1-5 are only using a single domain, while 96 and 97
|
||||||
|
are build out of a stack of three domain, each level performing a
|
||||||
|
particular function.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
===============
|
||||||
What is an IRQ?
|
What is an IRQ?
|
||||||
|
===============
|
||||||
|
|
||||||
An IRQ is an interrupt request from a device.
|
An IRQ is an interrupt request from a device.
|
||||||
Currently they can come in over a pin, or over a packet.
|
Currently they can come in over a pin, or over a packet.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
===================
|
||||||
Linux IOMMU Support
|
Linux IOMMU Support
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
@ -9,11 +10,11 @@ This guide gives a quick cheat sheet for some basic understanding.
|
||||||
|
|
||||||
Some Keywords
|
Some Keywords
|
||||||
|
|
||||||
DMAR - DMA remapping
|
- DMAR - DMA remapping
|
||||||
DRHD - DMA Remapping Hardware Unit Definition
|
- DRHD - DMA Remapping Hardware Unit Definition
|
||||||
RMRR - Reserved memory Region Reporting Structure
|
- RMRR - Reserved memory Region Reporting Structure
|
||||||
ZLR - Zero length reads from PCI devices
|
- ZLR - Zero length reads from PCI devices
|
||||||
IOVA - IO Virtual address.
|
- IOVA - IO Virtual address.
|
||||||
|
|
||||||
Basic stuff
|
Basic stuff
|
||||||
-----------
|
-----------
|
||||||
|
@ -33,7 +34,7 @@ devices that need to access these regions. OS is expected to setup
|
||||||
unity mappings for these regions for these devices to access these regions.
|
unity mappings for these regions for these devices to access these regions.
|
||||||
|
|
||||||
How is IOVA generated?
|
How is IOVA generated?
|
||||||
---------------------
|
----------------------
|
||||||
|
|
||||||
Well behaved drivers call pci_map_*() calls before sending command to device
|
Well behaved drivers call pci_map_*() calls before sending command to device
|
||||||
that needs to perform DMA. Once DMA is completed and mapping is no longer
|
that needs to perform DMA. Once DMA is completed and mapping is no longer
|
||||||
|
@ -82,7 +83,7 @@ in ACPI.
|
||||||
ACPI: DMAR (v001 A M I OEMDMAR 0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
|
ACPI: DMAR (v001 A M I OEMDMAR 0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
|
||||||
|
|
||||||
When DMAR is being processed and initialized by ACPI, prints DMAR locations
|
When DMAR is being processed and initialized by ACPI, prints DMAR locations
|
||||||
and any RMRR's processed.
|
and any RMRR's processed::
|
||||||
|
|
||||||
ACPI DMAR:Host address width 36
|
ACPI DMAR:Host address width 36
|
||||||
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
|
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
|
||||||
|
@ -98,6 +99,8 @@ PCI-DMA: Using DMAR IOMMU
|
||||||
Fault reporting
|
Fault reporting
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
|
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
|
||||||
DMAR:[fault reason 05] PTE Write access is not set
|
DMAR:[fault reason 05] PTE Write access is not set
|
||||||
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
|
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
|
||||||
|
|
|
@ -1 +1,126 @@
|
||||||
|
# -*- makefile -*-
|
||||||
|
# Makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
subdir-y :=
|
subdir-y :=
|
||||||
|
|
||||||
|
# You can set these variables from the command line.
|
||||||
|
SPHINXBUILD = sphinx-build
|
||||||
|
SPHINXOPTS =
|
||||||
|
SPHINXDIRS = .
|
||||||
|
_SPHINXDIRS = $(patsubst $(srctree)/Documentation/%/conf.py,%,$(wildcard $(srctree)/Documentation/*/conf.py))
|
||||||
|
SPHINX_CONF = conf.py
|
||||||
|
PAPER =
|
||||||
|
BUILDDIR = $(obj)/output
|
||||||
|
PDFLATEX = xelatex
|
||||||
|
LATEXOPTS = -interaction=batchmode
|
||||||
|
|
||||||
|
# User-friendly check for sphinx-build
|
||||||
|
HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
||||||
|
|
||||||
|
ifeq ($(HAVE_SPHINX),0)
|
||||||
|
|
||||||
|
.DEFAULT:
|
||||||
|
$(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.)
|
||||||
|
@echo " SKIP Sphinx $@ target."
|
||||||
|
|
||||||
|
else # HAVE_SPHINX
|
||||||
|
|
||||||
|
# User-friendly check for pdflatex
|
||||||
|
HAVE_PDFLATEX := $(shell if which $(PDFLATEX) >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
||||||
|
|
||||||
|
# Internal variables.
|
||||||
|
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||||
|
PAPEROPT_letter = -D latex_paper_size=letter
|
||||||
|
KERNELDOC = $(srctree)/scripts/kernel-doc
|
||||||
|
KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC)
|
||||||
|
ALLSPHINXOPTS = $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
|
||||||
|
# the i18n builder cannot share the environment and doctrees with the others
|
||||||
|
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||||
|
|
||||||
|
# commands; the 'cmd' from scripts/Kbuild.include is not *loopable*
|
||||||
|
loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit;
|
||||||
|
|
||||||
|
# $2 sphinx builder e.g. "html"
|
||||||
|
# $3 name of the build subfolder / e.g. "media", used as:
|
||||||
|
# * dest folder relative to $(BUILDDIR) and
|
||||||
|
# * cache folder relative to $(BUILDDIR)/.doctrees
|
||||||
|
# $4 dest subfolder e.g. "man" for man pages at media/man
|
||||||
|
# $5 reST source folder relative to $(srctree)/$(src),
|
||||||
|
# e.g. "media" for the linux-tv book-set at ./Documentation/media
|
||||||
|
|
||||||
|
quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
|
||||||
|
cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media $2 && \
|
||||||
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
|
||||||
|
$(SPHINXBUILD) \
|
||||||
|
-b $2 \
|
||||||
|
-c $(abspath $(srctree)/$(src)) \
|
||||||
|
-d $(abspath $(BUILDDIR)/.doctrees/$3) \
|
||||||
|
-D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) \
|
||||||
|
$(ALLSPHINXOPTS) \
|
||||||
|
$(abspath $(srctree)/$(src)/$5) \
|
||||||
|
$(abspath $(BUILDDIR)/$3/$4)
|
||||||
|
|
||||||
|
htmldocs:
|
||||||
|
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))
|
||||||
|
|
||||||
|
linkcheckdocs:
|
||||||
|
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,linkcheck,$(var),,$(var)))
|
||||||
|
|
||||||
|
latexdocs:
|
||||||
|
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,latex,$(var),latex,$(var)))
|
||||||
|
|
||||||
|
ifeq ($(HAVE_PDFLATEX),0)
|
||||||
|
|
||||||
|
pdfdocs:
|
||||||
|
$(warning The '$(PDFLATEX)' command was not found. Make sure you have it installed and in PATH to produce PDF output.)
|
||||||
|
@echo " SKIP Sphinx $@ target."
|
||||||
|
|
||||||
|
else # HAVE_PDFLATEX
|
||||||
|
|
||||||
|
pdfdocs: latexdocs
|
||||||
|
$(foreach var,$(SPHINXDIRS), $(MAKE) PDFLATEX=$(PDFLATEX) LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit;)
|
||||||
|
|
||||||
|
endif # HAVE_PDFLATEX
|
||||||
|
|
||||||
|
epubdocs:
|
||||||
|
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,epub,$(var),epub,$(var)))
|
||||||
|
|
||||||
|
xmldocs:
|
||||||
|
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,xml,$(var),xml,$(var)))
|
||||||
|
|
||||||
|
endif # HAVE_SPHINX
|
||||||
|
|
||||||
|
# The following targets are independent of HAVE_SPHINX, and the rules should
|
||||||
|
# work or silently pass without Sphinx.
|
||||||
|
|
||||||
|
# no-ops for the Sphinx toolchain
|
||||||
|
sgmldocs:
|
||||||
|
@:
|
||||||
|
psdocs:
|
||||||
|
@:
|
||||||
|
mandocs:
|
||||||
|
@:
|
||||||
|
installmandocs:
|
||||||
|
@:
|
||||||
|
|
||||||
|
cleandocs:
|
||||||
|
$(Q)rm -rf $(BUILDDIR)
|
||||||
|
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
||||||
|
|
||||||
|
dochelp:
|
||||||
|
@echo ' Linux kernel internal documentation in different formats from ReST:'
|
||||||
|
@echo ' htmldocs - HTML'
|
||||||
|
@echo ' latexdocs - LaTeX'
|
||||||
|
@echo ' pdfdocs - PDF'
|
||||||
|
@echo ' epubdocs - EPUB'
|
||||||
|
@echo ' xmldocs - XML'
|
||||||
|
@echo ' linkcheckdocs - check for broken external links (will connect to external hosts)'
|
||||||
|
@echo ' cleandocs - clean all generated files'
|
||||||
|
@echo
|
||||||
|
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
||||||
|
@echo ' valid values for SPHINXDIRS are: $(_SPHINXDIRS)'
|
||||||
|
@echo
|
||||||
|
@echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build'
|
||||||
|
@echo ' configuration. This is e.g. useful to build with nit-picking config.'
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
# -*- makefile -*-
|
|
||||||
# Makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
SPHINXBUILD = sphinx-build
|
|
||||||
SPHINXOPTS =
|
|
||||||
SPHINXDIRS = .
|
|
||||||
_SPHINXDIRS = $(patsubst $(srctree)/Documentation/%/conf.py,%,$(wildcard $(srctree)/Documentation/*/conf.py))
|
|
||||||
SPHINX_CONF = conf.py
|
|
||||||
PAPER =
|
|
||||||
BUILDDIR = $(obj)/output
|
|
||||||
PDFLATEX = xelatex
|
|
||||||
LATEXOPTS = -interaction=batchmode
|
|
||||||
|
|
||||||
# User-friendly check for sphinx-build
|
|
||||||
HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
|
||||||
|
|
||||||
ifeq ($(HAVE_SPHINX),0)
|
|
||||||
|
|
||||||
.DEFAULT:
|
|
||||||
$(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.)
|
|
||||||
@echo " SKIP Sphinx $@ target."
|
|
||||||
|
|
||||||
else ifneq ($(DOCBOOKS),)
|
|
||||||
|
|
||||||
# Skip Sphinx build if the user explicitly requested DOCBOOKS.
|
|
||||||
.DEFAULT:
|
|
||||||
@echo " SKIP Sphinx $@ target (DOCBOOKS specified)."
|
|
||||||
|
|
||||||
else # HAVE_SPHINX
|
|
||||||
|
|
||||||
# User-friendly check for pdflatex
|
|
||||||
HAVE_PDFLATEX := $(shell if which $(PDFLATEX) >/dev/null 2>&1; then echo 1; else echo 0; fi)
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
|
||||||
KERNELDOC = $(srctree)/scripts/kernel-doc
|
|
||||||
KERNELDOC_CONF = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC)
|
|
||||||
ALLSPHINXOPTS = $(KERNELDOC_CONF) $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
|
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
|
||||||
|
|
||||||
# commands; the 'cmd' from scripts/Kbuild.include is not *loopable*
|
|
||||||
loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit;
|
|
||||||
|
|
||||||
# $2 sphinx builder e.g. "html"
|
|
||||||
# $3 name of the build subfolder / e.g. "media", used as:
|
|
||||||
# * dest folder relative to $(BUILDDIR) and
|
|
||||||
# * cache folder relative to $(BUILDDIR)/.doctrees
|
|
||||||
# $4 dest subfolder e.g. "man" for man pages at media/man
|
|
||||||
# $5 reST source folder relative to $(srctree)/$(src),
|
|
||||||
# e.g. "media" for the linux-tv book-set at ./Documentation/media
|
|
||||||
|
|
||||||
quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
|
|
||||||
cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media $2 && \
|
|
||||||
PYTHONDONTWRITEBYTECODE=1 \
|
|
||||||
BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(srctree)/$(src)/$5/$(SPHINX_CONF)) \
|
|
||||||
$(SPHINXBUILD) \
|
|
||||||
-b $2 \
|
|
||||||
-c $(abspath $(srctree)/$(src)) \
|
|
||||||
-d $(abspath $(BUILDDIR)/.doctrees/$3) \
|
|
||||||
-D version=$(KERNELVERSION) -D release=$(KERNELRELEASE) \
|
|
||||||
$(ALLSPHINXOPTS) \
|
|
||||||
$(abspath $(srctree)/$(src)/$5) \
|
|
||||||
$(abspath $(BUILDDIR)/$3/$4)
|
|
||||||
|
|
||||||
htmldocs:
|
|
||||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))
|
|
||||||
|
|
||||||
linkcheckdocs:
|
|
||||||
@$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,linkcheck,$(var),,$(var)))
|
|
||||||
|
|
||||||
latexdocs:
|
|
||||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,latex,$(var),latex,$(var)))
|
|
||||||
|
|
||||||
ifeq ($(HAVE_PDFLATEX),0)
|
|
||||||
|
|
||||||
pdfdocs:
|
|
||||||
$(warning The '$(PDFLATEX)' command was not found. Make sure you have it installed and in PATH to produce PDF output.)
|
|
||||||
@echo " SKIP Sphinx $@ target."
|
|
||||||
|
|
||||||
else # HAVE_PDFLATEX
|
|
||||||
|
|
||||||
pdfdocs: latexdocs
|
|
||||||
$(foreach var,$(SPHINXDIRS), $(MAKE) PDFLATEX=$(PDFLATEX) LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit;)
|
|
||||||
|
|
||||||
endif # HAVE_PDFLATEX
|
|
||||||
|
|
||||||
epubdocs:
|
|
||||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,epub,$(var),epub,$(var)))
|
|
||||||
|
|
||||||
xmldocs:
|
|
||||||
@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,xml,$(var),xml,$(var)))
|
|
||||||
|
|
||||||
endif # HAVE_SPHINX
|
|
||||||
|
|
||||||
# The following targets are independent of HAVE_SPHINX, and the rules should
|
|
||||||
# work or silently pass without Sphinx.
|
|
||||||
|
|
||||||
# no-ops for the Sphinx toolchain
|
|
||||||
sgmldocs:
|
|
||||||
@:
|
|
||||||
psdocs:
|
|
||||||
@:
|
|
||||||
mandocs:
|
|
||||||
@:
|
|
||||||
installmandocs:
|
|
||||||
@:
|
|
||||||
|
|
||||||
cleandocs:
|
|
||||||
$(Q)rm -rf $(BUILDDIR)
|
|
||||||
$(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean
|
|
||||||
|
|
||||||
dochelp:
|
|
||||||
@echo ' Linux kernel internal documentation in different formats (Sphinx):'
|
|
||||||
@echo ' htmldocs - HTML'
|
|
||||||
@echo ' latexdocs - LaTeX'
|
|
||||||
@echo ' pdfdocs - PDF'
|
|
||||||
@echo ' epubdocs - EPUB'
|
|
||||||
@echo ' xmldocs - XML'
|
|
||||||
@echo ' linkcheckdocs - check for broken external links (will connect to external hosts)'
|
|
||||||
@echo ' cleandocs - clean all generated files'
|
|
||||||
@echo
|
|
||||||
@echo ' make SPHINXDIRS="s1 s2" [target] Generate only docs of folder s1, s2'
|
|
||||||
@echo ' valid values for SPHINXDIRS are: $(_SPHINXDIRS)'
|
|
||||||
@echo
|
|
||||||
@echo ' make SPHINX_CONF={conf-file} [target] use *additional* sphinx-build'
|
|
||||||
@echo ' configuration. This is e.g. useful to build with nit-picking config.'
|
|
|
@ -186,7 +186,7 @@ must disable interrupts while the lock is held. If the device sends
|
||||||
a different interrupt, the driver will deadlock trying to recursively
|
a different interrupt, the driver will deadlock trying to recursively
|
||||||
acquire the spinlock. Such deadlocks can be avoided by using
|
acquire the spinlock. Such deadlocks can be avoided by using
|
||||||
spin_lock_irqsave() or spin_lock_irq() which disable local interrupts
|
spin_lock_irqsave() or spin_lock_irq() which disable local interrupts
|
||||||
and acquire the lock (see Documentation/DocBook/kernel-locking).
|
and acquire the lock (see Documentation/kernel-hacking/locking.rst).
|
||||||
|
|
||||||
4.5 How to tell whether MSI/MSI-X is enabled on a device
|
4.5 How to tell whether MSI/MSI-X is enabled on a device
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,6 @@ stallwarn.txt
|
||||||
- RCU CPU stall warnings (module parameter rcu_cpu_stall_suppress)
|
- RCU CPU stall warnings (module parameter rcu_cpu_stall_suppress)
|
||||||
torture.txt
|
torture.txt
|
||||||
- RCU Torture Test Operation (CONFIG_RCU_TORTURE_TEST)
|
- RCU Torture Test Operation (CONFIG_RCU_TORTURE_TEST)
|
||||||
trace.txt
|
|
||||||
- CONFIG_RCU_TRACE debugfs files and formats
|
|
||||||
UP.txt
|
UP.txt
|
||||||
- RCU on Uniprocessor Systems
|
- RCU on Uniprocessor Systems
|
||||||
whatisRCU.txt
|
whatisRCU.txt
|
||||||
|
|
|
@ -559,9 +559,7 @@ The <tt>rcu_access_pointer()</tt> on line 6 is similar to
|
||||||
For <tt>remove_gp_synchronous()</tt>, as long as all modifications
|
For <tt>remove_gp_synchronous()</tt>, as long as all modifications
|
||||||
to <tt>gp</tt> are carried out while holding <tt>gp_lock</tt>,
|
to <tt>gp</tt> are carried out while holding <tt>gp_lock</tt>,
|
||||||
the above optimizations are harmless.
|
the above optimizations are harmless.
|
||||||
However,
|
However, <tt>sparse</tt> will complain if you
|
||||||
with <tt>CONFIG_SPARSE_RCU_POINTER=y</tt>,
|
|
||||||
<tt>sparse</tt> will complain if you
|
|
||||||
define <tt>gp</tt> with <tt>__rcu</tt> and then
|
define <tt>gp</tt> with <tt>__rcu</tt> and then
|
||||||
access it without using
|
access it without using
|
||||||
either <tt>rcu_access_pointer()</tt> or <tt>rcu_dereference()</tt>.
|
either <tt>rcu_access_pointer()</tt> or <tt>rcu_dereference()</tt>.
|
||||||
|
@ -1849,7 +1847,8 @@ mass storage, or user patience, whichever comes first.
|
||||||
If the nesting is not visible to the compiler, as is the case with
|
If the nesting is not visible to the compiler, as is the case with
|
||||||
mutually recursive functions each in its own translation unit,
|
mutually recursive functions each in its own translation unit,
|
||||||
stack overflow will result.
|
stack overflow will result.
|
||||||
If the nesting takes the form of loops, either the control variable
|
If the nesting takes the form of loops, perhaps in the guise of tail
|
||||||
|
recursion, either the control variable
|
||||||
will overflow or (in the Linux kernel) you will get an RCU CPU stall warning.
|
will overflow or (in the Linux kernel) you will get an RCU CPU stall warning.
|
||||||
Nevertheless, this class of RCU implementations is one
|
Nevertheless, this class of RCU implementations is one
|
||||||
of the most composable constructs in existence.
|
of the most composable constructs in existence.
|
||||||
|
@ -1977,9 +1976,8 @@ guard against mishaps and misuse:
|
||||||
and <tt>rcu_dereference()</tt>, perhaps (incorrectly)
|
and <tt>rcu_dereference()</tt>, perhaps (incorrectly)
|
||||||
substituting a simple assignment.
|
substituting a simple assignment.
|
||||||
To catch this sort of error, a given RCU-protected pointer may be
|
To catch this sort of error, a given RCU-protected pointer may be
|
||||||
tagged with <tt>__rcu</tt>, after which running sparse
|
tagged with <tt>__rcu</tt>, after which sparse
|
||||||
with <tt>CONFIG_SPARSE_RCU_POINTER=y</tt> will complain
|
will complain about simple-assignment accesses to that pointer.
|
||||||
about simple-assignment accesses to that pointer.
|
|
||||||
Arnd Bergmann made me aware of this requirement, and also
|
Arnd Bergmann made me aware of this requirement, and also
|
||||||
supplied the needed
|
supplied the needed
|
||||||
<a href="https://lwn.net/Articles/376011/">patch series</a>.
|
<a href="https://lwn.net/Articles/376011/">patch series</a>.
|
||||||
|
@ -2036,7 +2034,7 @@ guard against mishaps and misuse:
|
||||||
some other synchronization mechanism, for example, reference
|
some other synchronization mechanism, for example, reference
|
||||||
counting.
|
counting.
|
||||||
<li> In kernels built with <tt>CONFIG_RCU_TRACE=y</tt>, RCU-related
|
<li> In kernels built with <tt>CONFIG_RCU_TRACE=y</tt>, RCU-related
|
||||||
information is provided via both debugfs and event tracing.
|
information is provided via event tracing.
|
||||||
<li> Open-coded use of <tt>rcu_assign_pointer()</tt> and
|
<li> Open-coded use of <tt>rcu_assign_pointer()</tt> and
|
||||||
<tt>rcu_dereference()</tt> to create typical linked
|
<tt>rcu_dereference()</tt> to create typical linked
|
||||||
data structures can be surprisingly error-prone.
|
data structures can be surprisingly error-prone.
|
||||||
|
@ -2519,11 +2517,7 @@ It is similarly socially unacceptable to interrupt an
|
||||||
<tt>nohz_full</tt> CPU running in userspace.
|
<tt>nohz_full</tt> CPU running in userspace.
|
||||||
RCU must therefore track <tt>nohz_full</tt> userspace
|
RCU must therefore track <tt>nohz_full</tt> userspace
|
||||||
execution.
|
execution.
|
||||||
And in
|
RCU must therefore be able to sample state at two points in
|
||||||
<a href="https://lwn.net/Articles/558284/"><tt>CONFIG_NO_HZ_FULL_SYSIDLE=y</tt></a>
|
|
||||||
kernels, RCU must separately track idle CPUs on the one hand and
|
|
||||||
CPUs that are either idle or executing in userspace on the other.
|
|
||||||
In both cases, RCU must be able to sample state at two points in
|
|
||||||
time, and be able to determine whether or not some other CPU spent
|
time, and be able to determine whether or not some other CPU spent
|
||||||
any time idle and/or executing in userspace.
|
any time idle and/or executing in userspace.
|
||||||
|
|
||||||
|
@ -2935,6 +2929,20 @@ The reason that this is possible is that SRCU is insensitive
|
||||||
to whether or not a CPU is online, which means that <tt>srcu_barrier()</tt>
|
to whether or not a CPU is online, which means that <tt>srcu_barrier()</tt>
|
||||||
need not exclude CPU-hotplug operations.
|
need not exclude CPU-hotplug operations.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
SRCU also differs from other RCU flavors in that SRCU's expedited and
|
||||||
|
non-expedited grace periods are implemented by the same mechanism.
|
||||||
|
This means that in the current SRCU implementation, expediting a
|
||||||
|
future grace period has the side effect of expediting all prior
|
||||||
|
grace periods that have not yet completed.
|
||||||
|
(But please note that this is a property of the current implementation,
|
||||||
|
not necessarily of future implementations.)
|
||||||
|
In addition, if SRCU has been idle for longer than the interval
|
||||||
|
specified by the <tt>srcutree.exp_holdoff</tt> kernel boot parameter
|
||||||
|
(25 microseconds by default),
|
||||||
|
and if a <tt>synchronize_srcu()</tt> invocation ends this idle period,
|
||||||
|
that invocation will be automatically expedited.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
As of v4.12, SRCU's callbacks are maintained per-CPU, eliminating
|
As of v4.12, SRCU's callbacks are maintained per-CPU, eliminating
|
||||||
a locking bottleneck present in prior kernel versions.
|
a locking bottleneck present in prior kernel versions.
|
||||||
|
|
|
@ -413,11 +413,11 @@ over a rather long period of time, but improvements are always welcome!
|
||||||
read-side critical sections. It is the responsibility of the
|
read-side critical sections. It is the responsibility of the
|
||||||
RCU update-side primitives to deal with this.
|
RCU update-side primitives to deal with this.
|
||||||
|
|
||||||
17. Use CONFIG_PROVE_RCU, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the
|
17. Use CONFIG_PROVE_LOCKING, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and the
|
||||||
__rcu sparse checks (enabled by CONFIG_SPARSE_RCU_POINTER) to
|
__rcu sparse checks to validate your RCU code. These can help
|
||||||
validate your RCU code. These can help find problems as follows:
|
find problems as follows:
|
||||||
|
|
||||||
CONFIG_PROVE_RCU: check that accesses to RCU-protected data
|
CONFIG_PROVE_LOCKING: check that accesses to RCU-protected data
|
||||||
structures are carried out under the proper RCU
|
structures are carried out under the proper RCU
|
||||||
read-side critical section, while holding the right
|
read-side critical section, while holding the right
|
||||||
combination of locks, or whatever other conditions
|
combination of locks, or whatever other conditions
|
||||||
|
|
|
@ -1,535 +0,0 @@
|
||||||
CONFIG_RCU_TRACE debugfs Files and Formats
|
|
||||||
|
|
||||||
|
|
||||||
The rcutree and rcutiny implementations of RCU provide debugfs trace
|
|
||||||
output that summarizes counters and state. This information is useful for
|
|
||||||
debugging RCU itself, and can sometimes also help to debug abuses of RCU.
|
|
||||||
The following sections describe the debugfs files and formats, first
|
|
||||||
for rcutree and next for rcutiny.
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_TREE_RCU and CONFIG_PREEMPT_RCU debugfs Files and Formats
|
|
||||||
|
|
||||||
These implementations of RCU provide several debugfs directories under the
|
|
||||||
top-level directory "rcu":
|
|
||||||
|
|
||||||
rcu/rcu_bh
|
|
||||||
rcu/rcu_preempt
|
|
||||||
rcu/rcu_sched
|
|
||||||
|
|
||||||
Each directory contains files for the corresponding flavor of RCU.
|
|
||||||
Note that rcu/rcu_preempt is only present for CONFIG_PREEMPT_RCU.
|
|
||||||
For CONFIG_TREE_RCU, the RCU flavor maps onto the RCU-sched flavor,
|
|
||||||
so that activity for both appears in rcu/rcu_sched.
|
|
||||||
|
|
||||||
In addition, the following file appears in the top-level directory:
|
|
||||||
rcu/rcutorture. This file displays rcutorture test progress. The output
|
|
||||||
of "cat rcu/rcutorture" looks as follows:
|
|
||||||
|
|
||||||
rcutorture test sequence: 0 (test in progress)
|
|
||||||
rcutorture update version number: 615
|
|
||||||
|
|
||||||
The first line shows the number of rcutorture tests that have completed
|
|
||||||
since boot. If a test is currently running, the "(test in progress)"
|
|
||||||
string will appear as shown above. The second line shows the number of
|
|
||||||
update cycles that the current test has started, or zero if there is
|
|
||||||
no test in progress.
|
|
||||||
|
|
||||||
|
|
||||||
Within each flavor directory (rcu/rcu_bh, rcu/rcu_sched, and possibly
|
|
||||||
also rcu/rcu_preempt) the following files will be present:
|
|
||||||
|
|
||||||
rcudata:
|
|
||||||
Displays fields in struct rcu_data.
|
|
||||||
rcuexp:
|
|
||||||
Displays statistics for expedited grace periods.
|
|
||||||
rcugp:
|
|
||||||
Displays grace-period counters.
|
|
||||||
rcuhier:
|
|
||||||
Displays the struct rcu_node hierarchy.
|
|
||||||
rcu_pending:
|
|
||||||
Displays counts of the reasons rcu_pending() decided that RCU had
|
|
||||||
work to do.
|
|
||||||
rcuboost:
|
|
||||||
Displays RCU boosting statistics. Only present if
|
|
||||||
CONFIG_RCU_BOOST=y.
|
|
||||||
|
|
||||||
The output of "cat rcu/rcu_preempt/rcudata" looks as follows:
|
|
||||||
|
|
||||||
0!c=30455 g=30456 cnq=1/0:1 dt=126535/140000000000000/0 df=2002 of=4 ql=0/0 qs=N... b=10 ci=74572 nci=0 co=1131 ca=716
|
|
||||||
1!c=30719 g=30720 cnq=1/0:0 dt=132007/140000000000000/0 df=1874 of=10 ql=0/0 qs=N... b=10 ci=123209 nci=0 co=685 ca=982
|
|
||||||
2!c=30150 g=30151 cnq=1/1:1 dt=138537/140000000000000/0 df=1707 of=8 ql=0/0 qs=N... b=10 ci=80132 nci=0 co=1328 ca=1458
|
|
||||||
3 c=31249 g=31250 cnq=1/1:0 dt=107255/140000000000000/0 df=1749 of=6 ql=0/450 qs=NRW. b=10 ci=151700 nci=0 co=509 ca=622
|
|
||||||
4!c=29502 g=29503 cnq=1/0:1 dt=83647/140000000000000/0 df=965 of=5 ql=0/0 qs=N... b=10 ci=65643 nci=0 co=1373 ca=1521
|
|
||||||
5 c=31201 g=31202 cnq=1/0:1 dt=70422/0/0 df=535 of=7 ql=0/0 qs=.... b=10 ci=58500 nci=0 co=764 ca=698
|
|
||||||
6!c=30253 g=30254 cnq=1/0:1 dt=95363/140000000000000/0 df=780 of=5 ql=0/0 qs=N... b=10 ci=100607 nci=0 co=1414 ca=1353
|
|
||||||
7 c=31178 g=31178 cnq=1/0:0 dt=91536/0/0 df=547 of=4 ql=0/0 qs=.... b=10 ci=109819 nci=0 co=1115 ca=969
|
|
||||||
|
|
||||||
This file has one line per CPU, or eight for this 8-CPU system.
|
|
||||||
The fields are as follows:
|
|
||||||
|
|
||||||
o The number at the beginning of each line is the CPU number.
|
|
||||||
CPUs numbers followed by an exclamation mark are offline,
|
|
||||||
but have been online at least once since boot. There will be
|
|
||||||
no output for CPUs that have never been online, which can be
|
|
||||||
a good thing in the surprisingly common case where NR_CPUS is
|
|
||||||
substantially larger than the number of actual CPUs.
|
|
||||||
|
|
||||||
o "c" is the count of grace periods that this CPU believes have
|
|
||||||
completed. Offlined CPUs and CPUs in dynticks idle mode may lag
|
|
||||||
quite a ways behind, for example, CPU 4 under "rcu_sched" above,
|
|
||||||
which has been offline through 16 RCU grace periods. It is not
|
|
||||||
unusual to see offline CPUs lagging by thousands of grace periods.
|
|
||||||
Note that although the grace-period number is an unsigned long,
|
|
||||||
it is printed out as a signed long to allow more human-friendly
|
|
||||||
representation near boot time.
|
|
||||||
|
|
||||||
o "g" is the count of grace periods that this CPU believes have
|
|
||||||
started. Again, offlined CPUs and CPUs in dynticks idle mode
|
|
||||||
may lag behind. If the "c" and "g" values are equal, this CPU
|
|
||||||
has already reported a quiescent state for the last RCU grace
|
|
||||||
period that it is aware of, otherwise, the CPU believes that it
|
|
||||||
owes RCU a quiescent state.
|
|
||||||
|
|
||||||
o "pq" indicates that this CPU has passed through a quiescent state
|
|
||||||
for the current grace period. It is possible for "pq" to be
|
|
||||||
"1" and "c" different than "g", which indicates that although
|
|
||||||
the CPU has passed through a quiescent state, either (1) this
|
|
||||||
CPU has not yet reported that fact, (2) some other CPU has not
|
|
||||||
yet reported for this grace period, or (3) both.
|
|
||||||
|
|
||||||
o "qp" indicates that RCU still expects a quiescent state from
|
|
||||||
this CPU. Offlined CPUs and CPUs in dyntick idle mode might
|
|
||||||
well have qp=1, which is OK: RCU is still ignoring them.
|
|
||||||
|
|
||||||
o "dt" is the current value of the dyntick counter that is incremented
|
|
||||||
when entering or leaving idle, either due to a context switch or
|
|
||||||
due to an interrupt. This number is even if the CPU is in idle
|
|
||||||
from RCU's viewpoint and odd otherwise. The number after the
|
|
||||||
first "/" is the interrupt nesting depth when in idle state,
|
|
||||||
or a large number added to the interrupt-nesting depth when
|
|
||||||
running a non-idle task. Some architectures do not accurately
|
|
||||||
count interrupt nesting when running in non-idle kernel context,
|
|
||||||
which can result in interesting anomalies such as negative
|
|
||||||
interrupt-nesting levels. The number after the second "/"
|
|
||||||
is the NMI nesting depth.
|
|
||||||
|
|
||||||
o "df" is the number of times that some other CPU has forced a
|
|
||||||
quiescent state on behalf of this CPU due to this CPU being in
|
|
||||||
idle state.
|
|
||||||
|
|
||||||
o "of" is the number of times that some other CPU has forced a
|
|
||||||
quiescent state on behalf of this CPU due to this CPU being
|
|
||||||
offline. In a perfect world, this might never happen, but it
|
|
||||||
turns out that offlining and onlining a CPU can take several grace
|
|
||||||
periods, and so there is likely to be an extended period of time
|
|
||||||
when RCU believes that the CPU is online when it really is not.
|
|
||||||
Please note that erring in the other direction (RCU believing a
|
|
||||||
CPU is offline when it is really alive and kicking) is a fatal
|
|
||||||
error, so it makes sense to err conservatively.
|
|
||||||
|
|
||||||
o "ql" is the number of RCU callbacks currently residing on
|
|
||||||
this CPU. The first number is the number of "lazy" callbacks
|
|
||||||
that are known to RCU to only be freeing memory, and the number
|
|
||||||
after the "/" is the total number of callbacks, lazy or not.
|
|
||||||
These counters count callbacks regardless of what phase of
|
|
||||||
grace-period processing that they are in (new, waiting for
|
|
||||||
grace period to start, waiting for grace period to end, ready
|
|
||||||
to invoke).
|
|
||||||
|
|
||||||
o "qs" gives an indication of the state of the callback queue
|
|
||||||
with four characters:
|
|
||||||
|
|
||||||
"N" Indicates that there are callbacks queued that are not
|
|
||||||
ready to be handled by the next grace period, and thus
|
|
||||||
will be handled by the grace period following the next
|
|
||||||
one.
|
|
||||||
|
|
||||||
"R" Indicates that there are callbacks queued that are
|
|
||||||
ready to be handled by the next grace period.
|
|
||||||
|
|
||||||
"W" Indicates that there are callbacks queued that are
|
|
||||||
waiting on the current grace period.
|
|
||||||
|
|
||||||
"D" Indicates that there are callbacks queued that have
|
|
||||||
already been handled by a prior grace period, and are
|
|
||||||
thus waiting to be invoked. Note that callbacks in
|
|
||||||
the process of being invoked are not counted here.
|
|
||||||
Callbacks in the process of being invoked are those
|
|
||||||
that have been removed from the rcu_data structures
|
|
||||||
queues by rcu_do_batch(), but which have not yet been
|
|
||||||
invoked.
|
|
||||||
|
|
||||||
If there are no callbacks in a given one of the above states,
|
|
||||||
the corresponding character is replaced by ".".
|
|
||||||
|
|
||||||
o "b" is the batch limit for this CPU. If more than this number
|
|
||||||
of RCU callbacks is ready to invoke, then the remainder will
|
|
||||||
be deferred.
|
|
||||||
|
|
||||||
o "ci" is the number of RCU callbacks that have been invoked for
|
|
||||||
this CPU. Note that ci+nci+ql is the number of callbacks that have
|
|
||||||
been registered in absence of CPU-hotplug activity.
|
|
||||||
|
|
||||||
o "nci" is the number of RCU callbacks that have been offloaded from
|
|
||||||
this CPU. This will always be zero unless the kernel was built
|
|
||||||
with CONFIG_RCU_NOCB_CPU=y and the "rcu_nocbs=" kernel boot
|
|
||||||
parameter was specified.
|
|
||||||
|
|
||||||
o "co" is the number of RCU callbacks that have been orphaned due to
|
|
||||||
this CPU going offline. These orphaned callbacks have been moved
|
|
||||||
to an arbitrarily chosen online CPU.
|
|
||||||
|
|
||||||
o "ca" is the number of RCU callbacks that have been adopted by this
|
|
||||||
CPU due to other CPUs going offline. Note that ci+co-ca+ql is
|
|
||||||
the number of RCU callbacks registered on this CPU.
|
|
||||||
|
|
||||||
|
|
||||||
Kernels compiled with CONFIG_RCU_BOOST=y display the following from
|
|
||||||
/debug/rcu/rcu_preempt/rcudata:
|
|
||||||
|
|
||||||
0!c=12865 g=12866 cnq=1/0:1 dt=83113/140000000000000/0 df=288 of=11 ql=0/0 qs=N... kt=0/O ktl=944 b=10 ci=60709 nci=0 co=748 ca=871
|
|
||||||
1 c=14407 g=14408 cnq=1/0:0 dt=100679/140000000000000/0 df=378 of=7 ql=0/119 qs=NRW. kt=0/W ktl=9b6 b=10 ci=109740 nci=0 co=589 ca=485
|
|
||||||
2 c=14407 g=14408 cnq=1/0:0 dt=105486/0/0 df=90 of=9 ql=0/89 qs=NRW. kt=0/W ktl=c0c b=10 ci=83113 nci=0 co=533 ca=490
|
|
||||||
3 c=14407 g=14408 cnq=1/0:0 dt=107138/0/0 df=142 of=8 ql=0/188 qs=NRW. kt=0/W ktl=b96 b=10 ci=121114 nci=0 co=426 ca=290
|
|
||||||
4 c=14405 g=14406 cnq=1/0:1 dt=50238/0/0 df=706 of=7 ql=0/0 qs=.... kt=0/W ktl=812 b=10 ci=34929 nci=0 co=643 ca=114
|
|
||||||
5!c=14168 g=14169 cnq=1/0:0 dt=45465/140000000000000/0 df=161 of=11 ql=0/0 qs=N... kt=0/O ktl=b4d b=10 ci=47712 nci=0 co=677 ca=722
|
|
||||||
6 c=14404 g=14405 cnq=1/0:0 dt=59454/0/0 df=94 of=6 ql=0/0 qs=.... kt=0/W ktl=e57 b=10 ci=55597 nci=0 co=701 ca=811
|
|
||||||
7 c=14407 g=14408 cnq=1/0:1 dt=68850/0/0 df=31 of=8 ql=0/0 qs=.... kt=0/W ktl=14bd b=10 ci=77475 nci=0 co=508 ca=1042
|
|
||||||
|
|
||||||
This is similar to the output discussed above, but contains the following
|
|
||||||
additional fields:
|
|
||||||
|
|
||||||
o "kt" is the per-CPU kernel-thread state. The digit preceding
|
|
||||||
the first slash is zero if there is no work pending and 1
|
|
||||||
otherwise. The character between the first pair of slashes is
|
|
||||||
as follows:
|
|
||||||
|
|
||||||
"S" The kernel thread is stopped, in other words, all
|
|
||||||
CPUs corresponding to this rcu_node structure are
|
|
||||||
offline.
|
|
||||||
|
|
||||||
"R" The kernel thread is running.
|
|
||||||
|
|
||||||
"W" The kernel thread is waiting because there is no work
|
|
||||||
for it to do.
|
|
||||||
|
|
||||||
"O" The kernel thread is waiting because it has been
|
|
||||||
forced off of its designated CPU or because its
|
|
||||||
->cpus_allowed mask permits it to run on other than
|
|
||||||
its designated CPU.
|
|
||||||
|
|
||||||
"Y" The kernel thread is yielding to avoid hogging CPU.
|
|
||||||
|
|
||||||
"?" Unknown value, indicates a bug.
|
|
||||||
|
|
||||||
The number after the final slash is the CPU that the kthread
|
|
||||||
is actually running on.
|
|
||||||
|
|
||||||
This field is displayed only for CONFIG_RCU_BOOST kernels.
|
|
||||||
|
|
||||||
o "ktl" is the low-order 16 bits (in hexadecimal) of the count of
|
|
||||||
the number of times that this CPU's per-CPU kthread has gone
|
|
||||||
through its loop servicing invoke_rcu_cpu_kthread() requests.
|
|
||||||
|
|
||||||
This field is displayed only for CONFIG_RCU_BOOST kernels.
|
|
||||||
|
|
||||||
|
|
||||||
The output of "cat rcu/rcu_preempt/rcuexp" looks as follows:
|
|
||||||
|
|
||||||
s=21872 wd1=0 wd2=0 wd3=5 enq=0 sc=21872
|
|
||||||
|
|
||||||
These fields are as follows:
|
|
||||||
|
|
||||||
o "s" is the sequence number, with an odd number indicating that
|
|
||||||
an expedited grace period is in progress.
|
|
||||||
|
|
||||||
o "wd1", "wd2", and "wd3" are the number of times that an attempt
|
|
||||||
to start an expedited grace period found that someone else had
|
|
||||||
completed an expedited grace period that satisfies the attempted
|
|
||||||
request. "Our work is done."
|
|
||||||
|
|
||||||
o "enq" is the number of quiescent states still outstanding.
|
|
||||||
|
|
||||||
o "sc" is the number of times that the attempt to start a
|
|
||||||
new expedited grace period succeeded.
|
|
||||||
|
|
||||||
|
|
||||||
The output of "cat rcu/rcu_preempt/rcugp" looks as follows:
|
|
||||||
|
|
||||||
completed=31249 gpnum=31250 age=1 max=18
|
|
||||||
|
|
||||||
These fields are taken from the rcu_state structure, and are as follows:
|
|
||||||
|
|
||||||
o "completed" is the number of grace periods that have completed.
|
|
||||||
It is comparable to the "c" field from rcu/rcudata in that a
|
|
||||||
CPU whose "c" field matches the value of "completed" is aware
|
|
||||||
that the corresponding RCU grace period has completed.
|
|
||||||
|
|
||||||
o "gpnum" is the number of grace periods that have started. It is
|
|
||||||
similarly comparable to the "g" field from rcu/rcudata in that
|
|
||||||
a CPU whose "g" field matches the value of "gpnum" is aware that
|
|
||||||
the corresponding RCU grace period has started.
|
|
||||||
|
|
||||||
If these two fields are equal, then there is no grace period
|
|
||||||
in progress, in other words, RCU is idle. On the other hand,
|
|
||||||
if the two fields differ (as they are above), then an RCU grace
|
|
||||||
period is in progress.
|
|
||||||
|
|
||||||
o "age" is the number of jiffies that the current grace period
|
|
||||||
has extended for, or zero if there is no grace period currently
|
|
||||||
in effect.
|
|
||||||
|
|
||||||
o "max" is the age in jiffies of the longest-duration grace period
|
|
||||||
thus far.
|
|
||||||
|
|
||||||
The output of "cat rcu/rcu_preempt/rcuhier" looks as follows:
|
|
||||||
|
|
||||||
c=14407 g=14408 s=0 jfq=2 j=c863 nfqs=12040/nfqsng=0(12040) fqlh=1051 oqlen=0/0
|
|
||||||
3/3 ..>. 0:7 ^0
|
|
||||||
e/e ..>. 0:3 ^0 d/d ..>. 4:7 ^1
|
|
||||||
|
|
||||||
The fields are as follows:
|
|
||||||
|
|
||||||
o "c" is exactly the same as "completed" under rcu/rcu_preempt/rcugp.
|
|
||||||
|
|
||||||
o "g" is exactly the same as "gpnum" under rcu/rcu_preempt/rcugp.
|
|
||||||
|
|
||||||
o "s" is the current state of the force_quiescent_state()
|
|
||||||
state machine.
|
|
||||||
|
|
||||||
o "jfq" is the number of jiffies remaining for this grace period
|
|
||||||
before force_quiescent_state() is invoked to help push things
|
|
||||||
along. Note that CPUs in idle mode throughout the grace period
|
|
||||||
will not report on their own, but rather must be check by some
|
|
||||||
other CPU via force_quiescent_state().
|
|
||||||
|
|
||||||
o "j" is the low-order four hex digits of the jiffies counter.
|
|
||||||
Yes, Paul did run into a number of problems that turned out to
|
|
||||||
be due to the jiffies counter no longer counting. Why do you ask?
|
|
||||||
|
|
||||||
o "nfqs" is the number of calls to force_quiescent_state() since
|
|
||||||
boot.
|
|
||||||
|
|
||||||
o "nfqsng" is the number of useless calls to force_quiescent_state(),
|
|
||||||
where there wasn't actually a grace period active. This can
|
|
||||||
no longer happen due to grace-period processing being pushed
|
|
||||||
into a kthread. The number in parentheses is the difference
|
|
||||||
between "nfqs" and "nfqsng", or the number of times that
|
|
||||||
force_quiescent_state() actually did some real work.
|
|
||||||
|
|
||||||
o "fqlh" is the number of calls to force_quiescent_state() that
|
|
||||||
exited immediately (without even being counted in nfqs above)
|
|
||||||
due to contention on ->fqslock.
|
|
||||||
|
|
||||||
o Each element of the form "3/3 ..>. 0:7 ^0" represents one rcu_node
|
|
||||||
structure. Each line represents one level of the hierarchy,
|
|
||||||
from root to leaves. It is best to think of the rcu_data
|
|
||||||
structures as forming yet another level after the leaves.
|
|
||||||
Note that there might be either one, two, three, or even four
|
|
||||||
levels of rcu_node structures, depending on the relationship
|
|
||||||
between CONFIG_RCU_FANOUT, CONFIG_RCU_FANOUT_LEAF (possibly
|
|
||||||
adjusted using the rcu_fanout_leaf kernel boot parameter), and
|
|
||||||
CONFIG_NR_CPUS (possibly adjusted using the nr_cpu_ids count of
|
|
||||||
possible CPUs for the booting hardware).
|
|
||||||
|
|
||||||
o The numbers separated by the "/" are the qsmask followed
|
|
||||||
by the qsmaskinit. The qsmask will have one bit
|
|
||||||
set for each entity in the next lower level that has
|
|
||||||
not yet checked in for the current grace period ("e"
|
|
||||||
indicating CPUs 5, 6, and 7 in the example above).
|
|
||||||
The qsmaskinit will have one bit for each entity that is
|
|
||||||
currently expected to check in during each grace period.
|
|
||||||
The value of qsmaskinit is assigned to that of qsmask
|
|
||||||
at the beginning of each grace period.
|
|
||||||
|
|
||||||
o The characters separated by the ">" indicate the state
|
|
||||||
of the blocked-tasks lists. A "G" preceding the ">"
|
|
||||||
indicates that at least one task blocked in an RCU
|
|
||||||
read-side critical section blocks the current grace
|
|
||||||
period, while a "E" preceding the ">" indicates that
|
|
||||||
at least one task blocked in an RCU read-side critical
|
|
||||||
section blocks the current expedited grace period.
|
|
||||||
A "T" character following the ">" indicates that at
|
|
||||||
least one task is blocked within an RCU read-side
|
|
||||||
critical section, regardless of whether any current
|
|
||||||
grace period (expedited or normal) is inconvenienced.
|
|
||||||
A "." character appears if the corresponding condition
|
|
||||||
does not hold, so that "..>." indicates that no tasks
|
|
||||||
are blocked. In contrast, "GE>T" indicates maximal
|
|
||||||
inconvenience from blocked tasks. CONFIG_TREE_RCU
|
|
||||||
builds of the kernel will always show "..>.".
|
|
||||||
|
|
||||||
o The numbers separated by the ":" are the range of CPUs
|
|
||||||
served by this struct rcu_node. This can be helpful
|
|
||||||
in working out how the hierarchy is wired together.
|
|
||||||
|
|
||||||
For example, the example rcu_node structure shown above
|
|
||||||
has "0:7", indicating that it covers CPUs 0 through 7.
|
|
||||||
|
|
||||||
o The number after the "^" indicates the bit in the
|
|
||||||
next higher level rcu_node structure that this rcu_node
|
|
||||||
structure corresponds to. For example, the "d/d ..>. 4:7
|
|
||||||
^1" has a "1" in this position, indicating that it
|
|
||||||
corresponds to the "1" bit in the "3" shown in the
|
|
||||||
"3/3 ..>. 0:7 ^0" entry on the next level up.
|
|
||||||
|
|
||||||
|
|
||||||
The output of "cat rcu/rcu_sched/rcu_pending" looks as follows:
|
|
||||||
|
|
||||||
0!np=26111 qsp=29 rpq=5386 cbr=1 cng=570 gpc=3674 gps=577 nn=15903 ndw=0
|
|
||||||
1!np=28913 qsp=35 rpq=6097 cbr=1 cng=448 gpc=3700 gps=554 nn=18113 ndw=0
|
|
||||||
2!np=32740 qsp=37 rpq=6202 cbr=0 cng=476 gpc=4627 gps=546 nn=20889 ndw=0
|
|
||||||
3 np=23679 qsp=22 rpq=5044 cbr=1 cng=415 gpc=3403 gps=347 nn=14469 ndw=0
|
|
||||||
4!np=30714 qsp=4 rpq=5574 cbr=0 cng=528 gpc=3931 gps=639 nn=20042 ndw=0
|
|
||||||
5 np=28910 qsp=2 rpq=5246 cbr=0 cng=428 gpc=4105 gps=709 nn=18422 ndw=0
|
|
||||||
6!np=38648 qsp=5 rpq=7076 cbr=0 cng=840 gpc=4072 gps=961 nn=25699 ndw=0
|
|
||||||
7 np=37275 qsp=2 rpq=6873 cbr=0 cng=868 gpc=3416 gps=971 nn=25147 ndw=0
|
|
||||||
|
|
||||||
The fields are as follows:
|
|
||||||
|
|
||||||
o The leading number is the CPU number, with "!" indicating
|
|
||||||
an offline CPU.
|
|
||||||
|
|
||||||
o "np" is the number of times that __rcu_pending() has been invoked
|
|
||||||
for the corresponding flavor of RCU.
|
|
||||||
|
|
||||||
o "qsp" is the number of times that the RCU was waiting for a
|
|
||||||
quiescent state from this CPU.
|
|
||||||
|
|
||||||
o "rpq" is the number of times that the CPU had passed through
|
|
||||||
a quiescent state, but not yet reported it to RCU.
|
|
||||||
|
|
||||||
o "cbr" is the number of times that this CPU had RCU callbacks
|
|
||||||
that had passed through a grace period, and were thus ready
|
|
||||||
to be invoked.
|
|
||||||
|
|
||||||
o "cng" is the number of times that this CPU needed another
|
|
||||||
grace period while RCU was idle.
|
|
||||||
|
|
||||||
o "gpc" is the number of times that an old grace period had
|
|
||||||
completed, but this CPU was not yet aware of it.
|
|
||||||
|
|
||||||
o "gps" is the number of times that a new grace period had started,
|
|
||||||
but this CPU was not yet aware of it.
|
|
||||||
|
|
||||||
o "ndw" is the number of times that a wakeup of an rcuo
|
|
||||||
callback-offload kthread had to be deferred in order to avoid
|
|
||||||
deadlock.
|
|
||||||
|
|
||||||
o "nn" is the number of times that this CPU needed nothing.
|
|
||||||
|
|
||||||
|
|
||||||
The output of "cat rcu/rcuboost" looks as follows:
|
|
||||||
|
|
||||||
0:3 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=c864 bt=c894
|
|
||||||
balk: nt=0 egt=4695 bt=0 nb=0 ny=56 nos=0
|
|
||||||
4:7 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=c864 bt=c894
|
|
||||||
balk: nt=0 egt=6541 bt=0 nb=0 ny=126 nos=0
|
|
||||||
|
|
||||||
This information is output only for rcu_preempt. Each two-line entry
|
|
||||||
corresponds to a leaf rcu_node structure. The fields are as follows:
|
|
||||||
|
|
||||||
o "n:m" is the CPU-number range for the corresponding two-line
|
|
||||||
entry. In the sample output above, the first entry covers
|
|
||||||
CPUs zero through three and the second entry covers CPUs four
|
|
||||||
through seven.
|
|
||||||
|
|
||||||
o "tasks=TNEB" gives the state of the various segments of the
|
|
||||||
rnp->blocked_tasks list:
|
|
||||||
|
|
||||||
"T" This indicates that there are some tasks that blocked
|
|
||||||
while running on one of the corresponding CPUs while
|
|
||||||
in an RCU read-side critical section.
|
|
||||||
|
|
||||||
"N" This indicates that some of the blocked tasks are preventing
|
|
||||||
the current normal (non-expedited) grace period from
|
|
||||||
completing.
|
|
||||||
|
|
||||||
"E" This indicates that some of the blocked tasks are preventing
|
|
||||||
the current expedited grace period from completing.
|
|
||||||
|
|
||||||
"B" This indicates that some of the blocked tasks are in
|
|
||||||
need of RCU priority boosting.
|
|
||||||
|
|
||||||
Each character is replaced with "." if the corresponding
|
|
||||||
condition does not hold.
|
|
||||||
|
|
||||||
o "kt" is the state of the RCU priority-boosting kernel
|
|
||||||
thread associated with the corresponding rcu_node structure.
|
|
||||||
The state can be one of the following:
|
|
||||||
|
|
||||||
"S" The kernel thread is stopped, in other words, all
|
|
||||||
CPUs corresponding to this rcu_node structure are
|
|
||||||
offline.
|
|
||||||
|
|
||||||
"R" The kernel thread is running.
|
|
||||||
|
|
||||||
"W" The kernel thread is waiting because there is no work
|
|
||||||
for it to do.
|
|
||||||
|
|
||||||
"Y" The kernel thread is yielding to avoid hogging CPU.
|
|
||||||
|
|
||||||
"?" Unknown value, indicates a bug.
|
|
||||||
|
|
||||||
o "ntb" is the number of tasks boosted.
|
|
||||||
|
|
||||||
o "neb" is the number of tasks boosted in order to complete an
|
|
||||||
expedited grace period.
|
|
||||||
|
|
||||||
o "nnb" is the number of tasks boosted in order to complete a
|
|
||||||
normal (non-expedited) grace period. When boosting a task
|
|
||||||
that was blocking both an expedited and a normal grace period,
|
|
||||||
it is counted against the expedited total above.
|
|
||||||
|
|
||||||
o "j" is the low-order 16 bits of the jiffies counter in
|
|
||||||
hexadecimal.
|
|
||||||
|
|
||||||
o "bt" is the low-order 16 bits of the value that the jiffies
|
|
||||||
counter will have when we next start boosting, assuming that
|
|
||||||
the current grace period does not end beforehand. This is
|
|
||||||
also in hexadecimal.
|
|
||||||
|
|
||||||
o "balk: nt" counts the number of times we didn't boost (in
|
|
||||||
other words, we balked) even though it was time to boost because
|
|
||||||
there were no blocked tasks to boost. This situation occurs
|
|
||||||
when there is one blocked task on one rcu_node structure and
|
|
||||||
none on some other rcu_node structure.
|
|
||||||
|
|
||||||
o "egt" counts the number of times we balked because although
|
|
||||||
there were blocked tasks, none of them were blocking the
|
|
||||||
current grace period, whether expedited or otherwise.
|
|
||||||
|
|
||||||
o "bt" counts the number of times we balked because boosting
|
|
||||||
had already been initiated for the current grace period.
|
|
||||||
|
|
||||||
o "nb" counts the number of times we balked because there
|
|
||||||
was at least one task blocking the current non-expedited grace
|
|
||||||
period that never had blocked. If it is already running, it
|
|
||||||
just won't help to boost its priority!
|
|
||||||
|
|
||||||
o "ny" counts the number of times we balked because it was
|
|
||||||
not yet time to start boosting.
|
|
||||||
|
|
||||||
o "nos" counts the number of times we balked for other
|
|
||||||
reasons, e.g., the grace period ended first.
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_TINY_RCU debugfs Files and Formats
|
|
||||||
|
|
||||||
These implementations of RCU provides a single debugfs file under the
|
|
||||||
top-level directory RCU, namely rcu/rcudata, which displays fields in
|
|
||||||
rcu_bh_ctrlblk and rcu_sched_ctrlblk.
|
|
||||||
|
|
||||||
The output of "cat rcu/rcudata" is as follows:
|
|
||||||
|
|
||||||
rcu_sched: qlen: 0
|
|
||||||
rcu_bh: qlen: 0
|
|
||||||
|
|
||||||
This is split into rcu_sched and rcu_bh sections. The field is as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
o "qlen" is the number of RCU callbacks currently waiting either
|
|
||||||
for an RCU grace period or waiting to be invoked. This is the
|
|
||||||
only field present for rcu_sched and rcu_bh, due to the
|
|
||||||
short-circuiting of grace period in those two cases.
|
|
|
@ -1,5 +1,9 @@
|
||||||
Linux 2.4.2 Secure Attention Key (SAK) handling
|
=========================================
|
||||||
18 March 2001, Andrew Morton
|
Linux Secure Attention Key (SAK) handling
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
:Date: 18 March 2001
|
||||||
|
:Author: Andrew Morton
|
||||||
|
|
||||||
An operating system's Secure Attention Key is a security tool which is
|
An operating system's Secure Attention Key is a security tool which is
|
||||||
provided as protection against trojan password capturing programs. It
|
provided as protection against trojan password capturing programs. It
|
||||||
|
@ -13,7 +17,7 @@ this sequence. It is only available if the kernel was compiled with
|
||||||
sysrq support.
|
sysrq support.
|
||||||
|
|
||||||
The proper way of generating a SAK is to define the key sequence using
|
The proper way of generating a SAK is to define the key sequence using
|
||||||
`loadkeys'. This will work whether or not sysrq support is compiled
|
``loadkeys``. This will work whether or not sysrq support is compiled
|
||||||
into the kernel.
|
into the kernel.
|
||||||
|
|
||||||
SAK works correctly when the keyboard is in raw mode. This means that
|
SAK works correctly when the keyboard is in raw mode. This means that
|
||||||
|
@ -25,22 +29,21 @@ What key sequence should you use? Well, CTRL-ALT-DEL is used to reboot
|
||||||
the machine. CTRL-ALT-BACKSPACE is magical to the X server. We'll
|
the machine. CTRL-ALT-BACKSPACE is magical to the X server. We'll
|
||||||
choose CTRL-ALT-PAUSE.
|
choose CTRL-ALT-PAUSE.
|
||||||
|
|
||||||
In your rc.sysinit (or rc.local) file, add the command
|
In your rc.sysinit (or rc.local) file, add the command::
|
||||||
|
|
||||||
echo "control alt keycode 101 = SAK" | /bin/loadkeys
|
echo "control alt keycode 101 = SAK" | /bin/loadkeys
|
||||||
|
|
||||||
And that's it! Only the superuser may reprogram the SAK key.
|
And that's it! Only the superuser may reprogram the SAK key.
|
||||||
|
|
||||||
|
|
||||||
NOTES
|
.. note::
|
||||||
=====
|
|
||||||
|
|
||||||
1: Linux SAK is said to be not a "true SAK" as is required by
|
1. Linux SAK is said to be not a "true SAK" as is required by
|
||||||
systems which implement C2 level security. This author does not
|
systems which implement C2 level security. This author does not
|
||||||
know why.
|
know why.
|
||||||
|
|
||||||
|
|
||||||
2: On the PC keyboard, SAK kills all applications which have
|
2. On the PC keyboard, SAK kills all applications which have
|
||||||
/dev/console opened.
|
/dev/console opened.
|
||||||
|
|
||||||
Unfortunately this includes a number of things which you don't
|
Unfortunately this includes a number of things which you don't
|
||||||
|
@ -49,38 +52,38 @@ NOTES
|
||||||
Linux distributor about this!
|
Linux distributor about this!
|
||||||
|
|
||||||
You can identify processes which will be killed by SAK with the
|
You can identify processes which will be killed by SAK with the
|
||||||
command
|
command::
|
||||||
|
|
||||||
# ls -l /proc/[0-9]*/fd/* | grep console
|
# ls -l /proc/[0-9]*/fd/* | grep console
|
||||||
l-wx------ 1 root root 64 Mar 18 00:46 /proc/579/fd/0 -> /dev/console
|
l-wx------ 1 root root 64 Mar 18 00:46 /proc/579/fd/0 -> /dev/console
|
||||||
|
|
||||||
Then:
|
Then::
|
||||||
|
|
||||||
# ps aux|grep 579
|
# ps aux|grep 579
|
||||||
root 579 0.0 0.1 1088 436 ? S 00:43 0:00 gpm -t ps/2
|
root 579 0.0 0.1 1088 436 ? S 00:43 0:00 gpm -t ps/2
|
||||||
|
|
||||||
So `gpm' will be killed by SAK. This is a bug in gpm. It should
|
So ``gpm`` will be killed by SAK. This is a bug in gpm. It should
|
||||||
be closing standard input. You can work around this by finding the
|
be closing standard input. You can work around this by finding the
|
||||||
initscript which launches gpm and changing it thusly:
|
initscript which launches gpm and changing it thusly:
|
||||||
|
|
||||||
Old:
|
Old::
|
||||||
|
|
||||||
daemon gpm
|
daemon gpm
|
||||||
|
|
||||||
New:
|
New::
|
||||||
|
|
||||||
daemon gpm < /dev/null
|
daemon gpm < /dev/null
|
||||||
|
|
||||||
Vixie cron also seems to have this problem, and needs the same treatment.
|
Vixie cron also seems to have this problem, and needs the same treatment.
|
||||||
|
|
||||||
Also, one prominent Linux distribution has the following three
|
Also, one prominent Linux distribution has the following three
|
||||||
lines in its rc.sysinit and rc scripts:
|
lines in its rc.sysinit and rc scripts::
|
||||||
|
|
||||||
exec 3<&0
|
exec 3<&0
|
||||||
exec 4>&1
|
exec 4>&1
|
||||||
exec 5>&2
|
exec 5>&2
|
||||||
|
|
||||||
These commands cause *all* daemons which are launched by the
|
These commands cause **all** daemons which are launched by the
|
||||||
initscripts to have file descriptors 3, 4 and 5 attached to
|
initscripts to have file descriptors 3, 4 and 5 attached to
|
||||||
/dev/console. So SAK kills them all. A workaround is to simply
|
/dev/console. So SAK kills them all. A workaround is to simply
|
||||||
delete these lines, but this may cause system management
|
delete these lines, but this may cause system management
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
============
|
||||||
SM501 Driver
|
SM501 Driver
|
||||||
============
|
============
|
||||||
|
|
||||||
Copyright 2006, 2007 Simtec Electronics
|
:Copyright: |copy| 2006, 2007 Simtec Electronics
|
||||||
|
|
||||||
The Silicon Motion SM501 multimedia companion chip is a multifunction device
|
The Silicon Motion SM501 multimedia companion chip is a multifunction device
|
||||||
which may provide numerous interfaces including USB host controller USB gadget,
|
which may provide numerous interfaces including USB host controller USB gadget,
|
||||||
|
|
|
@ -156,3 +156,68 @@ pointed to by its first argument. That should be done in the driver's .probe()
|
||||||
routine. On removal, the driver should unregister its GPIO mapping table by
|
routine. On removal, the driver should unregister its GPIO mapping table by
|
||||||
calling acpi_dev_remove_driver_gpios() on the ACPI device object where that
|
calling acpi_dev_remove_driver_gpios() on the ACPI device object where that
|
||||||
table was previously registered.
|
table was previously registered.
|
||||||
|
|
||||||
|
Using the _CRS fallback
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
If a device does not have _DSD or the driver does not create ACPI GPIO
|
||||||
|
mapping, the Linux GPIO framework refuses to return any GPIOs. This is
|
||||||
|
because the driver does not know what it actually gets. For example if we
|
||||||
|
have a device like below:
|
||||||
|
|
||||||
|
Device (BTH)
|
||||||
|
{
|
||||||
|
Name (_HID, ...)
|
||||||
|
|
||||||
|
Name (_CRS, ResourceTemplate () {
|
||||||
|
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
|
||||||
|
"\\_SB.GPO0", 0, ResourceConsumer) {15}
|
||||||
|
GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionNone,
|
||||||
|
"\\_SB.GPO0", 0, ResourceConsumer) {27}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
The driver might expect to get the right GPIO when it does:
|
||||||
|
|
||||||
|
desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||||
|
|
||||||
|
but since there is no way to know the mapping between "reset" and
|
||||||
|
the GpioIo() in _CRS desc will hold ERR_PTR(-ENOENT).
|
||||||
|
|
||||||
|
The driver author can solve this by passing the mapping explictly
|
||||||
|
(the recommended way and documented in the above chapter).
|
||||||
|
|
||||||
|
The ACPI GPIO mapping tables should not contaminate drivers that are not
|
||||||
|
knowing about which exact device they are servicing on. It implies that
|
||||||
|
the ACPI GPIO mapping tables are hardly linked to ACPI ID and certain
|
||||||
|
objects, as listed in the above chapter, of the device in question.
|
||||||
|
|
||||||
|
Getting GPIO descriptor
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
There are two main approaches to get GPIO resource from ACPI:
|
||||||
|
desc = gpiod_get(dev, connection_id, flags);
|
||||||
|
desc = gpiod_get_index(dev, connection_id, index, flags);
|
||||||
|
|
||||||
|
We may consider two different cases here, i.e. when connection ID is
|
||||||
|
provided and otherwise.
|
||||||
|
|
||||||
|
Case 1:
|
||||||
|
desc = gpiod_get(dev, "non-null-connection-id", flags);
|
||||||
|
desc = gpiod_get_index(dev, "non-null-connection-id", index, flags);
|
||||||
|
|
||||||
|
Case 2:
|
||||||
|
desc = gpiod_get(dev, NULL, flags);
|
||||||
|
desc = gpiod_get_index(dev, NULL, index, flags);
|
||||||
|
|
||||||
|
Case 1 assumes that corresponding ACPI device description must have
|
||||||
|
defined device properties and will prevent to getting any GPIO resources
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
Case 2 explicitly tells GPIO core to look for resources in _CRS.
|
||||||
|
|
||||||
|
Be aware that gpiod_get_index() in cases 1 and 2, assuming that there
|
||||||
|
are two versions of ACPI device description provided and no mapping is
|
||||||
|
present in the driver, will return different resources. That's why a
|
||||||
|
certain driver has to handle them carefully as explained in previous
|
||||||
|
chapter.
|
||||||
|
|
21
kernel/Documentation/admin-guide/LSM/LoadPin.rst
Normal file
21
kernel/Documentation/admin-guide/LSM/LoadPin.rst
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
=======
|
||||||
|
LoadPin
|
||||||
|
=======
|
||||||
|
|
||||||
|
LoadPin is a Linux Security Module that ensures all kernel-loaded files
|
||||||
|
(modules, firmware, etc) all originate from the same filesystem, with
|
||||||
|
the expectation that such a filesystem is backed by a read-only device
|
||||||
|
such as dm-verity or CDROM. This allows systems that have a verified
|
||||||
|
and/or unchangeable filesystem to enforce module and firmware loading
|
||||||
|
restrictions without needing to sign the files individually.
|
||||||
|
|
||||||
|
The LSM is selectable at build-time with ``CONFIG_SECURITY_LOADPIN``, and
|
||||||
|
can be controlled at boot-time with the kernel command line option
|
||||||
|
"``loadpin.enabled``". By default, it is enabled, but can be disabled at
|
||||||
|
boot ("``loadpin.enabled=0``").
|
||||||
|
|
||||||
|
LoadPin starts pinning when it sees the first file loaded. If the
|
||||||
|
block device backing the filesystem is not read-only, a sysctl is
|
||||||
|
created to toggle pinning: ``/proc/sys/kernel/loadpin/enabled``. (Having
|
||||||
|
a mutable filesystem means pinning is mutable too, but having the
|
||||||
|
sysctl allows for easy testing on systems with a mutable filesystem.)
|
33
kernel/Documentation/admin-guide/LSM/SELinux.rst
Normal file
33
kernel/Documentation/admin-guide/LSM/SELinux.rst
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
=======
|
||||||
|
SELinux
|
||||||
|
=======
|
||||||
|
|
||||||
|
If you want to use SELinux, chances are you will want
|
||||||
|
to use the distro-provided policies, or install the
|
||||||
|
latest reference policy release from
|
||||||
|
|
||||||
|
http://oss.tresys.com/projects/refpolicy
|
||||||
|
|
||||||
|
However, if you want to install a dummy policy for
|
||||||
|
testing, you can do using ``mdp`` provided under
|
||||||
|
scripts/selinux. Note that this requires the selinux
|
||||||
|
userspace to be installed - in particular you will
|
||||||
|
need checkpolicy to compile a kernel, and setfiles and
|
||||||
|
fixfiles to label the filesystem.
|
||||||
|
|
||||||
|
1. Compile the kernel with selinux enabled.
|
||||||
|
2. Type ``make`` to compile ``mdp``.
|
||||||
|
3. Make sure that you are not running with
|
||||||
|
SELinux enabled and a real policy. If
|
||||||
|
you are, reboot with selinux disabled
|
||||||
|
before continuing.
|
||||||
|
4. Run install_policy.sh::
|
||||||
|
|
||||||
|
cd scripts/selinux
|
||||||
|
sh install_policy.sh
|
||||||
|
|
||||||
|
Step 4 will create a new dummy policy valid for your
|
||||||
|
kernel, with a single selinux user, role, and type.
|
||||||
|
It will compile the policy, will set your ``SELINUXTYPE`` to
|
||||||
|
``dummy`` in ``/etc/selinux/config``, install the compiled policy
|
||||||
|
as ``dummy``, and relabel your filesystem.
|
857
kernel/Documentation/admin-guide/LSM/Smack.rst
Normal file
857
kernel/Documentation/admin-guide/LSM/Smack.rst
Normal file
|
@ -0,0 +1,857 @@
|
||||||
|
=====
|
||||||
|
Smack
|
||||||
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
"Good for you, you've decided to clean the elevator!"
|
||||||
|
- The Elevator, from Dark Star
|
||||||
|
|
||||||
|
Smack is the Simplified Mandatory Access Control Kernel.
|
||||||
|
Smack is a kernel based implementation of mandatory access
|
||||||
|
control that includes simplicity in its primary design goals.
|
||||||
|
|
||||||
|
Smack is not the only Mandatory Access Control scheme
|
||||||
|
available for Linux. Those new to Mandatory Access Control
|
||||||
|
are encouraged to compare Smack with the other mechanisms
|
||||||
|
available to determine which is best suited to the problem
|
||||||
|
at hand.
|
||||||
|
|
||||||
|
Smack consists of three major components:
|
||||||
|
|
||||||
|
- The kernel
|
||||||
|
- Basic utilities, which are helpful but not required
|
||||||
|
- Configuration data
|
||||||
|
|
||||||
|
The kernel component of Smack is implemented as a Linux
|
||||||
|
Security Modules (LSM) module. It requires netlabel and
|
||||||
|
works best with file systems that support extended attributes,
|
||||||
|
although xattr support is not strictly required.
|
||||||
|
It is safe to run a Smack kernel under a "vanilla" distribution.
|
||||||
|
|
||||||
|
Smack kernels use the CIPSO IP option. Some network
|
||||||
|
configurations are intolerant of IP options and can impede
|
||||||
|
access to systems that use them as Smack does.
|
||||||
|
|
||||||
|
Smack is used in the Tizen operating system. Please
|
||||||
|
go to http://wiki.tizen.org for information about how
|
||||||
|
Smack is used in Tizen.
|
||||||
|
|
||||||
|
The current git repository for Smack user space is:
|
||||||
|
|
||||||
|
git://github.com/smack-team/smack.git
|
||||||
|
|
||||||
|
This should make and install on most modern distributions.
|
||||||
|
There are five commands included in smackutil:
|
||||||
|
|
||||||
|
chsmack:
|
||||||
|
display or set Smack extended attribute values
|
||||||
|
|
||||||
|
smackctl:
|
||||||
|
load the Smack access rules
|
||||||
|
|
||||||
|
smackaccess:
|
||||||
|
report if a process with one label has access
|
||||||
|
to an object with another
|
||||||
|
|
||||||
|
These two commands are obsolete with the introduction of
|
||||||
|
the smackfs/load2 and smackfs/cipso2 interfaces.
|
||||||
|
|
||||||
|
smackload:
|
||||||
|
properly formats data for writing to smackfs/load
|
||||||
|
|
||||||
|
smackcipso:
|
||||||
|
properly formats data for writing to smackfs/cipso
|
||||||
|
|
||||||
|
In keeping with the intent of Smack, configuration data is
|
||||||
|
minimal and not strictly required. The most important
|
||||||
|
configuration step is mounting the smackfs pseudo filesystem.
|
||||||
|
If smackutil is installed the startup script will take care
|
||||||
|
of this, but it can be manually as well.
|
||||||
|
|
||||||
|
Add this line to ``/etc/fstab``::
|
||||||
|
|
||||||
|
smackfs /sys/fs/smackfs smackfs defaults 0 0
|
||||||
|
|
||||||
|
The ``/sys/fs/smackfs`` directory is created by the kernel.
|
||||||
|
|
||||||
|
Smack uses extended attributes (xattrs) to store labels on filesystem
|
||||||
|
objects. The attributes are stored in the extended attribute security
|
||||||
|
name space. A process must have ``CAP_MAC_ADMIN`` to change any of these
|
||||||
|
attributes.
|
||||||
|
|
||||||
|
The extended attributes that Smack uses are:
|
||||||
|
|
||||||
|
SMACK64
|
||||||
|
Used to make access control decisions. In almost all cases
|
||||||
|
the label given to a new filesystem object will be the label
|
||||||
|
of the process that created it.
|
||||||
|
|
||||||
|
SMACK64EXEC
|
||||||
|
The Smack label of a process that execs a program file with
|
||||||
|
this attribute set will run with this attribute's value.
|
||||||
|
|
||||||
|
SMACK64MMAP
|
||||||
|
Don't allow the file to be mmapped by a process whose Smack
|
||||||
|
label does not allow all of the access permitted to a process
|
||||||
|
with the label contained in this attribute. This is a very
|
||||||
|
specific use case for shared libraries.
|
||||||
|
|
||||||
|
SMACK64TRANSMUTE
|
||||||
|
Can only have the value "TRUE". If this attribute is present
|
||||||
|
on a directory when an object is created in the directory and
|
||||||
|
the Smack rule (more below) that permitted the write access
|
||||||
|
to the directory includes the transmute ("t") mode the object
|
||||||
|
gets the label of the directory instead of the label of the
|
||||||
|
creating process. If the object being created is a directory
|
||||||
|
the SMACK64TRANSMUTE attribute is set as well.
|
||||||
|
|
||||||
|
SMACK64IPIN
|
||||||
|
This attribute is only available on file descriptors for sockets.
|
||||||
|
Use the Smack label in this attribute for access control
|
||||||
|
decisions on packets being delivered to this socket.
|
||||||
|
|
||||||
|
SMACK64IPOUT
|
||||||
|
This attribute is only available on file descriptors for sockets.
|
||||||
|
Use the Smack label in this attribute for access control
|
||||||
|
decisions on packets coming from this socket.
|
||||||
|
|
||||||
|
There are multiple ways to set a Smack label on a file::
|
||||||
|
|
||||||
|
# attr -S -s SMACK64 -V "value" path
|
||||||
|
# chsmack -a value path
|
||||||
|
|
||||||
|
A process can see the Smack label it is running with by
|
||||||
|
reading ``/proc/self/attr/current``. A process with ``CAP_MAC_ADMIN``
|
||||||
|
can set the process Smack by writing there.
|
||||||
|
|
||||||
|
Most Smack configuration is accomplished by writing to files
|
||||||
|
in the smackfs filesystem. This pseudo-filesystem is mounted
|
||||||
|
on ``/sys/fs/smackfs``.
|
||||||
|
|
||||||
|
access
|
||||||
|
Provided for backward compatibility. The access2 interface
|
||||||
|
is preferred and should be used instead.
|
||||||
|
This interface reports whether a subject with the specified
|
||||||
|
Smack label has a particular access to an object with a
|
||||||
|
specified Smack label. Write a fixed format access rule to
|
||||||
|
this file. The next read will indicate whether the access
|
||||||
|
would be permitted. The text will be either "1" indicating
|
||||||
|
access, or "0" indicating denial.
|
||||||
|
|
||||||
|
access2
|
||||||
|
This interface reports whether a subject with the specified
|
||||||
|
Smack label has a particular access to an object with a
|
||||||
|
specified Smack label. Write a long format access rule to
|
||||||
|
this file. The next read will indicate whether the access
|
||||||
|
would be permitted. The text will be either "1" indicating
|
||||||
|
access, or "0" indicating denial.
|
||||||
|
|
||||||
|
ambient
|
||||||
|
This contains the Smack label applied to unlabeled network
|
||||||
|
packets.
|
||||||
|
|
||||||
|
change-rule
|
||||||
|
This interface allows modification of existing access control rules.
|
||||||
|
The format accepted on write is::
|
||||||
|
|
||||||
|
"%s %s %s %s"
|
||||||
|
|
||||||
|
where the first string is the subject label, the second the
|
||||||
|
object label, the third the access to allow and the fourth the
|
||||||
|
access to deny. The access strings may contain only the characters
|
||||||
|
"rwxat-". If a rule for a given subject and object exists it will be
|
||||||
|
modified by enabling the permissions in the third string and disabling
|
||||||
|
those in the fourth string. If there is no such rule it will be
|
||||||
|
created using the access specified in the third and the fourth strings.
|
||||||
|
|
||||||
|
cipso
|
||||||
|
Provided for backward compatibility. The cipso2 interface
|
||||||
|
is preferred and should be used instead.
|
||||||
|
This interface allows a specific CIPSO header to be assigned
|
||||||
|
to a Smack label. The format accepted on write is::
|
||||||
|
|
||||||
|
"%24s%4d%4d"["%4d"]...
|
||||||
|
|
||||||
|
The first string is a fixed Smack label. The first number is
|
||||||
|
the level to use. The second number is the number of categories.
|
||||||
|
The following numbers are the categories::
|
||||||
|
|
||||||
|
"level-3-cats-5-19 3 2 5 19"
|
||||||
|
|
||||||
|
cipso2
|
||||||
|
This interface allows a specific CIPSO header to be assigned
|
||||||
|
to a Smack label. The format accepted on write is::
|
||||||
|
|
||||||
|
"%s%4d%4d"["%4d"]...
|
||||||
|
|
||||||
|
The first string is a long Smack label. The first number is
|
||||||
|
the level to use. The second number is the number of categories.
|
||||||
|
The following numbers are the categories::
|
||||||
|
|
||||||
|
"level-3-cats-5-19 3 2 5 19"
|
||||||
|
|
||||||
|
direct
|
||||||
|
This contains the CIPSO level used for Smack direct label
|
||||||
|
representation in network packets.
|
||||||
|
|
||||||
|
doi
|
||||||
|
This contains the CIPSO domain of interpretation used in
|
||||||
|
network packets.
|
||||||
|
|
||||||
|
ipv6host
|
||||||
|
This interface allows specific IPv6 internet addresses to be
|
||||||
|
treated as single label hosts. Packets are sent to single
|
||||||
|
label hosts only from processes that have Smack write access
|
||||||
|
to the host label. All packets received from single label hosts
|
||||||
|
are given the specified label. The format accepted on write is::
|
||||||
|
|
||||||
|
"%h:%h:%h:%h:%h:%h:%h:%h label" or
|
||||||
|
"%h:%h:%h:%h:%h:%h:%h:%h/%d label".
|
||||||
|
|
||||||
|
The "::" address shortcut is not supported.
|
||||||
|
If label is "-DELETE" a matched entry will be deleted.
|
||||||
|
|
||||||
|
load
|
||||||
|
Provided for backward compatibility. The load2 interface
|
||||||
|
is preferred and should be used instead.
|
||||||
|
This interface allows access control rules in addition to
|
||||||
|
the system defined rules to be specified. The format accepted
|
||||||
|
on write is::
|
||||||
|
|
||||||
|
"%24s%24s%5s"
|
||||||
|
|
||||||
|
where the first string is the subject label, the second the
|
||||||
|
object label, and the third the requested access. The access
|
||||||
|
string may contain only the characters "rwxat-", and specifies
|
||||||
|
which sort of access is allowed. The "-" is a placeholder for
|
||||||
|
permissions that are not allowed. The string "r-x--" would
|
||||||
|
specify read and execute access. Labels are limited to 23
|
||||||
|
characters in length.
|
||||||
|
|
||||||
|
load2
|
||||||
|
This interface allows access control rules in addition to
|
||||||
|
the system defined rules to be specified. The format accepted
|
||||||
|
on write is::
|
||||||
|
|
||||||
|
"%s %s %s"
|
||||||
|
|
||||||
|
where the first string is the subject label, the second the
|
||||||
|
object label, and the third the requested access. The access
|
||||||
|
string may contain only the characters "rwxat-", and specifies
|
||||||
|
which sort of access is allowed. The "-" is a placeholder for
|
||||||
|
permissions that are not allowed. The string "r-x--" would
|
||||||
|
specify read and execute access.
|
||||||
|
|
||||||
|
load-self
|
||||||
|
Provided for backward compatibility. The load-self2 interface
|
||||||
|
is preferred and should be used instead.
|
||||||
|
This interface allows process specific access rules to be
|
||||||
|
defined. These rules are only consulted if access would
|
||||||
|
otherwise be permitted, and are intended to provide additional
|
||||||
|
restrictions on the process. The format is the same as for
|
||||||
|
the load interface.
|
||||||
|
|
||||||
|
load-self2
|
||||||
|
This interface allows process specific access rules to be
|
||||||
|
defined. These rules are only consulted if access would
|
||||||
|
otherwise be permitted, and are intended to provide additional
|
||||||
|
restrictions on the process. The format is the same as for
|
||||||
|
the load2 interface.
|
||||||
|
|
||||||
|
logging
|
||||||
|
This contains the Smack logging state.
|
||||||
|
|
||||||
|
mapped
|
||||||
|
This contains the CIPSO level used for Smack mapped label
|
||||||
|
representation in network packets.
|
||||||
|
|
||||||
|
netlabel
|
||||||
|
This interface allows specific internet addresses to be
|
||||||
|
treated as single label hosts. Packets are sent to single
|
||||||
|
label hosts without CIPSO headers, but only from processes
|
||||||
|
that have Smack write access to the host label. All packets
|
||||||
|
received from single label hosts are given the specified
|
||||||
|
label. The format accepted on write is::
|
||||||
|
|
||||||
|
"%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label".
|
||||||
|
|
||||||
|
If the label specified is "-CIPSO" the address is treated
|
||||||
|
as a host that supports CIPSO headers.
|
||||||
|
|
||||||
|
onlycap
|
||||||
|
This contains labels processes must have for CAP_MAC_ADMIN
|
||||||
|
and ``CAP_MAC_OVERRIDE`` to be effective. If this file is empty
|
||||||
|
these capabilities are effective at for processes with any
|
||||||
|
label. The values are set by writing the desired labels, separated
|
||||||
|
by spaces, to the file or cleared by writing "-" to the file.
|
||||||
|
|
||||||
|
ptrace
|
||||||
|
This is used to define the current ptrace policy
|
||||||
|
|
||||||
|
0 - default:
|
||||||
|
this is the policy that relies on Smack access rules.
|
||||||
|
For the ``PTRACE_READ`` a subject needs to have a read access on
|
||||||
|
object. For the ``PTRACE_ATTACH`` a read-write access is required.
|
||||||
|
|
||||||
|
1 - exact:
|
||||||
|
this is the policy that limits ``PTRACE_ATTACH``. Attach is
|
||||||
|
only allowed when subject's and object's labels are equal.
|
||||||
|
``PTRACE_READ`` is not affected. Can be overridden with ``CAP_SYS_PTRACE``.
|
||||||
|
|
||||||
|
2 - draconian:
|
||||||
|
this policy behaves like the 'exact' above with an
|
||||||
|
exception that it can't be overridden with ``CAP_SYS_PTRACE``.
|
||||||
|
|
||||||
|
revoke-subject
|
||||||
|
Writing a Smack label here sets the access to '-' for all access
|
||||||
|
rules with that subject label.
|
||||||
|
|
||||||
|
unconfined
|
||||||
|
If the kernel is configured with ``CONFIG_SECURITY_SMACK_BRINGUP``
|
||||||
|
a process with ``CAP_MAC_ADMIN`` can write a label into this interface.
|
||||||
|
Thereafter, accesses that involve that label will be logged and
|
||||||
|
the access permitted if it wouldn't be otherwise. Note that this
|
||||||
|
is dangerous and can ruin the proper labeling of your system.
|
||||||
|
It should never be used in production.
|
||||||
|
|
||||||
|
relabel-self
|
||||||
|
This interface contains a list of labels to which the process can
|
||||||
|
transition to, by writing to ``/proc/self/attr/current``.
|
||||||
|
Normally a process can change its own label to any legal value, but only
|
||||||
|
if it has ``CAP_MAC_ADMIN``. This interface allows a process without
|
||||||
|
``CAP_MAC_ADMIN`` to relabel itself to one of labels from predefined list.
|
||||||
|
A process without ``CAP_MAC_ADMIN`` can change its label only once. When it
|
||||||
|
does, this list will be cleared.
|
||||||
|
The values are set by writing the desired labels, separated
|
||||||
|
by spaces, to the file or cleared by writing "-" to the file.
|
||||||
|
|
||||||
|
If you are using the smackload utility
|
||||||
|
you can add access rules in ``/etc/smack/accesses``. They take the form::
|
||||||
|
|
||||||
|
subjectlabel objectlabel access
|
||||||
|
|
||||||
|
access is a combination of the letters rwxatb which specify the
|
||||||
|
kind of access permitted a subject with subjectlabel on an
|
||||||
|
object with objectlabel. If there is no rule no access is allowed.
|
||||||
|
|
||||||
|
Look for additional programs on http://schaufler-ca.com
|
||||||
|
|
||||||
|
The Simplified Mandatory Access Control Kernel (Whitepaper)
|
||||||
|
===========================================================
|
||||||
|
|
||||||
|
Casey Schaufler
|
||||||
|
casey@schaufler-ca.com
|
||||||
|
|
||||||
|
Mandatory Access Control
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Computer systems employ a variety of schemes to constrain how information is
|
||||||
|
shared among the people and services using the machine. Some of these schemes
|
||||||
|
allow the program or user to decide what other programs or users are allowed
|
||||||
|
access to pieces of data. These schemes are called discretionary access
|
||||||
|
control mechanisms because the access control is specified at the discretion
|
||||||
|
of the user. Other schemes do not leave the decision regarding what a user or
|
||||||
|
program can access up to users or programs. These schemes are called mandatory
|
||||||
|
access control mechanisms because you don't have a choice regarding the users
|
||||||
|
or programs that have access to pieces of data.
|
||||||
|
|
||||||
|
Bell & LaPadula
|
||||||
|
---------------
|
||||||
|
|
||||||
|
From the middle of the 1980's until the turn of the century Mandatory Access
|
||||||
|
Control (MAC) was very closely associated with the Bell & LaPadula security
|
||||||
|
model, a mathematical description of the United States Department of Defense
|
||||||
|
policy for marking paper documents. MAC in this form enjoyed a following
|
||||||
|
within the Capital Beltway and Scandinavian supercomputer centers but was
|
||||||
|
often sited as failing to address general needs.
|
||||||
|
|
||||||
|
Domain Type Enforcement
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Around the turn of the century Domain Type Enforcement (DTE) became popular.
|
||||||
|
This scheme organizes users, programs, and data into domains that are
|
||||||
|
protected from each other. This scheme has been widely deployed as a component
|
||||||
|
of popular Linux distributions. The administrative overhead required to
|
||||||
|
maintain this scheme and the detailed understanding of the whole system
|
||||||
|
necessary to provide a secure domain mapping leads to the scheme being
|
||||||
|
disabled or used in limited ways in the majority of cases.
|
||||||
|
|
||||||
|
Smack
|
||||||
|
-----
|
||||||
|
|
||||||
|
Smack is a Mandatory Access Control mechanism designed to provide useful MAC
|
||||||
|
while avoiding the pitfalls of its predecessors. The limitations of Bell &
|
||||||
|
LaPadula are addressed by providing a scheme whereby access can be controlled
|
||||||
|
according to the requirements of the system and its purpose rather than those
|
||||||
|
imposed by an arcane government policy. The complexity of Domain Type
|
||||||
|
Enforcement and avoided by defining access controls in terms of the access
|
||||||
|
modes already in use.
|
||||||
|
|
||||||
|
Smack Terminology
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The jargon used to talk about Smack will be familiar to those who have dealt
|
||||||
|
with other MAC systems and shouldn't be too difficult for the uninitiated to
|
||||||
|
pick up. There are four terms that are used in a specific way and that are
|
||||||
|
especially important:
|
||||||
|
|
||||||
|
Subject:
|
||||||
|
A subject is an active entity on the computer system.
|
||||||
|
On Smack a subject is a task, which is in turn the basic unit
|
||||||
|
of execution.
|
||||||
|
|
||||||
|
Object:
|
||||||
|
An object is a passive entity on the computer system.
|
||||||
|
On Smack files of all types, IPC, and tasks can be objects.
|
||||||
|
|
||||||
|
Access:
|
||||||
|
Any attempt by a subject to put information into or get
|
||||||
|
information from an object is an access.
|
||||||
|
|
||||||
|
Label:
|
||||||
|
Data that identifies the Mandatory Access Control
|
||||||
|
characteristics of a subject or an object.
|
||||||
|
|
||||||
|
These definitions are consistent with the traditional use in the security
|
||||||
|
community. There are also some terms from Linux that are likely to crop up:
|
||||||
|
|
||||||
|
Capability:
|
||||||
|
A task that possesses a capability has permission to
|
||||||
|
violate an aspect of the system security policy, as identified by
|
||||||
|
the specific capability. A task that possesses one or more
|
||||||
|
capabilities is a privileged task, whereas a task with no
|
||||||
|
capabilities is an unprivileged task.
|
||||||
|
|
||||||
|
Privilege:
|
||||||
|
A task that is allowed to violate the system security
|
||||||
|
policy is said to have privilege. As of this writing a task can
|
||||||
|
have privilege either by possessing capabilities or by having an
|
||||||
|
effective user of root.
|
||||||
|
|
||||||
|
Smack Basics
|
||||||
|
------------
|
||||||
|
|
||||||
|
Smack is an extension to a Linux system. It enforces additional restrictions
|
||||||
|
on what subjects can access which objects, based on the labels attached to
|
||||||
|
each of the subject and the object.
|
||||||
|
|
||||||
|
Labels
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
Smack labels are ASCII character strings. They can be up to 255 characters
|
||||||
|
long, but keeping them to twenty-three characters is recommended.
|
||||||
|
Single character labels using special characters, that being anything
|
||||||
|
other than a letter or digit, are reserved for use by the Smack development
|
||||||
|
team. Smack labels are unstructured, case sensitive, and the only operation
|
||||||
|
ever performed on them is comparison for equality. Smack labels cannot
|
||||||
|
contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
|
||||||
|
(quote) and '"' (double-quote) characters.
|
||||||
|
Smack labels cannot begin with a '-'. This is reserved for special options.
|
||||||
|
|
||||||
|
There are some predefined labels::
|
||||||
|
|
||||||
|
_ Pronounced "floor", a single underscore character.
|
||||||
|
^ Pronounced "hat", a single circumflex character.
|
||||||
|
* Pronounced "star", a single asterisk character.
|
||||||
|
? Pronounced "huh", a single question mark character.
|
||||||
|
@ Pronounced "web", a single at sign character.
|
||||||
|
|
||||||
|
Every task on a Smack system is assigned a label. The Smack label
|
||||||
|
of a process will usually be assigned by the system initialization
|
||||||
|
mechanism.
|
||||||
|
|
||||||
|
Access Rules
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Smack uses the traditional access modes of Linux. These modes are read,
|
||||||
|
execute, write, and occasionally append. There are a few cases where the
|
||||||
|
access mode may not be obvious. These include:
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
A signal is a write operation from the subject task to
|
||||||
|
the object task.
|
||||||
|
|
||||||
|
Internet Domain IPC:
|
||||||
|
Transmission of a packet is considered a
|
||||||
|
write operation from the source task to the destination task.
|
||||||
|
|
||||||
|
Smack restricts access based on the label attached to a subject and the label
|
||||||
|
attached to the object it is trying to access. The rules enforced are, in
|
||||||
|
order:
|
||||||
|
|
||||||
|
1. Any access requested by a task labeled "*" is denied.
|
||||||
|
2. A read or execute access requested by a task labeled "^"
|
||||||
|
is permitted.
|
||||||
|
3. A read or execute access requested on an object labeled "_"
|
||||||
|
is permitted.
|
||||||
|
4. Any access requested on an object labeled "*" is permitted.
|
||||||
|
5. Any access requested by a task on an object with the same
|
||||||
|
label is permitted.
|
||||||
|
6. Any access requested that is explicitly defined in the loaded
|
||||||
|
rule set is permitted.
|
||||||
|
7. Any other access is denied.
|
||||||
|
|
||||||
|
Smack Access Rules
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
With the isolation provided by Smack access separation is simple. There are
|
||||||
|
many interesting cases where limited access by subjects to objects with
|
||||||
|
different labels is desired. One example is the familiar spy model of
|
||||||
|
sensitivity, where a scientist working on a highly classified project would be
|
||||||
|
able to read documents of lower classifications and anything she writes will
|
||||||
|
be "born" highly classified. To accommodate such schemes Smack includes a
|
||||||
|
mechanism for specifying rules allowing access between labels.
|
||||||
|
|
||||||
|
Access Rule Format
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The format of an access rule is::
|
||||||
|
|
||||||
|
subject-label object-label access
|
||||||
|
|
||||||
|
Where subject-label is the Smack label of the task, object-label is the Smack
|
||||||
|
label of the thing being accessed, and access is a string specifying the sort
|
||||||
|
of access allowed. The access specification is searched for letters that
|
||||||
|
describe access modes:
|
||||||
|
|
||||||
|
a: indicates that append access should be granted.
|
||||||
|
r: indicates that read access should be granted.
|
||||||
|
w: indicates that write access should be granted.
|
||||||
|
x: indicates that execute access should be granted.
|
||||||
|
t: indicates that the rule requests transmutation.
|
||||||
|
b: indicates that the rule should be reported for bring-up.
|
||||||
|
|
||||||
|
Uppercase values for the specification letters are allowed as well.
|
||||||
|
Access mode specifications can be in any order. Examples of acceptable rules
|
||||||
|
are::
|
||||||
|
|
||||||
|
TopSecret Secret rx
|
||||||
|
Secret Unclass R
|
||||||
|
Manager Game x
|
||||||
|
User HR w
|
||||||
|
Snap Crackle rwxatb
|
||||||
|
New Old rRrRr
|
||||||
|
Closed Off -
|
||||||
|
|
||||||
|
Examples of unacceptable rules are::
|
||||||
|
|
||||||
|
Top Secret Secret rx
|
||||||
|
Ace Ace r
|
||||||
|
Odd spells waxbeans
|
||||||
|
|
||||||
|
Spaces are not allowed in labels. Since a subject always has access to files
|
||||||
|
with the same label specifying a rule for that case is pointless. Only
|
||||||
|
valid letters (rwxatbRWXATB) and the dash ('-') character are allowed in
|
||||||
|
access specifications. The dash is a placeholder, so "a-r" is the same
|
||||||
|
as "ar". A lone dash is used to specify that no access should be allowed.
|
||||||
|
|
||||||
|
Applying Access Rules
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The developers of Linux rarely define new sorts of things, usually importing
|
||||||
|
schemes and concepts from other systems. Most often, the other systems are
|
||||||
|
variants of Unix. Unix has many endearing properties, but consistency of
|
||||||
|
access control models is not one of them. Smack strives to treat accesses as
|
||||||
|
uniformly as is sensible while keeping with the spirit of the underlying
|
||||||
|
mechanism.
|
||||||
|
|
||||||
|
File system objects including files, directories, named pipes, symbolic links,
|
||||||
|
and devices require access permissions that closely match those used by mode
|
||||||
|
bit access. To open a file for reading read access is required on the file. To
|
||||||
|
search a directory requires execute access. Creating a file with write access
|
||||||
|
requires both read and write access on the containing directory. Deleting a
|
||||||
|
file requires read and write access to the file and to the containing
|
||||||
|
directory. It is possible that a user may be able to see that a file exists
|
||||||
|
but not any of its attributes by the circumstance of having read access to the
|
||||||
|
containing directory but not to the differently labeled file. This is an
|
||||||
|
artifact of the file name being data in the directory, not a part of the file.
|
||||||
|
|
||||||
|
If a directory is marked as transmuting (SMACK64TRANSMUTE=TRUE) and the
|
||||||
|
access rule that allows a process to create an object in that directory
|
||||||
|
includes 't' access the label assigned to the new object will be that
|
||||||
|
of the directory, not the creating process. This makes it much easier
|
||||||
|
for two processes with different labels to share data without granting
|
||||||
|
access to all of their files.
|
||||||
|
|
||||||
|
IPC objects, message queues, semaphore sets, and memory segments exist in flat
|
||||||
|
namespaces and access requests are only required to match the object in
|
||||||
|
question.
|
||||||
|
|
||||||
|
Process objects reflect tasks on the system and the Smack label used to access
|
||||||
|
them is the same Smack label that the task would use for its own access
|
||||||
|
attempts. Sending a signal via the kill() system call is a write operation
|
||||||
|
from the signaler to the recipient. Debugging a process requires both reading
|
||||||
|
and writing. Creating a new task is an internal operation that results in two
|
||||||
|
tasks with identical Smack labels and requires no access checks.
|
||||||
|
|
||||||
|
Sockets are data structures attached to processes and sending a packet from
|
||||||
|
one process to another requires that the sender have write access to the
|
||||||
|
receiver. The receiver is not required to have read access to the sender.
|
||||||
|
|
||||||
|
Setting Access Rules
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The configuration file /etc/smack/accesses contains the rules to be set at
|
||||||
|
system startup. The contents are written to the special file
|
||||||
|
/sys/fs/smackfs/load2. Rules can be added at any time and take effect
|
||||||
|
immediately. For any pair of subject and object labels there can be only
|
||||||
|
one rule, with the most recently specified overriding any earlier
|
||||||
|
specification.
|
||||||
|
|
||||||
|
Task Attribute
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The Smack label of a process can be read from /proc/<pid>/attr/current. A
|
||||||
|
process can read its own Smack label from /proc/self/attr/current. A
|
||||||
|
privileged process can change its own Smack label by writing to
|
||||||
|
/proc/self/attr/current but not the label of another process.
|
||||||
|
|
||||||
|
File Attribute
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The Smack label of a filesystem object is stored as an extended attribute
|
||||||
|
named SMACK64 on the file. This attribute is in the security namespace. It can
|
||||||
|
only be changed by a process with privilege.
|
||||||
|
|
||||||
|
Privilege
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
A process with CAP_MAC_OVERRIDE or CAP_MAC_ADMIN is privileged.
|
||||||
|
CAP_MAC_OVERRIDE allows the process access to objects it would
|
||||||
|
be denied otherwise. CAP_MAC_ADMIN allows a process to change
|
||||||
|
Smack data, including rules and attributes.
|
||||||
|
|
||||||
|
Smack Networking
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
As mentioned before, Smack enforces access control on network protocol
|
||||||
|
transmissions. Every packet sent by a Smack process is tagged with its Smack
|
||||||
|
label. This is done by adding a CIPSO tag to the header of the IP packet. Each
|
||||||
|
packet received is expected to have a CIPSO tag that identifies the label and
|
||||||
|
if it lacks such a tag the network ambient label is assumed. Before the packet
|
||||||
|
is delivered a check is made to determine that a subject with the label on the
|
||||||
|
packet has write access to the receiving process and if that is not the case
|
||||||
|
the packet is dropped.
|
||||||
|
|
||||||
|
CIPSO Configuration
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
It is normally unnecessary to specify the CIPSO configuration. The default
|
||||||
|
values used by the system handle all internal cases. Smack will compose CIPSO
|
||||||
|
label values to match the Smack labels being used without administrative
|
||||||
|
intervention. Unlabeled packets that come into the system will be given the
|
||||||
|
ambient label.
|
||||||
|
|
||||||
|
Smack requires configuration in the case where packets from a system that is
|
||||||
|
not Smack that speaks CIPSO may be encountered. Usually this will be a Trusted
|
||||||
|
Solaris system, but there are other, less widely deployed systems out there.
|
||||||
|
CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level,
|
||||||
|
and a category set with each packet. The DOI is intended to identify a group
|
||||||
|
of systems that use compatible labeling schemes, and the DOI specified on the
|
||||||
|
Smack system must match that of the remote system or packets will be
|
||||||
|
discarded. The DOI is 3 by default. The value can be read from
|
||||||
|
/sys/fs/smackfs/doi and can be changed by writing to /sys/fs/smackfs/doi.
|
||||||
|
|
||||||
|
The label and category set are mapped to a Smack label as defined in
|
||||||
|
/etc/smack/cipso.
|
||||||
|
|
||||||
|
A Smack/CIPSO mapping has the form::
|
||||||
|
|
||||||
|
smack level [category [category]*]
|
||||||
|
|
||||||
|
Smack does not expect the level or category sets to be related in any
|
||||||
|
particular way and does not assume or assign accesses based on them. Some
|
||||||
|
examples of mappings::
|
||||||
|
|
||||||
|
TopSecret 7
|
||||||
|
TS:A,B 7 1 2
|
||||||
|
SecBDE 5 2 4 6
|
||||||
|
RAFTERS 7 12 26
|
||||||
|
|
||||||
|
The ":" and "," characters are permitted in a Smack label but have no special
|
||||||
|
meaning.
|
||||||
|
|
||||||
|
The mapping of Smack labels to CIPSO values is defined by writing to
|
||||||
|
/sys/fs/smackfs/cipso2.
|
||||||
|
|
||||||
|
In addition to explicit mappings Smack supports direct CIPSO mappings. One
|
||||||
|
CIPSO level is used to indicate that the category set passed in the packet is
|
||||||
|
in fact an encoding of the Smack label. The level used is 250 by default. The
|
||||||
|
value can be read from /sys/fs/smackfs/direct and changed by writing to
|
||||||
|
/sys/fs/smackfs/direct.
|
||||||
|
|
||||||
|
Socket Attributes
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
There are two attributes that are associated with sockets. These attributes
|
||||||
|
can only be set by privileged tasks, but any task can read them for their own
|
||||||
|
sockets.
|
||||||
|
|
||||||
|
SMACK64IPIN:
|
||||||
|
The Smack label of the task object. A privileged
|
||||||
|
program that will enforce policy may set this to the star label.
|
||||||
|
|
||||||
|
SMACK64IPOUT:
|
||||||
|
The Smack label transmitted with outgoing packets.
|
||||||
|
A privileged program may set this to match the label of another
|
||||||
|
task with which it hopes to communicate.
|
||||||
|
|
||||||
|
Smack Netlabel Exceptions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
You will often find that your labeled application has to talk to the outside,
|
||||||
|
unlabeled world. To do this there's a special file /sys/fs/smackfs/netlabel
|
||||||
|
where you can add some exceptions in the form of::
|
||||||
|
|
||||||
|
@IP1 LABEL1 or
|
||||||
|
@IP2/MASK LABEL2
|
||||||
|
|
||||||
|
It means that your application will have unlabeled access to @IP1 if it has
|
||||||
|
write access on LABEL1, and access to the subnet @IP2/MASK if it has write
|
||||||
|
access on LABEL2.
|
||||||
|
|
||||||
|
Entries in the /sys/fs/smackfs/netlabel file are matched by longest mask
|
||||||
|
first, like in classless IPv4 routing.
|
||||||
|
|
||||||
|
A special label '@' and an option '-CIPSO' can be used there::
|
||||||
|
|
||||||
|
@ means Internet, any application with any label has access to it
|
||||||
|
-CIPSO means standard CIPSO networking
|
||||||
|
|
||||||
|
If you don't know what CIPSO is and don't plan to use it, you can just do::
|
||||||
|
|
||||||
|
echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/netlabel
|
||||||
|
echo 0.0.0.0/0 @ > /sys/fs/smackfs/netlabel
|
||||||
|
|
||||||
|
If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
|
||||||
|
Internet access, you can have::
|
||||||
|
|
||||||
|
echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/netlabel
|
||||||
|
echo 192.168.0.0/16 -CIPSO > /sys/fs/smackfs/netlabel
|
||||||
|
echo 0.0.0.0/0 @ > /sys/fs/smackfs/netlabel
|
||||||
|
|
||||||
|
Writing Applications for Smack
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
There are three sorts of applications that will run on a Smack system. How an
|
||||||
|
application interacts with Smack will determine what it will have to do to
|
||||||
|
work properly under Smack.
|
||||||
|
|
||||||
|
Smack Ignorant Applications
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
By far the majority of applications have no reason whatever to care about the
|
||||||
|
unique properties of Smack. Since invoking a program has no impact on the
|
||||||
|
Smack label associated with the process the only concern likely to arise is
|
||||||
|
whether the process has execute access to the program.
|
||||||
|
|
||||||
|
Smack Relevant Applications
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Some programs can be improved by teaching them about Smack, but do not make
|
||||||
|
any security decisions themselves. The utility ls(1) is one example of such a
|
||||||
|
program.
|
||||||
|
|
||||||
|
Smack Enforcing Applications
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
These are special programs that not only know about Smack, but participate in
|
||||||
|
the enforcement of system policy. In most cases these are the programs that
|
||||||
|
set up user sessions. There are also network services that provide information
|
||||||
|
to processes running with various labels.
|
||||||
|
|
||||||
|
File System Interfaces
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Smack maintains labels on file system objects using extended attributes. The
|
||||||
|
Smack label of a file, directory, or other file system object can be obtained
|
||||||
|
using getxattr(2)::
|
||||||
|
|
||||||
|
len = getxattr("/", "security.SMACK64", value, sizeof (value));
|
||||||
|
|
||||||
|
will put the Smack label of the root directory into value. A privileged
|
||||||
|
process can set the Smack label of a file system object with setxattr(2)::
|
||||||
|
|
||||||
|
len = strlen("Rubble");
|
||||||
|
rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0);
|
||||||
|
|
||||||
|
will set the Smack label of /foo to "Rubble" if the program has appropriate
|
||||||
|
privilege.
|
||||||
|
|
||||||
|
Socket Interfaces
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The socket attributes can be read using fgetxattr(2).
|
||||||
|
|
||||||
|
A privileged process can set the Smack label of outgoing packets with
|
||||||
|
fsetxattr(2)::
|
||||||
|
|
||||||
|
len = strlen("Rubble");
|
||||||
|
rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0);
|
||||||
|
|
||||||
|
will set the Smack label "Rubble" on packets going out from the socket if the
|
||||||
|
program has appropriate privilege::
|
||||||
|
|
||||||
|
rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0);
|
||||||
|
|
||||||
|
will set the Smack label "*" as the object label against which incoming
|
||||||
|
packets will be checked if the program has appropriate privilege.
|
||||||
|
|
||||||
|
Administration
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Smack supports some mount options:
|
||||||
|
|
||||||
|
smackfsdef=label:
|
||||||
|
specifies the label to give files that lack
|
||||||
|
the Smack label extended attribute.
|
||||||
|
|
||||||
|
smackfsroot=label:
|
||||||
|
specifies the label to assign the root of the
|
||||||
|
file system if it lacks the Smack extended attribute.
|
||||||
|
|
||||||
|
smackfshat=label:
|
||||||
|
specifies a label that must have read access to
|
||||||
|
all labels set on the filesystem. Not yet enforced.
|
||||||
|
|
||||||
|
smackfsfloor=label:
|
||||||
|
specifies a label to which all labels set on the
|
||||||
|
filesystem must have read access. Not yet enforced.
|
||||||
|
|
||||||
|
These mount options apply to all file system types.
|
||||||
|
|
||||||
|
Smack auditing
|
||||||
|
--------------
|
||||||
|
|
||||||
|
If you want Smack auditing of security events, you need to set CONFIG_AUDIT
|
||||||
|
in your kernel configuration.
|
||||||
|
By default, all denied events will be audited. You can change this behavior by
|
||||||
|
writing a single character to the /sys/fs/smackfs/logging file::
|
||||||
|
|
||||||
|
0 : no logging
|
||||||
|
1 : log denied (default)
|
||||||
|
2 : log accepted
|
||||||
|
3 : log denied & accepted
|
||||||
|
|
||||||
|
Events are logged as 'key=value' pairs, for each event you at least will get
|
||||||
|
the subject, the object, the rights requested, the action, the kernel function
|
||||||
|
that triggered the event, plus other pairs depending on the type of event
|
||||||
|
audited.
|
||||||
|
|
||||||
|
Bringup Mode
|
||||||
|
------------
|
||||||
|
|
||||||
|
Bringup mode provides logging features that can make application
|
||||||
|
configuration and system bringup easier. Configure the kernel with
|
||||||
|
CONFIG_SECURITY_SMACK_BRINGUP to enable these features. When bringup
|
||||||
|
mode is enabled accesses that succeed due to rules marked with the "b"
|
||||||
|
access mode will logged. When a new label is introduced for processes
|
||||||
|
rules can be added aggressively, marked with the "b". The logging allows
|
||||||
|
tracking of which rules actual get used for that label.
|
||||||
|
|
||||||
|
Another feature of bringup mode is the "unconfined" option. Writing
|
||||||
|
a label to /sys/fs/smackfs/unconfined makes subjects with that label
|
||||||
|
able to access any object, and objects with that label accessible to
|
||||||
|
all subjects. Any access that is granted because a label is unconfined
|
||||||
|
is logged. This feature is dangerous, as files and directories may
|
||||||
|
be created in places they couldn't if the policy were being enforced.
|
74
kernel/Documentation/admin-guide/LSM/Yama.rst
Normal file
74
kernel/Documentation/admin-guide/LSM/Yama.rst
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
====
|
||||||
|
Yama
|
||||||
|
====
|
||||||
|
|
||||||
|
Yama is a Linux Security Module that collects system-wide DAC security
|
||||||
|
protections that are not handled by the core kernel itself. This is
|
||||||
|
selectable at build-time with ``CONFIG_SECURITY_YAMA``, and can be controlled
|
||||||
|
at run-time through sysctls in ``/proc/sys/kernel/yama``:
|
||||||
|
|
||||||
|
ptrace_scope
|
||||||
|
============
|
||||||
|
|
||||||
|
As Linux grows in popularity, it will become a larger target for
|
||||||
|
malware. One particularly troubling weakness of the Linux process
|
||||||
|
interfaces is that a single user is able to examine the memory and
|
||||||
|
running state of any of their processes. For example, if one application
|
||||||
|
(e.g. Pidgin) was compromised, it would be possible for an attacker to
|
||||||
|
attach to other running processes (e.g. Firefox, SSH sessions, GPG agent,
|
||||||
|
etc) to extract additional credentials and continue to expand the scope
|
||||||
|
of their attack without resorting to user-assisted phishing.
|
||||||
|
|
||||||
|
This is not a theoretical problem. SSH session hijacking
|
||||||
|
(http://www.storm.net.nz/projects/7) and arbitrary code injection
|
||||||
|
(http://c-skills.blogspot.com/2007/05/injectso.html) attacks already
|
||||||
|
exist and remain possible if ptrace is allowed to operate as before.
|
||||||
|
Since ptrace is not commonly used by non-developers and non-admins, system
|
||||||
|
builders should be allowed the option to disable this debugging system.
|
||||||
|
|
||||||
|
For a solution, some applications use ``prctl(PR_SET_DUMPABLE, ...)`` to
|
||||||
|
specifically disallow such ptrace attachment (e.g. ssh-agent), but many
|
||||||
|
do not. A more general solution is to only allow ptrace directly from a
|
||||||
|
parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still
|
||||||
|
work), or with ``CAP_SYS_PTRACE`` (i.e. "gdb --pid=PID", and "strace -p PID"
|
||||||
|
still work as root).
|
||||||
|
|
||||||
|
In mode 1, software that has defined application-specific relationships
|
||||||
|
between a debugging process and its inferior (crash handlers, etc),
|
||||||
|
``prctl(PR_SET_PTRACER, pid, ...)`` can be used. An inferior can declare which
|
||||||
|
other process (and its descendants) are allowed to call ``PTRACE_ATTACH``
|
||||||
|
against it. Only one such declared debugging process can exists for
|
||||||
|
each inferior at a time. For example, this is used by KDE, Chromium, and
|
||||||
|
Firefox's crash handlers, and by Wine for allowing only Wine processes
|
||||||
|
to ptrace each other. If a process wishes to entirely disable these ptrace
|
||||||
|
restrictions, it can call ``prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)``
|
||||||
|
so that any otherwise allowed process (even those in external pid namespaces)
|
||||||
|
may attach.
|
||||||
|
|
||||||
|
The sysctl settings (writable only with ``CAP_SYS_PTRACE``) are:
|
||||||
|
|
||||||
|
0 - classic ptrace permissions:
|
||||||
|
a process can ``PTRACE_ATTACH`` to any other
|
||||||
|
process running under the same uid, as long as it is dumpable (i.e.
|
||||||
|
did not transition uids, start privileged, or have called
|
||||||
|
``prctl(PR_SET_DUMPABLE...)`` already). Similarly, ``PTRACE_TRACEME`` is
|
||||||
|
unchanged.
|
||||||
|
|
||||||
|
1 - restricted ptrace:
|
||||||
|
a process must have a predefined relationship
|
||||||
|
with the inferior it wants to call ``PTRACE_ATTACH`` on. By default,
|
||||||
|
this relationship is that of only its descendants when the above
|
||||||
|
classic criteria is also met. To change the relationship, an
|
||||||
|
inferior can call ``prctl(PR_SET_PTRACER, debugger, ...)`` to declare
|
||||||
|
an allowed debugger PID to call ``PTRACE_ATTACH`` on the inferior.
|
||||||
|
Using ``PTRACE_TRACEME`` is unchanged.
|
||||||
|
|
||||||
|
2 - admin-only attach:
|
||||||
|
only processes with ``CAP_SYS_PTRACE`` may use ptrace
|
||||||
|
with ``PTRACE_ATTACH``, or through children calling ``PTRACE_TRACEME``.
|
||||||
|
|
||||||
|
3 - no attach:
|
||||||
|
no processes may use ptrace with ``PTRACE_ATTACH`` nor via
|
||||||
|
``PTRACE_TRACEME``. Once set, this sysctl value cannot be changed.
|
||||||
|
|
||||||
|
The original children-only logic was based on the restrictions in grsecurity.
|
51
kernel/Documentation/admin-guide/LSM/apparmor.rst
Normal file
51
kernel/Documentation/admin-guide/LSM/apparmor.rst
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
========
|
||||||
|
AppArmor
|
||||||
|
========
|
||||||
|
|
||||||
|
What is AppArmor?
|
||||||
|
=================
|
||||||
|
|
||||||
|
AppArmor is MAC style security extension for the Linux kernel. It implements
|
||||||
|
a task centered policy, with task "profiles" being created and loaded
|
||||||
|
from user space. Tasks on the system that do not have a profile defined for
|
||||||
|
them run in an unconfined state which is equivalent to standard Linux DAC
|
||||||
|
permissions.
|
||||||
|
|
||||||
|
How to enable/disable
|
||||||
|
=====================
|
||||||
|
|
||||||
|
set ``CONFIG_SECURITY_APPARMOR=y``
|
||||||
|
|
||||||
|
If AppArmor should be selected as the default security module then set::
|
||||||
|
|
||||||
|
CONFIG_DEFAULT_SECURITY="apparmor"
|
||||||
|
CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1
|
||||||
|
|
||||||
|
Build the kernel
|
||||||
|
|
||||||
|
If AppArmor is not the default security module it can be enabled by passing
|
||||||
|
``security=apparmor`` on the kernel's command line.
|
||||||
|
|
||||||
|
If AppArmor is the default security module it can be disabled by passing
|
||||||
|
``apparmor=0, security=XXXX`` (where ``XXXX`` is valid security module), on the
|
||||||
|
kernel's command line.
|
||||||
|
|
||||||
|
For AppArmor to enforce any restrictions beyond standard Linux DAC permissions
|
||||||
|
policy must be loaded into the kernel from user space (see the Documentation
|
||||||
|
and tools links).
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
=============
|
||||||
|
|
||||||
|
Documentation can be found on the wiki, linked below.
|
||||||
|
|
||||||
|
Links
|
||||||
|
=====
|
||||||
|
|
||||||
|
Mailing List - apparmor@lists.ubuntu.com
|
||||||
|
|
||||||
|
Wiki - http://apparmor.wiki.kernel.org/
|
||||||
|
|
||||||
|
User space tools - https://launchpad.net/apparmor
|
||||||
|
|
||||||
|
Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
|
41
kernel/Documentation/admin-guide/LSM/index.rst
Normal file
41
kernel/Documentation/admin-guide/LSM/index.rst
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
===========================
|
||||||
|
Linux Security Module Usage
|
||||||
|
===========================
|
||||||
|
|
||||||
|
The Linux Security Module (LSM) framework provides a mechanism for
|
||||||
|
various security checks to be hooked by new kernel extensions. The name
|
||||||
|
"module" is a bit of a misnomer since these extensions are not actually
|
||||||
|
loadable kernel modules. Instead, they are selectable at build-time via
|
||||||
|
CONFIG_DEFAULT_SECURITY and can be overridden at boot-time via the
|
||||||
|
``"security=..."`` kernel command line argument, in the case where multiple
|
||||||
|
LSMs were built into a given kernel.
|
||||||
|
|
||||||
|
The primary users of the LSM interface are Mandatory Access Control
|
||||||
|
(MAC) extensions which provide a comprehensive security policy. Examples
|
||||||
|
include SELinux, Smack, Tomoyo, and AppArmor. In addition to the larger
|
||||||
|
MAC extensions, other extensions can be built using the LSM to provide
|
||||||
|
specific changes to system operation when these tweaks are not available
|
||||||
|
in the core functionality of Linux itself.
|
||||||
|
|
||||||
|
Without a specific LSM built into the kernel, the default LSM will be the
|
||||||
|
Linux capabilities system. Most LSMs choose to extend the capabilities
|
||||||
|
system, building their checks on top of the defined capability hooks.
|
||||||
|
For more details on capabilities, see ``capabilities(7)`` in the Linux
|
||||||
|
man-pages project.
|
||||||
|
|
||||||
|
A list of the active security modules can be found by reading
|
||||||
|
``/sys/kernel/security/lsm``. This is a comma separated list, and
|
||||||
|
will always include the capability module. The list reflects the
|
||||||
|
order in which checks are made. The capability module will always
|
||||||
|
be first, followed by any "minor" modules (e.g. Yama) and then
|
||||||
|
the one "major" module (e.g. SELinux) if there is one configured.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
apparmor
|
||||||
|
LoadPin
|
||||||
|
SELinux
|
||||||
|
Smack
|
||||||
|
tomoyo
|
||||||
|
Yama
|
65
kernel/Documentation/admin-guide/LSM/tomoyo.rst
Normal file
65
kernel/Documentation/admin-guide/LSM/tomoyo.rst
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
======
|
||||||
|
TOMOYO
|
||||||
|
======
|
||||||
|
|
||||||
|
What is TOMOYO?
|
||||||
|
===============
|
||||||
|
|
||||||
|
TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel.
|
||||||
|
|
||||||
|
LiveCD-based tutorials are available at
|
||||||
|
|
||||||
|
http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/
|
||||||
|
http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/
|
||||||
|
|
||||||
|
Though these tutorials use non-LSM version of TOMOYO, they are useful for you
|
||||||
|
to know what TOMOYO is.
|
||||||
|
|
||||||
|
How to enable TOMOYO?
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Build the kernel with ``CONFIG_SECURITY_TOMOYO=y`` and pass ``security=tomoyo`` on
|
||||||
|
kernel's command line.
|
||||||
|
|
||||||
|
Please see http://tomoyo.sourceforge.jp/2.3/ for details.
|
||||||
|
|
||||||
|
Where is documentation?
|
||||||
|
=======================
|
||||||
|
|
||||||
|
User <-> Kernel interface documentation is available at
|
||||||
|
http://tomoyo.sourceforge.jp/2.3/policy-reference.html .
|
||||||
|
|
||||||
|
Materials we prepared for seminars and symposiums are available at
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
|
||||||
|
Below lists are chosen from three aspects.
|
||||||
|
|
||||||
|
What is TOMOYO?
|
||||||
|
TOMOYO Linux Overview
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf
|
||||||
|
TOMOYO Linux: pragmatic and manageable security for Linux
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
|
||||||
|
TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
|
||||||
|
|
||||||
|
What can TOMOYO do?
|
||||||
|
Deep inside TOMOYO Linux
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
|
||||||
|
The role of "pathname based access control" in security.
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf
|
||||||
|
|
||||||
|
History of TOMOYO?
|
||||||
|
Realities of Mainlining
|
||||||
|
http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf
|
||||||
|
|
||||||
|
What is future plan?
|
||||||
|
====================
|
||||||
|
|
||||||
|
We believe that inode based security and name based security are complementary
|
||||||
|
and both should be used together. But unfortunately, so far, we cannot enable
|
||||||
|
multiple LSM modules at the same time. We feel sorry that you have to give up
|
||||||
|
SELinux/SMACK/AppArmor etc. when you want to use TOMOYO.
|
||||||
|
|
||||||
|
We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM
|
||||||
|
version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ .
|
||||||
|
LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning
|
||||||
|
to port non-LSM version's functionalities to LSM versions.
|
|
@ -55,12 +55,6 @@ Documentation
|
||||||
contains information about the problems, which may result by upgrading
|
contains information about the problems, which may result by upgrading
|
||||||
your kernel.
|
your kernel.
|
||||||
|
|
||||||
- The Documentation/DocBook/ subdirectory contains several guides for
|
|
||||||
kernel developers and users. These guides can be rendered in a
|
|
||||||
number of formats: PostScript (.ps), PDF, HTML, & man-pages, among others.
|
|
||||||
After installation, ``make psdocs``, ``make pdfdocs``, ``make htmldocs``,
|
|
||||||
or ``make mandocs`` will render the documentation in the requested format.
|
|
||||||
|
|
||||||
Installing the kernel source
|
Installing the kernel source
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
|
@ -369,8 +369,10 @@
|
||||||
237 = /dev/loop-control Loopback control device
|
237 = /dev/loop-control Loopback control device
|
||||||
238 = /dev/vhost-net Host kernel accelerator for virtio net
|
238 = /dev/vhost-net Host kernel accelerator for virtio net
|
||||||
239 = /dev/uhid User-space I/O driver support for HID subsystem
|
239 = /dev/uhid User-space I/O driver support for HID subsystem
|
||||||
|
240 = /dev/userio Serio driver testing device
|
||||||
|
241 = /dev/vhost-vsock Host kernel driver for virtio vsock
|
||||||
|
|
||||||
240-254 Reserved for local use
|
242-254 Reserved for local use
|
||||||
255 Reserved for MISC_DYNAMIC_MINOR
|
255 Reserved for MISC_DYNAMIC_MINOR
|
||||||
|
|
||||||
11 char Raw keyboard device (Linux/SPARC only)
|
11 char Raw keyboard device (Linux/SPARC only)
|
||||||
|
|
|
@ -61,6 +61,8 @@ configure specific aspects of kernel behavior to your liking.
|
||||||
java
|
java
|
||||||
ras
|
ras
|
||||||
pm/index
|
pm/index
|
||||||
|
thunderbolt
|
||||||
|
LSM/index
|
||||||
|
|
||||||
.. only:: subproject and html
|
.. only:: subproject and html
|
||||||
|
|
||||||
|
|
|
@ -649,6 +649,13 @@
|
||||||
/proc/<pid>/coredump_filter.
|
/proc/<pid>/coredump_filter.
|
||||||
See also Documentation/filesystems/proc.txt.
|
See also Documentation/filesystems/proc.txt.
|
||||||
|
|
||||||
|
coresight_cpu_debug.enable
|
||||||
|
[ARM,ARM64]
|
||||||
|
Format: <bool>
|
||||||
|
Enable/disable the CPU sampling based debugging.
|
||||||
|
0: default value, disable debugging
|
||||||
|
1: enable debugging at boot time
|
||||||
|
|
||||||
cpuidle.off=1 [CPU_IDLE]
|
cpuidle.off=1 [CPU_IDLE]
|
||||||
disable the cpuidle sub-system
|
disable the cpuidle sub-system
|
||||||
|
|
||||||
|
@ -720,7 +727,8 @@
|
||||||
See also Documentation/input/joystick-parport.txt
|
See also Documentation/input/joystick-parport.txt
|
||||||
|
|
||||||
ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
|
ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
|
||||||
time. See Documentation/dynamic-debug-howto.txt for
|
time. See
|
||||||
|
Documentation/admin-guide/dynamic-debug-howto.rst for
|
||||||
details. Deprecated, see dyndbg.
|
details. Deprecated, see dyndbg.
|
||||||
|
|
||||||
debug [KNL] Enable kernel debugging (events log level).
|
debug [KNL] Enable kernel debugging (events log level).
|
||||||
|
@ -883,7 +891,8 @@
|
||||||
dyndbg[="val"] [KNL,DYNAMIC_DEBUG]
|
dyndbg[="val"] [KNL,DYNAMIC_DEBUG]
|
||||||
module.dyndbg[="val"]
|
module.dyndbg[="val"]
|
||||||
Enable debug messages at boot time. See
|
Enable debug messages at boot time. See
|
||||||
Documentation/dynamic-debug-howto.txt for details.
|
Documentation/admin-guide/dynamic-debug-howto.rst
|
||||||
|
for details.
|
||||||
|
|
||||||
nompx [X86] Disables Intel Memory Protection Extensions.
|
nompx [X86] Disables Intel Memory Protection Extensions.
|
||||||
See Documentation/x86/intel_mpx.txt for more
|
See Documentation/x86/intel_mpx.txt for more
|
||||||
|
@ -954,6 +963,12 @@
|
||||||
must already be setup and configured. Options are not
|
must already be setup and configured. Options are not
|
||||||
yet supported.
|
yet supported.
|
||||||
|
|
||||||
|
owl,<addr>
|
||||||
|
Start an early, polled-mode console on a serial port
|
||||||
|
of an Actions Semi SoC, such as S500 or S900, at the
|
||||||
|
specified address. The serial port must already be
|
||||||
|
setup and configured. Options are not yet supported.
|
||||||
|
|
||||||
smh Use ARM semihosting calls for early console.
|
smh Use ARM semihosting calls for early console.
|
||||||
|
|
||||||
s3c2410,<addr>
|
s3c2410,<addr>
|
||||||
|
@ -1486,12 +1501,21 @@
|
||||||
in crypto/hash_info.h.
|
in crypto/hash_info.h.
|
||||||
|
|
||||||
ima_policy= [IMA]
|
ima_policy= [IMA]
|
||||||
The builtin measurement policy to load during IMA
|
The builtin policies to load during IMA setup.
|
||||||
setup. Specyfing "tcb" as the value, measures all
|
Format: "tcb | appraise_tcb | secure_boot"
|
||||||
programs exec'd, files mmap'd for exec, and all files
|
|
||||||
opened with the read mode bit set by either the
|
The "tcb" policy measures all programs exec'd, files
|
||||||
effective uid (euid=0) or uid=0.
|
mmap'd for exec, and all files opened with the read
|
||||||
Format: "tcb"
|
mode bit set by either the effective uid (euid=0) or
|
||||||
|
uid=0.
|
||||||
|
|
||||||
|
The "appraise_tcb" policy appraises the integrity of
|
||||||
|
all files owned by root. (This is the equivalent
|
||||||
|
of ima_appraise_tcb.)
|
||||||
|
|
||||||
|
The "secure_boot" policy appraises the integrity
|
||||||
|
of files (eg. kexec kernel image, kernel modules,
|
||||||
|
firmware, policy, etc) based on file signatures.
|
||||||
|
|
||||||
ima_tcb [IMA] Deprecated. Use ima_policy= instead.
|
ima_tcb [IMA] Deprecated. Use ima_policy= instead.
|
||||||
Load a policy which meets the needs of the Trusted
|
Load a policy which meets the needs of the Trusted
|
||||||
|
@ -1838,6 +1862,18 @@
|
||||||
for all guests.
|
for all guests.
|
||||||
Default is 1 (enabled) if in 64-bit or 32-bit PAE mode.
|
Default is 1 (enabled) if in 64-bit or 32-bit PAE mode.
|
||||||
|
|
||||||
|
kvm-arm.vgic_v3_group0_trap=
|
||||||
|
[KVM,ARM] Trap guest accesses to GICv3 group-0
|
||||||
|
system registers
|
||||||
|
|
||||||
|
kvm-arm.vgic_v3_group1_trap=
|
||||||
|
[KVM,ARM] Trap guest accesses to GICv3 group-1
|
||||||
|
system registers
|
||||||
|
|
||||||
|
kvm-arm.vgic_v3_common_trap=
|
||||||
|
[KVM,ARM] Trap guest accesses to GICv3 common
|
||||||
|
system registers
|
||||||
|
|
||||||
kvm-intel.ept= [KVM,Intel] Disable extended page tables
|
kvm-intel.ept= [KVM,Intel] Disable extended page tables
|
||||||
(virtualized MMU) support on capable Intel chips.
|
(virtualized MMU) support on capable Intel chips.
|
||||||
Default is 1 (enabled)
|
Default is 1 (enabled)
|
||||||
|
@ -2136,6 +2172,12 @@
|
||||||
memmap=nn[KMG]@ss[KMG]
|
memmap=nn[KMG]@ss[KMG]
|
||||||
[KNL] Force usage of a specific region of memory.
|
[KNL] Force usage of a specific region of memory.
|
||||||
Region of memory to be used is from ss to ss+nn.
|
Region of memory to be used is from ss to ss+nn.
|
||||||
|
If @ss[KMG] is omitted, it is equivalent to mem=nn[KMG],
|
||||||
|
which limits max address to nn[KMG].
|
||||||
|
Multiple different regions can be specified,
|
||||||
|
comma delimited.
|
||||||
|
Example:
|
||||||
|
memmap=100M@2G,100M#3G,1G!1024G
|
||||||
|
|
||||||
memmap=nn[KMG]#ss[KMG]
|
memmap=nn[KMG]#ss[KMG]
|
||||||
[KNL,ACPI] Mark specific memory as ACPI data.
|
[KNL,ACPI] Mark specific memory as ACPI data.
|
||||||
|
@ -2148,6 +2190,9 @@
|
||||||
memmap=64K$0x18690000
|
memmap=64K$0x18690000
|
||||||
or
|
or
|
||||||
memmap=0x10000$0x18690000
|
memmap=0x10000$0x18690000
|
||||||
|
Some bootloaders may need an escape character before '$',
|
||||||
|
like Grub2, otherwise '$' and the following number
|
||||||
|
will be eaten.
|
||||||
|
|
||||||
memmap=nn[KMG]!ss[KMG]
|
memmap=nn[KMG]!ss[KMG]
|
||||||
[KNL,X86] Mark specific memory as protected.
|
[KNL,X86] Mark specific memory as protected.
|
||||||
|
@ -2270,8 +2315,11 @@
|
||||||
that the amount of memory usable for all allocations
|
that the amount of memory usable for all allocations
|
||||||
is not too small.
|
is not too small.
|
||||||
|
|
||||||
movable_node [KNL] Boot-time switch to enable the effects
|
movable_node [KNL] Boot-time switch to make hotplugable memory
|
||||||
of CONFIG_MOVABLE_NODE=y. See mm/Kconfig for details.
|
NUMA nodes to be movable. This means that the memory
|
||||||
|
of such nodes will be usable only for movable
|
||||||
|
allocations which rules out almost all kernel
|
||||||
|
allocations. Use with caution!
|
||||||
|
|
||||||
MTD_Partition= [MTD]
|
MTD_Partition= [MTD]
|
||||||
Format: <name>,<region-number>,<size>,<offset>
|
Format: <name>,<region-number>,<size>,<offset>
|
||||||
|
@ -3238,21 +3286,17 @@
|
||||||
|
|
||||||
rcutree.gp_cleanup_delay= [KNL]
|
rcutree.gp_cleanup_delay= [KNL]
|
||||||
Set the number of jiffies to delay each step of
|
Set the number of jiffies to delay each step of
|
||||||
RCU grace-period cleanup. This only has effect
|
RCU grace-period cleanup.
|
||||||
when CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP is set.
|
|
||||||
|
|
||||||
rcutree.gp_init_delay= [KNL]
|
rcutree.gp_init_delay= [KNL]
|
||||||
Set the number of jiffies to delay each step of
|
Set the number of jiffies to delay each step of
|
||||||
RCU grace-period initialization. This only has
|
RCU grace-period initialization.
|
||||||
effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT
|
|
||||||
is set.
|
|
||||||
|
|
||||||
rcutree.gp_preinit_delay= [KNL]
|
rcutree.gp_preinit_delay= [KNL]
|
||||||
Set the number of jiffies to delay each step of
|
Set the number of jiffies to delay each step of
|
||||||
RCU grace-period pre-initialization, that is,
|
RCU grace-period pre-initialization, that is,
|
||||||
the propagation of recent CPU-hotplug changes up
|
the propagation of recent CPU-hotplug changes up
|
||||||
the rcu_node combining tree. This only has effect
|
the rcu_node combining tree.
|
||||||
when CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT is set.
|
|
||||||
|
|
||||||
rcutree.rcu_fanout_exact= [KNL]
|
rcutree.rcu_fanout_exact= [KNL]
|
||||||
Disable autobalancing of the rcu_node combining
|
Disable autobalancing of the rcu_node combining
|
||||||
|
@ -3328,6 +3372,17 @@
|
||||||
This wake_up() will be accompanied by a
|
This wake_up() will be accompanied by a
|
||||||
WARN_ONCE() splat and an ftrace_dump().
|
WARN_ONCE() splat and an ftrace_dump().
|
||||||
|
|
||||||
|
rcuperf.gp_async= [KNL]
|
||||||
|
Measure performance of asynchronous
|
||||||
|
grace-period primitives such as call_rcu().
|
||||||
|
|
||||||
|
rcuperf.gp_async_max= [KNL]
|
||||||
|
Specify the maximum number of outstanding
|
||||||
|
callbacks per writer thread. When a writer
|
||||||
|
thread exceeds this limit, it invokes the
|
||||||
|
corresponding flavor of rcu_barrier() to allow
|
||||||
|
previously posted callbacks to drain.
|
||||||
|
|
||||||
rcuperf.gp_exp= [KNL]
|
rcuperf.gp_exp= [KNL]
|
||||||
Measure performance of expedited synchronous
|
Measure performance of expedited synchronous
|
||||||
grace-period primitives.
|
grace-period primitives.
|
||||||
|
@ -3355,17 +3410,22 @@
|
||||||
rcuperf.perf_runnable= [BOOT]
|
rcuperf.perf_runnable= [BOOT]
|
||||||
Start rcuperf running at boot time.
|
Start rcuperf running at boot time.
|
||||||
|
|
||||||
|
rcuperf.perf_type= [KNL]
|
||||||
|
Specify the RCU implementation to test.
|
||||||
|
|
||||||
rcuperf.shutdown= [KNL]
|
rcuperf.shutdown= [KNL]
|
||||||
Shut the system down after performance tests
|
Shut the system down after performance tests
|
||||||
complete. This is useful for hands-off automated
|
complete. This is useful for hands-off automated
|
||||||
testing.
|
testing.
|
||||||
|
|
||||||
rcuperf.perf_type= [KNL]
|
|
||||||
Specify the RCU implementation to test.
|
|
||||||
|
|
||||||
rcuperf.verbose= [KNL]
|
rcuperf.verbose= [KNL]
|
||||||
Enable additional printk() statements.
|
Enable additional printk() statements.
|
||||||
|
|
||||||
|
rcuperf.writer_holdoff= [KNL]
|
||||||
|
Write-side holdoff between grace periods,
|
||||||
|
in microseconds. The default of zero says
|
||||||
|
no holdoff.
|
||||||
|
|
||||||
rcutorture.cbflood_inter_holdoff= [KNL]
|
rcutorture.cbflood_inter_holdoff= [KNL]
|
||||||
Set holdoff time (jiffies) between successive
|
Set holdoff time (jiffies) between successive
|
||||||
callback-flood tests.
|
callback-flood tests.
|
||||||
|
@ -3715,8 +3775,14 @@
|
||||||
slab_nomerge [MM]
|
slab_nomerge [MM]
|
||||||
Disable merging of slabs with similar size. May be
|
Disable merging of slabs with similar size. May be
|
||||||
necessary if there is some reason to distinguish
|
necessary if there is some reason to distinguish
|
||||||
allocs to different slabs. Debug options disable
|
allocs to different slabs, especially in hardened
|
||||||
merging on their own.
|
environments where the risk of heap overflows and
|
||||||
|
layout control by attackers can usually be
|
||||||
|
frustrated by disabling merging. This will reduce
|
||||||
|
most of the exposure of a heap attack to a single
|
||||||
|
cache (risks via metadata attacks are mostly
|
||||||
|
unchanged). Debug options disable merging on their
|
||||||
|
own.
|
||||||
For more information see Documentation/vm/slub.txt.
|
For more information see Documentation/vm/slub.txt.
|
||||||
|
|
||||||
slab_max_order= [MM, SLAB]
|
slab_max_order= [MM, SLAB]
|
||||||
|
@ -3803,6 +3869,15 @@
|
||||||
spia_pedr=
|
spia_pedr=
|
||||||
spia_peddr=
|
spia_peddr=
|
||||||
|
|
||||||
|
srcutree.counter_wrap_check [KNL]
|
||||||
|
Specifies how frequently to check for
|
||||||
|
grace-period sequence counter wrap for the
|
||||||
|
srcu_data structure's ->srcu_gp_seq_needed field.
|
||||||
|
The greater the number of bits set in this kernel
|
||||||
|
parameter, the less frequently counter wrap will
|
||||||
|
be checked for. Note that the bottom two bits
|
||||||
|
are ignored.
|
||||||
|
|
||||||
srcutree.exp_holdoff [KNL]
|
srcutree.exp_holdoff [KNL]
|
||||||
Specifies how many nanoseconds must elapse
|
Specifies how many nanoseconds must elapse
|
||||||
since the end of the last SRCU grace period for
|
since the end of the last SRCU grace period for
|
||||||
|
|
|
@ -237,6 +237,14 @@ are the following:
|
||||||
This attribute is not present if the scaling driver in use does not
|
This attribute is not present if the scaling driver in use does not
|
||||||
support it.
|
support it.
|
||||||
|
|
||||||
|
``cpuinfo_cur_freq``
|
||||||
|
Current frequency of the CPUs belonging to this policy as obtained from
|
||||||
|
the hardware (in KHz).
|
||||||
|
|
||||||
|
This is expected to be the frequency the hardware actually runs at.
|
||||||
|
If that frequency cannot be determined, this attribute should not
|
||||||
|
be present.
|
||||||
|
|
||||||
``cpuinfo_max_freq``
|
``cpuinfo_max_freq``
|
||||||
Maximum possible operating frequency the CPUs belonging to this policy
|
Maximum possible operating frequency the CPUs belonging to this policy
|
||||||
can run at (in kHz).
|
can run at (in kHz).
|
||||||
|
@ -269,16 +277,16 @@ are the following:
|
||||||
``scaling_cur_freq``
|
``scaling_cur_freq``
|
||||||
Current frequency of all of the CPUs belonging to this policy (in kHz).
|
Current frequency of all of the CPUs belonging to this policy (in kHz).
|
||||||
|
|
||||||
For the majority of scaling drivers, this is the frequency of the last
|
In the majority of cases, this is the frequency of the last P-state
|
||||||
P-state requested by the driver from the hardware using the scaling
|
requested by the scaling driver from the hardware using the scaling
|
||||||
interface provided by it, which may or may not reflect the frequency
|
interface provided by it, which may or may not reflect the frequency
|
||||||
the CPU is actually running at (due to hardware design and other
|
the CPU is actually running at (due to hardware design and other
|
||||||
limitations).
|
limitations).
|
||||||
|
|
||||||
Some scaling drivers (e.g. |intel_pstate|) attempt to provide
|
Some architectures (e.g. ``x86``) may attempt to provide information
|
||||||
information more precisely reflecting the current CPU frequency through
|
more precisely reflecting the current CPU frequency through this
|
||||||
this attribute, but that still may not be the exact current CPU
|
attribute, but that still may not be the exact current CPU frequency as
|
||||||
frequency as seen by the hardware at the moment.
|
seen by the hardware at the moment.
|
||||||
|
|
||||||
``scaling_driver``
|
``scaling_driver``
|
||||||
The scaling driver currently in use.
|
The scaling driver currently in use.
|
||||||
|
|
|
@ -157,10 +157,8 @@ Without HWP, this P-state selection algorithm is always the same regardless of
|
||||||
the processor model and platform configuration.
|
the processor model and platform configuration.
|
||||||
|
|
||||||
It selects the maximum P-state it is allowed to use, subject to limits set via
|
It selects the maximum P-state it is allowed to use, subject to limits set via
|
||||||
``sysfs``, every time the P-state selection computations are carried out by the
|
``sysfs``, every time the driver configuration for the given CPU is updated
|
||||||
driver's utilization update callback for the given CPU (that does not happen
|
(e.g. via ``sysfs``).
|
||||||
more often than every 10 ms), but the hardware configuration will not be changed
|
|
||||||
if the new P-state is the same as the current one.
|
|
||||||
|
|
||||||
This is the default P-state selection algorithm if the
|
This is the default P-state selection algorithm if the
|
||||||
:c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option
|
:c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option
|
||||||
|
|
|
@ -344,9 +344,9 @@ for more than 2 channels, like Fully Buffered DIMMs (FB-DIMMs) memory
|
||||||
controllers. The following example will assume 2 channels:
|
controllers. The following example will assume 2 channels:
|
||||||
|
|
||||||
+------------+-----------------------+
|
+------------+-----------------------+
|
||||||
| Chip | Channels |
|
| CS Rows | Channels |
|
||||||
| Select +-----------+-----------+
|
+------------+-----------+-----------+
|
||||||
| rows | ``ch0`` | ``ch1`` |
|
| | ``ch0`` | ``ch1`` |
|
||||||
+============+===========+===========+
|
+============+===========+===========+
|
||||||
| ``csrow0`` | DIMM_A0 | DIMM_B0 |
|
| ``csrow0`` | DIMM_A0 | DIMM_B0 |
|
||||||
+------------+ | |
|
+------------+ | |
|
||||||
|
@ -698,7 +698,7 @@ information indicating that errors have been detected::
|
||||||
The structure of the message is:
|
The structure of the message is:
|
||||||
|
|
||||||
+---------------------------------------+-------------+
|
+---------------------------------------+-------------+
|
||||||
| Content + Example |
|
| Content | Example |
|
||||||
+=======================================+=============+
|
+=======================================+=============+
|
||||||
| The memory controller | MC0 |
|
| The memory controller | MC0 |
|
||||||
+---------------------------------------+-------------+
|
+---------------------------------------+-------------+
|
||||||
|
@ -713,7 +713,7 @@ The structure of the message is:
|
||||||
+---------------------------------------+-------------+
|
+---------------------------------------+-------------+
|
||||||
| The error syndrome | 0xb741 |
|
| The error syndrome | 0xb741 |
|
||||||
+---------------------------------------+-------------+
|
+---------------------------------------+-------------+
|
||||||
| Memory row | row 0 +
|
| Memory row | row 0 |
|
||||||
+---------------------------------------+-------------+
|
+---------------------------------------+-------------+
|
||||||
| Memory channel | channel 1 |
|
| Memory channel | channel 1 |
|
||||||
+---------------------------------------+-------------+
|
+---------------------------------------+-------------+
|
||||||
|
|
199
kernel/Documentation/admin-guide/thunderbolt.rst
Normal file
199
kernel/Documentation/admin-guide/thunderbolt.rst
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
=============
|
||||||
|
Thunderbolt
|
||||||
|
=============
|
||||||
|
The interface presented here is not meant for end users. Instead there
|
||||||
|
should be a userspace tool that handles all the low-level details, keeps
|
||||||
|
database of the authorized devices and prompts user for new connections.
|
||||||
|
|
||||||
|
More details about the sysfs interface for Thunderbolt devices can be
|
||||||
|
found in ``Documentation/ABI/testing/sysfs-bus-thunderbolt``.
|
||||||
|
|
||||||
|
Those users who just want to connect any device without any sort of
|
||||||
|
manual work, can add following line to
|
||||||
|
``/etc/udev/rules.d/99-local.rules``::
|
||||||
|
|
||||||
|
ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}=="0", ATTR{authorized}="1"
|
||||||
|
|
||||||
|
This will authorize all devices automatically when they appear. However,
|
||||||
|
keep in mind that this bypasses the security levels and makes the system
|
||||||
|
vulnerable to DMA attacks.
|
||||||
|
|
||||||
|
Security levels and how to use them
|
||||||
|
-----------------------------------
|
||||||
|
Starting from Intel Falcon Ridge Thunderbolt controller there are 4
|
||||||
|
security levels available. The reason for these is the fact that the
|
||||||
|
connected devices can be DMA masters and thus read contents of the host
|
||||||
|
memory without CPU and OS knowing about it. There are ways to prevent
|
||||||
|
this by setting up an IOMMU but it is not always available for various
|
||||||
|
reasons.
|
||||||
|
|
||||||
|
The security levels are as follows:
|
||||||
|
|
||||||
|
none
|
||||||
|
All devices are automatically connected by the firmware. No user
|
||||||
|
approval is needed. In BIOS settings this is typically called
|
||||||
|
*Legacy mode*.
|
||||||
|
|
||||||
|
user
|
||||||
|
User is asked whether the device is allowed to be connected.
|
||||||
|
Based on the device identification information available through
|
||||||
|
``/sys/bus/thunderbolt/devices``. user then can do the decision.
|
||||||
|
In BIOS settings this is typically called *Unique ID*.
|
||||||
|
|
||||||
|
secure
|
||||||
|
User is asked whether the device is allowed to be connected. In
|
||||||
|
addition to UUID the device (if it supports secure connect) is sent
|
||||||
|
a challenge that should match the expected one based on a random key
|
||||||
|
written to ``key`` sysfs attribute. In BIOS settings this is
|
||||||
|
typically called *One time saved key*.
|
||||||
|
|
||||||
|
dponly
|
||||||
|
The firmware automatically creates tunnels for Display Port and
|
||||||
|
USB. No PCIe tunneling is done. In BIOS settings this is
|
||||||
|
typically called *Display Port Only*.
|
||||||
|
|
||||||
|
The current security level can be read from
|
||||||
|
``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is
|
||||||
|
the Thunderbolt domain the host controller manages. There is typically
|
||||||
|
one domain per Thunderbolt host controller.
|
||||||
|
|
||||||
|
If the security level reads as ``user`` or ``secure`` the connected
|
||||||
|
device must be authorized by the user before PCIe tunnels are created
|
||||||
|
(e.g the PCIe device appears).
|
||||||
|
|
||||||
|
Each Thunderbolt device plugged in will appear in sysfs under
|
||||||
|
``/sys/bus/thunderbolt/devices``. The device directory carries
|
||||||
|
information that can be used to identify the particular device,
|
||||||
|
including its name and UUID.
|
||||||
|
|
||||||
|
Authorizing devices when security level is ``user`` or ``secure``
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
When a device is plugged in it will appear in sysfs as follows::
|
||||||
|
|
||||||
|
/sys/bus/thunderbolt/devices/0-1/authorized - 0
|
||||||
|
/sys/bus/thunderbolt/devices/0-1/device - 0x8004
|
||||||
|
/sys/bus/thunderbolt/devices/0-1/device_name - Thunderbolt to FireWire Adapter
|
||||||
|
/sys/bus/thunderbolt/devices/0-1/vendor - 0x1
|
||||||
|
/sys/bus/thunderbolt/devices/0-1/vendor_name - Apple, Inc.
|
||||||
|
/sys/bus/thunderbolt/devices/0-1/unique_id - e0376f00-0300-0100-ffff-ffffffffffff
|
||||||
|
|
||||||
|
The ``authorized`` attribute reads 0 which means no PCIe tunnels are
|
||||||
|
created yet. The user can authorize the device by simply::
|
||||||
|
|
||||||
|
# echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized
|
||||||
|
|
||||||
|
This will create the PCIe tunnels and the device is now connected.
|
||||||
|
|
||||||
|
If the device supports secure connect, and the domain security level is
|
||||||
|
set to ``secure``, it has an additional attribute ``key`` which can hold
|
||||||
|
a random 32 byte value used for authorization and challenging the device in
|
||||||
|
future connects::
|
||||||
|
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/authorized - 0
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/device - 0x305
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/device_name - AKiTiO Thunder3 PCIe Box
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/key -
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/vendor - 0x41
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/vendor_name - inXtron
|
||||||
|
/sys/bus/thunderbolt/devices/0-3/unique_id - dc010000-0000-8508-a22d-32ca6421cb16
|
||||||
|
|
||||||
|
Notice the key is empty by default.
|
||||||
|
|
||||||
|
If the user does not want to use secure connect it can just ``echo 1``
|
||||||
|
to the ``authorized`` attribute and the PCIe tunnels will be created in
|
||||||
|
the same way than in ``user`` security level.
|
||||||
|
|
||||||
|
If the user wants to use secure connect, the first time the device is
|
||||||
|
plugged a key needs to be created and send to the device::
|
||||||
|
|
||||||
|
# key=$(openssl rand -hex 32)
|
||||||
|
# echo $key > /sys/bus/thunderbolt/devices/0-3/key
|
||||||
|
# echo 1 > /sys/bus/thunderbolt/devices/0-3/authorized
|
||||||
|
|
||||||
|
Now the device is connected (PCIe tunnels are created) and in addition
|
||||||
|
the key is stored on the device NVM.
|
||||||
|
|
||||||
|
Next time the device is plugged in the user can verify (challenge) the
|
||||||
|
device using the same key::
|
||||||
|
|
||||||
|
# echo $key > /sys/bus/thunderbolt/devices/0-3/key
|
||||||
|
# echo 2 > /sys/bus/thunderbolt/devices/0-3/authorized
|
||||||
|
|
||||||
|
If the challenge the device returns back matches the one we expect based
|
||||||
|
on the key, the device is connected and the PCIe tunnels are created.
|
||||||
|
However, if the challenge failed no tunnels are created and error is
|
||||||
|
returned to the user.
|
||||||
|
|
||||||
|
If the user still wants to connect the device it can either approve
|
||||||
|
the device without a key or write new key and write 1 to the
|
||||||
|
``authorized`` file to get the new key stored on the device NVM.
|
||||||
|
|
||||||
|
Upgrading NVM on Thunderbolt device or host
|
||||||
|
-------------------------------------------
|
||||||
|
Since most of the functionality is handled in a firmware running on a
|
||||||
|
host controller or a device, it is important that the firmware can be
|
||||||
|
upgraded to the latest where possible bugs in it have been fixed.
|
||||||
|
Typically OEMs provide this firmware from their support site.
|
||||||
|
|
||||||
|
There is also a central site which has links where to download firmwares
|
||||||
|
for some machines:
|
||||||
|
|
||||||
|
`Thunderbolt Updates <https://thunderbolttechnology.net/updates>`_
|
||||||
|
|
||||||
|
Before you upgrade firmware on a device or host, please make sure it is
|
||||||
|
the suitable. Failing to do that may render the device (or host) in a
|
||||||
|
state where it cannot be used properly anymore without special tools!
|
||||||
|
|
||||||
|
Host NVM upgrade on Apple Macs is not supported.
|
||||||
|
|
||||||
|
Once the NVM image has been downloaded, you need to plug in a
|
||||||
|
Thunderbolt device so that the host controller appears. It does not
|
||||||
|
matter which device is connected (unless you are upgrading NVM on a
|
||||||
|
device - then you need to connect that particular device).
|
||||||
|
|
||||||
|
Note OEM-specific method to power the controller up ("force power") may
|
||||||
|
be available for your system in which case there is no need to plug in a
|
||||||
|
Thunderbolt device.
|
||||||
|
|
||||||
|
After that we can write the firmware to the non-active parts of the NVM
|
||||||
|
of the host or device. As an example here is how Intel NUC6i7KYK (Skull
|
||||||
|
Canyon) Thunderbolt controller NVM is upgraded::
|
||||||
|
|
||||||
|
# dd if=KYK_TBT_FW_0018.bin of=/sys/bus/thunderbolt/devices/0-0/nvm_non_active0/nvmem
|
||||||
|
|
||||||
|
Once the operation completes we can trigger NVM authentication and
|
||||||
|
upgrade process as follows::
|
||||||
|
|
||||||
|
# echo 1 > /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
|
||||||
|
|
||||||
|
If no errors are returned, the host controller shortly disappears. Once
|
||||||
|
it comes back the driver notices it and initiates a full power cycle.
|
||||||
|
After a while the host controller appears again and this time it should
|
||||||
|
be fully functional.
|
||||||
|
|
||||||
|
We can verify that the new NVM firmware is active by running following
|
||||||
|
commands::
|
||||||
|
|
||||||
|
# cat /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
|
||||||
|
0x0
|
||||||
|
# cat /sys/bus/thunderbolt/devices/0-0/nvm_version
|
||||||
|
18.0
|
||||||
|
|
||||||
|
If ``nvm_authenticate`` contains anything else than 0x0 it is the error
|
||||||
|
code from the last authentication cycle, which means the authentication
|
||||||
|
of the NVM image failed.
|
||||||
|
|
||||||
|
Note names of the NVMem devices ``nvm_activeN`` and ``nvm_non_activeN``
|
||||||
|
depends on the order they are registered in the NVMem subsystem. N in
|
||||||
|
the name is the identifier added by the NVMem subsystem.
|
||||||
|
|
||||||
|
Upgrading NVM when host controller is in safe mode
|
||||||
|
--------------------------------------------------
|
||||||
|
If the existing NVM is not properly authenticated (or is missing) the
|
||||||
|
host controller goes into safe mode which means that only available
|
||||||
|
functionality is flashing new NVM image. When in this mode the reading
|
||||||
|
``nvm_version`` fails with ``ENODATA`` and the device identification
|
||||||
|
information is missing.
|
||||||
|
|
||||||
|
To recover from this mode, one needs to flash a valid NVM image to the
|
||||||
|
host host controller in the same way it is done in the previous chapter.
|
|
@ -16,7 +16,7 @@ git branches/tags and email subject always contain this "at91" sub-string.
|
||||||
|
|
||||||
AT91 SoCs
|
AT91 SoCs
|
||||||
---------
|
---------
|
||||||
Documentation and detailled datasheet for each product are available on
|
Documentation and detailed datasheet for each product are available on
|
||||||
the Atmel website: http://www.atmel.com.
|
the Atmel website: http://www.atmel.com.
|
||||||
|
|
||||||
Flavors:
|
Flavors:
|
||||||
|
@ -101,6 +101,42 @@ the Atmel website: http://www.atmel.com.
|
||||||
+ Datasheet
|
+ Datasheet
|
||||||
http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf
|
http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf
|
||||||
|
|
||||||
|
* ARM Cortex-M7 MCUs
|
||||||
|
- sams70 family
|
||||||
|
- sams70j19
|
||||||
|
- sams70j20
|
||||||
|
- sams70j21
|
||||||
|
- sams70n19
|
||||||
|
- sams70n20
|
||||||
|
- sams70n21
|
||||||
|
- sams70q19
|
||||||
|
- sams70q20
|
||||||
|
- sams70q21
|
||||||
|
+ Datasheet
|
||||||
|
http://www.atmel.com/Images/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf
|
||||||
|
|
||||||
|
- samv70 family
|
||||||
|
- samv70j19
|
||||||
|
- samv70j20
|
||||||
|
- samv70n19
|
||||||
|
- samv70n20
|
||||||
|
- samv70q19
|
||||||
|
- samv70q20
|
||||||
|
+ Datasheet
|
||||||
|
http://www.atmel.com/Images/Atmel-11297-32-bit-Cortex-M7-Microcontroller-SAM-V70Q-SAM-V70N-SAM-V70J_Datasheet.pdf
|
||||||
|
|
||||||
|
- samv71 family
|
||||||
|
- samv71j19
|
||||||
|
- samv71j20
|
||||||
|
- samv71j21
|
||||||
|
- samv71n19
|
||||||
|
- samv71n20
|
||||||
|
- samv71n21
|
||||||
|
- samv71q19
|
||||||
|
- samv71q20
|
||||||
|
- samv71q21
|
||||||
|
+ Datasheet
|
||||||
|
http://www.atmel.com/Images/Atmel-44003-32-bit-Cortex-M7-Microcontroller-SAM-V71Q-SAM-V71N-SAM-V71J_Datasheet.pdf
|
||||||
|
|
||||||
Linux kernel information
|
Linux kernel information
|
||||||
------------------------
|
------------------------
|
||||||
|
|
|
@ -61,11 +61,15 @@ stable kernels.
|
||||||
| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
|
| Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 |
|
||||||
| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
|
| Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 |
|
||||||
| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
|
| Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 |
|
||||||
|
| Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 |
|
||||||
| Cavium | ThunderX SMMUv2 | #27704 | N/A |
|
| Cavium | ThunderX SMMUv2 | #27704 | N/A |
|
||||||
|
| Cavium | ThunderX2 SMMUv3| #74 | N/A |
|
||||||
|
| Cavium | ThunderX2 SMMUv3| #126 | N/A |
|
||||||
| | | | |
|
| | | | |
|
||||||
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
|
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
|
||||||
| | | | |
|
| | | | |
|
||||||
| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
|
| Hisilicon | Hip0{5,6,7} | #161010101 | HISILICON_ERRATUM_161010101 |
|
||||||
|
| Hisilicon | Hip0{6,7} | #161010701 | N/A |
|
||||||
| | | | |
|
| | | | |
|
||||||
| Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
|
| Qualcomm Tech. | Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
|
||||||
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
|
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
|
============================
|
||||||
|
A block layer cache (bcache)
|
||||||
|
============================
|
||||||
|
|
||||||
Say you've got a big slow raid 6, and an ssd or three. Wouldn't it be
|
Say you've got a big slow raid 6, and an ssd or three. Wouldn't it be
|
||||||
nice if you could use them as cache... Hence bcache.
|
nice if you could use them as cache... Hence bcache.
|
||||||
|
|
||||||
Wiki and git repositories are at:
|
Wiki and git repositories are at:
|
||||||
http://bcache.evilpiepirate.org
|
|
||||||
http://evilpiepirate.org/git/linux-bcache.git
|
- http://bcache.evilpiepirate.org
|
||||||
http://evilpiepirate.org/git/bcache-tools.git
|
- http://evilpiepirate.org/git/linux-bcache.git
|
||||||
|
- http://evilpiepirate.org/git/bcache-tools.git
|
||||||
|
|
||||||
It's designed around the performance characteristics of SSDs - it only allocates
|
It's designed around the performance characteristics of SSDs - it only allocates
|
||||||
in erase block sized buckets, and it uses a hybrid btree/log to track cached
|
in erase block sized buckets, and it uses a hybrid btree/log to track cached
|
||||||
|
@ -37,17 +42,19 @@ to be flushed.
|
||||||
|
|
||||||
Getting started:
|
Getting started:
|
||||||
You'll need make-bcache from the bcache-tools repository. Both the cache device
|
You'll need make-bcache from the bcache-tools repository. Both the cache device
|
||||||
and backing device must be formatted before use.
|
and backing device must be formatted before use::
|
||||||
|
|
||||||
make-bcache -B /dev/sdb
|
make-bcache -B /dev/sdb
|
||||||
make-bcache -C /dev/sdc
|
make-bcache -C /dev/sdc
|
||||||
|
|
||||||
make-bcache has the ability to format multiple devices at the same time - if
|
make-bcache has the ability to format multiple devices at the same time - if
|
||||||
you format your backing devices and cache device at the same time, you won't
|
you format your backing devices and cache device at the same time, you won't
|
||||||
have to manually attach:
|
have to manually attach::
|
||||||
|
|
||||||
make-bcache -B /dev/sda /dev/sdb -C /dev/sdc
|
make-bcache -B /dev/sda /dev/sdb -C /dev/sdc
|
||||||
|
|
||||||
bcache-tools now ships udev rules, and bcache devices are known to the kernel
|
bcache-tools now ships udev rules, and bcache devices are known to the kernel
|
||||||
immediately. Without udev, you can manually register devices like this:
|
immediately. Without udev, you can manually register devices like this::
|
||||||
|
|
||||||
echo /dev/sdb > /sys/fs/bcache/register
|
echo /dev/sdb > /sys/fs/bcache/register
|
||||||
echo /dev/sdc > /sys/fs/bcache/register
|
echo /dev/sdc > /sys/fs/bcache/register
|
||||||
|
@ -60,16 +67,16 @@ slow devices as bcache backing devices without a cache, and you can choose to ad
|
||||||
a caching device later.
|
a caching device later.
|
||||||
See 'ATTACHING' section below.
|
See 'ATTACHING' section below.
|
||||||
|
|
||||||
The devices show up as:
|
The devices show up as::
|
||||||
|
|
||||||
/dev/bcache<N>
|
/dev/bcache<N>
|
||||||
|
|
||||||
As well as (with udev):
|
As well as (with udev)::
|
||||||
|
|
||||||
/dev/bcache/by-uuid/<uuid>
|
/dev/bcache/by-uuid/<uuid>
|
||||||
/dev/bcache/by-label/<label>
|
/dev/bcache/by-label/<label>
|
||||||
|
|
||||||
To get started:
|
To get started::
|
||||||
|
|
||||||
mkfs.ext4 /dev/bcache0
|
mkfs.ext4 /dev/bcache0
|
||||||
mount /dev/bcache0 /mnt
|
mount /dev/bcache0 /mnt
|
||||||
|
@ -81,13 +88,13 @@ Cache devices are managed as sets; multiple caches per set isn't supported yet
|
||||||
but will allow for mirroring of metadata and dirty data in the future. Your new
|
but will allow for mirroring of metadata and dirty data in the future. Your new
|
||||||
cache set shows up as /sys/fs/bcache/<UUID>
|
cache set shows up as /sys/fs/bcache/<UUID>
|
||||||
|
|
||||||
ATTACHING
|
Attaching
|
||||||
---------
|
---------
|
||||||
|
|
||||||
After your cache device and backing device are registered, the backing device
|
After your cache device and backing device are registered, the backing device
|
||||||
must be attached to your cache set to enable caching. Attaching a backing
|
must be attached to your cache set to enable caching. Attaching a backing
|
||||||
device to a cache set is done thusly, with the UUID of the cache set in
|
device to a cache set is done thusly, with the UUID of the cache set in
|
||||||
/sys/fs/bcache:
|
/sys/fs/bcache::
|
||||||
|
|
||||||
echo <CSET-UUID> > /sys/block/bcache0/bcache/attach
|
echo <CSET-UUID> > /sys/block/bcache0/bcache/attach
|
||||||
|
|
||||||
|
@ -97,7 +104,7 @@ your bcache devices. If a backing device has data in a cache somewhere, the
|
||||||
important if you have writeback caching turned on.
|
important if you have writeback caching turned on.
|
||||||
|
|
||||||
If you're booting up and your cache device is gone and never coming back, you
|
If you're booting up and your cache device is gone and never coming back, you
|
||||||
can force run the backing device:
|
can force run the backing device::
|
||||||
|
|
||||||
echo 1 > /sys/block/sdb/bcache/running
|
echo 1 > /sys/block/sdb/bcache/running
|
||||||
|
|
||||||
|
@ -110,7 +117,7 @@ but all the cached data will be invalidated. If there was dirty data in the
|
||||||
cache, don't expect the filesystem to be recoverable - you will have massive
|
cache, don't expect the filesystem to be recoverable - you will have massive
|
||||||
filesystem corruption, though ext4's fsck does work miracles.
|
filesystem corruption, though ext4's fsck does work miracles.
|
||||||
|
|
||||||
ERROR HANDLING
|
Error Handling
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Bcache tries to transparently handle IO errors to/from the cache device without
|
Bcache tries to transparently handle IO errors to/from the cache device without
|
||||||
|
@ -134,25 +141,27 @@ the backing devices to passthrough mode.
|
||||||
read some of the dirty data, though.
|
read some of the dirty data, though.
|
||||||
|
|
||||||
|
|
||||||
HOWTO/COOKBOOK
|
Howto/cookbook
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
A) Starting a bcache with a missing caching device
|
A) Starting a bcache with a missing caching device
|
||||||
|
|
||||||
If registering the backing device doesn't help, it's already there, you just need
|
If registering the backing device doesn't help, it's already there, you just need
|
||||||
to force it to run without the cache:
|
to force it to run without the cache::
|
||||||
|
|
||||||
host:~# echo /dev/sdb1 > /sys/fs/bcache/register
|
host:~# echo /dev/sdb1 > /sys/fs/bcache/register
|
||||||
[ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered
|
[ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered
|
||||||
|
|
||||||
Next, you try to register your caching device if it's present. However
|
Next, you try to register your caching device if it's present. However
|
||||||
if it's absent, or registration fails for some reason, you can still
|
if it's absent, or registration fails for some reason, you can still
|
||||||
start your bcache without its cache, like so:
|
start your bcache without its cache, like so::
|
||||||
|
|
||||||
host:/sys/block/sdb/sdb1/bcache# echo 1 > running
|
host:/sys/block/sdb/sdb1/bcache# echo 1 > running
|
||||||
|
|
||||||
Note that this may cause data loss if you were running in writeback mode.
|
Note that this may cause data loss if you were running in writeback mode.
|
||||||
|
|
||||||
|
|
||||||
B) Bcache does not find its cache
|
B) Bcache does not find its cache::
|
||||||
|
|
||||||
host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach
|
host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach
|
||||||
[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set
|
[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set
|
||||||
|
@ -160,7 +169,8 @@ B) Bcache does not find its cache
|
||||||
[ 1933.478179] : cache set not found
|
[ 1933.478179] : cache set not found
|
||||||
|
|
||||||
In this case, the caching device was simply not registered at boot
|
In this case, the caching device was simply not registered at boot
|
||||||
or disappeared and came back, and needs to be (re-)registered:
|
or disappeared and came back, and needs to be (re-)registered::
|
||||||
|
|
||||||
host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register
|
host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,7 +190,8 @@ device is still available at an 8KiB offset. So either via a loopdev
|
||||||
of the backing device created with --offset 8K, or any value defined by
|
of the backing device created with --offset 8K, or any value defined by
|
||||||
--data-offset when you originally formatted bcache with `make-bcache`.
|
--data-offset when you originally formatted bcache with `make-bcache`.
|
||||||
|
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
losetup -o 8192 /dev/loop0 /dev/your_bcache_backing_dev
|
losetup -o 8192 /dev/loop0 /dev/your_bcache_backing_dev
|
||||||
|
|
||||||
This should present your unmodified backing device data in /dev/loop0
|
This should present your unmodified backing device data in /dev/loop0
|
||||||
|
@ -191,11 +202,14 @@ cache device without loosing data.
|
||||||
|
|
||||||
E) Wiping a cache device
|
E) Wiping a cache device
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
host:~# wipefs -a /dev/sdh2
|
host:~# wipefs -a /dev/sdh2
|
||||||
16 bytes were erased at offset 0x1018 (bcache)
|
16 bytes were erased at offset 0x1018 (bcache)
|
||||||
they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81
|
they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81
|
||||||
|
|
||||||
After you boot back with bcache enabled, you recreate the cache and attach it:
|
After you boot back with bcache enabled, you recreate the cache and attach it::
|
||||||
|
|
||||||
host:~# make-bcache -C /dev/sdh2
|
host:~# make-bcache -C /dev/sdh2
|
||||||
UUID: 7be7e175-8f4c-4f99-94b2-9c904d227045
|
UUID: 7be7e175-8f4c-4f99-94b2-9c904d227045
|
||||||
Set UUID: 5bc072a8-ab17-446d-9744-e247949913c1
|
Set UUID: 5bc072a8-ab17-446d-9744-e247949913c1
|
||||||
|
@ -209,15 +223,17 @@ first_bucket: 1
|
||||||
[ 650.511912] bcache: run_cache_set() invalidating existing data
|
[ 650.511912] bcache: run_cache_set() invalidating existing data
|
||||||
[ 650.549228] bcache: register_cache() registered cache device sdh2
|
[ 650.549228] bcache: register_cache() registered cache device sdh2
|
||||||
|
|
||||||
start backing device with missing cache:
|
start backing device with missing cache::
|
||||||
|
|
||||||
host:/sys/block/md5/bcache# echo 1 > running
|
host:/sys/block/md5/bcache# echo 1 > running
|
||||||
|
|
||||||
attach new cache:
|
attach new cache::
|
||||||
|
|
||||||
host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach
|
host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach
|
||||||
[ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1
|
[ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1
|
||||||
|
|
||||||
|
|
||||||
F) Remove or replace a caching device
|
F) Remove or replace a caching device::
|
||||||
|
|
||||||
host:/sys/block/sda/sda7/bcache# echo 1 > detach
|
host:/sys/block/sda/sda7/bcache# echo 1 > detach
|
||||||
[ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7
|
[ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7
|
||||||
|
@ -226,13 +242,15 @@ F) Remove or replace a caching device
|
||||||
wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy
|
wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy
|
||||||
Ooops, it's disabled, but not unregistered, so it's still protected
|
Ooops, it's disabled, but not unregistered, so it's still protected
|
||||||
|
|
||||||
We need to go and unregister it:
|
We need to go and unregister it::
|
||||||
|
|
||||||
host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0
|
host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0
|
||||||
lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/
|
lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/
|
||||||
host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop
|
host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop
|
||||||
kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered
|
kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered
|
||||||
|
|
||||||
Now we can wipe it:
|
Now we can wipe it::
|
||||||
|
|
||||||
host:~# wipefs -a /dev/nvme0n1p4
|
host:~# wipefs -a /dev/nvme0n1p4
|
||||||
/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81
|
/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81
|
||||||
|
|
||||||
|
@ -252,15 +270,18 @@ if there are any active backing or caching devices left on it:
|
||||||
|
|
||||||
1) Is it present in /dev/bcache* ? (there are times where it won't be)
|
1) Is it present in /dev/bcache* ? (there are times where it won't be)
|
||||||
|
|
||||||
If so, it's easy:
|
If so, it's easy::
|
||||||
|
|
||||||
host:/sys/block/bcache0/bcache# echo 1 > stop
|
host:/sys/block/bcache0/bcache# echo 1 > stop
|
||||||
|
|
||||||
2) But if your backing device is gone, this won't work:
|
2) But if your backing device is gone, this won't work::
|
||||||
|
|
||||||
host:/sys/block/bcache0# cd bcache
|
host:/sys/block/bcache0# cd bcache
|
||||||
bash: cd: bcache: No such file or directory
|
bash: cd: bcache: No such file or directory
|
||||||
|
|
||||||
In this case, you may have to unregister the dmcrypt block device that
|
In this case, you may have to unregister the dmcrypt block device that
|
||||||
references this bcache to free it up:
|
references this bcache to free it up::
|
||||||
|
|
||||||
host:~# dmsetup remove oldds1
|
host:~# dmsetup remove oldds1
|
||||||
bcache: bcache_device_free() bcache0 stopped
|
bcache: bcache_device_free() bcache0 stopped
|
||||||
bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered
|
bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered
|
||||||
|
@ -269,7 +290,7 @@ This causes the backing bcache to be removed from /sys/fs/bcache and
|
||||||
then it can be reused. This would be true of any block device stacking
|
then it can be reused. This would be true of any block device stacking
|
||||||
where bcache is a lower device.
|
where bcache is a lower device.
|
||||||
|
|
||||||
3) In other cases, you can also look in /sys/fs/bcache/:
|
3) In other cases, you can also look in /sys/fs/bcache/::
|
||||||
|
|
||||||
host:/sys/fs/bcache# ls -l */{cache?,bdev?}
|
host:/sys/fs/bcache# ls -l */{cache?,bdev?}
|
||||||
lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/
|
lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/
|
||||||
|
@ -277,7 +298,8 @@ lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache
|
||||||
lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdl/sdl2/bcache/
|
lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdl/sdl2/bcache/
|
||||||
|
|
||||||
The device names will show which UUID is relevant, cd in that directory
|
The device names will show which UUID is relevant, cd in that directory
|
||||||
and stop the cache:
|
and stop the cache::
|
||||||
|
|
||||||
host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop
|
host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop
|
||||||
|
|
||||||
This will free up bcache references and let you reuse the partition for
|
This will free up bcache references and let you reuse the partition for
|
||||||
|
@ -285,7 +307,7 @@ other purposes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TROUBLESHOOTING PERFORMANCE
|
Troubleshooting performance
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Bcache has a bunch of config options and tunables. The defaults are intended to
|
Bcache has a bunch of config options and tunables. The defaults are intended to
|
||||||
|
@ -301,11 +323,13 @@ want for getting the best possible numbers when benchmarking.
|
||||||
raid stripe size to get the disk multiples that you would like.
|
raid stripe size to get the disk multiples that you would like.
|
||||||
|
|
||||||
For example: If you have a 64k stripe size, then the following offset
|
For example: If you have a 64k stripe size, then the following offset
|
||||||
would provide alignment for many common RAID5 data spindle counts:
|
would provide alignment for many common RAID5 data spindle counts::
|
||||||
|
|
||||||
64k * 2*2*2*3*3*5*7 bytes = 161280k
|
64k * 2*2*2*3*3*5*7 bytes = 161280k
|
||||||
|
|
||||||
That space is wasted, but for only 157.5MB you can grow your RAID 5
|
That space is wasted, but for only 157.5MB you can grow your RAID 5
|
||||||
volume to the following data-spindle counts without re-aligning:
|
volume to the following data-spindle counts without re-aligning::
|
||||||
|
|
||||||
3,4,5,6,7,8,9,10,12,14,15,18,20,21 ...
|
3,4,5,6,7,8,9,10,12,14,15,18,20,21 ...
|
||||||
|
|
||||||
- Bad write performance
|
- Bad write performance
|
||||||
|
@ -313,7 +337,7 @@ want for getting the best possible numbers when benchmarking.
|
||||||
If write performance is not what you expected, you probably wanted to be
|
If write performance is not what you expected, you probably wanted to be
|
||||||
running in writeback mode, which isn't the default (not due to a lack of
|
running in writeback mode, which isn't the default (not due to a lack of
|
||||||
maturity, but simply because in writeback mode you'll lose data if something
|
maturity, but simply because in writeback mode you'll lose data if something
|
||||||
happens to your SSD)
|
happens to your SSD)::
|
||||||
|
|
||||||
# echo writeback > /sys/block/bcache0/bcache/cache_mode
|
# echo writeback > /sys/block/bcache0/bcache/cache_mode
|
||||||
|
|
||||||
|
@ -325,11 +349,11 @@ want for getting the best possible numbers when benchmarking.
|
||||||
accessed data out of your cache.
|
accessed data out of your cache.
|
||||||
|
|
||||||
But if you want to benchmark reads from cache, and you start out with fio
|
But if you want to benchmark reads from cache, and you start out with fio
|
||||||
writing an 8 gigabyte test file - so you want to disable that.
|
writing an 8 gigabyte test file - so you want to disable that::
|
||||||
|
|
||||||
# echo 0 > /sys/block/bcache0/bcache/sequential_cutoff
|
# echo 0 > /sys/block/bcache0/bcache/sequential_cutoff
|
||||||
|
|
||||||
To set it back to the default (4 mb), do
|
To set it back to the default (4 mb), do::
|
||||||
|
|
||||||
# echo 4M > /sys/block/bcache0/bcache/sequential_cutoff
|
# echo 4M > /sys/block/bcache0/bcache/sequential_cutoff
|
||||||
|
|
||||||
|
@ -344,7 +368,7 @@ want for getting the best possible numbers when benchmarking.
|
||||||
throttles traffic if the latency exceeds a threshold (it does this by
|
throttles traffic if the latency exceeds a threshold (it does this by
|
||||||
cranking down the sequential bypass).
|
cranking down the sequential bypass).
|
||||||
|
|
||||||
You can disable this if you need to by setting the thresholds to 0:
|
You can disable this if you need to by setting the thresholds to 0::
|
||||||
|
|
||||||
# echo 0 > /sys/fs/bcache/<cache set>/congested_read_threshold_us
|
# echo 0 > /sys/fs/bcache/<cache set>/congested_read_threshold_us
|
||||||
# echo 0 > /sys/fs/bcache/<cache set>/congested_write_threshold_us
|
# echo 0 > /sys/fs/bcache/<cache set>/congested_write_threshold_us
|
||||||
|
@ -369,7 +393,7 @@ want for getting the best possible numbers when benchmarking.
|
||||||
a fix for the issue there).
|
a fix for the issue there).
|
||||||
|
|
||||||
|
|
||||||
SYSFS - BACKING DEVICE
|
Sysfs - backing device
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Available at /sys/block/<bdev>/bcache, /sys/block/bcache*/bcache and
|
Available at /sys/block/<bdev>/bcache, /sys/block/bcache*/bcache and
|
||||||
|
@ -454,7 +478,8 @@ writeback_running
|
||||||
still be added to the cache until it is mostly full; only meant for
|
still be added to the cache until it is mostly full; only meant for
|
||||||
benchmarking. Defaults to on.
|
benchmarking. Defaults to on.
|
||||||
|
|
||||||
SYSFS - BACKING DEVICE STATS:
|
Sysfs - backing device stats
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
There are directories with these numbers for a running total, as well as
|
There are directories with these numbers for a running total, as well as
|
||||||
versions that decay over the past day, hour and 5 minutes; they're also
|
versions that decay over the past day, hour and 5 minutes; they're also
|
||||||
|
@ -463,14 +488,11 @@ aggregated in the cache set directory as well.
|
||||||
bypassed
|
bypassed
|
||||||
Amount of IO (both reads and writes) that has bypassed the cache
|
Amount of IO (both reads and writes) that has bypassed the cache
|
||||||
|
|
||||||
cache_hits
|
cache_hits, cache_misses, cache_hit_ratio
|
||||||
cache_misses
|
|
||||||
cache_hit_ratio
|
|
||||||
Hits and misses are counted per individual IO as bcache sees them; a
|
Hits and misses are counted per individual IO as bcache sees them; a
|
||||||
partial hit is counted as a miss.
|
partial hit is counted as a miss.
|
||||||
|
|
||||||
cache_bypass_hits
|
cache_bypass_hits, cache_bypass_misses
|
||||||
cache_bypass_misses
|
|
||||||
Hits and misses for IO that is intended to skip the cache are still counted,
|
Hits and misses for IO that is intended to skip the cache are still counted,
|
||||||
but broken out here.
|
but broken out here.
|
||||||
|
|
||||||
|
@ -482,7 +504,8 @@ cache_miss_collisions
|
||||||
cache_readaheads
|
cache_readaheads
|
||||||
Count of times readahead occurred.
|
Count of times readahead occurred.
|
||||||
|
|
||||||
SYSFS - CACHE SET:
|
Sysfs - cache set
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Available at /sys/fs/bcache/<cset-uuid>
|
Available at /sys/fs/bcache/<cset-uuid>
|
||||||
|
|
||||||
|
@ -520,8 +543,7 @@ flash_vol_create
|
||||||
Echoing a size to this file (in human readable units, k/M/G) creates a thinly
|
Echoing a size to this file (in human readable units, k/M/G) creates a thinly
|
||||||
provisioned volume backed by the cache set.
|
provisioned volume backed by the cache set.
|
||||||
|
|
||||||
io_error_halflife
|
io_error_halflife, io_error_limit
|
||||||
io_error_limit
|
|
||||||
These determines how many errors we accept before disabling the cache.
|
These determines how many errors we accept before disabling the cache.
|
||||||
Each error is decayed by the half life (in # ios). If the decaying count
|
Each error is decayed by the half life (in # ios). If the decaying count
|
||||||
reaches io_error_limit dirty data is written out and the cache is disabled.
|
reaches io_error_limit dirty data is written out and the cache is disabled.
|
||||||
|
@ -545,7 +567,8 @@ unregister
|
||||||
Detaches all backing devices and closes the cache devices; if dirty data is
|
Detaches all backing devices and closes the cache devices; if dirty data is
|
||||||
present it will disable writeback caching and wait for it to be flushed.
|
present it will disable writeback caching and wait for it to be flushed.
|
||||||
|
|
||||||
SYSFS - CACHE SET INTERNAL:
|
Sysfs - cache set internal
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
This directory also exposes timings for a number of internal operations, with
|
This directory also exposes timings for a number of internal operations, with
|
||||||
separate files for average duration, average frequency, last occurrence and max
|
separate files for average duration, average frequency, last occurrence and max
|
||||||
|
@ -574,7 +597,8 @@ cache_read_races
|
||||||
trigger_gc
|
trigger_gc
|
||||||
Writing to this file forces garbage collection to run.
|
Writing to this file forces garbage collection to run.
|
||||||
|
|
||||||
SYSFS - CACHE DEVICE:
|
Sysfs - Cache device
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Available at /sys/block/<cdev>/bcache
|
Available at /sys/block/<cdev>/bcache
|
||||||
|
|
||||||
|
|
|
@ -632,7 +632,7 @@ to i/o submission, if the bio fields are likely to be accessed after the
|
||||||
i/o is issued (since the bio may otherwise get freed in case i/o completion
|
i/o is issued (since the bio may otherwise get freed in case i/o completion
|
||||||
happens in the meantime).
|
happens in the meantime).
|
||||||
|
|
||||||
The bio_clone() routine may be used to duplicate a bio, where the clone
|
The bio_clone_fast() routine may be used to duplicate a bio, where the clone
|
||||||
shares the bio_vec_list with the original bio (i.e. both point to the
|
shares the bio_vec_list with the original bio (i.e. both point to the
|
||||||
same bio_vec_list). This would typically be used for splitting i/o requests
|
same bio_vec_list). This would typically be used for splitting i/o requests
|
||||||
in lvm or md.
|
in lvm or md.
|
||||||
|
|
|
@ -192,7 +192,7 @@ will require extra work due to the application tag.
|
||||||
supported by the block device.
|
supported by the block device.
|
||||||
|
|
||||||
|
|
||||||
int bio_integrity_prep(bio);
|
bool bio_integrity_prep(bio);
|
||||||
|
|
||||||
To generate IMD for WRITE and to set up buffers for READ, the
|
To generate IMD for WRITE and to set up buffers for READ, the
|
||||||
filesystem must call bio_integrity_prep(bio).
|
filesystem must call bio_integrity_prep(bio).
|
||||||
|
@ -201,9 +201,7 @@ will require extra work due to the application tag.
|
||||||
sector must be set, and the bio should have all data pages
|
sector must be set, and the bio should have all data pages
|
||||||
added. It is up to the caller to ensure that the bio does not
|
added. It is up to the caller to ensure that the bio does not
|
||||||
change while I/O is in progress.
|
change while I/O is in progress.
|
||||||
|
Complete bio with error if prepare failed for some reson.
|
||||||
bio_integrity_prep() should only be called if
|
|
||||||
bio_integrity_enabled() returned 1.
|
|
||||||
|
|
||||||
|
|
||||||
5.3 PASSING EXISTING INTEGRITY METADATA
|
5.3 PASSING EXISTING INTEGRITY METADATA
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
===============================================================
|
===================================================================
|
||||||
== BT8XXGPIO driver ==
|
A driver for a selfmade cheap BT8xx based PCI GPIO-card (bt8xxgpio)
|
||||||
== ==
|
===================================================================
|
||||||
== A driver for a selfmade cheap BT8xx based PCI GPIO-card ==
|
|
||||||
== ==
|
|
||||||
== For advanced documentation, see ==
|
|
||||||
== http://www.bu3sch.de/btgpio.php ==
|
|
||||||
===============================================================
|
|
||||||
|
|
||||||
|
For advanced documentation, see http://www.bu3sch.de/btgpio.php
|
||||||
|
|
||||||
A generic digital 24-port PCI GPIO card can be built out of an ordinary
|
A generic digital 24-port PCI GPIO card can be built out of an ordinary
|
||||||
Brooktree bt848, bt849, bt878 or bt879 based analog TV tuner card. The
|
Brooktree bt848, bt849, bt878 or bt879 based analog TV tuner card. The
|
||||||
|
@ -17,9 +13,8 @@ The bt8xx chip does have 24 digital GPIO ports.
|
||||||
These ports are accessible via 24 pins on the SMD chip package.
|
These ports are accessible via 24 pins on the SMD chip package.
|
||||||
|
|
||||||
|
|
||||||
==============================================
|
How to physically access the GPIO pins
|
||||||
== How to physically access the GPIO pins ==
|
======================================
|
||||||
==============================================
|
|
||||||
|
|
||||||
The are several ways to access these pins. One might unsolder the whole chip
|
The are several ways to access these pins. One might unsolder the whole chip
|
||||||
and put it on a custom PCI board, or one might only unsolder each individual
|
and put it on a custom PCI board, or one might only unsolder each individual
|
||||||
|
@ -27,7 +22,7 @@ GPIO pin and solder that to some tiny wire. As the chip package really is tiny
|
||||||
there are some advanced soldering skills needed in any case.
|
there are some advanced soldering skills needed in any case.
|
||||||
|
|
||||||
The physical pinouts are drawn in the following ASCII art.
|
The physical pinouts are drawn in the following ASCII art.
|
||||||
The GPIO pins are marked with G00-G23
|
The GPIO pins are marked with G00-G23::
|
||||||
|
|
||||||
G G G G G G G G G G G G G G G G G G
|
G G G G G G G G G G G G G G G G G G
|
||||||
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
|
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
=======================================================================
|
=============
|
||||||
README for btmrvl driver
|
btmrvl driver
|
||||||
=======================================================================
|
=============
|
||||||
|
|
||||||
|
|
||||||
All commands are used via debugfs interface.
|
All commands are used via debugfs interface.
|
||||||
|
|
||||||
=====================
|
Set/get driver configurations
|
||||||
Set/get driver configurations:
|
=============================
|
||||||
|
|
||||||
Path: /debug/btmrvl/config/
|
Path: /debug/btmrvl/config/
|
||||||
|
|
||||||
gpiogap=[n]
|
gpiogap=[n], hscfgcmd
|
||||||
hscfgcmd
|
These commands are used to configure the host sleep parameters::
|
||||||
These commands are used to configure the host sleep parameters.
|
|
||||||
bit 8:0 -- Gap
|
bit 8:0 -- Gap
|
||||||
bit 16:8 -- GPIO
|
bit 16:8 -- GPIO
|
||||||
|
|
||||||
|
@ -23,7 +21,8 @@ hscfgcmd
|
||||||
where Gap is the gap in milli seconds between wakeup signal and
|
where Gap is the gap in milli seconds between wakeup signal and
|
||||||
wakeup event, or 0xff for special host sleep setting.
|
wakeup event, or 0xff for special host sleep setting.
|
||||||
|
|
||||||
Usage:
|
Usage::
|
||||||
|
|
||||||
# Use SDIO interface to wake up the host and set GAP to 0x80:
|
# Use SDIO interface to wake up the host and set GAP to 0x80:
|
||||||
echo 0xff80 > /debug/btmrvl/config/gpiogap
|
echo 0xff80 > /debug/btmrvl/config/gpiogap
|
||||||
echo 1 > /debug/btmrvl/config/hscfgcmd
|
echo 1 > /debug/btmrvl/config/hscfgcmd
|
||||||
|
@ -32,15 +31,16 @@ hscfgcmd
|
||||||
echo 0x03ff > /debug/btmrvl/config/gpiogap
|
echo 0x03ff > /debug/btmrvl/config/gpiogap
|
||||||
echo 1 > /debug/btmrvl/config/hscfgcmd
|
echo 1 > /debug/btmrvl/config/hscfgcmd
|
||||||
|
|
||||||
psmode=[n]
|
psmode=[n], pscmd
|
||||||
pscmd
|
|
||||||
These commands are used to enable/disable auto sleep mode
|
These commands are used to enable/disable auto sleep mode
|
||||||
|
|
||||||
where the option is:
|
where the option is::
|
||||||
|
|
||||||
1 -- Enable auto sleep mode
|
1 -- Enable auto sleep mode
|
||||||
0 -- Disable auto sleep mode
|
0 -- Disable auto sleep mode
|
||||||
|
|
||||||
Usage:
|
Usage::
|
||||||
|
|
||||||
# Enable auto sleep mode
|
# Enable auto sleep mode
|
||||||
echo 1 > /debug/btmrvl/config/psmode
|
echo 1 > /debug/btmrvl/config/psmode
|
||||||
echo 1 > /debug/btmrvl/config/pscmd
|
echo 1 > /debug/btmrvl/config/pscmd
|
||||||
|
@ -50,15 +50,16 @@ pscmd
|
||||||
echo 1 > /debug/btmrvl/config/pscmd
|
echo 1 > /debug/btmrvl/config/pscmd
|
||||||
|
|
||||||
|
|
||||||
hsmode=[n]
|
hsmode=[n], hscmd
|
||||||
hscmd
|
|
||||||
These commands are used to enable host sleep or wake up firmware
|
These commands are used to enable host sleep or wake up firmware
|
||||||
|
|
||||||
where the option is:
|
where the option is::
|
||||||
|
|
||||||
1 -- Enable host sleep
|
1 -- Enable host sleep
|
||||||
0 -- Wake up firmware
|
0 -- Wake up firmware
|
||||||
|
|
||||||
Usage:
|
Usage::
|
||||||
|
|
||||||
# Enable host sleep
|
# Enable host sleep
|
||||||
echo 1 > /debug/btmrvl/config/hsmode
|
echo 1 > /debug/btmrvl/config/hsmode
|
||||||
echo 1 > /debug/btmrvl/config/hscmd
|
echo 1 > /debug/btmrvl/config/hscmd
|
||||||
|
@ -68,12 +69,13 @@ hscmd
|
||||||
echo 1 > /debug/btmrvl/config/hscmd
|
echo 1 > /debug/btmrvl/config/hscmd
|
||||||
|
|
||||||
|
|
||||||
======================
|
Get driver status
|
||||||
Get driver status:
|
=================
|
||||||
|
|
||||||
Path: /debug/btmrvl/status/
|
Path: /debug/btmrvl/status/
|
||||||
|
|
||||||
Usage:
|
Usage::
|
||||||
|
|
||||||
cat /debug/btmrvl/status/<args>
|
cat /debug/btmrvl/status/<args>
|
||||||
|
|
||||||
where the args are:
|
where the args are:
|
||||||
|
@ -90,14 +92,17 @@ hsstate
|
||||||
txdnldrdy
|
txdnldrdy
|
||||||
This command displays the value of Tx download ready flag.
|
This command displays the value of Tx download ready flag.
|
||||||
|
|
||||||
|
Issuing a raw hci command
|
||||||
=====================
|
=========================
|
||||||
|
|
||||||
Use hcitool to issue raw hci command, refer to hcitool manual
|
Use hcitool to issue raw hci command, refer to hcitool manual
|
||||||
|
|
||||||
Usage: Hcitool cmd <ogf> <ocf> [Parameters]
|
Usage::
|
||||||
|
|
||||||
|
Hcitool cmd <ogf> <ocf> [Parameters]
|
||||||
|
|
||||||
|
Interface Control Command::
|
||||||
|
|
||||||
Interface Control Command
|
|
||||||
hcitool cmd 0x3f 0x5b 0xf5 0x01 0x00 --Enable All interface
|
hcitool cmd 0x3f 0x5b 0xf5 0x01 0x00 --Enable All interface
|
||||||
hcitool cmd 0x3f 0x5b 0xf5 0x01 0x01 --Enable Wlan interface
|
hcitool cmd 0x3f 0x5b 0xf5 0x01 0x01 --Enable Wlan interface
|
||||||
hcitool cmd 0x3f 0x5b 0xf5 0x01 0x02 --Enable BT interface
|
hcitool cmd 0x3f 0x5b 0xf5 0x01 0x02 --Enable BT interface
|
||||||
|
@ -105,13 +110,13 @@ Use hcitool to issue raw hci command, refer to hcitool manual
|
||||||
hcitool cmd 0x3f 0x5b 0xf5 0x00 0x01 --Disable Wlan interface
|
hcitool cmd 0x3f 0x5b 0xf5 0x00 0x01 --Disable Wlan interface
|
||||||
hcitool cmd 0x3f 0x5b 0xf5 0x00 0x02 --Disable BT interface
|
hcitool cmd 0x3f 0x5b 0xf5 0x00 0x02 --Disable BT interface
|
||||||
|
|
||||||
=======================================================================
|
SD8688 firmware
|
||||||
|
===============
|
||||||
|
|
||||||
|
Images:
|
||||||
|
|
||||||
SD8688 firmware:
|
- /lib/firmware/sd8688_helper.bin
|
||||||
|
- /lib/firmware/sd8688.bin
|
||||||
/lib/firmware/sd8688_helper.bin
|
|
||||||
/lib/firmware/sd8688.bin
|
|
||||||
|
|
||||||
|
|
||||||
The images can be downloaded from:
|
The images can be downloaded from:
|
||||||
|
|
|
@ -1,8 +1,18 @@
|
||||||
[ NOTE: The virt_to_bus() and bus_to_virt() functions have been
|
==========================================================
|
||||||
|
How to access I/O mapped memory from within device drivers
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
:Author: Linus
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The virt_to_bus() and bus_to_virt() functions have been
|
||||||
superseded by the functionality provided by the PCI DMA interface
|
superseded by the functionality provided by the PCI DMA interface
|
||||||
(see Documentation/DMA-API-HOWTO.txt). They continue
|
(see Documentation/DMA-API-HOWTO.txt). They continue
|
||||||
to be documented below for historical purposes, but new code
|
to be documented below for historical purposes, but new code
|
||||||
must not use them. --davidm 00/12/12 ]
|
must not use them. --davidm 00/12/12
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
[ This is a mail message in response to a query on IO mapping, thus the
|
[ This is a mail message in response to a query on IO mapping, thus the
|
||||||
strange format for a "document" ]
|
strange format for a "document" ]
|
||||||
|
@ -11,7 +21,7 @@ The AHA-1542 is a bus-master device, and your patch makes the driver give the
|
||||||
controller the physical address of the buffers, which is correct on x86
|
controller the physical address of the buffers, which is correct on x86
|
||||||
(because all bus master devices see the physical memory mappings directly).
|
(because all bus master devices see the physical memory mappings directly).
|
||||||
|
|
||||||
However, on many setups, there are actually _three_ different ways of looking
|
However, on many setups, there are actually **three** different ways of looking
|
||||||
at memory addresses, and in this case we actually want the third, the
|
at memory addresses, and in this case we actually want the third, the
|
||||||
so-called "bus address".
|
so-called "bus address".
|
||||||
|
|
||||||
|
@ -38,7 +48,7 @@ because the memory and the devices share the same address space, and that is
|
||||||
not generally necessarily true on other PCI/ISA setups.
|
not generally necessarily true on other PCI/ISA setups.
|
||||||
|
|
||||||
Now, just as an example, on the PReP (PowerPC Reference Platform), the
|
Now, just as an example, on the PReP (PowerPC Reference Platform), the
|
||||||
CPU sees a memory map something like this (this is from memory):
|
CPU sees a memory map something like this (this is from memory)::
|
||||||
|
|
||||||
0-2 GB "real memory"
|
0-2 GB "real memory"
|
||||||
2 GB-3 GB "system IO" (inb/out and similar accesses on x86)
|
2 GB-3 GB "system IO" (inb/out and similar accesses on x86)
|
||||||
|
@ -52,7 +62,7 @@ So when the CPU wants any bus master to write to physical memory 0, it
|
||||||
has to give the master address 0x80000000 as the memory address.
|
has to give the master address 0x80000000 as the memory address.
|
||||||
|
|
||||||
So, for example, depending on how the kernel is actually mapped on the
|
So, for example, depending on how the kernel is actually mapped on the
|
||||||
PPC, you can end up with a setup like this:
|
PPC, you can end up with a setup like this::
|
||||||
|
|
||||||
physical address: 0
|
physical address: 0
|
||||||
virtual address: 0xC0000000
|
virtual address: 0xC0000000
|
||||||
|
@ -61,7 +71,7 @@ PPC, you can end up with a setup like this:
|
||||||
where all the addresses actually point to the same thing. It's just seen
|
where all the addresses actually point to the same thing. It's just seen
|
||||||
through different translations..
|
through different translations..
|
||||||
|
|
||||||
Similarly, on the Alpha, the normal translation is
|
Similarly, on the Alpha, the normal translation is::
|
||||||
|
|
||||||
physical address: 0
|
physical address: 0
|
||||||
virtual address: 0xfffffc0000000000
|
virtual address: 0xfffffc0000000000
|
||||||
|
@ -70,7 +80,7 @@ Similarly, on the Alpha, the normal translation is
|
||||||
(but there are also Alphas where the physical address and the bus address
|
(but there are also Alphas where the physical address and the bus address
|
||||||
are the same).
|
are the same).
|
||||||
|
|
||||||
Anyway, the way to look up all these translations, you do
|
Anyway, the way to look up all these translations, you do::
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
@ -81,8 +91,8 @@ Anyway, the way to look up all these translations, you do
|
||||||
|
|
||||||
Now, when do you need these?
|
Now, when do you need these?
|
||||||
|
|
||||||
You want the _virtual_ address when you are actually going to access that
|
You want the **virtual** address when you are actually going to access that
|
||||||
pointer from the kernel. So you can have something like this:
|
pointer from the kernel. So you can have something like this::
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is the hardware "mailbox" we use to communicate with
|
* this is the hardware "mailbox" we use to communicate with
|
||||||
|
@ -104,7 +114,7 @@ pointer from the kernel. So you can have something like this:
|
||||||
...
|
...
|
||||||
|
|
||||||
on the other hand, you want the bus address when you have a buffer that
|
on the other hand, you want the bus address when you have a buffer that
|
||||||
you want to give to the controller:
|
you want to give to the controller::
|
||||||
|
|
||||||
/* ask the controller to read the sense status into "sense_buffer" */
|
/* ask the controller to read the sense status into "sense_buffer" */
|
||||||
mbox.bufstart = virt_to_bus(&sense_buffer);
|
mbox.bufstart = virt_to_bus(&sense_buffer);
|
||||||
|
@ -112,7 +122,7 @@ you want to give to the controller:
|
||||||
mbox.status = 0;
|
mbox.status = 0;
|
||||||
notify_controller(&mbox);
|
notify_controller(&mbox);
|
||||||
|
|
||||||
And you generally _never_ want to use the physical address, because you can't
|
And you generally **never** want to use the physical address, because you can't
|
||||||
use that from the CPU (the CPU only uses translated virtual addresses), and
|
use that from the CPU (the CPU only uses translated virtual addresses), and
|
||||||
you can't use it from the bus master.
|
you can't use it from the bus master.
|
||||||
|
|
||||||
|
@ -124,7 +134,9 @@ be remapped as measured in units of pages, a.k.a. the pfn (the memory
|
||||||
management layer doesn't know about devices outside the CPU, so it
|
management layer doesn't know about devices outside the CPU, so it
|
||||||
shouldn't need to know about "bus addresses" etc).
|
shouldn't need to know about "bus addresses" etc).
|
||||||
|
|
||||||
NOTE NOTE NOTE! The above is only one part of the whole equation. The above
|
.. note::
|
||||||
|
|
||||||
|
The above is only one part of the whole equation. The above
|
||||||
only talks about "real memory", that is, CPU memory (RAM).
|
only talks about "real memory", that is, CPU memory (RAM).
|
||||||
|
|
||||||
There is a completely different type of memory too, and that's the "shared
|
There is a completely different type of memory too, and that's the "shared
|
||||||
|
@ -137,20 +149,22 @@ whatever, and there is only one way to access it: the readb/writeb and
|
||||||
related functions. You should never take the address of such memory, because
|
related functions. You should never take the address of such memory, because
|
||||||
there is really nothing you can do with such an address: it's not
|
there is really nothing you can do with such an address: it's not
|
||||||
conceptually in the same memory space as "real memory" at all, so you cannot
|
conceptually in the same memory space as "real memory" at all, so you cannot
|
||||||
just dereference a pointer. (Sadly, on x86 it _is_ in the same memory space,
|
just dereference a pointer. (Sadly, on x86 it **is** in the same memory space,
|
||||||
so on x86 it actually works to just deference a pointer, but it's not
|
so on x86 it actually works to just deference a pointer, but it's not
|
||||||
portable).
|
portable).
|
||||||
|
|
||||||
For such memory, you can do things like
|
For such memory, you can do things like:
|
||||||
|
|
||||||
|
- reading::
|
||||||
|
|
||||||
- reading:
|
|
||||||
/*
|
/*
|
||||||
* read first 32 bits from ISA memory at 0xC0000, aka
|
* read first 32 bits from ISA memory at 0xC0000, aka
|
||||||
* C000:0000 in DOS terms
|
* C000:0000 in DOS terms
|
||||||
*/
|
*/
|
||||||
unsigned int signature = isa_readl(0xC0000);
|
unsigned int signature = isa_readl(0xC0000);
|
||||||
|
|
||||||
- remapping and writing:
|
- remapping and writing::
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remap framebuffer PCI memory area at 0xFC000000,
|
* remap framebuffer PCI memory area at 0xFC000000,
|
||||||
* size 1MB, so that we can access it: We can directly
|
* size 1MB, so that we can access it: We can directly
|
||||||
|
@ -165,7 +179,8 @@ For such memory, you can do things like
|
||||||
/* unmap when we unload the driver */
|
/* unmap when we unload the driver */
|
||||||
iounmap(baseptr);
|
iounmap(baseptr);
|
||||||
|
|
||||||
- copying and clearing:
|
- copying and clearing::
|
||||||
|
|
||||||
/* get the 6-byte Ethernet address at ISA address E000:0040 */
|
/* get the 6-byte Ethernet address at ISA address E000:0040 */
|
||||||
memcpy_fromio(kernel_buffer, 0xE0040, 6);
|
memcpy_fromio(kernel_buffer, 0xE0040, 6);
|
||||||
/* write a packet to the driver */
|
/* write a packet to the driver */
|
||||||
|
@ -181,7 +196,7 @@ happy that your driver works ;)
|
||||||
Note that kernel versions 2.0.x (and earlier) mistakenly called the
|
Note that kernel versions 2.0.x (and earlier) mistakenly called the
|
||||||
ioremap() function "vremap()". ioremap() is the proper name, but I
|
ioremap() function "vremap()". ioremap() is the proper name, but I
|
||||||
didn't think straight when I wrote it originally. People who have to
|
didn't think straight when I wrote it originally. People who have to
|
||||||
support both can do something like:
|
support both can do something like::
|
||||||
|
|
||||||
/* support old naming silliness */
|
/* support old naming silliness */
|
||||||
#if LINUX_VERSION_CODE < 0x020100
|
#if LINUX_VERSION_CODE < 0x020100
|
||||||
|
@ -196,13 +211,10 @@ And the above sounds worse than it really is. Most real drivers really
|
||||||
don't do all that complex things (or rather: the complexity is not so
|
don't do all that complex things (or rather: the complexity is not so
|
||||||
much in the actual IO accesses as in error handling and timeouts etc).
|
much in the actual IO accesses as in error handling and timeouts etc).
|
||||||
It's generally not hard to fix drivers, and in many cases the code
|
It's generally not hard to fix drivers, and in many cases the code
|
||||||
actually looks better afterwards:
|
actually looks better afterwards::
|
||||||
|
|
||||||
unsigned long signature = *(unsigned int *) 0xC0000;
|
unsigned long signature = *(unsigned int *) 0xC0000;
|
||||||
vs
|
vs
|
||||||
unsigned long signature = readl(0xC0000);
|
unsigned long signature = readl(0xC0000);
|
||||||
|
|
||||||
I think the second version actually is more readable, no?
|
I think the second version actually is more readable, no?
|
||||||
|
|
||||||
Linus
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
Cache and TLB Flushing
|
==================================
|
||||||
Under Linux
|
Cache and TLB Flushing Under Linux
|
||||||
|
==================================
|
||||||
|
|
||||||
David S. Miller <davem@redhat.com>
|
:Author: David S. Miller <davem@redhat.com>
|
||||||
|
|
||||||
This document describes the cache/tlb flushing interfaces called
|
This document describes the cache/tlb flushing interfaces called
|
||||||
by the Linux VM subsystem. It enumerates over each interface,
|
by the Linux VM subsystem. It enumerates over each interface,
|
||||||
|
@ -28,7 +29,7 @@ Therefore when software page table changes occur, the kernel will
|
||||||
invoke one of the following flush methods _after_ the page table
|
invoke one of the following flush methods _after_ the page table
|
||||||
changes occur:
|
changes occur:
|
||||||
|
|
||||||
1) void flush_tlb_all(void)
|
1) ``void flush_tlb_all(void)``
|
||||||
|
|
||||||
The most severe flush of all. After this interface runs,
|
The most severe flush of all. After this interface runs,
|
||||||
any previous page table modification whatsoever will be
|
any previous page table modification whatsoever will be
|
||||||
|
@ -37,7 +38,7 @@ changes occur:
|
||||||
This is usually invoked when the kernel page tables are
|
This is usually invoked when the kernel page tables are
|
||||||
changed, since such translations are "global" in nature.
|
changed, since such translations are "global" in nature.
|
||||||
|
|
||||||
2) void flush_tlb_mm(struct mm_struct *mm)
|
2) ``void flush_tlb_mm(struct mm_struct *mm)``
|
||||||
|
|
||||||
This interface flushes an entire user address space from
|
This interface flushes an entire user address space from
|
||||||
the TLB. After running, this interface must make sure that
|
the TLB. After running, this interface must make sure that
|
||||||
|
@ -49,8 +50,8 @@ changes occur:
|
||||||
page table operations such as what happens during
|
page table operations such as what happens during
|
||||||
fork, and exec.
|
fork, and exec.
|
||||||
|
|
||||||
3) void flush_tlb_range(struct vm_area_struct *vma,
|
3) ``void flush_tlb_range(struct vm_area_struct *vma,
|
||||||
unsigned long start, unsigned long end)
|
unsigned long start, unsigned long end)``
|
||||||
|
|
||||||
Here we are flushing a specific range of (user) virtual
|
Here we are flushing a specific range of (user) virtual
|
||||||
address translations from the TLB. After running, this
|
address translations from the TLB. After running, this
|
||||||
|
@ -69,7 +70,7 @@ changes occur:
|
||||||
call flush_tlb_page (see below) for each entry which may be
|
call flush_tlb_page (see below) for each entry which may be
|
||||||
modified.
|
modified.
|
||||||
|
|
||||||
4) void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
|
4) ``void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)``
|
||||||
|
|
||||||
This time we need to remove the PAGE_SIZE sized translation
|
This time we need to remove the PAGE_SIZE sized translation
|
||||||
from the TLB. The 'vma' is the backing structure used by
|
from the TLB. The 'vma' is the backing structure used by
|
||||||
|
@ -87,8 +88,8 @@ changes occur:
|
||||||
|
|
||||||
This is used primarily during fault processing.
|
This is used primarily during fault processing.
|
||||||
|
|
||||||
5) void update_mmu_cache(struct vm_area_struct *vma,
|
5) ``void update_mmu_cache(struct vm_area_struct *vma,
|
||||||
unsigned long address, pte_t *ptep)
|
unsigned long address, pte_t *ptep)``
|
||||||
|
|
||||||
At the end of every page fault, this routine is invoked to
|
At the end of every page fault, this routine is invoked to
|
||||||
tell the architecture specific code that a translation
|
tell the architecture specific code that a translation
|
||||||
|
@ -100,7 +101,7 @@ changes occur:
|
||||||
translations for software managed TLB configurations.
|
translations for software managed TLB configurations.
|
||||||
The sparc64 port currently does this.
|
The sparc64 port currently does this.
|
||||||
|
|
||||||
6) void tlb_migrate_finish(struct mm_struct *mm)
|
6) ``void tlb_migrate_finish(struct mm_struct *mm)``
|
||||||
|
|
||||||
This interface is called at the end of an explicit
|
This interface is called at the end of an explicit
|
||||||
process migration. This interface provides a hook
|
process migration. This interface provides a hook
|
||||||
|
@ -112,7 +113,7 @@ changes occur:
|
||||||
|
|
||||||
Next, we have the cache flushing interfaces. In general, when Linux
|
Next, we have the cache flushing interfaces. In general, when Linux
|
||||||
is changing an existing virtual-->physical mapping to a new value,
|
is changing an existing virtual-->physical mapping to a new value,
|
||||||
the sequence will be in one of the following forms:
|
the sequence will be in one of the following forms::
|
||||||
|
|
||||||
1) flush_cache_mm(mm);
|
1) flush_cache_mm(mm);
|
||||||
change_all_page_tables_of(mm);
|
change_all_page_tables_of(mm);
|
||||||
|
@ -143,7 +144,7 @@ and have no dependency on translation information.
|
||||||
|
|
||||||
Here are the routines, one by one:
|
Here are the routines, one by one:
|
||||||
|
|
||||||
1) void flush_cache_mm(struct mm_struct *mm)
|
1) ``void flush_cache_mm(struct mm_struct *mm)``
|
||||||
|
|
||||||
This interface flushes an entire user address space from
|
This interface flushes an entire user address space from
|
||||||
the caches. That is, after running, there will be no cache
|
the caches. That is, after running, there will be no cache
|
||||||
|
@ -152,7 +153,7 @@ Here are the routines, one by one:
|
||||||
This interface is used to handle whole address space
|
This interface is used to handle whole address space
|
||||||
page table operations such as what happens during exit and exec.
|
page table operations such as what happens during exit and exec.
|
||||||
|
|
||||||
2) void flush_cache_dup_mm(struct mm_struct *mm)
|
2) ``void flush_cache_dup_mm(struct mm_struct *mm)``
|
||||||
|
|
||||||
This interface flushes an entire user address space from
|
This interface flushes an entire user address space from
|
||||||
the caches. That is, after running, there will be no cache
|
the caches. That is, after running, there will be no cache
|
||||||
|
@ -164,8 +165,8 @@ Here are the routines, one by one:
|
||||||
This option is separate from flush_cache_mm to allow some
|
This option is separate from flush_cache_mm to allow some
|
||||||
optimizations for VIPT caches.
|
optimizations for VIPT caches.
|
||||||
|
|
||||||
3) void flush_cache_range(struct vm_area_struct *vma,
|
3) ``void flush_cache_range(struct vm_area_struct *vma,
|
||||||
unsigned long start, unsigned long end)
|
unsigned long start, unsigned long end)``
|
||||||
|
|
||||||
Here we are flushing a specific range of (user) virtual
|
Here we are flushing a specific range of (user) virtual
|
||||||
addresses from the cache. After running, there will be no
|
addresses from the cache. After running, there will be no
|
||||||
|
@ -181,7 +182,7 @@ Here are the routines, one by one:
|
||||||
call flush_cache_page (see below) for each entry which may be
|
call flush_cache_page (see below) for each entry which may be
|
||||||
modified.
|
modified.
|
||||||
|
|
||||||
4) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
|
4) ``void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)``
|
||||||
|
|
||||||
This time we need to remove a PAGE_SIZE sized range
|
This time we need to remove a PAGE_SIZE sized range
|
||||||
from the cache. The 'vma' is the backing structure used by
|
from the cache. The 'vma' is the backing structure used by
|
||||||
|
@ -202,7 +203,7 @@ Here are the routines, one by one:
|
||||||
|
|
||||||
This is used primarily during fault processing.
|
This is used primarily during fault processing.
|
||||||
|
|
||||||
5) void flush_cache_kmaps(void)
|
5) ``void flush_cache_kmaps(void)``
|
||||||
|
|
||||||
This routine need only be implemented if the platform utilizes
|
This routine need only be implemented if the platform utilizes
|
||||||
highmem. It will be called right before all of the kmaps
|
highmem. It will be called right before all of the kmaps
|
||||||
|
@ -214,8 +215,8 @@ Here are the routines, one by one:
|
||||||
|
|
||||||
This routing should be implemented in asm/highmem.h
|
This routing should be implemented in asm/highmem.h
|
||||||
|
|
||||||
6) void flush_cache_vmap(unsigned long start, unsigned long end)
|
6) ``void flush_cache_vmap(unsigned long start, unsigned long end)``
|
||||||
void flush_cache_vunmap(unsigned long start, unsigned long end)
|
``void flush_cache_vunmap(unsigned long start, unsigned long end)``
|
||||||
|
|
||||||
Here in these two interfaces we are flushing a specific range
|
Here in these two interfaces we are flushing a specific range
|
||||||
of (kernel) virtual addresses from the cache. After running,
|
of (kernel) virtual addresses from the cache. After running,
|
||||||
|
@ -243,7 +244,9 @@ size). This setting will force the SYSv IPC layer to only allow user
|
||||||
processes to mmap shared memory at address which are a multiple of
|
processes to mmap shared memory at address which are a multiple of
|
||||||
this value.
|
this value.
|
||||||
|
|
||||||
NOTE: This does not fix shared mmaps, check out the sparc64 port for
|
.. note::
|
||||||
|
|
||||||
|
This does not fix shared mmaps, check out the sparc64 port for
|
||||||
one way to solve this (in particular SPARC_FLAG_MMAPSHARED).
|
one way to solve this (in particular SPARC_FLAG_MMAPSHARED).
|
||||||
|
|
||||||
Next, you have to solve the D-cache aliasing issue for all
|
Next, you have to solve the D-cache aliasing issue for all
|
||||||
|
@ -255,8 +258,8 @@ physical page into its address space, by implication the D-cache
|
||||||
aliasing problem has the potential to exist since the kernel already
|
aliasing problem has the potential to exist since the kernel already
|
||||||
maps this page at its virtual address.
|
maps this page at its virtual address.
|
||||||
|
|
||||||
void copy_user_page(void *to, void *from, unsigned long addr, struct page *page)
|
``void copy_user_page(void *to, void *from, unsigned long addr, struct page *page)``
|
||||||
void clear_user_page(void *to, unsigned long addr, struct page *page)
|
``void clear_user_page(void *to, unsigned long addr, struct page *page)``
|
||||||
|
|
||||||
These two routines store data in user anonymous or COW
|
These two routines store data in user anonymous or COW
|
||||||
pages. It allows a port to efficiently avoid D-cache alias
|
pages. It allows a port to efficiently avoid D-cache alias
|
||||||
|
@ -276,14 +279,16 @@ maps this page at its virtual address.
|
||||||
If D-cache aliasing is not an issue, these two routines may
|
If D-cache aliasing is not an issue, these two routines may
|
||||||
simply call memcpy/memset directly and do nothing more.
|
simply call memcpy/memset directly and do nothing more.
|
||||||
|
|
||||||
void flush_dcache_page(struct page *page)
|
``void flush_dcache_page(struct page *page)``
|
||||||
|
|
||||||
Any time the kernel writes to a page cache page, _OR_
|
Any time the kernel writes to a page cache page, _OR_
|
||||||
the kernel is about to read from a page cache page and
|
the kernel is about to read from a page cache page and
|
||||||
user space shared/writable mappings of this page potentially
|
user space shared/writable mappings of this page potentially
|
||||||
exist, this routine is called.
|
exist, this routine is called.
|
||||||
|
|
||||||
NOTE: This routine need only be called for page cache pages
|
.. note::
|
||||||
|
|
||||||
|
This routine need only be called for page cache pages
|
||||||
which can potentially ever be mapped into the address
|
which can potentially ever be mapped into the address
|
||||||
space of a user process. So for example, VFS layer code
|
space of a user process. So for example, VFS layer code
|
||||||
handling vfs symlinks in the page cache need not call
|
handling vfs symlinks in the page cache need not call
|
||||||
|
@ -322,18 +327,19 @@ maps this page at its virtual address.
|
||||||
made of this flag bit, and if set the flush is done and the flag
|
made of this flag bit, and if set the flush is done and the flag
|
||||||
bit is cleared.
|
bit is cleared.
|
||||||
|
|
||||||
IMPORTANT NOTE: It is often important, if you defer the flush,
|
.. important::
|
||||||
|
|
||||||
|
It is often important, if you defer the flush,
|
||||||
that the actual flush occurs on the same CPU
|
that the actual flush occurs on the same CPU
|
||||||
as did the cpu stores into the page to make it
|
as did the cpu stores into the page to make it
|
||||||
dirty. Again, see sparc64 for examples of how
|
dirty. Again, see sparc64 for examples of how
|
||||||
to deal with this.
|
to deal with this.
|
||||||
|
|
||||||
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
|
``void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
|
||||||
unsigned long user_vaddr,
|
unsigned long user_vaddr, void *dst, void *src, int len)``
|
||||||
void *dst, void *src, int len)
|
``void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
|
||||||
void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
|
unsigned long user_vaddr, void *dst, void *src, int len)``
|
||||||
unsigned long user_vaddr,
|
|
||||||
void *dst, void *src, int len)
|
|
||||||
When the kernel needs to copy arbitrary data in and out
|
When the kernel needs to copy arbitrary data in and out
|
||||||
of arbitrary user pages (f.e. for ptrace()) it will use
|
of arbitrary user pages (f.e. for ptrace()) it will use
|
||||||
these two routines.
|
these two routines.
|
||||||
|
@ -344,8 +350,9 @@ maps this page at its virtual address.
|
||||||
likely that you will need to flush the instruction cache
|
likely that you will need to flush the instruction cache
|
||||||
for copy_to_user_page().
|
for copy_to_user_page().
|
||||||
|
|
||||||
void flush_anon_page(struct vm_area_struct *vma, struct page *page,
|
``void flush_anon_page(struct vm_area_struct *vma, struct page *page,
|
||||||
unsigned long vmaddr)
|
unsigned long vmaddr)``
|
||||||
|
|
||||||
When the kernel needs to access the contents of an anonymous
|
When the kernel needs to access the contents of an anonymous
|
||||||
page, it calls this function (currently only
|
page, it calls this function (currently only
|
||||||
get_user_pages()). Note: flush_dcache_page() deliberately
|
get_user_pages()). Note: flush_dcache_page() deliberately
|
||||||
|
@ -354,7 +361,8 @@ maps this page at its virtual address.
|
||||||
architectures). For incoherent architectures, it should flush
|
architectures). For incoherent architectures, it should flush
|
||||||
the cache of the page at vmaddr.
|
the cache of the page at vmaddr.
|
||||||
|
|
||||||
void flush_kernel_dcache_page(struct page *page)
|
``void flush_kernel_dcache_page(struct page *page)``
|
||||||
|
|
||||||
When the kernel needs to modify a user page is has obtained
|
When the kernel needs to modify a user page is has obtained
|
||||||
with kmap, it calls this function after all modifications are
|
with kmap, it calls this function after all modifications are
|
||||||
complete (but before kunmapping it) to bring the underlying
|
complete (but before kunmapping it) to bring the underlying
|
||||||
|
@ -366,14 +374,16 @@ maps this page at its virtual address.
|
||||||
the kernel cache for page (using page_address(page)).
|
the kernel cache for page (using page_address(page)).
|
||||||
|
|
||||||
|
|
||||||
void flush_icache_range(unsigned long start, unsigned long end)
|
``void flush_icache_range(unsigned long start, unsigned long end)``
|
||||||
|
|
||||||
When the kernel stores into addresses that it will execute
|
When the kernel stores into addresses that it will execute
|
||||||
out of (eg when loading modules), this function is called.
|
out of (eg when loading modules), this function is called.
|
||||||
|
|
||||||
If the icache does not snoop stores then this routine will need
|
If the icache does not snoop stores then this routine will need
|
||||||
to flush it.
|
to flush it.
|
||||||
|
|
||||||
void flush_icache_page(struct vm_area_struct *vma, struct page *page)
|
``void flush_icache_page(struct vm_area_struct *vma, struct page *page)``
|
||||||
|
|
||||||
All the functionality of flush_icache_page can be implemented in
|
All the functionality of flush_icache_page can be implemented in
|
||||||
flush_dcache_page and update_mmu_cache. In the future, the hope
|
flush_dcache_page and update_mmu_cache. In the future, the hope
|
||||||
is to remove this interface completely.
|
is to remove this interface completely.
|
||||||
|
@ -387,7 +397,8 @@ the kernel trying to do I/O to vmap areas must manually manage
|
||||||
coherency. It must do this by flushing the vmap range before doing
|
coherency. It must do this by flushing the vmap range before doing
|
||||||
I/O and invalidating it after the I/O returns.
|
I/O and invalidating it after the I/O returns.
|
||||||
|
|
||||||
void flush_kernel_vmap_range(void *vaddr, int size)
|
``void flush_kernel_vmap_range(void *vaddr, int size)``
|
||||||
|
|
||||||
flushes the kernel cache for a given virtual address range in
|
flushes the kernel cache for a given virtual address range in
|
||||||
the vmap area. This is to make sure that any data the kernel
|
the vmap area. This is to make sure that any data the kernel
|
||||||
modified in the vmap range is made visible to the physical
|
modified in the vmap range is made visible to the physical
|
||||||
|
@ -395,7 +406,8 @@ I/O and invalidating it after the I/O returns.
|
||||||
Note that this API does *not* also flush the offset map alias
|
Note that this API does *not* also flush the offset map alias
|
||||||
of the area.
|
of the area.
|
||||||
|
|
||||||
void invalidate_kernel_vmap_range(void *vaddr, int size) invalidates
|
``void invalidate_kernel_vmap_range(void *vaddr, int size) invalidates``
|
||||||
|
|
||||||
the cache for a given virtual address range in the vmap area
|
the cache for a given virtual address range in the vmap area
|
||||||
which prevents the processor from making the cache stale by
|
which prevents the processor from making the cache stale by
|
||||||
speculatively reading data while the I/O was occurring to the
|
speculatively reading data while the I/O was occurring to the
|
||||||
|
|
|
@ -789,23 +789,46 @@ way to trigger. Applications should do whatever they can to help the
|
||||||
system. It might be too late to consult with vmstat or any other
|
system. It might be too late to consult with vmstat or any other
|
||||||
statistics, so it's advisable to take an immediate action.
|
statistics, so it's advisable to take an immediate action.
|
||||||
|
|
||||||
The events are propagated upward until the event is handled, i.e. the
|
By default, events are propagated upward until the event is handled, i.e. the
|
||||||
events are not pass-through. Here is what this means: for example you have
|
events are not pass-through. For example, you have three cgroups: A->B->C. Now
|
||||||
three cgroups: A->B->C. Now you set up an event listener on cgroups A, B
|
you set up an event listener on cgroups A, B and C, and suppose group C
|
||||||
and C, and suppose group C experiences some pressure. In this situation,
|
experiences some pressure. In this situation, only group C will receive the
|
||||||
only group C will receive the notification, i.e. groups A and B will not
|
notification, i.e. groups A and B will not receive it. This is done to avoid
|
||||||
receive it. This is done to avoid excessive "broadcasting" of messages,
|
excessive "broadcasting" of messages, which disturbs the system and which is
|
||||||
which disturbs the system and which is especially bad if we are low on
|
especially bad if we are low on memory or thrashing. Group B, will receive
|
||||||
memory or thrashing. So, organize the cgroups wisely, or propagate the
|
notification only if there are no event listers for group C.
|
||||||
events manually (or, ask us to implement the pass-through events,
|
|
||||||
explaining why would you need them.)
|
There are three optional modes that specify different propagation behavior:
|
||||||
|
|
||||||
|
- "default": this is the default behavior specified above. This mode is the
|
||||||
|
same as omitting the optional mode parameter, preserved by backwards
|
||||||
|
compatibility.
|
||||||
|
|
||||||
|
- "hierarchy": events always propagate up to the root, similar to the default
|
||||||
|
behavior, except that propagation continues regardless of whether there are
|
||||||
|
event listeners at each level, with the "hierarchy" mode. In the above
|
||||||
|
example, groups A, B, and C will receive notification of memory pressure.
|
||||||
|
|
||||||
|
- "local": events are pass-through, i.e. they only receive notifications when
|
||||||
|
memory pressure is experienced in the memcg for which the notification is
|
||||||
|
registered. In the above example, group C will receive notification if
|
||||||
|
registered for "local" notification and the group experiences memory
|
||||||
|
pressure. However, group B will never receive notification, regardless if
|
||||||
|
there is an event listener for group C or not, if group B is registered for
|
||||||
|
local notification.
|
||||||
|
|
||||||
|
The level and event notification mode ("hierarchy" or "local", if necessary) are
|
||||||
|
specified by a comma-delimited string, i.e. "low,hierarchy" specifies
|
||||||
|
hierarchical, pass-through, notification for all ancestor memcgs. Notification
|
||||||
|
that is the default, non pass-through behavior, does not specify a mode.
|
||||||
|
"medium,local" specifies pass-through notification for the medium level.
|
||||||
|
|
||||||
The file memory.pressure_level is only used to setup an eventfd. To
|
The file memory.pressure_level is only used to setup an eventfd. To
|
||||||
register a notification, an application must:
|
register a notification, an application must:
|
||||||
|
|
||||||
- create an eventfd using eventfd(2);
|
- create an eventfd using eventfd(2);
|
||||||
- open memory.pressure_level;
|
- open memory.pressure_level;
|
||||||
- write string like "<event_fd> <fd of memory.pressure_level> <level>"
|
- write string as "<event_fd> <fd of memory.pressure_level> <level[,mode]>"
|
||||||
to cgroup.event_control.
|
to cgroup.event_control.
|
||||||
|
|
||||||
Application will be notified through eventfd when memory pressure is at
|
Application will be notified through eventfd when memory pressure is at
|
||||||
|
@ -821,7 +844,7 @@ Test:
|
||||||
# cd /sys/fs/cgroup/memory/
|
# cd /sys/fs/cgroup/memory/
|
||||||
# mkdir foo
|
# mkdir foo
|
||||||
# cd foo
|
# cd foo
|
||||||
# cgroup_event_listener memory.pressure_level low &
|
# cgroup_event_listener memory.pressure_level low,hierarchy &
|
||||||
# echo 8000000 > memory.limit_in_bytes
|
# echo 8000000 > memory.limit_in_bytes
|
||||||
# echo 8000000 > memory.memsw.limit_in_bytes
|
# echo 8000000 > memory.memsw.limit_in_bytes
|
||||||
# echo $$ > tasks
|
# echo $$ > tasks
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,9 @@
|
||||||
================
|
================
|
||||||
CIRCULAR BUFFERS
|
Circular Buffers
|
||||||
================
|
================
|
||||||
|
|
||||||
By: David Howells <dhowells@redhat.com>
|
:Author: David Howells <dhowells@redhat.com>
|
||||||
Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
:Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
Linux provides a number of features that can be used to implement circular
|
Linux provides a number of features that can be used to implement circular
|
||||||
|
@ -20,7 +20,7 @@ producer and just one consumer. It is possible to handle multiple producers by
|
||||||
serialising them, and to handle multiple consumers by serialising them.
|
serialising them, and to handle multiple consumers by serialising them.
|
||||||
|
|
||||||
|
|
||||||
Contents:
|
.. Contents:
|
||||||
|
|
||||||
(*) What is a circular buffer?
|
(*) What is a circular buffer?
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ Contents:
|
||||||
- The consumer.
|
- The consumer.
|
||||||
|
|
||||||
|
|
||||||
==========================
|
|
||||||
WHAT IS A CIRCULAR BUFFER?
|
What is a circular buffer?
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
First of all, what is a circular buffer? A circular buffer is a buffer of
|
First of all, what is a circular buffer? A circular buffer is a buffer of
|
||||||
|
@ -60,9 +60,7 @@ buffer, provided that neither index overtakes the other. The implementer must
|
||||||
be careful, however, as a region more than one unit in size may wrap the end of
|
be careful, however, as a region more than one unit in size may wrap the end of
|
||||||
the buffer and be broken into two segments.
|
the buffer and be broken into two segments.
|
||||||
|
|
||||||
|
Measuring power-of-2 buffers
|
||||||
============================
|
|
||||||
MEASURING POWER-OF-2 BUFFERS
|
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Calculation of the occupancy or the remaining capacity of an arbitrarily sized
|
Calculation of the occupancy or the remaining capacity of an arbitrarily sized
|
||||||
|
@ -71,13 +69,13 @@ modulus (divide) instruction. However, if the buffer is of a power-of-2 size,
|
||||||
then a much quicker bitwise-AND instruction can be used instead.
|
then a much quicker bitwise-AND instruction can be used instead.
|
||||||
|
|
||||||
Linux provides a set of macros for handling power-of-2 circular buffers. These
|
Linux provides a set of macros for handling power-of-2 circular buffers. These
|
||||||
can be made use of by:
|
can be made use of by::
|
||||||
|
|
||||||
#include <linux/circ_buf.h>
|
#include <linux/circ_buf.h>
|
||||||
|
|
||||||
The macros are:
|
The macros are:
|
||||||
|
|
||||||
(*) Measure the remaining capacity of a buffer:
|
(#) Measure the remaining capacity of a buffer::
|
||||||
|
|
||||||
CIRC_SPACE(head_index, tail_index, buffer_size);
|
CIRC_SPACE(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
|
@ -85,7 +83,7 @@ The macros are:
|
||||||
can be inserted.
|
can be inserted.
|
||||||
|
|
||||||
|
|
||||||
(*) Measure the maximum consecutive immediate space in a buffer:
|
(#) Measure the maximum consecutive immediate space in a buffer::
|
||||||
|
|
||||||
CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
|
CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
|
@ -94,14 +92,14 @@ The macros are:
|
||||||
beginning of the buffer.
|
beginning of the buffer.
|
||||||
|
|
||||||
|
|
||||||
(*) Measure the occupancy of a buffer:
|
(#) Measure the occupancy of a buffer::
|
||||||
|
|
||||||
CIRC_CNT(head_index, tail_index, buffer_size);
|
CIRC_CNT(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
This returns the number of items currently occupying a buffer[2].
|
This returns the number of items currently occupying a buffer[2].
|
||||||
|
|
||||||
|
|
||||||
(*) Measure the non-wrapping occupancy of a buffer:
|
(#) Measure the non-wrapping occupancy of a buffer::
|
||||||
|
|
||||||
CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
|
CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
|
@ -112,7 +110,7 @@ The macros are:
|
||||||
Each of these macros will nominally return a value between 0 and buffer_size-1,
|
Each of these macros will nominally return a value between 0 and buffer_size-1,
|
||||||
however:
|
however:
|
||||||
|
|
||||||
[1] CIRC_SPACE*() are intended to be used in the producer. To the producer
|
(1) CIRC_SPACE*() are intended to be used in the producer. To the producer
|
||||||
they will return a lower bound as the producer controls the head index,
|
they will return a lower bound as the producer controls the head index,
|
||||||
but the consumer may still be depleting the buffer on another CPU and
|
but the consumer may still be depleting the buffer on another CPU and
|
||||||
moving the tail index.
|
moving the tail index.
|
||||||
|
@ -120,7 +118,7 @@ however:
|
||||||
To the consumer it will show an upper bound as the producer may be busy
|
To the consumer it will show an upper bound as the producer may be busy
|
||||||
depleting the space.
|
depleting the space.
|
||||||
|
|
||||||
[2] CIRC_CNT*() are intended to be used in the consumer. To the consumer they
|
(2) CIRC_CNT*() are intended to be used in the consumer. To the consumer they
|
||||||
will return a lower bound as the consumer controls the tail index, but the
|
will return a lower bound as the consumer controls the tail index, but the
|
||||||
producer may still be filling the buffer on another CPU and moving the
|
producer may still be filling the buffer on another CPU and moving the
|
||||||
head index.
|
head index.
|
||||||
|
@ -128,14 +126,12 @@ however:
|
||||||
To the producer it will show an upper bound as the consumer may be busy
|
To the producer it will show an upper bound as the consumer may be busy
|
||||||
emptying the buffer.
|
emptying the buffer.
|
||||||
|
|
||||||
[3] To a third party, the order in which the writes to the indices by the
|
(3) To a third party, the order in which the writes to the indices by the
|
||||||
producer and consumer become visible cannot be guaranteed as they are
|
producer and consumer become visible cannot be guaranteed as they are
|
||||||
independent and may be made on different CPUs - so the result in such a
|
independent and may be made on different CPUs - so the result in such a
|
||||||
situation will merely be a guess, and may even be negative.
|
situation will merely be a guess, and may even be negative.
|
||||||
|
|
||||||
|
Using memory barriers with circular buffers
|
||||||
===========================================
|
|
||||||
USING MEMORY BARRIERS WITH CIRCULAR BUFFERS
|
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
By using memory barriers in conjunction with circular buffers, you can avoid
|
By using memory barriers in conjunction with circular buffers, you can avoid
|
||||||
|
@ -152,10 +148,10 @@ time, and only one thing should be emptying a buffer at any one time, but the
|
||||||
two sides can operate simultaneously.
|
two sides can operate simultaneously.
|
||||||
|
|
||||||
|
|
||||||
THE PRODUCER
|
The producer
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The producer will look something like this:
|
The producer will look something like this::
|
||||||
|
|
||||||
spin_lock(&producer_lock);
|
spin_lock(&producer_lock);
|
||||||
|
|
||||||
|
@ -193,10 +189,10 @@ ordering between the read of the index indicating that the consumer has
|
||||||
vacated a given element and the write by the producer to that same element.
|
vacated a given element and the write by the producer to that same element.
|
||||||
|
|
||||||
|
|
||||||
THE CONSUMER
|
The Consumer
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The consumer will look something like this:
|
The consumer will look something like this::
|
||||||
|
|
||||||
spin_lock(&consumer_lock);
|
spin_lock(&consumer_lock);
|
||||||
|
|
||||||
|
@ -235,8 +231,7 @@ prevents the compiler from tearing the store, and enforces ordering
|
||||||
against previous accesses.
|
against previous accesses.
|
||||||
|
|
||||||
|
|
||||||
===============
|
Further reading
|
||||||
FURTHER READING
|
|
||||||
===============
|
===============
|
||||||
|
|
||||||
See also Documentation/memory-barriers.txt for a description of Linux's memory
|
See also Documentation/memory-barriers.txt for a description of Linux's memory
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
|
========================
|
||||||
The Common Clk Framework
|
The Common Clk Framework
|
||||||
Mike Turquette <mturquette@ti.com>
|
========================
|
||||||
|
|
||||||
|
:Author: Mike Turquette <mturquette@ti.com>
|
||||||
|
|
||||||
This document endeavours to explain the common clk framework details,
|
This document endeavours to explain the common clk framework details,
|
||||||
and how to port a platform over to this framework. It is not yet a
|
and how to port a platform over to this framework. It is not yet a
|
||||||
detailed explanation of the clock api in include/linux/clk.h, but
|
detailed explanation of the clock api in include/linux/clk.h, but
|
||||||
perhaps someday it will include that information.
|
perhaps someday it will include that information.
|
||||||
|
|
||||||
Part 1 - introduction and interface split
|
Introduction and interface split
|
||||||
|
================================
|
||||||
|
|
||||||
The common clk framework is an interface to control the clock nodes
|
The common clk framework is an interface to control the clock nodes
|
||||||
available on various devices today. This may come in the form of clock
|
available on various devices today. This may come in the form of clock
|
||||||
|
@ -35,10 +39,11 @@ is defined in struct clk_foo and pointed to within struct clk_core. This
|
||||||
allows for easy navigation between the two discrete halves of the common
|
allows for easy navigation between the two discrete halves of the common
|
||||||
clock interface.
|
clock interface.
|
||||||
|
|
||||||
Part 2 - common data structures and api
|
Common data structures and api
|
||||||
|
==============================
|
||||||
|
|
||||||
Below is the common struct clk_core definition from
|
Below is the common struct clk_core definition from
|
||||||
drivers/clk/clk.c, modified for brevity:
|
drivers/clk/clk.c, modified for brevity::
|
||||||
|
|
||||||
struct clk_core {
|
struct clk_core {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -59,7 +64,7 @@ struct clk. That api is documented in include/linux/clk.h.
|
||||||
|
|
||||||
Platforms and devices utilizing the common struct clk_core use the struct
|
Platforms and devices utilizing the common struct clk_core use the struct
|
||||||
clk_ops pointer in struct clk_core to perform the hardware-specific parts of
|
clk_ops pointer in struct clk_core to perform the hardware-specific parts of
|
||||||
the operations defined in clk-provider.h:
|
the operations defined in clk-provider.h::
|
||||||
|
|
||||||
struct clk_ops {
|
struct clk_ops {
|
||||||
int (*prepare)(struct clk_hw *hw);
|
int (*prepare)(struct clk_hw *hw);
|
||||||
|
@ -95,12 +100,13 @@ the operations defined in clk-provider.h:
|
||||||
struct dentry *dentry);
|
struct dentry *dentry);
|
||||||
};
|
};
|
||||||
|
|
||||||
Part 3 - hardware clk implementations
|
Hardware clk implementations
|
||||||
|
============================
|
||||||
|
|
||||||
The strength of the common struct clk_core comes from its .ops and .hw pointers
|
The strength of the common struct clk_core comes from its .ops and .hw pointers
|
||||||
which abstract the details of struct clk from the hardware-specific bits, and
|
which abstract the details of struct clk from the hardware-specific bits, and
|
||||||
vice versa. To illustrate consider the simple gateable clk implementation in
|
vice versa. To illustrate consider the simple gateable clk implementation in
|
||||||
drivers/clk/clk-gate.c:
|
drivers/clk/clk-gate.c::
|
||||||
|
|
||||||
struct clk_gate {
|
struct clk_gate {
|
||||||
struct clk_hw hw;
|
struct clk_hw hw;
|
||||||
|
@ -115,7 +121,7 @@ Nothing about clock topology or accounting, such as enable_count or
|
||||||
notifier_count, is needed here. That is all handled by the common
|
notifier_count, is needed here. That is all handled by the common
|
||||||
framework code and struct clk_core.
|
framework code and struct clk_core.
|
||||||
|
|
||||||
Let's walk through enabling this clk from driver code:
|
Let's walk through enabling this clk from driver code::
|
||||||
|
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
clk = clk_get(NULL, "my_gateable_clk");
|
clk = clk_get(NULL, "my_gateable_clk");
|
||||||
|
@ -123,7 +129,7 @@ Let's walk through enabling this clk from driver code:
|
||||||
clk_prepare(clk);
|
clk_prepare(clk);
|
||||||
clk_enable(clk);
|
clk_enable(clk);
|
||||||
|
|
||||||
The call graph for clk_enable is very simple:
|
The call graph for clk_enable is very simple::
|
||||||
|
|
||||||
clk_enable(clk);
|
clk_enable(clk);
|
||||||
clk->ops->enable(clk->hw);
|
clk->ops->enable(clk->hw);
|
||||||
|
@ -132,7 +138,7 @@ clk_enable(clk);
|
||||||
[resolves struct clk gate with to_clk_gate(hw)]
|
[resolves struct clk gate with to_clk_gate(hw)]
|
||||||
clk_gate_set_bit(gate);
|
clk_gate_set_bit(gate);
|
||||||
|
|
||||||
And the definition of clk_gate_set_bit:
|
And the definition of clk_gate_set_bit::
|
||||||
|
|
||||||
static void clk_gate_set_bit(struct clk_gate *gate)
|
static void clk_gate_set_bit(struct clk_gate *gate)
|
||||||
{
|
{
|
||||||
|
@ -143,22 +149,23 @@ static void clk_gate_set_bit(struct clk_gate *gate)
|
||||||
writel(reg, gate->reg);
|
writel(reg, gate->reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Note that to_clk_gate is defined as:
|
Note that to_clk_gate is defined as::
|
||||||
|
|
||||||
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
|
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
|
||||||
|
|
||||||
This pattern of abstraction is used for every clock hardware
|
This pattern of abstraction is used for every clock hardware
|
||||||
representation.
|
representation.
|
||||||
|
|
||||||
Part 4 - supporting your own clk hardware
|
Supporting your own clk hardware
|
||||||
|
================================
|
||||||
|
|
||||||
When implementing support for a new type of clock it is only necessary to
|
When implementing support for a new type of clock it is only necessary to
|
||||||
include the following header:
|
include the following header::
|
||||||
|
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
|
|
||||||
To construct a clk hardware structure for your platform you must define
|
To construct a clk hardware structure for your platform you must define
|
||||||
the following:
|
the following::
|
||||||
|
|
||||||
struct clk_foo {
|
struct clk_foo {
|
||||||
struct clk_hw hw;
|
struct clk_hw hw;
|
||||||
|
@ -166,14 +173,14 @@ struct clk_foo {
|
||||||
};
|
};
|
||||||
|
|
||||||
To take advantage of your data you'll need to support valid operations
|
To take advantage of your data you'll need to support valid operations
|
||||||
for your clk:
|
for your clk::
|
||||||
|
|
||||||
struct clk_ops clk_foo_ops {
|
struct clk_ops clk_foo_ops {
|
||||||
.enable = &clk_foo_enable;
|
.enable = &clk_foo_enable;
|
||||||
.disable = &clk_foo_disable;
|
.disable = &clk_foo_disable;
|
||||||
};
|
};
|
||||||
|
|
||||||
Implement the above functions using container_of:
|
Implement the above functions using container_of::
|
||||||
|
|
||||||
#define to_clk_foo(_hw) container_of(_hw, struct clk_foo, hw)
|
#define to_clk_foo(_hw) container_of(_hw, struct clk_foo, hw)
|
||||||
|
|
||||||
|
@ -194,41 +201,56 @@ mandatory, a cell marked as "n" implies that either including that
|
||||||
callback is invalid or otherwise unnecessary. Empty cells are either
|
callback is invalid or otherwise unnecessary. Empty cells are either
|
||||||
optional or must be evaluated on a case-by-case basis.
|
optional or must be evaluated on a case-by-case basis.
|
||||||
|
|
||||||
clock hardware characteristics
|
.. table:: clock hardware characteristics
|
||||||
-----------------------------------------------------------
|
|
||||||
| gate | change rate | single parent | multiplexer | root |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|------|-------------|---------------|-------------|------|
|
| | gate | change rate | single parent | multiplexer | root |
|
||||||
.prepare | | | | | |
|
+================+======+=============+===============+=============+======+
|
||||||
.unprepare | | | | | |
|
|.prepare | | | | | |
|
||||||
| | | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.enable | y | | | | |
|
|.unprepare | | | | | |
|
||||||
.disable | y | | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.is_enabled | y | | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
| | | | | |
|
|.enable | y | | | | |
|
||||||
.recalc_rate | | y | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.round_rate | | y [1] | | | |
|
|.disable | y | | | | |
|
||||||
.determine_rate | | y [1] | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.set_rate | | y | | | |
|
|.is_enabled | y | | | | |
|
||||||
| | | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.set_parent | | | n | y | n |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.get_parent | | | n | y | n |
|
|.recalc_rate | | y | | | |
|
||||||
| | | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.recalc_accuracy| | | | | |
|
|.round_rate | | y [1]_ | | | |
|
||||||
| | | | | |
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
.init | | | | | |
|
|.determine_rate | | y [1]_ | | | |
|
||||||
-----------------------------------------------------------
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
[1] either one of round_rate or determine_rate is required.
|
|.set_rate | | y | | | |
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
|.set_parent | | | n | y | n |
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
|.get_parent | | | n | y | n |
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
|.recalc_accuracy| | | | | |
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
|.init | | | | | |
|
||||||
|
+----------------+------+-------------+---------------+-------------+------+
|
||||||
|
|
||||||
|
.. [1] either one of round_rate or determine_rate is required.
|
||||||
|
|
||||||
Finally, register your clock at run-time with a hardware-specific
|
Finally, register your clock at run-time with a hardware-specific
|
||||||
registration function. This function simply populates struct clk_foo's
|
registration function. This function simply populates struct clk_foo's
|
||||||
data and then passes the common struct clk parameters to the framework
|
data and then passes the common struct clk parameters to the framework
|
||||||
with a call to:
|
with a call to::
|
||||||
|
|
||||||
clk_register(...)
|
clk_register(...)
|
||||||
|
|
||||||
See the basic clock types in drivers/clk/clk-*.c for examples.
|
See the basic clock types in ``drivers/clk/clk-*.c`` for examples.
|
||||||
|
|
||||||
Part 5 - Disabling clock gating of unused clocks
|
Disabling clock gating of unused clocks
|
||||||
|
=======================================
|
||||||
|
|
||||||
Sometimes during development it can be useful to be able to bypass the
|
Sometimes during development it can be useful to be able to bypass the
|
||||||
default disabling of unused clocks. For example, if drivers aren't enabling
|
default disabling of unused clocks. For example, if drivers aren't enabling
|
||||||
|
@ -239,7 +261,8 @@ are sorted out.
|
||||||
To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
|
To bypass this disabling, include "clk_ignore_unused" in the bootargs to the
|
||||||
kernel.
|
kernel.
|
||||||
|
|
||||||
Part 6 - Locking
|
Locking
|
||||||
|
=======
|
||||||
|
|
||||||
The common clock framework uses two global locks, the prepare lock and the
|
The common clock framework uses two global locks, the prepare lock and the
|
||||||
enable lock.
|
enable lock.
|
||||||
|
|
|
@ -271,8 +271,7 @@ latex_elements = {
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
# Additional stuff for the LaTeX preamble.
|
||||||
'preamble': '''
|
'preamble': '''
|
||||||
% Adjust margins
|
\\usepackage{ifthen}
|
||||||
\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}
|
|
||||||
|
|
||||||
% Allow generate some pages in landscape
|
% Allow generate some pages in landscape
|
||||||
\\usepackage{lscape}
|
\\usepackage{lscape}
|
||||||
|
@ -281,6 +280,7 @@ latex_elements = {
|
||||||
\\definecolor{NoteColor}{RGB}{204,255,255}
|
\\definecolor{NoteColor}{RGB}{204,255,255}
|
||||||
\\definecolor{WarningColor}{RGB}{255,204,204}
|
\\definecolor{WarningColor}{RGB}{255,204,204}
|
||||||
\\definecolor{AttentionColor}{RGB}{255,255,204}
|
\\definecolor{AttentionColor}{RGB}{255,255,204}
|
||||||
|
\\definecolor{ImportantColor}{RGB}{192,255,204}
|
||||||
\\definecolor{OtherColor}{RGB}{204,204,204}
|
\\definecolor{OtherColor}{RGB}{204,204,204}
|
||||||
\\newlength{\\mynoticelength}
|
\\newlength{\\mynoticelength}
|
||||||
\\makeatletter\\newenvironment{coloredbox}[1]{%
|
\\makeatletter\\newenvironment{coloredbox}[1]{%
|
||||||
|
@ -301,9 +301,14 @@ latex_elements = {
|
||||||
\\ifthenelse%
|
\\ifthenelse%
|
||||||
{\\equal{\\py@noticetype}{attention}}%
|
{\\equal{\\py@noticetype}{attention}}%
|
||||||
{\\colorbox{AttentionColor}{\\usebox{\\@tempboxa}}}%
|
{\\colorbox{AttentionColor}{\\usebox{\\@tempboxa}}}%
|
||||||
|
{%
|
||||||
|
\\ifthenelse%
|
||||||
|
{\\equal{\\py@noticetype}{important}}%
|
||||||
|
{\\colorbox{ImportantColor}{\\usebox{\\@tempboxa}}}%
|
||||||
{\\colorbox{OtherColor}{\\usebox{\\@tempboxa}}}%
|
{\\colorbox{OtherColor}{\\usebox{\\@tempboxa}}}%
|
||||||
}%
|
}%
|
||||||
}%
|
}%
|
||||||
|
}%
|
||||||
}\\makeatother
|
}\\makeatother
|
||||||
|
|
||||||
\\makeatletter
|
\\makeatletter
|
||||||
|
@ -336,30 +341,51 @@ latex_elements = {
|
||||||
if major == 1 and minor > 3:
|
if major == 1 and minor > 3:
|
||||||
latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n'
|
latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n'
|
||||||
|
|
||||||
|
if major == 1 and minor <= 4:
|
||||||
|
latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}'
|
||||||
|
elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)):
|
||||||
|
latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=0.5in'
|
||||||
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
# (source start file, target name, title,
|
# (source start file, target name, title,
|
||||||
# author, documentclass [howto, manual, or own class]).
|
# author, documentclass [howto, manual, or own class]).
|
||||||
|
# Sorted in alphabetical order
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
('doc-guide/index', 'kernel-doc-guide.tex', 'Linux Kernel Documentation Guide',
|
|
||||||
'The kernel development community', 'manual'),
|
|
||||||
('admin-guide/index', 'linux-user.tex', 'Linux Kernel User Documentation',
|
('admin-guide/index', 'linux-user.tex', 'Linux Kernel User Documentation',
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
('core-api/index', 'core-api.tex', 'The kernel core API manual',
|
('core-api/index', 'core-api.tex', 'The kernel core API manual',
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
|
('crypto/index', 'crypto-api.tex', 'Linux Kernel Crypto API manual',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
|
('dev-tools/index', 'dev-tools.tex', 'Development tools for the Kernel',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
|
('doc-guide/index', 'kernel-doc-guide.tex', 'Linux Kernel Documentation Guide',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
('driver-api/index', 'driver-api.tex', 'The kernel driver API manual',
|
('driver-api/index', 'driver-api.tex', 'The kernel driver API manual',
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
('input/index', 'linux-input.tex', 'The Linux input driver subsystem',
|
('filesystems/index', 'filesystems.tex', 'Linux Filesystems API',
|
||||||
'The kernel development community', 'manual'),
|
|
||||||
('kernel-documentation', 'kernel-documentation.tex', 'The Linux Kernel Documentation',
|
|
||||||
'The kernel development community', 'manual'),
|
|
||||||
('process/index', 'development-process.tex', 'Linux Kernel Development Documentation',
|
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
('gpu/index', 'gpu.tex', 'Linux GPU Driver Developer\'s Guide',
|
('gpu/index', 'gpu.tex', 'Linux GPU Driver Developer\'s Guide',
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
|
('input/index', 'linux-input.tex', 'The Linux input driver subsystem',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
|
('kernel-hacking/index', 'kernel-hacking.tex', 'Unreliable Guide To Hacking The Linux Kernel',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
('media/index', 'media.tex', 'Linux Media Subsystem Documentation',
|
('media/index', 'media.tex', 'Linux Media Subsystem Documentation',
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
|
('networking/index', 'networking.tex', 'Linux Networking Documentation',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
|
('process/index', 'development-process.tex', 'Linux Kernel Development Documentation',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
('security/index', 'security.tex', 'The kernel security subsystem manual',
|
('security/index', 'security.tex', 'The kernel security subsystem manual',
|
||||||
'The kernel development community', 'manual'),
|
'The kernel development community', 'manual'),
|
||||||
|
('sh/index', 'sh.tex', 'SuperH architecture implementation manual',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
|
('sound/index', 'sound.tex', 'Linux Sound Subsystem Documentation',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
|
('userspace-api/index', 'userspace-api.tex', 'The Linux kernel user-space API guide',
|
||||||
|
'The kernel development community', 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
|
|
@ -10,7 +10,10 @@ properties:
|
||||||
|
|
||||||
1. Objects are opaque pointers. The implementation does not care where they
|
1. Objects are opaque pointers. The implementation does not care where they
|
||||||
point (if anywhere) or what they point to (if anything).
|
point (if anywhere) or what they point to (if anything).
|
||||||
.. note:: Pointers to objects _must_ be zero in the least significant bit.
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Pointers to objects _must_ be zero in the least significant bit.
|
||||||
|
|
||||||
2. Objects do not need to contain linkage blocks for use by the array. This
|
2. Objects do not need to contain linkage blocks for use by the array. This
|
||||||
permits an object to be located in multiple arrays simultaneously.
|
permits an object to be located in multiple arrays simultaneously.
|
||||||
|
|
|
@ -303,6 +303,11 @@ defined which accomplish this::
|
||||||
void smp_mb__before_atomic(void);
|
void smp_mb__before_atomic(void);
|
||||||
void smp_mb__after_atomic(void);
|
void smp_mb__after_atomic(void);
|
||||||
|
|
||||||
|
Preceding a non-value-returning read-modify-write atomic operation with
|
||||||
|
smp_mb__before_atomic() and following it with smp_mb__after_atomic()
|
||||||
|
provides the same full ordering that is provided by value-returning
|
||||||
|
read-modify-write atomic operations.
|
||||||
|
|
||||||
For example, smp_mb__before_atomic() can be used like so::
|
For example, smp_mb__before_atomic() can be used like so::
|
||||||
|
|
||||||
obj->dead = 1;
|
obj->dead = 1;
|
||||||
|
|
|
@ -19,6 +19,7 @@ Core utilities
|
||||||
workqueue
|
workqueue
|
||||||
genericirq
|
genericirq
|
||||||
flexible-arrays
|
flexible-arrays
|
||||||
|
librs
|
||||||
|
|
||||||
Interfaces for kernel debugging
|
Interfaces for kernel debugging
|
||||||
===============================
|
===============================
|
||||||
|
|
|
@ -114,7 +114,7 @@ The Slab Cache
|
||||||
User Space Memory Access
|
User Space Memory Access
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
.. kernel-doc:: arch/x86/include/asm/uaccess_32.h
|
.. kernel-doc:: arch/x86/include/asm/uaccess.h
|
||||||
:internal:
|
:internal:
|
||||||
|
|
||||||
.. kernel-doc:: arch/x86/lib/usercopy_32.c
|
.. kernel-doc:: arch/x86/lib/usercopy_32.c
|
||||||
|
|
212
kernel/Documentation/core-api/librs.rst
Normal file
212
kernel/Documentation/core-api/librs.rst
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
==========================================
|
||||||
|
Reed-Solomon Library Programming Interface
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
:Author: Thomas Gleixner
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
The generic Reed-Solomon Library provides encoding, decoding and error
|
||||||
|
correction functions.
|
||||||
|
|
||||||
|
Reed-Solomon codes are used in communication and storage applications to
|
||||||
|
ensure data integrity.
|
||||||
|
|
||||||
|
This documentation is provided for developers who want to utilize the
|
||||||
|
functions provided by the library.
|
||||||
|
|
||||||
|
Known Bugs And Assumptions
|
||||||
|
==========================
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
This chapter provides examples of how to use the library.
|
||||||
|
|
||||||
|
Initializing
|
||||||
|
------------
|
||||||
|
|
||||||
|
The init function init_rs returns a pointer to an rs decoder structure,
|
||||||
|
which holds the necessary information for encoding, decoding and error
|
||||||
|
correction with the given polynomial. It either uses an existing
|
||||||
|
matching decoder or creates a new one. On creation all the lookup tables
|
||||||
|
for fast en/decoding are created. The function may take a while, so make
|
||||||
|
sure not to call it in critical code paths.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/* the Reed Solomon control structure */
|
||||||
|
static struct rs_control *rs_decoder;
|
||||||
|
|
||||||
|
/* Symbolsize is 10 (bits)
|
||||||
|
* Primitive polynomial is x^10+x^3+1
|
||||||
|
* first consecutive root is 0
|
||||||
|
* primitive element to generate roots = 1
|
||||||
|
* generator polynomial degree (number of roots) = 6
|
||||||
|
*/
|
||||||
|
rs_decoder = init_rs (10, 0x409, 0, 1, 6);
|
||||||
|
|
||||||
|
|
||||||
|
Encoding
|
||||||
|
--------
|
||||||
|
|
||||||
|
The encoder calculates the Reed-Solomon code over the given data length
|
||||||
|
and stores the result in the parity buffer. Note that the parity buffer
|
||||||
|
must be initialized before calling the encoder.
|
||||||
|
|
||||||
|
The expanded data can be inverted on the fly by providing a non-zero
|
||||||
|
inversion mask. The expanded data is XOR'ed with the mask. This is used
|
||||||
|
e.g. for FLASH ECC, where the all 0xFF is inverted to an all 0x00. The
|
||||||
|
Reed-Solomon code for all 0x00 is all 0x00. The code is inverted before
|
||||||
|
storing to FLASH so it is 0xFF too. This prevents that reading from an
|
||||||
|
erased FLASH results in ECC errors.
|
||||||
|
|
||||||
|
The databytes are expanded to the given symbol size on the fly. There is
|
||||||
|
no support for encoding continuous bitstreams with a symbol size != 8 at
|
||||||
|
the moment. If it is necessary it should be not a big deal to implement
|
||||||
|
such functionality.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/* Parity buffer. Size = number of roots */
|
||||||
|
uint16_t par[6];
|
||||||
|
/* Initialize the parity buffer */
|
||||||
|
memset(par, 0, sizeof(par));
|
||||||
|
/* Encode 512 byte in data8. Store parity in buffer par */
|
||||||
|
encode_rs8 (rs_decoder, data8, 512, par, 0);
|
||||||
|
|
||||||
|
|
||||||
|
Decoding
|
||||||
|
--------
|
||||||
|
|
||||||
|
The decoder calculates the syndrome over the given data length and the
|
||||||
|
received parity symbols and corrects errors in the data.
|
||||||
|
|
||||||
|
If a syndrome is available from a hardware decoder then the syndrome
|
||||||
|
calculation is skipped.
|
||||||
|
|
||||||
|
The correction of the data buffer can be suppressed by providing a
|
||||||
|
correction pattern buffer and an error location buffer to the decoder.
|
||||||
|
The decoder stores the calculated error location and the correction
|
||||||
|
bitmask in the given buffers. This is useful for hardware decoders which
|
||||||
|
use a weird bit ordering scheme.
|
||||||
|
|
||||||
|
The databytes are expanded to the given symbol size on the fly. There is
|
||||||
|
no support for decoding continuous bitstreams with a symbolsize != 8 at
|
||||||
|
the moment. If it is necessary it should be not a big deal to implement
|
||||||
|
such functionality.
|
||||||
|
|
||||||
|
Decoding with syndrome calculation, direct data correction
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/* Parity buffer. Size = number of roots */
|
||||||
|
uint16_t par[6];
|
||||||
|
uint8_t data[512];
|
||||||
|
int numerr;
|
||||||
|
/* Receive data */
|
||||||
|
.....
|
||||||
|
/* Receive parity */
|
||||||
|
.....
|
||||||
|
/* Decode 512 byte in data8.*/
|
||||||
|
numerr = decode_rs8 (rs_decoder, data8, par, 512, NULL, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
Decoding with syndrome given by hardware decoder, direct data correction
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/* Parity buffer. Size = number of roots */
|
||||||
|
uint16_t par[6], syn[6];
|
||||||
|
uint8_t data[512];
|
||||||
|
int numerr;
|
||||||
|
/* Receive data */
|
||||||
|
.....
|
||||||
|
/* Receive parity */
|
||||||
|
.....
|
||||||
|
/* Get syndrome from hardware decoder */
|
||||||
|
.....
|
||||||
|
/* Decode 512 byte in data8.*/
|
||||||
|
numerr = decode_rs8 (rs_decoder, data8, par, 512, syn, 0, NULL, 0, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
Decoding with syndrome given by hardware decoder, no direct data correction.
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Note: It's not necessary to give data and received parity to the
|
||||||
|
decoder.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/* Parity buffer. Size = number of roots */
|
||||||
|
uint16_t par[6], syn[6], corr[8];
|
||||||
|
uint8_t data[512];
|
||||||
|
int numerr, errpos[8];
|
||||||
|
/* Receive data */
|
||||||
|
.....
|
||||||
|
/* Receive parity */
|
||||||
|
.....
|
||||||
|
/* Get syndrome from hardware decoder */
|
||||||
|
.....
|
||||||
|
/* Decode 512 byte in data8.*/
|
||||||
|
numerr = decode_rs8 (rs_decoder, NULL, NULL, 512, syn, 0, errpos, 0, corr);
|
||||||
|
for (i = 0; i < numerr; i++) {
|
||||||
|
do_error_correction_in_your_buffer(errpos[i], corr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Cleanup
|
||||||
|
-------
|
||||||
|
|
||||||
|
The function free_rs frees the allocated resources, if the caller is
|
||||||
|
the last user of the decoder.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
/* Release resources */
|
||||||
|
free_rs(rs_decoder);
|
||||||
|
|
||||||
|
|
||||||
|
Structures
|
||||||
|
==========
|
||||||
|
|
||||||
|
This chapter contains the autogenerated documentation of the structures
|
||||||
|
which are used in the Reed-Solomon Library and are relevant for a
|
||||||
|
developer.
|
||||||
|
|
||||||
|
.. kernel-doc:: include/linux/rslib.h
|
||||||
|
:internal:
|
||||||
|
|
||||||
|
Public Functions Provided
|
||||||
|
=========================
|
||||||
|
|
||||||
|
This chapter contains the autogenerated documentation of the
|
||||||
|
Reed-Solomon functions which are exported.
|
||||||
|
|
||||||
|
.. kernel-doc:: lib/reed_solomon/reed_solomon.c
|
||||||
|
:export:
|
||||||
|
|
||||||
|
Credits
|
||||||
|
=======
|
||||||
|
|
||||||
|
The library code for encoding and decoding was written by Phil Karn.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
Copyright 2002, Phil Karn, KA9Q
|
||||||
|
May be used under the terms of the GNU General Public License (GPL)
|
||||||
|
|
||||||
|
|
||||||
|
The wrapper functions and interfaces are written by Thomas Gleixner.
|
||||||
|
|
||||||
|
Many users have provided bugfixes, improvements and helping hands for
|
||||||
|
testing. Thanks a lot.
|
||||||
|
|
||||||
|
The following people have contributed to this document:
|
||||||
|
|
||||||
|
Thomas Gleixner\ tglx@linutronix.de
|
|
@ -1,9 +1,10 @@
|
||||||
|
========
|
||||||
CPU load
|
CPU load
|
||||||
--------
|
========
|
||||||
|
|
||||||
Linux exports various bits of information via `/proc/stat' and
|
Linux exports various bits of information via ``/proc/stat`` and
|
||||||
`/proc/uptime' that userland tools, such as top(1), use to calculate
|
``/proc/uptime`` that userland tools, such as top(1), use to calculate
|
||||||
the average time system spent in a particular state, for example:
|
the average time system spent in a particular state, for example::
|
||||||
|
|
||||||
$ iostat
|
$ iostat
|
||||||
Linux 2.6.18.3-exp (linmac) 02/20/2007
|
Linux 2.6.18.3-exp (linmac) 02/20/2007
|
||||||
|
@ -17,7 +18,7 @@ Here the system thinks that over the default sampling period the
|
||||||
system spent 10.01% of the time doing work in user space, 2.92% in the
|
system spent 10.01% of the time doing work in user space, 2.92% in the
|
||||||
kernel, and was overall 81.63% of the time idle.
|
kernel, and was overall 81.63% of the time idle.
|
||||||
|
|
||||||
In most cases the `/proc/stat' information reflects the reality quite
|
In most cases the ``/proc/stat`` information reflects the reality quite
|
||||||
closely, however due to the nature of how/when the kernel collects
|
closely, however due to the nature of how/when the kernel collects
|
||||||
this data sometimes it can not be trusted at all.
|
this data sometimes it can not be trusted at all.
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
If we imagine the system with one task that periodically burns cycles
|
If we imagine the system with one task that periodically burns cycles
|
||||||
in the following manner:
|
in the following manner::
|
||||||
|
|
||||||
time line between two timer interrupts
|
time line between two timer interrupts
|
||||||
|--------------------------------------|
|
|--------------------------------------|
|
||||||
|
@ -43,12 +44,12 @@ in the following manner:
|
||||||
(only to be awaken quite soon)
|
(only to be awaken quite soon)
|
||||||
|
|
||||||
In the above situation the system will be 0% loaded according to the
|
In the above situation the system will be 0% loaded according to the
|
||||||
`/proc/stat' (since the timer interrupt will always happen when the
|
``/proc/stat`` (since the timer interrupt will always happen when the
|
||||||
system is executing the idle handler), but in reality the load is
|
system is executing the idle handler), but in reality the load is
|
||||||
closer to 99%.
|
closer to 99%.
|
||||||
|
|
||||||
One can imagine many more situations where this behavior of the kernel
|
One can imagine many more situations where this behavior of the kernel
|
||||||
will lead to quite erratic information inside `/proc/stat'.
|
will lead to quite erratic information inside ``/proc/stat``::
|
||||||
|
|
||||||
|
|
||||||
/* gcc -o hog smallhog.c */
|
/* gcc -o hog smallhog.c */
|
||||||
|
@ -103,8 +104,8 @@ int main (void)
|
||||||
References
|
References
|
||||||
----------
|
----------
|
||||||
|
|
||||||
http://lkml.org/lkml/2007/2/12/6
|
- http://lkml.org/lkml/2007/2/12/6
|
||||||
Documentation/filesystems/proc.txt (1.8)
|
- Documentation/filesystems/proc.txt (1.8)
|
||||||
|
|
||||||
|
|
||||||
Thanks
|
Thanks
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
===========================================
|
||||||
|
How CPU topology info is exported via sysfs
|
||||||
|
===========================================
|
||||||
|
|
||||||
Export CPU topology info via sysfs. Items (attributes) are similar
|
Export CPU topology info via sysfs. Items (attributes) are similar
|
||||||
to /proc/cpuinfo output of some architectures:
|
to /proc/cpuinfo output of some architectures:
|
||||||
|
@ -75,7 +78,8 @@ CONFIG_SCHED_BOOK and CONFIG_DRAWER are currently only used on s390, where
|
||||||
they reflect the cpu and cache hierarchy.
|
they reflect the cpu and cache hierarchy.
|
||||||
|
|
||||||
For an architecture to support this feature, it must define some of
|
For an architecture to support this feature, it must define some of
|
||||||
these macros in include/asm-XXX/topology.h:
|
these macros in include/asm-XXX/topology.h::
|
||||||
|
|
||||||
#define topology_physical_package_id(cpu)
|
#define topology_physical_package_id(cpu)
|
||||||
#define topology_core_id(cpu)
|
#define topology_core_id(cpu)
|
||||||
#define topology_book_id(cpu)
|
#define topology_book_id(cpu)
|
||||||
|
@ -85,14 +89,15 @@ these macros in include/asm-XXX/topology.h:
|
||||||
#define topology_book_cpumask(cpu)
|
#define topology_book_cpumask(cpu)
|
||||||
#define topology_drawer_cpumask(cpu)
|
#define topology_drawer_cpumask(cpu)
|
||||||
|
|
||||||
The type of **_id macros is int.
|
The type of ``**_id macros`` is int.
|
||||||
The type of **_cpumask macros is (const) struct cpumask *. The latter
|
The type of ``**_cpumask macros`` is ``(const) struct cpumask *``. The latter
|
||||||
correspond with appropriate **_siblings sysfs attributes (except for
|
correspond with appropriate ``**_siblings`` sysfs attributes (except for
|
||||||
topology_sibling_cpumask() which corresponds with thread_siblings).
|
topology_sibling_cpumask() which corresponds with thread_siblings).
|
||||||
|
|
||||||
To be consistent on all architectures, include/linux/topology.h
|
To be consistent on all architectures, include/linux/topology.h
|
||||||
provides default definitions for any of the above macros that are
|
provides default definitions for any of the above macros that are
|
||||||
not defined by include/asm-XXX/topology.h:
|
not defined by include/asm-XXX/topology.h:
|
||||||
|
|
||||||
1) physical_package_id: -1
|
1) physical_package_id: -1
|
||||||
2) core_id: 0
|
2) core_id: 0
|
||||||
3) sibling_cpumask: just the given CPU
|
3) sibling_cpumask: just the given CPU
|
||||||
|
@ -107,6 +112,7 @@ Additionally, CPU topology information is provided under
|
||||||
/sys/devices/system/cpu and includes these files. The internal
|
/sys/devices/system/cpu and includes these files. The internal
|
||||||
source for the output is in brackets ("[]").
|
source for the output is in brackets ("[]").
|
||||||
|
|
||||||
|
=========== ==========================================================
|
||||||
kernel_max: the maximum CPU index allowed by the kernel configuration.
|
kernel_max: the maximum CPU index allowed by the kernel configuration.
|
||||||
[NR_CPUS-1]
|
[NR_CPUS-1]
|
||||||
|
|
||||||
|
@ -122,6 +128,7 @@ source for the output is in brackets ("[]").
|
||||||
|
|
||||||
present: CPUs that have been identified as being present in the
|
present: CPUs that have been identified as being present in the
|
||||||
system. [cpu_present_mask]
|
system. [cpu_present_mask]
|
||||||
|
=========== ==========================================================
|
||||||
|
|
||||||
The format for the above output is compatible with cpulist_parse()
|
The format for the above output is compatible with cpulist_parse()
|
||||||
[see <linux/cpumask.h>]. Some examples follow.
|
[see <linux/cpumask.h>]. Some examples follow.
|
||||||
|
@ -129,7 +136,7 @@ The format for the above output is compatible with cpulist_parse()
|
||||||
In this example, there are 64 CPUs in the system but cpus 32-63 exceed
|
In this example, there are 64 CPUs in the system but cpus 32-63 exceed
|
||||||
the kernel max which is limited to 0..31 by the NR_CPUS config option
|
the kernel max which is limited to 0..31 by the NR_CPUS config option
|
||||||
being 32. Note also that CPUs 2 and 4-31 are not online but could be
|
being 32. Note also that CPUs 2 and 4-31 are not online but could be
|
||||||
brought online as they are both present and possible.
|
brought online as they are both present and possible::
|
||||||
|
|
||||||
kernel_max: 31
|
kernel_max: 31
|
||||||
offline: 2,4-31,32-63
|
offline: 2,4-31,32-63
|
||||||
|
@ -140,7 +147,7 @@ brought online as they are both present and possible.
|
||||||
In this example, the NR_CPUS config option is 128, but the kernel was
|
In this example, the NR_CPUS config option is 128, but the kernel was
|
||||||
started with possible_cpus=144. There are 4 CPUs in the system and cpu2
|
started with possible_cpus=144. There are 4 CPUs in the system and cpu2
|
||||||
was manually taken offline (and is the only CPU that can be brought
|
was manually taken offline (and is the only CPU that can be brought
|
||||||
online.)
|
online.)::
|
||||||
|
|
||||||
kernel_max: 127
|
kernel_max: 127
|
||||||
offline: 2,4-127,128-143
|
offline: 2,4-127,128-143
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
A brief CRC tutorial.
|
=================================
|
||||||
|
brief tutorial on CRC computation
|
||||||
|
=================================
|
||||||
|
|
||||||
A CRC is a long-division remainder. You add the CRC to the message,
|
A CRC is a long-division remainder. You add the CRC to the message,
|
||||||
and the whole thing (message+CRC) is a multiple of the given
|
and the whole thing (message+CRC) is a multiple of the given
|
||||||
|
@ -8,7 +10,8 @@ remainder computed on the message+CRC is 0. This latter approach
|
||||||
is used by a lot of hardware implementations, and is why so many
|
is used by a lot of hardware implementations, and is why so many
|
||||||
protocols put the end-of-frame flag after the CRC.
|
protocols put the end-of-frame flag after the CRC.
|
||||||
|
|
||||||
It's actually the same long division you learned in school, except that
|
It's actually the same long division you learned in school, except that:
|
||||||
|
|
||||||
- We're working in binary, so the digits are only 0 and 1, and
|
- We're working in binary, so the digits are only 0 and 1, and
|
||||||
- When dividing polynomials, there are no carries. Rather than add and
|
- When dividing polynomials, there are no carries. Rather than add and
|
||||||
subtract, we just xor. Thus, we tend to get a bit sloppy about
|
subtract, we just xor. Thus, we tend to get a bit sloppy about
|
||||||
|
@ -40,7 +43,8 @@ throw the quotient bit away, but subtract the appropriate multiple of
|
||||||
the polynomial from the remainder and we're back to where we started,
|
the polynomial from the remainder and we're back to where we started,
|
||||||
ready to process the next bit.
|
ready to process the next bit.
|
||||||
|
|
||||||
A big-endian CRC written this way would be coded like:
|
A big-endian CRC written this way would be coded like::
|
||||||
|
|
||||||
for (i = 0; i < input_bits; i++) {
|
for (i = 0; i < input_bits; i++) {
|
||||||
multiple = remainder & 0x80000000 ? CRCPOLY : 0;
|
multiple = remainder & 0x80000000 ? CRCPOLY : 0;
|
||||||
remainder = (remainder << 1 | next_input_bit()) ^ multiple;
|
remainder = (remainder << 1 | next_input_bit()) ^ multiple;
|
||||||
|
@ -54,12 +58,12 @@ the remainder don't actually affect any decision-making until
|
||||||
32 bits later. Thus, the first 32 cycles of this are pretty boring.
|
32 bits later. Thus, the first 32 cycles of this are pretty boring.
|
||||||
Also, to add the CRC to a message, we need a 32-bit-long hole for it at
|
Also, to add the CRC to a message, we need a 32-bit-long hole for it at
|
||||||
the end, so we have to add 32 extra cycles shifting in zeros at the
|
the end, so we have to add 32 extra cycles shifting in zeros at the
|
||||||
end of every message,
|
end of every message.
|
||||||
|
|
||||||
These details lead to a standard trick: rearrange merging in the
|
These details lead to a standard trick: rearrange merging in the
|
||||||
next_input_bit() until the moment it's needed. Then the first 32 cycles
|
next_input_bit() until the moment it's needed. Then the first 32 cycles
|
||||||
can be precomputed, and merging in the final 32 zero bits to make room
|
can be precomputed, and merging in the final 32 zero bits to make room
|
||||||
for the CRC can be skipped entirely. This changes the code to:
|
for the CRC can be skipped entirely. This changes the code to::
|
||||||
|
|
||||||
for (i = 0; i < input_bits; i++) {
|
for (i = 0; i < input_bits; i++) {
|
||||||
remainder ^= next_input_bit() << 31;
|
remainder ^= next_input_bit() << 31;
|
||||||
|
@ -67,7 +71,8 @@ for (i = 0; i < input_bits; i++) {
|
||||||
remainder = (remainder << 1) ^ multiple;
|
remainder = (remainder << 1) ^ multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
With this optimization, the little-endian code is particularly simple:
|
With this optimization, the little-endian code is particularly simple::
|
||||||
|
|
||||||
for (i = 0; i < input_bits; i++) {
|
for (i = 0; i < input_bits; i++) {
|
||||||
remainder ^= next_input_bit();
|
remainder ^= next_input_bit();
|
||||||
multiple = (remainder & 1) ? CRCPOLY : 0;
|
multiple = (remainder & 1) ? CRCPOLY : 0;
|
||||||
|
@ -81,7 +86,8 @@ be bit-reversed) and next_input_bit().
|
||||||
|
|
||||||
As long as next_input_bit is returning the bits in a sensible order, we don't
|
As long as next_input_bit is returning the bits in a sensible order, we don't
|
||||||
*have* to wait until the last possible moment to merge in additional bits.
|
*have* to wait until the last possible moment to merge in additional bits.
|
||||||
We can do it 8 bits at a time rather than 1 bit at a time:
|
We can do it 8 bits at a time rather than 1 bit at a time::
|
||||||
|
|
||||||
for (i = 0; i < input_bytes; i++) {
|
for (i = 0; i < input_bytes; i++) {
|
||||||
remainder ^= next_input_byte() << 24;
|
remainder ^= next_input_byte() << 24;
|
||||||
for (j = 0; j < 8; j++) {
|
for (j = 0; j < 8; j++) {
|
||||||
|
@ -90,7 +96,8 @@ for (i = 0; i < input_bytes; i++) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Or in little-endian:
|
Or in little-endian::
|
||||||
|
|
||||||
for (i = 0; i < input_bytes; i++) {
|
for (i = 0; i < input_bytes; i++) {
|
||||||
remainder ^= next_input_byte();
|
remainder ^= next_input_byte();
|
||||||
for (j = 0; j < 8; j++) {
|
for (j = 0; j < 8; j++) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue