Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

No conflicts.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2022-06-23 12:33:24 -07:00
commit 93817be8b6
293 changed files with 3709 additions and 2585 deletions

View File

@ -40,7 +40,6 @@ properties:
value to be used for converting remote channel measurements to value to be used for converting remote channel measurements to
temperature. temperature.
$ref: /schemas/types.yaml#/definitions/int32 $ref: /schemas/types.yaml#/definitions/int32
items:
minimum: -128 minimum: -128
maximum: 127 maximum: 127

View File

@ -30,6 +30,7 @@ properties:
- socionext,uniphier-ld11-aidet - socionext,uniphier-ld11-aidet
- socionext,uniphier-ld20-aidet - socionext,uniphier-ld20-aidet
- socionext,uniphier-pxs3-aidet - socionext,uniphier-pxs3-aidet
- socionext,uniphier-nx1-aidet
reg: reg:
maxItems: 1 maxItems: 1

View File

@ -13,8 +13,8 @@ disappeared as of Linux 3.0.
There are two places where extended attributes can be found. The first There are two places where extended attributes can be found. The first
place is between the end of each inode entry and the beginning of the place is between the end of each inode entry and the beginning of the
next inode entry. For example, if inode.i\_extra\_isize = 28 and next inode entry. For example, if inode.i_extra_isize = 28 and
sb.inode\_size = 256, then there are 256 - (128 + 28) = 100 bytes sb.inode_size = 256, then there are 256 - (128 + 28) = 100 bytes
available for in-inode extended attribute storage. The second place available for in-inode extended attribute storage. The second place
where extended attributes can be found is in the block pointed to by where extended attributes can be found is in the block pointed to by
``inode.i_file_acl``. As of Linux 3.11, it is not possible for this ``inode.i_file_acl``. As of Linux 3.11, it is not possible for this
@ -38,8 +38,8 @@ Extended attributes, when stored after the inode, have a header
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- h\_magic - h_magic
- Magic number for identification, 0xEA020000. This value is set by the - Magic number for identification, 0xEA020000. This value is set by the
Linux driver, though e2fsprogs doesn't seem to check it(?) Linux driver, though e2fsprogs doesn't seem to check it(?)
@ -55,28 +55,28 @@ The beginning of an extended attribute block is in
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- h\_magic - h_magic
- Magic number for identification, 0xEA020000. - Magic number for identification, 0xEA020000.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- h\_refcount - h_refcount
- Reference count. - Reference count.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- h\_blocks - h_blocks
- Number of disk blocks used. - Number of disk blocks used.
* - 0xC * - 0xC
- \_\_le32 - __le32
- h\_hash - h_hash
- Hash value of all attributes. - Hash value of all attributes.
* - 0x10 * - 0x10
- \_\_le32 - __le32
- h\_checksum - h_checksum
- Checksum of the extended attribute block. - Checksum of the extended attribute block.
* - 0x14 * - 0x14
- \_\_u32 - __u32
- h\_reserved[3] - h_reserved[3]
- Zero. - Zero.
The checksum is calculated against the FS UUID, the 64-bit block number The checksum is calculated against the FS UUID, the 64-bit block number
@ -100,46 +100,46 @@ Attributes stored inside an inode do not need be stored in sorted order.
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_u8 - __u8
- e\_name\_len - e_name_len
- Length of name. - Length of name.
* - 0x1 * - 0x1
- \_\_u8 - __u8
- e\_name\_index - e_name_index
- Attribute name index. There is a discussion of this below. - Attribute name index. There is a discussion of this below.
* - 0x2 * - 0x2
- \_\_le16 - __le16
- e\_value\_offs - e_value_offs
- Location of this attribute's value on the disk block where it is stored. - Location of this attribute's value on the disk block where it is stored.
Multiple attributes can share the same value. For an inode attribute Multiple attributes can share the same value. For an inode attribute
this value is relative to the start of the first entry; for a block this this value is relative to the start of the first entry; for a block this
value is relative to the start of the block (i.e. the header). value is relative to the start of the block (i.e. the header).
* - 0x4 * - 0x4
- \_\_le32 - __le32
- e\_value\_inum - e_value_inum
- The inode where the value is stored. Zero indicates the value is in the - The inode where the value is stored. Zero indicates the value is in the
same block as this entry. This field is only used if the same block as this entry. This field is only used if the
INCOMPAT\_EA\_INODE feature is enabled. INCOMPAT_EA_INODE feature is enabled.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- e\_value\_size - e_value_size
- Length of attribute value. - Length of attribute value.
* - 0xC * - 0xC
- \_\_le32 - __le32
- e\_hash - e_hash
- Hash value of attribute name and attribute value. The kernel doesn't - Hash value of attribute name and attribute value. The kernel doesn't
update the hash for in-inode attributes, so for that case this value update the hash for in-inode attributes, so for that case this value
must be zero, because e2fsck validates any non-zero hash regardless of must be zero, because e2fsck validates any non-zero hash regardless of
where the xattr lives. where the xattr lives.
* - 0x10 * - 0x10
- char - char
- e\_name[e\_name\_len] - e_name[e_name_len]
- Attribute name. Does not include trailing NULL. - Attribute name. Does not include trailing NULL.
Attribute values can follow the end of the entry table. There appears to Attribute values can follow the end of the entry table. There appears to
be a requirement that they be aligned to 4-byte boundaries. The values be a requirement that they be aligned to 4-byte boundaries. The values
are stored starting at the end of the block and grow towards the are stored starting at the end of the block and grow towards the
xattr\_header/xattr\_entry table. When the two collide, the overflow is xattr_header/xattr_entry table. When the two collide, the overflow is
put into a separate disk block. If the disk block fills up, the put into a separate disk block. If the disk block fills up, the
filesystem returns -ENOSPC. filesystem returns -ENOSPC.
@ -167,15 +167,15 @@ the key name. Here is a map of name index values to key prefixes:
* - 1 * - 1
- “user.” - “user.”
* - 2 * - 2
- “system.posix\_acl\_access” - “system.posix_acl_access”
* - 3 * - 3
- “system.posix\_acl\_default” - “system.posix_acl_default”
* - 4 * - 4
- “trusted.” - “trusted.”
* - 6 * - 6
- “security.” - “security.”
* - 7 * - 7
- “system.” (inline\_data only?) - “system.” (inline_data only?)
* - 8 * - 8
- “system.richacl” (SuSE kernels only?) - “system.richacl” (SuSE kernels only?)

View File

@ -23,7 +23,7 @@ means that a block group addresses 32 gigabytes instead of 128 megabytes,
also shrinking the amount of file system overhead for metadata. also shrinking the amount of file system overhead for metadata.
The administrator can set a block cluster size at mkfs time (which is The administrator can set a block cluster size at mkfs time (which is
stored in the s\_log\_cluster\_size field in the superblock); from then stored in the s_log_cluster_size field in the superblock); from then
on, the block bitmaps track clusters, not individual blocks. This means on, the block bitmaps track clusters, not individual blocks. This means
that block groups can be several gigabytes in size (instead of just that block groups can be several gigabytes in size (instead of just
128MiB); however, the minimum allocation unit becomes a cluster, not a 128MiB); however, the minimum allocation unit becomes a cluster, not a

View File

@ -9,15 +9,15 @@ group.
The inode bitmap records which entries in the inode table are in use. The inode bitmap records which entries in the inode table are in use.
As with most bitmaps, one bit represents the usage status of one data As with most bitmaps, one bit represents the usage status of one data
block or inode table entry. This implies a block group size of 8 \* block or inode table entry. This implies a block group size of 8 *
number\_of\_bytes\_in\_a\_logical\_block. number_of_bytes_in_a_logical_block.
NOTE: If ``BLOCK_UNINIT`` is set for a given block group, various parts NOTE: If ``BLOCK_UNINIT`` is set for a given block group, various parts
of the kernel and e2fsprogs code pretends that the block bitmap contains of the kernel and e2fsprogs code pretends that the block bitmap contains
zeros (i.e. all blocks in the group are free). However, it is not zeros (i.e. all blocks in the group are free). However, it is not
necessarily the case that no blocks are in use -- if ``meta_bg`` is set, necessarily the case that no blocks are in use -- if ``meta_bg`` is set,
the bitmaps and group descriptor live inside the group. Unfortunately, the bitmaps and group descriptor live inside the group. Unfortunately,
ext2fs\_test\_block\_bitmap2() will return '0' for those locations, ext2fs_test_block_bitmap2() will return '0' for those locations,
which produces confusing debugfs output. which produces confusing debugfs output.
Inode Table Inode Table

View File

@ -56,39 +56,39 @@ established that the super block and the group descriptor table, if
present, will be at the beginning of the block group. The bitmaps and present, will be at the beginning of the block group. The bitmaps and
the inode table can be anywhere, and it is quite possible for the the inode table can be anywhere, and it is quite possible for the
bitmaps to come after the inode table, or for both to be in different bitmaps to come after the inode table, or for both to be in different
groups (flex\_bg). Leftover space is used for file data blocks, indirect groups (flex_bg). Leftover space is used for file data blocks, indirect
block maps, extent tree blocks, and extended attributes. block maps, extent tree blocks, and extended attributes.
Flexible Block Groups Flexible Block Groups
--------------------- ---------------------
Starting in ext4, there is a new feature called flexible block groups Starting in ext4, there is a new feature called flexible block groups
(flex\_bg). In a flex\_bg, several block groups are tied together as one (flex_bg). In a flex_bg, several block groups are tied together as one
logical block group; the bitmap spaces and the inode table space in the logical block group; the bitmap spaces and the inode table space in the
first block group of the flex\_bg are expanded to include the bitmaps first block group of the flex_bg are expanded to include the bitmaps
and inode tables of all other block groups in the flex\_bg. For example, and inode tables of all other block groups in the flex_bg. For example,
if the flex\_bg size is 4, then group 0 will contain (in order) the if the flex_bg size is 4, then group 0 will contain (in order) the
superblock, group descriptors, data block bitmaps for groups 0-3, inode superblock, group descriptors, data block bitmaps for groups 0-3, inode
bitmaps for groups 0-3, inode tables for groups 0-3, and the remaining bitmaps for groups 0-3, inode tables for groups 0-3, and the remaining
space in group 0 is for file data. The effect of this is to group the space in group 0 is for file data. The effect of this is to group the
block group metadata close together for faster loading, and to enable block group metadata close together for faster loading, and to enable
large files to be continuous on disk. Backup copies of the superblock large files to be continuous on disk. Backup copies of the superblock
and group descriptors are always at the beginning of block groups, even and group descriptors are always at the beginning of block groups, even
if flex\_bg is enabled. The number of block groups that make up a if flex_bg is enabled. The number of block groups that make up a
flex\_bg is given by 2 ^ ``sb.s_log_groups_per_flex``. flex_bg is given by 2 ^ ``sb.s_log_groups_per_flex``.
Meta Block Groups Meta Block Groups
----------------- -----------------
Without the option META\_BG, for safety concerns, all block group Without the option META_BG, for safety concerns, all block group
descriptors copies are kept in the first block group. Given the default descriptors copies are kept in the first block group. Given the default
128MiB(2^27 bytes) block group size and 64-byte group descriptors, ext4 128MiB(2^27 bytes) block group size and 64-byte group descriptors, ext4
can have at most 2^27/64 = 2^21 block groups. This limits the entire can have at most 2^27/64 = 2^21 block groups. This limits the entire
filesystem size to 2^21 * 2^27 = 2^48bytes or 256TiB. filesystem size to 2^21 * 2^27 = 2^48bytes or 256TiB.
The solution to this problem is to use the metablock group feature The solution to this problem is to use the metablock group feature
(META\_BG), which is already in ext3 for all 2.6 releases. With the (META_BG), which is already in ext3 for all 2.6 releases. With the
META\_BG feature, ext4 filesystems are partitioned into many metablock META_BG feature, ext4 filesystems are partitioned into many metablock
groups. Each metablock group is a cluster of block groups whose group groups. Each metablock group is a cluster of block groups whose group
descriptor structures can be stored in a single disk block. For ext4 descriptor structures can be stored in a single disk block. For ext4
filesystems with 4 KB block size, a single metablock group partition filesystems with 4 KB block size, a single metablock group partition
@ -110,7 +110,7 @@ bytes, a meta-block group contains 32 block groups for filesystems with
a 1KB block size, and 128 block groups for filesystems with a 4KB a 1KB block size, and 128 block groups for filesystems with a 4KB
blocksize. Filesystems can either be created using this new block group blocksize. Filesystems can either be created using this new block group
descriptor layout, or existing filesystems can be resized on-line, and descriptor layout, or existing filesystems can be resized on-line, and
the field s\_first\_meta\_bg in the superblock will indicate the first the field s_first_meta_bg in the superblock will indicate the first
block group using this new layout. block group using this new layout.
Please see an important note about ``BLOCK_UNINIT`` in the section about Please see an important note about ``BLOCK_UNINIT`` in the section about
@ -121,15 +121,15 @@ Lazy Block Group Initialization
A new feature for ext4 are three block group descriptor flags that A new feature for ext4 are three block group descriptor flags that
enable mkfs to skip initializing other parts of the block group enable mkfs to skip initializing other parts of the block group
metadata. Specifically, the INODE\_UNINIT and BLOCK\_UNINIT flags mean metadata. Specifically, the INODE_UNINIT and BLOCK_UNINIT flags mean
that the inode and block bitmaps for that group can be calculated and that the inode and block bitmaps for that group can be calculated and
therefore the on-disk bitmap blocks are not initialized. This is therefore the on-disk bitmap blocks are not initialized. This is
generally the case for an empty block group or a block group containing generally the case for an empty block group or a block group containing
only fixed-location block group metadata. The INODE\_ZEROED flag means only fixed-location block group metadata. The INODE_ZEROED flag means
that the inode table has been initialized; mkfs will unset this flag and that the inode table has been initialized; mkfs will unset this flag and
rely on the kernel to initialize the inode tables in the background. rely on the kernel to initialize the inode tables in the background.
By not writing zeroes to the bitmaps and inode table, mkfs time is By not writing zeroes to the bitmaps and inode table, mkfs time is
reduced considerably. Note the feature flag is RO\_COMPAT\_GDT\_CSUM, reduced considerably. Note the feature flag is RO_COMPAT_GDT_CSUM,
but the dumpe2fs output prints this as “uninit\_bg”. They are the same but the dumpe2fs output prints this as “uninit_bg”. They are the same
thing. thing.

View File

@ -1,7 +1,7 @@
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| i.i\_block Offset | Where It Points | | i.i_block Offset | Where It Points |
+=====================+==============================================================================================================================================================================================================================+ +=====================+==============================================================================================================================================================================================================================+
| 0 to 11 | Direct map to file blocks 0 to 11. | | 0 to 11 | Direct map to file blocks 0 to 11. |
+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

View File

@ -4,7 +4,7 @@ Checksums
--------- ---------
Starting in early 2012, metadata checksums were added to all major ext4 Starting in early 2012, metadata checksums were added to all major ext4
and jbd2 data structures. The associated feature flag is metadata\_csum. and jbd2 data structures. The associated feature flag is metadata_csum.
The desired checksum algorithm is indicated in the superblock, though as The desired checksum algorithm is indicated in the superblock, though as
of October 2012 the only supported algorithm is crc32c. Some data of October 2012 the only supported algorithm is crc32c. Some data
structures did not have space to fit a full 32-bit checksum, so only the structures did not have space to fit a full 32-bit checksum, so only the
@ -20,7 +20,7 @@ encounters directory blocks that lack sufficient empty space to add a
checksum, it will request that you run ``e2fsck -D`` to have the checksum, it will request that you run ``e2fsck -D`` to have the
directories rebuilt with checksums. This has the added benefit of directories rebuilt with checksums. This has the added benefit of
removing slack space from the directory files and rebalancing the htree removing slack space from the directory files and rebalancing the htree
indexes. If you \_ignore\_ this step, your directories will not be indexes. If you _ignore_ this step, your directories will not be
protected by a checksum! protected by a checksum!
The following table describes the data elements that go into each type The following table describes the data elements that go into each type
@ -35,39 +35,39 @@ of checksum. The checksum function is whatever the superblock describes
- Length - Length
- Ingredients - Ingredients
* - Superblock * - Superblock
- \_\_le32 - __le32
- The entire superblock up to the checksum field. The UUID lives inside - The entire superblock up to the checksum field. The UUID lives inside
the superblock. the superblock.
* - MMP * - MMP
- \_\_le32 - __le32
- UUID + the entire MMP block up to the checksum field. - UUID + the entire MMP block up to the checksum field.
* - Extended Attributes * - Extended Attributes
- \_\_le32 - __le32
- UUID + the entire extended attribute block. The checksum field is set to - UUID + the entire extended attribute block. The checksum field is set to
zero. zero.
* - Directory Entries * - Directory Entries
- \_\_le32 - __le32
- UUID + inode number + inode generation + the directory block up to the - UUID + inode number + inode generation + the directory block up to the
fake entry enclosing the checksum field. fake entry enclosing the checksum field.
* - HTREE Nodes * - HTREE Nodes
- \_\_le32 - __le32
- UUID + inode number + inode generation + all valid extents + HTREE tail. - UUID + inode number + inode generation + all valid extents + HTREE tail.
The checksum field is set to zero. The checksum field is set to zero.
* - Extents * - Extents
- \_\_le32 - __le32
- UUID + inode number + inode generation + the entire extent block up to - UUID + inode number + inode generation + the entire extent block up to
the checksum field. the checksum field.
* - Bitmaps * - Bitmaps
- \_\_le32 or \_\_le16 - __le32 or __le16
- UUID + the entire bitmap. Checksums are stored in the group descriptor, - UUID + the entire bitmap. Checksums are stored in the group descriptor,
and truncated if the group descriptor size is 32 bytes (i.e. ^64bit) and truncated if the group descriptor size is 32 bytes (i.e. ^64bit)
* - Inodes * - Inodes
- \_\_le32 - __le32
- UUID + inode number + inode generation + the entire inode. The checksum - UUID + inode number + inode generation + the entire inode. The checksum
field is set to zero. Each inode has its own checksum. field is set to zero. Each inode has its own checksum.
* - Group Descriptors * - Group Descriptors
- \_\_le16 - __le16
- If metadata\_csum, then UUID + group number + the entire descriptor; - If metadata_csum, then UUID + group number + the entire descriptor;
else if gdt\_csum, then crc16(UUID + group number + the entire else if gdt_csum, then crc16(UUID + group number + the entire
descriptor). In all cases, only the lower 16 bits are stored. descriptor). In all cases, only the lower 16 bits are stored.

View File

@ -42,24 +42,24 @@ is at most 263 bytes long, though on disk you'll need to reference
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- inode - inode
- Number of the inode that this directory entry points to. - Number of the inode that this directory entry points to.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- rec\_len - rec_len
- Length of this directory entry. Must be a multiple of 4. - Length of this directory entry. Must be a multiple of 4.
* - 0x6 * - 0x6
- \_\_le16 - __le16
- name\_len - name_len
- Length of the file name. - Length of the file name.
* - 0x8 * - 0x8
- char - char
- name[EXT4\_NAME\_LEN] - name[EXT4_NAME_LEN]
- File name. - File name.
Since file names cannot be longer than 255 bytes, the new directory Since file names cannot be longer than 255 bytes, the new directory
entry format shortens the name\_len field and uses the space for a file entry format shortens the name_len field and uses the space for a file
type flag, probably to avoid having to load every inode during directory type flag, probably to avoid having to load every inode during directory
tree traversal. This format is ``ext4_dir_entry_2``, which is at most tree traversal. This format is ``ext4_dir_entry_2``, which is at most
263 bytes long, though on disk you'll need to reference 263 bytes long, though on disk you'll need to reference
@ -74,24 +74,24 @@ tree traversal. This format is ``ext4_dir_entry_2``, which is at most
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- inode - inode
- Number of the inode that this directory entry points to. - Number of the inode that this directory entry points to.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- rec\_len - rec_len
- Length of this directory entry. - Length of this directory entry.
* - 0x6 * - 0x6
- \_\_u8 - __u8
- name\_len - name_len
- Length of the file name. - Length of the file name.
* - 0x7 * - 0x7
- \_\_u8 - __u8
- file\_type - file_type
- File type code, see ftype_ table below. - File type code, see ftype_ table below.
* - 0x8 * - 0x8
- char - char
- name[EXT4\_NAME\_LEN] - name[EXT4_NAME_LEN]
- File name. - File name.
.. _ftype: .. _ftype:
@ -137,19 +137,19 @@ entry uses this extension, it may be up to 271 bytes.
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- hash - hash
- The hash of the directory name - The hash of the directory name
* - 0x4 * - 0x4
- \_\_le32 - __le32
- minor\_hash - minor_hash
- The minor hash of the directory name - The minor hash of the directory name
In order to add checksums to these classic directory blocks, a phony In order to add checksums to these classic directory blocks, a phony
``struct ext4_dir_entry`` is placed at the end of each leaf block to ``struct ext4_dir_entry`` is placed at the end of each leaf block to
hold the checksum. The directory entry is 12 bytes long. The inode hold the checksum. The directory entry is 12 bytes long. The inode
number and name\_len fields are set to zero to fool old software into number and name_len fields are set to zero to fool old software into
ignoring an apparently empty directory entry, and the checksum is stored ignoring an apparently empty directory entry, and the checksum is stored
in the place where the name normally goes. The structure is in the place where the name normally goes. The structure is
``struct ext4_dir_entry_tail``: ``struct ext4_dir_entry_tail``:
@ -163,24 +163,24 @@ in the place where the name normally goes. The structure is
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- det\_reserved\_zero1 - det_reserved_zero1
- Inode number, which must be zero. - Inode number, which must be zero.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- det\_rec\_len - det_rec_len
- Length of this directory entry, which must be 12. - Length of this directory entry, which must be 12.
* - 0x6 * - 0x6
- \_\_u8 - __u8
- det\_reserved\_zero2 - det_reserved_zero2
- Length of the file name, which must be zero. - Length of the file name, which must be zero.
* - 0x7 * - 0x7
- \_\_u8 - __u8
- det\_reserved\_ft - det_reserved_ft
- File type, which must be 0xDE. - File type, which must be 0xDE.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- det\_checksum - det_checksum
- Directory leaf block checksum. - Directory leaf block checksum.
The leaf directory block checksum is calculated against the FS UUID, the The leaf directory block checksum is calculated against the FS UUID, the
@ -194,7 +194,7 @@ Hash Tree Directories
A linear array of directory entries isn't great for performance, so a A linear array of directory entries isn't great for performance, so a
new feature was added to ext3 to provide a faster (but peculiar) new feature was added to ext3 to provide a faster (but peculiar)
balanced tree keyed off a hash of the directory entry name. If the balanced tree keyed off a hash of the directory entry name. If the
EXT4\_INDEX\_FL (0x1000) flag is set in the inode, this directory uses a EXT4_INDEX_FL (0x1000) flag is set in the inode, this directory uses a
hashed btree (htree) to organize and find directory entries. For hashed btree (htree) to organize and find directory entries. For
backwards read-only compatibility with ext2, this tree is actually backwards read-only compatibility with ext2, this tree is actually
hidden inside the directory file, masquerading as “empty” directory data hidden inside the directory file, masquerading as “empty” directory data
@ -206,14 +206,14 @@ rest of the directory block is empty so that it moves on.
The root of the tree always lives in the first data block of the The root of the tree always lives in the first data block of the
directory. By ext2 custom, the '.' and '..' entries must appear at the directory. By ext2 custom, the '.' and '..' entries must appear at the
beginning of this first block, so they are put here as two beginning of this first block, so they are put here as two
``struct ext4_dir_entry_2``\ s and not stored in the tree. The rest of ``struct ext4_dir_entry_2`` s and not stored in the tree. The rest of
the root node contains metadata about the tree and finally a hash->block the root node contains metadata about the tree and finally a hash->block
map to find nodes that are lower in the htree. If map to find nodes that are lower in the htree. If
``dx_root.info.indirect_levels`` is non-zero then the htree has two ``dx_root.info.indirect_levels`` is non-zero then the htree has two
levels; the data block pointed to by the root node's map is an interior levels; the data block pointed to by the root node's map is an interior
node, which is indexed by a minor hash. Interior nodes in this tree node, which is indexed by a minor hash. Interior nodes in this tree
contains a zeroed out ``struct ext4_dir_entry_2`` followed by a contains a zeroed out ``struct ext4_dir_entry_2`` followed by a
minor\_hash->block map to find leafe nodes. Leaf nodes contain a linear minor_hash->block map to find leafe nodes. Leaf nodes contain a linear
array of all ``struct ext4_dir_entry_2``; all of these entries array of all ``struct ext4_dir_entry_2``; all of these entries
(presumably) hash to the same value. If there is an overflow, the (presumably) hash to the same value. If there is an overflow, the
entries simply overflow into the next leaf node, and the entries simply overflow into the next leaf node, and the
@ -245,83 +245,83 @@ of a data block:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- dot.inode - dot.inode
- inode number of this directory. - inode number of this directory.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- dot.rec\_len - dot.rec_len
- Length of this record, 12. - Length of this record, 12.
* - 0x6 * - 0x6
- u8 - u8
- dot.name\_len - dot.name_len
- Length of the name, 1. - Length of the name, 1.
* - 0x7 * - 0x7
- u8 - u8
- dot.file\_type - dot.file_type
- File type of this entry, 0x2 (directory) (if the feature flag is set). - File type of this entry, 0x2 (directory) (if the feature flag is set).
* - 0x8 * - 0x8
- char - char
- dot.name[4] - dot.name[4]
- “.\\0\\0\\0” - “.\0\0\0”
* - 0xC * - 0xC
- \_\_le32 - __le32
- dotdot.inode - dotdot.inode
- inode number of parent directory. - inode number of parent directory.
* - 0x10 * - 0x10
- \_\_le16 - __le16
- dotdot.rec\_len - dotdot.rec_len
- block\_size - 12. The record length is long enough to cover all htree - block_size - 12. The record length is long enough to cover all htree
data. data.
* - 0x12 * - 0x12
- u8 - u8
- dotdot.name\_len - dotdot.name_len
- Length of the name, 2. - Length of the name, 2.
* - 0x13 * - 0x13
- u8 - u8
- dotdot.file\_type - dotdot.file_type
- File type of this entry, 0x2 (directory) (if the feature flag is set). - File type of this entry, 0x2 (directory) (if the feature flag is set).
* - 0x14 * - 0x14
- char - char
- dotdot\_name[4] - dotdot_name[4]
- “..\\0\\0” - “..\0\0”
* - 0x18 * - 0x18
- \_\_le32 - __le32
- struct dx\_root\_info.reserved\_zero - struct dx_root_info.reserved_zero
- Zero. - Zero.
* - 0x1C * - 0x1C
- u8 - u8
- struct dx\_root\_info.hash\_version - struct dx_root_info.hash_version
- Hash type, see dirhash_ table below. - Hash type, see dirhash_ table below.
* - 0x1D * - 0x1D
- u8 - u8
- struct dx\_root\_info.info\_length - struct dx_root_info.info_length
- Length of the tree information, 0x8. - Length of the tree information, 0x8.
* - 0x1E * - 0x1E
- u8 - u8
- struct dx\_root\_info.indirect\_levels - struct dx_root_info.indirect_levels
- Depth of the htree. Cannot be larger than 3 if the INCOMPAT\_LARGEDIR - Depth of the htree. Cannot be larger than 3 if the INCOMPAT_LARGEDIR
feature is set; cannot be larger than 2 otherwise. feature is set; cannot be larger than 2 otherwise.
* - 0x1F * - 0x1F
- u8 - u8
- struct dx\_root\_info.unused\_flags - struct dx_root_info.unused_flags
- -
* - 0x20 * - 0x20
- \_\_le16 - __le16
- limit - limit
- Maximum number of dx\_entries that can follow this header, plus 1 for - Maximum number of dx_entries that can follow this header, plus 1 for
the header itself. the header itself.
* - 0x22 * - 0x22
- \_\_le16 - __le16
- count - count
- Actual number of dx\_entries that follow this header, plus 1 for the - Actual number of dx_entries that follow this header, plus 1 for the
header itself. header itself.
* - 0x24 * - 0x24
- \_\_le32 - __le32
- block - block
- The block number (within the directory file) that goes with hash=0. - The block number (within the directory file) that goes with hash=0.
* - 0x28 * - 0x28
- struct dx\_entry - struct dx_entry
- entries[0] - entries[0]
- As many 8-byte ``struct dx_entry`` as fits in the rest of the data block. - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block.
@ -362,38 +362,38 @@ also the full length of a data block:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- fake.inode - fake.inode
- Zero, to make it look like this entry is not in use. - Zero, to make it look like this entry is not in use.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- fake.rec\_len - fake.rec_len
- The size of the block, in order to hide all of the dx\_node data. - The size of the block, in order to hide all of the dx_node data.
* - 0x6 * - 0x6
- u8 - u8
- name\_len - name_len
- Zero. There is no name for this “unused” directory entry. - Zero. There is no name for this “unused” directory entry.
* - 0x7 * - 0x7
- u8 - u8
- file\_type - file_type
- Zero. There is no file type for this “unused” directory entry. - Zero. There is no file type for this “unused” directory entry.
* - 0x8 * - 0x8
- \_\_le16 - __le16
- limit - limit
- Maximum number of dx\_entries that can follow this header, plus 1 for - Maximum number of dx_entries that can follow this header, plus 1 for
the header itself. the header itself.
* - 0xA * - 0xA
- \_\_le16 - __le16
- count - count
- Actual number of dx\_entries that follow this header, plus 1 for the - Actual number of dx_entries that follow this header, plus 1 for the
header itself. header itself.
* - 0xE * - 0xE
- \_\_le32 - __le32
- block - block
- The block number (within the directory file) that goes with the lowest - The block number (within the directory file) that goes with the lowest
hash value of this block. This value is stored in the parent block. hash value of this block. This value is stored in the parent block.
* - 0x12 * - 0x12
- struct dx\_entry - struct dx_entry
- entries[0] - entries[0]
- As many 8-byte ``struct dx_entry`` as fits in the rest of the data block. - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block.
@ -410,11 +410,11 @@ long:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- hash - hash
- Hash code. - Hash code.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- block - block
- Block number (within the directory file, not filesystem blocks) of the - Block number (within the directory file, not filesystem blocks) of the
next node in the htree. next node in the htree.
@ -423,13 +423,13 @@ long:
author.) author.)
If metadata checksums are enabled, the last 8 bytes of the directory If metadata checksums are enabled, the last 8 bytes of the directory
block (precisely the length of one dx\_entry) are used to store a block (precisely the length of one dx_entry) are used to store a
``struct dx_tail``, which contains the checksum. The ``limit`` and ``struct dx_tail``, which contains the checksum. The ``limit`` and
``count`` entries in the dx\_root/dx\_node structures are adjusted as ``count`` entries in the dx_root/dx_node structures are adjusted as
necessary to fit the dx\_tail into the block. If there is no space for necessary to fit the dx_tail into the block. If there is no space for
the dx\_tail, the user is notified to run e2fsck -D to rebuild the the dx_tail, the user is notified to run e2fsck -D to rebuild the
directory index (which will ensure that there's space for the checksum. directory index (which will ensure that there's space for the checksum.
The dx\_tail structure is 8 bytes long and looks like this: The dx_tail structure is 8 bytes long and looks like this:
.. list-table:: .. list-table::
:widths: 8 8 24 40 :widths: 8 8 24 40
@ -441,13 +441,13 @@ The dx\_tail structure is 8 bytes long and looks like this:
- Description - Description
* - 0x0 * - 0x0
- u32 - u32
- dt\_reserved - dt_reserved
- Zero. - Zero.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- dt\_checksum - dt_checksum
- Checksum of the htree directory block. - Checksum of the htree directory block.
The checksum is calculated against the FS UUID, the htree index header The checksum is calculated against the FS UUID, the htree index header
(dx\_root or dx\_node), all of the htree indices (dx\_entry) that are in (dx_root or dx_node), all of the htree indices (dx_entry) that are in
use, and the tail block (dx\_tail). use, and the tail block (dx_tail).

View File

@ -5,14 +5,14 @@ Large Extended Attribute Values
To enable ext4 to store extended attribute values that do not fit in the To enable ext4 to store extended attribute values that do not fit in the
inode or in the single extended attribute block attached to an inode, inode or in the single extended attribute block attached to an inode,
the EA\_INODE feature allows us to store the value in the data blocks of the EA_INODE feature allows us to store the value in the data blocks of
a regular file inode. This “EA inode” is linked only from the extended a regular file inode. This “EA inode” is linked only from the extended
attribute name index and must not appear in a directory entry. The attribute name index and must not appear in a directory entry. The
inode's i\_atime field is used to store a checksum of the xattr value; inode's i_atime field is used to store a checksum of the xattr value;
and i\_ctime/i\_version store a 64-bit reference count, which enables and i_ctime/i_version store a 64-bit reference count, which enables
sharing of large xattr values between multiple owning inodes. For sharing of large xattr values between multiple owning inodes. For
backward compatibility with older versions of this feature, the backward compatibility with older versions of this feature, the
i\_mtime/i\_generation *may* store a back-reference to the inode number i_mtime/i_generation *may* store a back-reference to the inode number
and i\_generation of the **one** owning inode (in cases where the EA and i_generation of the **one** owning inode (in cases where the EA
inode is not referenced by multiple inodes) to verify that the EA inode inode is not referenced by multiple inodes) to verify that the EA inode
is the correct one being accessed. is the correct one being accessed.

View File

@ -7,34 +7,34 @@ Each block group on the filesystem has one of these descriptors
associated with it. As noted in the Layout section above, the group associated with it. As noted in the Layout section above, the group
descriptors (if present) are the second item in the block group. The descriptors (if present) are the second item in the block group. The
standard configuration is for each block group to contain a full copy of standard configuration is for each block group to contain a full copy of
the block group descriptor table unless the sparse\_super feature flag the block group descriptor table unless the sparse_super feature flag
is set. is set.
Notice how the group descriptor records the location of both bitmaps and Notice how the group descriptor records the location of both bitmaps and
the inode table (i.e. they can float). This means that within a block the inode table (i.e. they can float). This means that within a block
group, the only data structures with fixed locations are the superblock group, the only data structures with fixed locations are the superblock
and the group descriptor table. The flex\_bg mechanism uses this and the group descriptor table. The flex_bg mechanism uses this
property to group several block groups into a flex group and lay out all property to group several block groups into a flex group and lay out all
of the groups' bitmaps and inode tables into one long run in the first of the groups' bitmaps and inode tables into one long run in the first
group of the flex group. group of the flex group.
If the meta\_bg feature flag is set, then several block groups are If the meta_bg feature flag is set, then several block groups are
grouped together into a meta group. Note that in the meta\_bg case, grouped together into a meta group. Note that in the meta_bg case,
however, the first and last two block groups within the larger meta however, the first and last two block groups within the larger meta
group contain only group descriptors for the groups inside the meta group contain only group descriptors for the groups inside the meta
group. group.
flex\_bg and meta\_bg do not appear to be mutually exclusive features. flex_bg and meta_bg do not appear to be mutually exclusive features.
In ext2, ext3, and ext4 (when the 64bit feature is not enabled), the In ext2, ext3, and ext4 (when the 64bit feature is not enabled), the
block group descriptor was only 32 bytes long and therefore ends at block group descriptor was only 32 bytes long and therefore ends at
bg\_checksum. On an ext4 filesystem with the 64bit feature enabled, the bg_checksum. On an ext4 filesystem with the 64bit feature enabled, the
block group descriptor expands to at least the 64 bytes described below; block group descriptor expands to at least the 64 bytes described below;
the size is stored in the superblock. the size is stored in the superblock.
If gdt\_csum is set and metadata\_csum is not set, the block group If gdt_csum is set and metadata_csum is not set, the block group
checksum is the crc16 of the FS UUID, the group number, and the group checksum is the crc16 of the FS UUID, the group number, and the group
descriptor structure. If metadata\_csum is set, then the block group descriptor structure. If metadata_csum is set, then the block group
checksum is the lower 16 bits of the checksum of the FS UUID, the group checksum is the lower 16 bits of the checksum of the FS UUID, the group
number, and the group descriptor structure. Both block and inode bitmap number, and the group descriptor structure. Both block and inode bitmap
checksums are calculated against the FS UUID, the group number, and the checksums are calculated against the FS UUID, the group number, and the
@ -51,59 +51,59 @@ The block group descriptor is laid out in ``struct ext4_group_desc``.
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- bg\_block\_bitmap\_lo - bg_block_bitmap_lo
- Lower 32-bits of location of block bitmap. - Lower 32-bits of location of block bitmap.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- bg\_inode\_bitmap\_lo - bg_inode_bitmap_lo
- Lower 32-bits of location of inode bitmap. - Lower 32-bits of location of inode bitmap.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- bg\_inode\_table\_lo - bg_inode_table_lo
- Lower 32-bits of location of inode table. - Lower 32-bits of location of inode table.
* - 0xC * - 0xC
- \_\_le16 - __le16
- bg\_free\_blocks\_count\_lo - bg_free_blocks_count_lo
- Lower 16-bits of free block count. - Lower 16-bits of free block count.
* - 0xE * - 0xE
- \_\_le16 - __le16
- bg\_free\_inodes\_count\_lo - bg_free_inodes_count_lo
- Lower 16-bits of free inode count. - Lower 16-bits of free inode count.
* - 0x10 * - 0x10
- \_\_le16 - __le16
- bg\_used\_dirs\_count\_lo - bg_used_dirs_count_lo
- Lower 16-bits of directory count. - Lower 16-bits of directory count.
* - 0x12 * - 0x12
- \_\_le16 - __le16
- bg\_flags - bg_flags
- Block group flags. See the bgflags_ table below. - Block group flags. See the bgflags_ table below.
* - 0x14 * - 0x14
- \_\_le32 - __le32
- bg\_exclude\_bitmap\_lo - bg_exclude_bitmap_lo
- Lower 32-bits of location of snapshot exclusion bitmap. - Lower 32-bits of location of snapshot exclusion bitmap.
* - 0x18 * - 0x18
- \_\_le16 - __le16
- bg\_block\_bitmap\_csum\_lo - bg_block_bitmap_csum_lo
- Lower 16-bits of the block bitmap checksum. - Lower 16-bits of the block bitmap checksum.
* - 0x1A * - 0x1A
- \_\_le16 - __le16
- bg\_inode\_bitmap\_csum\_lo - bg_inode_bitmap_csum_lo
- Lower 16-bits of the inode bitmap checksum. - Lower 16-bits of the inode bitmap checksum.
* - 0x1C * - 0x1C
- \_\_le16 - __le16
- bg\_itable\_unused\_lo - bg_itable_unused_lo
- Lower 16-bits of unused inode count. If set, we needn't scan past the - Lower 16-bits of unused inode count. If set, we needn't scan past the
``(sb.s_inodes_per_group - gdt.bg_itable_unused)``\ th entry in the ``(sb.s_inodes_per_group - gdt.bg_itable_unused)`` th entry in the
inode table for this group. inode table for this group.
* - 0x1E * - 0x1E
- \_\_le16 - __le16
- bg\_checksum - bg_checksum
- Group descriptor checksum; crc16(sb\_uuid+group\_num+bg\_desc) if the - Group descriptor checksum; crc16(sb_uuid+group_num+bg_desc) if the
RO\_COMPAT\_GDT\_CSUM feature is set, or RO_COMPAT_GDT_CSUM feature is set, or
crc32c(sb\_uuid+group\_num+bg\_desc) & 0xFFFF if the crc32c(sb_uuid+group_num+bg_desc) & 0xFFFF if the
RO\_COMPAT\_METADATA\_CSUM feature is set. The bg\_checksum RO_COMPAT_METADATA_CSUM feature is set. The bg_checksum
field in bg\_desc is skipped when calculating crc16 checksum, field in bg_desc is skipped when calculating crc16 checksum,
and set to zero if crc32c checksum is used. and set to zero if crc32c checksum is used.
* - * -
- -
@ -111,48 +111,48 @@ The block group descriptor is laid out in ``struct ext4_group_desc``.
- These fields only exist if the 64bit feature is enabled and s_desc_size - These fields only exist if the 64bit feature is enabled and s_desc_size
> 32. > 32.
* - 0x20 * - 0x20
- \_\_le32 - __le32
- bg\_block\_bitmap\_hi - bg_block_bitmap_hi
- Upper 32-bits of location of block bitmap. - Upper 32-bits of location of block bitmap.
* - 0x24 * - 0x24
- \_\_le32 - __le32
- bg\_inode\_bitmap\_hi - bg_inode_bitmap_hi
- Upper 32-bits of location of inodes bitmap. - Upper 32-bits of location of inodes bitmap.
* - 0x28 * - 0x28
- \_\_le32 - __le32
- bg\_inode\_table\_hi - bg_inode_table_hi
- Upper 32-bits of location of inodes table. - Upper 32-bits of location of inodes table.
* - 0x2C * - 0x2C
- \_\_le16 - __le16
- bg\_free\_blocks\_count\_hi - bg_free_blocks_count_hi
- Upper 16-bits of free block count. - Upper 16-bits of free block count.
* - 0x2E * - 0x2E
- \_\_le16 - __le16
- bg\_free\_inodes\_count\_hi - bg_free_inodes_count_hi
- Upper 16-bits of free inode count. - Upper 16-bits of free inode count.
* - 0x30 * - 0x30
- \_\_le16 - __le16
- bg\_used\_dirs\_count\_hi - bg_used_dirs_count_hi
- Upper 16-bits of directory count. - Upper 16-bits of directory count.
* - 0x32 * - 0x32
- \_\_le16 - __le16
- bg\_itable\_unused\_hi - bg_itable_unused_hi
- Upper 16-bits of unused inode count. - Upper 16-bits of unused inode count.
* - 0x34 * - 0x34
- \_\_le32 - __le32
- bg\_exclude\_bitmap\_hi - bg_exclude_bitmap_hi
- Upper 32-bits of location of snapshot exclusion bitmap. - Upper 32-bits of location of snapshot exclusion bitmap.
* - 0x38 * - 0x38
- \_\_le16 - __le16
- bg\_block\_bitmap\_csum\_hi - bg_block_bitmap_csum_hi
- Upper 16-bits of the block bitmap checksum. - Upper 16-bits of the block bitmap checksum.
* - 0x3A * - 0x3A
- \_\_le16 - __le16
- bg\_inode\_bitmap\_csum\_hi - bg_inode_bitmap_csum_hi
- Upper 16-bits of the inode bitmap checksum. - Upper 16-bits of the inode bitmap checksum.
* - 0x3C * - 0x3C
- \_\_u32 - __u32
- bg\_reserved - bg_reserved
- Padding to 64 bytes. - Padding to 64 bytes.
.. _bgflags: .. _bgflags:
@ -166,8 +166,8 @@ Block group flags can be any combination of the following:
* - Value * - Value
- Description - Description
* - 0x1 * - 0x1
- inode table and bitmap are not initialized (EXT4\_BG\_INODE\_UNINIT). - inode table and bitmap are not initialized (EXT4_BG_INODE_UNINIT).
* - 0x2 * - 0x2
- block bitmap is not initialized (EXT4\_BG\_BLOCK\_UNINIT). - block bitmap is not initialized (EXT4_BG_BLOCK_UNINIT).
* - 0x4 * - 0x4
- inode table is zeroed (EXT4\_BG\_INODE\_ZEROED). - inode table is zeroed (EXT4_BG_INODE_ZEROED).

View File

@ -1,6 +1,6 @@
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
The Contents of inode.i\_block The Contents of inode.i_block
------------------------------ ------------------------------
Depending on the type of file an inode describes, the 60 bytes of Depending on the type of file an inode describes, the 60 bytes of
@ -47,7 +47,7 @@ In ext4, the file to logical block map has been replaced with an extent
tree. Under the old scheme, allocating a contiguous run of 1,000 blocks tree. Under the old scheme, allocating a contiguous run of 1,000 blocks
requires an indirect block to map all 1,000 entries; with extents, the requires an indirect block to map all 1,000 entries; with extents, the
mapping is reduced to a single ``struct ext4_extent`` with mapping is reduced to a single ``struct ext4_extent`` with
``ee_len = 1000``. If flex\_bg is enabled, it is possible to allocate ``ee_len = 1000``. If flex_bg is enabled, it is possible to allocate
very large files with a single extent, at a considerable reduction in very large files with a single extent, at a considerable reduction in
metadata block use, and some improvement in disk efficiency. The inode metadata block use, and some improvement in disk efficiency. The inode
must have the extents flag (0x80000) flag set for this feature to be in must have the extents flag (0x80000) flag set for this feature to be in
@ -76,28 +76,28 @@ which is 12 bytes long:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le16 - __le16
- eh\_magic - eh_magic
- Magic number, 0xF30A. - Magic number, 0xF30A.
* - 0x2 * - 0x2
- \_\_le16 - __le16
- eh\_entries - eh_entries
- Number of valid entries following the header. - Number of valid entries following the header.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- eh\_max - eh_max
- Maximum number of entries that could follow the header. - Maximum number of entries that could follow the header.
* - 0x6 * - 0x6
- \_\_le16 - __le16
- eh\_depth - eh_depth
- Depth of this extent node in the extent tree. 0 = this extent node - Depth of this extent node in the extent tree. 0 = this extent node
points to data blocks; otherwise, this extent node points to other points to data blocks; otherwise, this extent node points to other
extent nodes. The extent tree can be at most 5 levels deep: a logical extent nodes. The extent tree can be at most 5 levels deep: a logical
block number can be at most ``2^32``, and the smallest ``n`` that block number can be at most ``2^32``, and the smallest ``n`` that
satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5. satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- eh\_generation - eh_generation
- Generation of the tree. (Used by Lustre, but not standard ext4). - Generation of the tree. (Used by Lustre, but not standard ext4).
Internal nodes of the extent tree, also known as index nodes, are Internal nodes of the extent tree, also known as index nodes, are
@ -112,22 +112,22 @@ recorded as ``struct ext4_extent_idx``, and are 12 bytes long:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- ei\_block - ei_block
- This index node covers file blocks from 'block' onward. - This index node covers file blocks from 'block' onward.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- ei\_leaf\_lo - ei_leaf_lo
- Lower 32-bits of the block number of the extent node that is the next - Lower 32-bits of the block number of the extent node that is the next
level lower in the tree. The tree node pointed to can be either another level lower in the tree. The tree node pointed to can be either another
internal node or a leaf node, described below. internal node or a leaf node, described below.
* - 0x8 * - 0x8
- \_\_le16 - __le16
- ei\_leaf\_hi - ei_leaf_hi
- Upper 16-bits of the previous field. - Upper 16-bits of the previous field.
* - 0xA * - 0xA
- \_\_u16 - __u16
- ei\_unused - ei_unused
- -
Leaf nodes of the extent tree are recorded as ``struct ext4_extent``, Leaf nodes of the extent tree are recorded as ``struct ext4_extent``,
@ -142,24 +142,24 @@ and are also 12 bytes long:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- ee\_block - ee_block
- First file block number that this extent covers. - First file block number that this extent covers.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- ee\_len - ee_len
- Number of blocks covered by extent. If the value of this field is <= - Number of blocks covered by extent. If the value of this field is <=
32768, the extent is initialized. If the value of the field is > 32768, 32768, the extent is initialized. If the value of the field is > 32768,
the extent is uninitialized and the actual extent length is ``ee_len`` - the extent is uninitialized and the actual extent length is ``ee_len`` -
32768. Therefore, the maximum length of a initialized extent is 32768 32768. Therefore, the maximum length of a initialized extent is 32768
blocks, and the maximum length of an uninitialized extent is 32767. blocks, and the maximum length of an uninitialized extent is 32767.
* - 0x6 * - 0x6
- \_\_le16 - __le16
- ee\_start\_hi - ee_start_hi
- Upper 16-bits of the block number to which this extent points. - Upper 16-bits of the block number to which this extent points.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- ee\_start\_lo - ee_start_lo
- Lower 32-bits of the block number to which this extent points. - Lower 32-bits of the block number to which this extent points.
Prior to the introduction of metadata checksums, the extent header + Prior to the introduction of metadata checksums, the extent header +
@ -182,8 +182,8 @@ including) the checksum itself.
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- eb\_checksum - eb_checksum
- Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock) - Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock)
Inline Data Inline Data

View File

@ -11,12 +11,12 @@ file is smaller than 60 bytes, then the data are stored inline in
attribute space, then it might be found as an extended attribute attribute space, then it might be found as an extended attribute
“system.data” within the inode body (“ibody EA”). This of course “system.data” within the inode body (“ibody EA”). This of course
constrains the amount of extended attributes one can attach to an inode. constrains the amount of extended attributes one can attach to an inode.
If the data size increases beyond i\_block + ibody EA, a regular block If the data size increases beyond i_block + ibody EA, a regular block
is allocated and the contents moved to that block. is allocated and the contents moved to that block.
Pending a change to compact the extended attribute key used to store Pending a change to compact the extended attribute key used to store
inline data, one ought to be able to store 160 bytes of data in a inline data, one ought to be able to store 160 bytes of data in a
256-byte inode (as of June 2015, when i\_extra\_isize is 28). Prior to 256-byte inode (as of June 2015, when i_extra_isize is 28). Prior to
that, the limit was 156 bytes due to inefficient use of inode space. that, the limit was 156 bytes due to inefficient use of inode space.
The inline data feature requires the presence of an extended attribute The inline data feature requires the presence of an extended attribute
@ -25,12 +25,12 @@ for “system.data”, even if the attribute value is zero length.
Inline Directories Inline Directories
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
The first four bytes of i\_block are the inode number of the parent The first four bytes of i_block are the inode number of the parent
directory. Following that is a 56-byte space for an array of directory directory. Following that is a 56-byte space for an array of directory
entries; see ``struct ext4_dir_entry``. If there is a “system.data” entries; see ``struct ext4_dir_entry``. If there is a “system.data”
attribute in the inode body, the EA value is an array of attribute in the inode body, the EA value is an array of
``struct ext4_dir_entry`` as well. Note that for inline directories, the ``struct ext4_dir_entry`` as well. Note that for inline directories, the
i\_block and EA space are treated as separate dirent blocks; directory i_block and EA space are treated as separate dirent blocks; directory
entries cannot span the two. entries cannot span the two.
Inline directory entries are not checksummed, as the inode checksum Inline directory entries are not checksummed, as the inode checksum

View File

@ -38,138 +38,138 @@ The inode table entry is laid out in ``struct ext4_inode``.
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le16 - __le16
- i\_mode - i_mode
- File mode. See the table i_mode_ below. - File mode. See the table i_mode_ below.
* - 0x2 * - 0x2
- \_\_le16 - __le16
- i\_uid - i_uid
- Lower 16-bits of Owner UID. - Lower 16-bits of Owner UID.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- i\_size\_lo - i_size_lo
- Lower 32-bits of size in bytes. - Lower 32-bits of size in bytes.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- i\_atime - i_atime
- Last access time, in seconds since the epoch. However, if the EA\_INODE - Last access time, in seconds since the epoch. However, if the EA_INODE
inode flag is set, this inode stores an extended attribute value and inode flag is set, this inode stores an extended attribute value and
this field contains the checksum of the value. this field contains the checksum of the value.
* - 0xC * - 0xC
- \_\_le32 - __le32
- i\_ctime - i_ctime
- Last inode change time, in seconds since the epoch. However, if the - Last inode change time, in seconds since the epoch. However, if the
EA\_INODE inode flag is set, this inode stores an extended attribute EA_INODE inode flag is set, this inode stores an extended attribute
value and this field contains the lower 32 bits of the attribute value's value and this field contains the lower 32 bits of the attribute value's
reference count. reference count.
* - 0x10 * - 0x10
- \_\_le32 - __le32
- i\_mtime - i_mtime
- Last data modification time, in seconds since the epoch. However, if the - Last data modification time, in seconds since the epoch. However, if the
EA\_INODE inode flag is set, this inode stores an extended attribute EA_INODE inode flag is set, this inode stores an extended attribute
value and this field contains the number of the inode that owns the value and this field contains the number of the inode that owns the
extended attribute. extended attribute.
* - 0x14 * - 0x14
- \_\_le32 - __le32
- i\_dtime - i_dtime
- Deletion Time, in seconds since the epoch. - Deletion Time, in seconds since the epoch.
* - 0x18 * - 0x18
- \_\_le16 - __le16
- i\_gid - i_gid
- Lower 16-bits of GID. - Lower 16-bits of GID.
* - 0x1A * - 0x1A
- \_\_le16 - __le16
- i\_links\_count - i_links_count
- Hard link count. Normally, ext4 does not permit an inode to have more - Hard link count. Normally, ext4 does not permit an inode to have more
than 65,000 hard links. This applies to files as well as directories, than 65,000 hard links. This applies to files as well as directories,
which means that there cannot be more than 64,998 subdirectories in a which means that there cannot be more than 64,998 subdirectories in a
directory (each subdirectory's '..' entry counts as a hard link, as does directory (each subdirectory's '..' entry counts as a hard link, as does
the '.' entry in the directory itself). With the DIR\_NLINK feature the '.' entry in the directory itself). With the DIR_NLINK feature
enabled, ext4 supports more than 64,998 subdirectories by setting this enabled, ext4 supports more than 64,998 subdirectories by setting this
field to 1 to indicate that the number of hard links is not known. field to 1 to indicate that the number of hard links is not known.
* - 0x1C * - 0x1C
- \_\_le32 - __le32
- i\_blocks\_lo - i_blocks_lo
- Lower 32-bits of “block” count. If the huge\_file feature flag is not - Lower 32-bits of “block” count. If the huge_file feature flag is not
set on the filesystem, the file consumes ``i_blocks_lo`` 512-byte blocks set on the filesystem, the file consumes ``i_blocks_lo`` 512-byte blocks
on disk. If huge\_file is set and EXT4\_HUGE\_FILE\_FL is NOT set in on disk. If huge_file is set and EXT4_HUGE_FILE_FL is NOT set in
``inode.i_flags``, then the file consumes ``i_blocks_lo + (i_blocks_hi ``inode.i_flags``, then the file consumes ``i_blocks_lo + (i_blocks_hi
<< 32)`` 512-byte blocks on disk. If huge\_file is set and << 32)`` 512-byte blocks on disk. If huge_file is set and
EXT4\_HUGE\_FILE\_FL IS set in ``inode.i_flags``, then this file EXT4_HUGE_FILE_FL IS set in ``inode.i_flags``, then this file
consumes (``i_blocks_lo + i_blocks_hi`` << 32) filesystem blocks on consumes (``i_blocks_lo + i_blocks_hi`` << 32) filesystem blocks on
disk. disk.
* - 0x20 * - 0x20
- \_\_le32 - __le32
- i\_flags - i_flags
- Inode flags. See the table i_flags_ below. - Inode flags. See the table i_flags_ below.
* - 0x24 * - 0x24
- 4 bytes - 4 bytes
- i\_osd1 - i_osd1
- See the table i_osd1_ for more details. - See the table i_osd1_ for more details.
* - 0x28 * - 0x28
- 60 bytes - 60 bytes
- i\_block[EXT4\_N\_BLOCKS=15] - i_block[EXT4_N_BLOCKS=15]
- Block map or extent tree. See the section “The Contents of inode.i\_block”. - Block map or extent tree. See the section “The Contents of inode.i_block”.
* - 0x64 * - 0x64
- \_\_le32 - __le32
- i\_generation - i_generation
- File version (for NFS). - File version (for NFS).
* - 0x68 * - 0x68
- \_\_le32 - __le32
- i\_file\_acl\_lo - i_file_acl_lo
- Lower 32-bits of extended attribute block. ACLs are of course one of - Lower 32-bits of extended attribute block. ACLs are of course one of
many possible extended attributes; I think the name of this field is a many possible extended attributes; I think the name of this field is a
result of the first use of extended attributes being for ACLs. result of the first use of extended attributes being for ACLs.
* - 0x6C * - 0x6C
- \_\_le32 - __le32
- i\_size\_high / i\_dir\_acl - i_size_high / i_dir_acl
- Upper 32-bits of file/directory size. In ext2/3 this field was named - Upper 32-bits of file/directory size. In ext2/3 this field was named
i\_dir\_acl, though it was usually set to zero and never used. i_dir_acl, though it was usually set to zero and never used.
* - 0x70 * - 0x70
- \_\_le32 - __le32
- i\_obso\_faddr - i_obso_faddr
- (Obsolete) fragment address. - (Obsolete) fragment address.
* - 0x74 * - 0x74
- 12 bytes - 12 bytes
- i\_osd2 - i_osd2
- See the table i_osd2_ for more details. - See the table i_osd2_ for more details.
* - 0x80 * - 0x80
- \_\_le16 - __le16
- i\_extra\_isize - i_extra_isize
- Size of this inode - 128. Alternately, the size of the extended inode - Size of this inode - 128. Alternately, the size of the extended inode
fields beyond the original ext2 inode, including this field. fields beyond the original ext2 inode, including this field.
* - 0x82 * - 0x82
- \_\_le16 - __le16
- i\_checksum\_hi - i_checksum_hi
- Upper 16-bits of the inode checksum. - Upper 16-bits of the inode checksum.
* - 0x84 * - 0x84
- \_\_le32 - __le32
- i\_ctime\_extra - i_ctime_extra
- Extra change time bits. This provides sub-second precision. See Inode - Extra change time bits. This provides sub-second precision. See Inode
Timestamps section. Timestamps section.
* - 0x88 * - 0x88
- \_\_le32 - __le32
- i\_mtime\_extra - i_mtime_extra
- Extra modification time bits. This provides sub-second precision. - Extra modification time bits. This provides sub-second precision.
* - 0x8C * - 0x8C
- \_\_le32 - __le32
- i\_atime\_extra - i_atime_extra
- Extra access time bits. This provides sub-second precision. - Extra access time bits. This provides sub-second precision.
* - 0x90 * - 0x90
- \_\_le32 - __le32
- i\_crtime - i_crtime
- File creation time, in seconds since the epoch. - File creation time, in seconds since the epoch.
* - 0x94 * - 0x94
- \_\_le32 - __le32
- i\_crtime\_extra - i_crtime_extra
- Extra file creation time bits. This provides sub-second precision. - Extra file creation time bits. This provides sub-second precision.
* - 0x98 * - 0x98
- \_\_le32 - __le32
- i\_version\_hi - i_version_hi
- Upper 32-bits for version number. - Upper 32-bits for version number.
* - 0x9C * - 0x9C
- \_\_le32 - __le32
- i\_projid - i_projid
- Project ID. - Project ID.
.. _i_mode: .. _i_mode:
@ -183,45 +183,45 @@ The ``i_mode`` value is a combination of the following flags:
* - Value * - Value
- Description - Description
* - 0x1 * - 0x1
- S\_IXOTH (Others may execute) - S_IXOTH (Others may execute)
* - 0x2 * - 0x2
- S\_IWOTH (Others may write) - S_IWOTH (Others may write)
* - 0x4 * - 0x4
- S\_IROTH (Others may read) - S_IROTH (Others may read)
* - 0x8 * - 0x8
- S\_IXGRP (Group members may execute) - S_IXGRP (Group members may execute)
* - 0x10 * - 0x10
- S\_IWGRP (Group members may write) - S_IWGRP (Group members may write)
* - 0x20 * - 0x20
- S\_IRGRP (Group members may read) - S_IRGRP (Group members may read)
* - 0x40 * - 0x40
- S\_IXUSR (Owner may execute) - S_IXUSR (Owner may execute)
* - 0x80 * - 0x80
- S\_IWUSR (Owner may write) - S_IWUSR (Owner may write)
* - 0x100 * - 0x100
- S\_IRUSR (Owner may read) - S_IRUSR (Owner may read)
* - 0x200 * - 0x200
- S\_ISVTX (Sticky bit) - S_ISVTX (Sticky bit)
* - 0x400 * - 0x400
- S\_ISGID (Set GID) - S_ISGID (Set GID)
* - 0x800 * - 0x800
- S\_ISUID (Set UID) - S_ISUID (Set UID)
* - * -
- These are mutually-exclusive file types: - These are mutually-exclusive file types:
* - 0x1000 * - 0x1000
- S\_IFIFO (FIFO) - S_IFIFO (FIFO)
* - 0x2000 * - 0x2000
- S\_IFCHR (Character device) - S_IFCHR (Character device)
* - 0x4000 * - 0x4000
- S\_IFDIR (Directory) - S_IFDIR (Directory)
* - 0x6000 * - 0x6000
- S\_IFBLK (Block device) - S_IFBLK (Block device)
* - 0x8000 * - 0x8000
- S\_IFREG (Regular file) - S_IFREG (Regular file)
* - 0xA000 * - 0xA000
- S\_IFLNK (Symbolic link) - S_IFLNK (Symbolic link)
* - 0xC000 * - 0xC000
- S\_IFSOCK (Socket) - S_IFSOCK (Socket)
.. _i_flags: .. _i_flags:
@ -234,56 +234,56 @@ The ``i_flags`` field is a combination of these values:
* - Value * - Value
- Description - Description
* - 0x1 * - 0x1
- This file requires secure deletion (EXT4\_SECRM\_FL). (not implemented) - This file requires secure deletion (EXT4_SECRM_FL). (not implemented)
* - 0x2 * - 0x2
- This file should be preserved, should undeletion be desired - This file should be preserved, should undeletion be desired
(EXT4\_UNRM\_FL). (not implemented) (EXT4_UNRM_FL). (not implemented)
* - 0x4 * - 0x4
- File is compressed (EXT4\_COMPR\_FL). (not really implemented) - File is compressed (EXT4_COMPR_FL). (not really implemented)
* - 0x8 * - 0x8
- All writes to the file must be synchronous (EXT4\_SYNC\_FL). - All writes to the file must be synchronous (EXT4_SYNC_FL).
* - 0x10 * - 0x10
- File is immutable (EXT4\_IMMUTABLE\_FL). - File is immutable (EXT4_IMMUTABLE_FL).
* - 0x20 * - 0x20
- File can only be appended (EXT4\_APPEND\_FL). - File can only be appended (EXT4_APPEND_FL).
* - 0x40 * - 0x40
- The dump(1) utility should not dump this file (EXT4\_NODUMP\_FL). - The dump(1) utility should not dump this file (EXT4_NODUMP_FL).
* - 0x80 * - 0x80
- Do not update access time (EXT4\_NOATIME\_FL). - Do not update access time (EXT4_NOATIME_FL).
* - 0x100 * - 0x100
- Dirty compressed file (EXT4\_DIRTY\_FL). (not used) - Dirty compressed file (EXT4_DIRTY_FL). (not used)
* - 0x200 * - 0x200
- File has one or more compressed clusters (EXT4\_COMPRBLK\_FL). (not used) - File has one or more compressed clusters (EXT4_COMPRBLK_FL). (not used)
* - 0x400 * - 0x400
- Do not compress file (EXT4\_NOCOMPR\_FL). (not used) - Do not compress file (EXT4_NOCOMPR_FL). (not used)
* - 0x800 * - 0x800
- Encrypted inode (EXT4\_ENCRYPT\_FL). This bit value previously was - Encrypted inode (EXT4_ENCRYPT_FL). This bit value previously was
EXT4\_ECOMPR\_FL (compression error), which was never used. EXT4_ECOMPR_FL (compression error), which was never used.
* - 0x1000 * - 0x1000
- Directory has hashed indexes (EXT4\_INDEX\_FL). - Directory has hashed indexes (EXT4_INDEX_FL).
* - 0x2000 * - 0x2000
- AFS magic directory (EXT4\_IMAGIC\_FL). - AFS magic directory (EXT4_IMAGIC_FL).
* - 0x4000 * - 0x4000
- File data must always be written through the journal - File data must always be written through the journal
(EXT4\_JOURNAL\_DATA\_FL). (EXT4_JOURNAL_DATA_FL).
* - 0x8000 * - 0x8000
- File tail should not be merged (EXT4\_NOTAIL\_FL). (not used by ext4) - File tail should not be merged (EXT4_NOTAIL_FL). (not used by ext4)
* - 0x10000 * - 0x10000
- All directory entry data should be written synchronously (see - All directory entry data should be written synchronously (see
``dirsync``) (EXT4\_DIRSYNC\_FL). ``dirsync``) (EXT4_DIRSYNC_FL).
* - 0x20000 * - 0x20000
- Top of directory hierarchy (EXT4\_TOPDIR\_FL). - Top of directory hierarchy (EXT4_TOPDIR_FL).
* - 0x40000 * - 0x40000
- This is a huge file (EXT4\_HUGE\_FILE\_FL). - This is a huge file (EXT4_HUGE_FILE_FL).
* - 0x80000 * - 0x80000
- Inode uses extents (EXT4\_EXTENTS\_FL). - Inode uses extents (EXT4_EXTENTS_FL).
* - 0x100000 * - 0x100000
- Verity protected file (EXT4\_VERITY\_FL). - Verity protected file (EXT4_VERITY_FL).
* - 0x200000 * - 0x200000
- Inode stores a large extended attribute value in its data blocks - Inode stores a large extended attribute value in its data blocks
(EXT4\_EA\_INODE\_FL). (EXT4_EA_INODE_FL).
* - 0x400000 * - 0x400000
- This file has blocks allocated past EOF (EXT4\_EOFBLOCKS\_FL). - This file has blocks allocated past EOF (EXT4_EOFBLOCKS_FL).
(deprecated) (deprecated)
* - 0x01000000 * - 0x01000000
- Inode is a snapshot (``EXT4_SNAPFILE_FL``). (not in mainline) - Inode is a snapshot (``EXT4_SNAPFILE_FL``). (not in mainline)
@ -294,21 +294,21 @@ The ``i_flags`` field is a combination of these values:
- Snapshot shrink has completed (``EXT4_SNAPFILE_SHRUNK_FL``). (not in - Snapshot shrink has completed (``EXT4_SNAPFILE_SHRUNK_FL``). (not in
mainline) mainline)
* - 0x10000000 * - 0x10000000
- Inode has inline data (EXT4\_INLINE\_DATA\_FL). - Inode has inline data (EXT4_INLINE_DATA_FL).
* - 0x20000000 * - 0x20000000
- Create children with the same project ID (EXT4\_PROJINHERIT\_FL). - Create children with the same project ID (EXT4_PROJINHERIT_FL).
* - 0x80000000 * - 0x80000000
- Reserved for ext4 library (EXT4\_RESERVED\_FL). - Reserved for ext4 library (EXT4_RESERVED_FL).
* - * -
- Aggregate flags: - Aggregate flags:
* - 0x705BDFFF * - 0x705BDFFF
- User-visible flags. - User-visible flags.
* - 0x604BC0FF * - 0x604BC0FF
- User-modifiable flags. Note that while EXT4\_JOURNAL\_DATA\_FL and - User-modifiable flags. Note that while EXT4_JOURNAL_DATA_FL and
EXT4\_EXTENTS\_FL can be set with setattr, they are not in the kernel's EXT4_EXTENTS_FL can be set with setattr, they are not in the kernel's
EXT4\_FL\_USER\_MODIFIABLE mask, since it needs to handle the setting of EXT4_FL_USER_MODIFIABLE mask, since it needs to handle the setting of
these flags in a special manner and they are masked out of the set of these flags in a special manner and they are masked out of the set of
flags that are saved directly to i\_flags. flags that are saved directly to i_flags.
.. _i_osd1: .. _i_osd1:
@ -325,9 +325,9 @@ Linux:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- l\_i\_version - l_i_version
- Inode version. However, if the EA\_INODE inode flag is set, this inode - Inode version. However, if the EA_INODE inode flag is set, this inode
stores an extended attribute value and this field contains the upper 32 stores an extended attribute value and this field contains the upper 32
bits of the attribute value's reference count. bits of the attribute value's reference count.
@ -342,8 +342,8 @@ Hurd:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- h\_i\_translator - h_i_translator
- ?? - ??
Masix: Masix:
@ -357,8 +357,8 @@ Masix:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- m\_i\_reserved - m_i_reserved
- ?? - ??
.. _i_osd2: .. _i_osd2:
@ -376,30 +376,30 @@ Linux:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le16 - __le16
- l\_i\_blocks\_high - l_i_blocks_high
- Upper 16-bits of the block count. Please see the note attached to - Upper 16-bits of the block count. Please see the note attached to
i\_blocks\_lo. i_blocks_lo.
* - 0x2 * - 0x2
- \_\_le16 - __le16
- l\_i\_file\_acl\_high - l_i_file_acl_high
- Upper 16-bits of the extended attribute block (historically, the file - Upper 16-bits of the extended attribute block (historically, the file
ACL location). See the Extended Attributes section below. ACL location). See the Extended Attributes section below.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- l\_i\_uid\_high - l_i_uid_high
- Upper 16-bits of the Owner UID. - Upper 16-bits of the Owner UID.
* - 0x6 * - 0x6
- \_\_le16 - __le16
- l\_i\_gid\_high - l_i_gid_high
- Upper 16-bits of the GID. - Upper 16-bits of the GID.
* - 0x8 * - 0x8
- \_\_le16 - __le16
- l\_i\_checksum\_lo - l_i_checksum_lo
- Lower 16-bits of the inode checksum. - Lower 16-bits of the inode checksum.
* - 0xA * - 0xA
- \_\_le16 - __le16
- l\_i\_reserved - l_i_reserved
- Unused. - Unused.
Hurd: Hurd:
@ -413,24 +413,24 @@ Hurd:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le16 - __le16
- h\_i\_reserved1 - h_i_reserved1
- ?? - ??
* - 0x2 * - 0x2
- \_\_u16 - __u16
- h\_i\_mode\_high - h_i_mode_high
- Upper 16-bits of the file mode. - Upper 16-bits of the file mode.
* - 0x4 * - 0x4
- \_\_le16 - __le16
- h\_i\_uid\_high - h_i_uid_high
- Upper 16-bits of the Owner UID. - Upper 16-bits of the Owner UID.
* - 0x6 * - 0x6
- \_\_le16 - __le16
- h\_i\_gid\_high - h_i_gid_high
- Upper 16-bits of the GID. - Upper 16-bits of the GID.
* - 0x8 * - 0x8
- \_\_u32 - __u32
- h\_i\_author - h_i_author
- Author code? - Author code?
Masix: Masix:
@ -444,17 +444,17 @@ Masix:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le16 - __le16
- h\_i\_reserved1 - h_i_reserved1
- ?? - ??
* - 0x2 * - 0x2
- \_\_u16 - __u16
- m\_i\_file\_acl\_high - m_i_file_acl_high
- Upper 16-bits of the extended attribute block (historically, the file - Upper 16-bits of the extended attribute block (historically, the file
ACL location). ACL location).
* - 0x4 * - 0x4
- \_\_u32 - __u32
- m\_i\_reserved2[2] - m_i_reserved2[2]
- ?? - ??
Inode Size Inode Size
@ -466,11 +466,11 @@ In ext2 and ext3, the inode structure size was fixed at 128 bytes
on-disk inode at format time for all inodes in the filesystem to provide on-disk inode at format time for all inodes in the filesystem to provide
space beyond the end of the original ext2 inode. The on-disk inode space beyond the end of the original ext2 inode. The on-disk inode
record size is recorded in the superblock as ``s_inode_size``. The record size is recorded in the superblock as ``s_inode_size``. The
number of bytes actually used by struct ext4\_inode beyond the original number of bytes actually used by struct ext4_inode beyond the original
128-byte ext2 inode is recorded in the ``i_extra_isize`` field for each 128-byte ext2 inode is recorded in the ``i_extra_isize`` field for each
inode, which allows struct ext4\_inode to grow for a new kernel without inode, which allows struct ext4_inode to grow for a new kernel without
having to upgrade all of the on-disk inodes. Access to fields beyond having to upgrade all of the on-disk inodes. Access to fields beyond
EXT2\_GOOD\_OLD\_INODE\_SIZE should be verified to be within EXT2_GOOD_OLD_INODE_SIZE should be verified to be within
``i_extra_isize``. By default, ext4 inode records are 256 bytes, and (as ``i_extra_isize``. By default, ext4 inode records are 256 bytes, and (as
of August 2019) the inode structure is 160 bytes of August 2019) the inode structure is 160 bytes
(``i_extra_isize = 32``). The extra space between the end of the inode (``i_extra_isize = 32``). The extra space between the end of the inode
@ -516,7 +516,7 @@ creation time (crtime); this field is 64-bits wide and decoded in the
same manner as 64-bit [cma]time. Neither crtime nor dtime are accessible same manner as 64-bit [cma]time. Neither crtime nor dtime are accessible
through the regular stat() interface, though debugfs will report them. through the regular stat() interface, though debugfs will report them.
We use the 32-bit signed time value plus (2^32 \* (extra epoch bits)). We use the 32-bit signed time value plus (2^32 * (extra epoch bits)).
In other words: In other words:
.. list-table:: .. list-table::
@ -525,8 +525,8 @@ In other words:
* - Extra epoch bits * - Extra epoch bits
- MSB of 32-bit time - MSB of 32-bit time
- Adjustment for signed 32-bit to 64-bit tv\_sec - Adjustment for signed 32-bit to 64-bit tv_sec
- Decoded 64-bit tv\_sec - Decoded 64-bit tv_sec
- valid time range - valid time range
* - 0 0 * - 0 0
- 1 - 1

View File

@ -63,8 +63,8 @@ Generally speaking, the journal has this format:
:header-rows: 1 :header-rows: 1
* - Superblock * - Superblock
- descriptor\_block (data\_blocks or revocation\_block) [more data or - descriptor_block (data_blocks or revocation_block) [more data or
revocations] commmit\_block revocations] commmit_block
- [more transactions...] - [more transactions...]
* - * -
- One transaction - One transaction
@ -93,8 +93,8 @@ superblock.
* - 1024 bytes of padding * - 1024 bytes of padding
- ext4 Superblock - ext4 Superblock
- Journal Superblock - Journal Superblock
- descriptor\_block (data\_blocks or revocation\_block) [more data or - descriptor_block (data_blocks or revocation_block) [more data or
revocations] commmit\_block revocations] commmit_block
- [more transactions...] - [more transactions...]
* - * -
- -
@ -117,17 +117,17 @@ Every block in the journal starts with a common 12-byte header
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_be32 - __be32
- h\_magic - h_magic
- jbd2 magic number, 0xC03B3998. - jbd2 magic number, 0xC03B3998.
* - 0x4 * - 0x4
- \_\_be32 - __be32
- h\_blocktype - h_blocktype
- Description of what this block contains. See the jbd2_blocktype_ table - Description of what this block contains. See the jbd2_blocktype_ table
below. below.
* - 0x8 * - 0x8
- \_\_be32 - __be32
- h\_sequence - h_sequence
- The transaction ID that goes with this block. - The transaction ID that goes with this block.
.. _jbd2_blocktype: .. _jbd2_blocktype:
@ -177,99 +177,99 @@ which is 1024 bytes long:
- -
- Static information describing the journal. - Static information describing the journal.
* - 0x0 * - 0x0
- journal\_header\_t (12 bytes) - journal_header_t (12 bytes)
- s\_header - s_header
- Common header identifying this as a superblock. - Common header identifying this as a superblock.
* - 0xC * - 0xC
- \_\_be32 - __be32
- s\_blocksize - s_blocksize
- Journal device block size. - Journal device block size.
* - 0x10 * - 0x10
- \_\_be32 - __be32
- s\_maxlen - s_maxlen
- Total number of blocks in this journal. - Total number of blocks in this journal.
* - 0x14 * - 0x14
- \_\_be32 - __be32
- s\_first - s_first
- First block of log information. - First block of log information.
* - * -
- -
- -
- Dynamic information describing the current state of the log. - Dynamic information describing the current state of the log.
* - 0x18 * - 0x18
- \_\_be32 - __be32
- s\_sequence - s_sequence
- First commit ID expected in log. - First commit ID expected in log.
* - 0x1C * - 0x1C
- \_\_be32 - __be32
- s\_start - s_start
- Block number of the start of log. Contrary to the comments, this field - Block number of the start of log. Contrary to the comments, this field
being zero does not imply that the journal is clean! being zero does not imply that the journal is clean!
* - 0x20 * - 0x20
- \_\_be32 - __be32
- s\_errno - s_errno
- Error value, as set by jbd2\_journal\_abort(). - Error value, as set by jbd2_journal_abort().
* - * -
- -
- -
- The remaining fields are only valid in a v2 superblock. - The remaining fields are only valid in a v2 superblock.
* - 0x24 * - 0x24
- \_\_be32 - __be32
- s\_feature\_compat; - s_feature_compat;
- Compatible feature set. See the table jbd2_compat_ below. - Compatible feature set. See the table jbd2_compat_ below.
* - 0x28 * - 0x28
- \_\_be32 - __be32
- s\_feature\_incompat - s_feature_incompat
- Incompatible feature set. See the table jbd2_incompat_ below. - Incompatible feature set. See the table jbd2_incompat_ below.
* - 0x2C * - 0x2C
- \_\_be32 - __be32
- s\_feature\_ro\_compat - s_feature_ro_compat
- Read-only compatible feature set. There aren't any of these currently. - Read-only compatible feature set. There aren't any of these currently.
* - 0x30 * - 0x30
- \_\_u8 - __u8
- s\_uuid[16] - s_uuid[16]
- 128-bit uuid for journal. This is compared against the copy in the ext4 - 128-bit uuid for journal. This is compared against the copy in the ext4
super block at mount time. super block at mount time.
* - 0x40 * - 0x40
- \_\_be32 - __be32
- s\_nr\_users - s_nr_users
- Number of file systems sharing this journal. - Number of file systems sharing this journal.
* - 0x44 * - 0x44
- \_\_be32 - __be32
- s\_dynsuper - s_dynsuper
- Location of dynamic super block copy. (Not used?) - Location of dynamic super block copy. (Not used?)
* - 0x48 * - 0x48
- \_\_be32 - __be32
- s\_max\_transaction - s_max_transaction
- Limit of journal blocks per transaction. (Not used?) - Limit of journal blocks per transaction. (Not used?)
* - 0x4C * - 0x4C
- \_\_be32 - __be32
- s\_max\_trans\_data - s_max_trans_data
- Limit of data blocks per transaction. (Not used?) - Limit of data blocks per transaction. (Not used?)
* - 0x50 * - 0x50
- \_\_u8 - __u8
- s\_checksum\_type - s_checksum_type
- Checksum algorithm used for the journal. See jbd2_checksum_type_ for - Checksum algorithm used for the journal. See jbd2_checksum_type_ for
more info. more info.
* - 0x51 * - 0x51
- \_\_u8[3] - __u8[3]
- s\_padding2 - s_padding2
- -
* - 0x54 * - 0x54
- \_\_be32 - __be32
- s\_num\_fc\_blocks - s_num_fc_blocks
- Number of fast commit blocks in the journal. - Number of fast commit blocks in the journal.
* - 0x58 * - 0x58
- \_\_u32 - __u32
- s\_padding[42] - s_padding[42]
- -
* - 0xFC * - 0xFC
- \_\_be32 - __be32
- s\_checksum - s_checksum
- Checksum of the entire superblock, with this field set to zero. - Checksum of the entire superblock, with this field set to zero.
* - 0x100 * - 0x100
- \_\_u8 - __u8
- s\_users[16\*48] - s_users[16*48]
- ids of all file systems sharing the log. e2fsprogs/Linux don't allow - ids of all file systems sharing the log. e2fsprogs/Linux don't allow
shared external journals, but I imagine Lustre (or ocfs2?), which use shared external journals, but I imagine Lustre (or ocfs2?), which use
the jbd2 code, might. the jbd2 code, might.
@ -286,7 +286,7 @@ The journal compat features are any combination of the following:
- Description - Description
* - 0x1 * - 0x1
- Journal maintains checksums on the data blocks. - Journal maintains checksums on the data blocks.
(JBD2\_FEATURE\_COMPAT\_CHECKSUM) (JBD2_FEATURE_COMPAT_CHECKSUM)
.. _jbd2_incompat: .. _jbd2_incompat:
@ -299,23 +299,23 @@ The journal incompat features are any combination of the following:
* - Value * - Value
- Description - Description
* - 0x1 * - 0x1
- Journal has block revocation records. (JBD2\_FEATURE\_INCOMPAT\_REVOKE) - Journal has block revocation records. (JBD2_FEATURE_INCOMPAT_REVOKE)
* - 0x2 * - 0x2
- Journal can deal with 64-bit block numbers. - Journal can deal with 64-bit block numbers.
(JBD2\_FEATURE\_INCOMPAT\_64BIT) (JBD2_FEATURE_INCOMPAT_64BIT)
* - 0x4 * - 0x4
- Journal commits asynchronously. (JBD2\_FEATURE\_INCOMPAT\_ASYNC\_COMMIT) - Journal commits asynchronously. (JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)
* - 0x8 * - 0x8
- This journal uses v2 of the checksum on-disk format. Each journal - This journal uses v2 of the checksum on-disk format. Each journal
metadata block gets its own checksum, and the block tags in the metadata block gets its own checksum, and the block tags in the
descriptor table contain checksums for each of the data blocks in the descriptor table contain checksums for each of the data blocks in the
journal. (JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2) journal. (JBD2_FEATURE_INCOMPAT_CSUM_V2)
* - 0x10 * - 0x10
- This journal uses v3 of the checksum on-disk format. This is the same as - This journal uses v3 of the checksum on-disk format. This is the same as
v2, but the journal block tag size is fixed regardless of the size of v2, but the journal block tag size is fixed regardless of the size of
block numbers. (JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3) block numbers. (JBD2_FEATURE_INCOMPAT_CSUM_V3)
* - 0x20 * - 0x20
- Journal has fast commit blocks. (JBD2\_FEATURE\_INCOMPAT\_FAST\_COMMIT) - Journal has fast commit blocks. (JBD2_FEATURE_INCOMPAT_FAST_COMMIT)
.. _jbd2_checksum_type: .. _jbd2_checksum_type:
@ -355,11 +355,11 @@ Descriptor blocks consume at least 36 bytes, but use a full block:
- Name - Name
- Descriptor - Descriptor
* - 0x0 * - 0x0
- journal\_header\_t - journal_header_t
- (open coded) - (open coded)
- Common block header. - Common block header.
* - 0xC * - 0xC
- struct journal\_block\_tag\_s - struct journal_block_tag_s
- open coded array[] - open coded array[]
- Enough tags either to fill up the block or to describe all the data - Enough tags either to fill up the block or to describe all the data
blocks that follow this descriptor block. blocks that follow this descriptor block.
@ -367,7 +367,7 @@ Descriptor blocks consume at least 36 bytes, but use a full block:
Journal block tags have any of the following formats, depending on which Journal block tags have any of the following formats, depending on which
journal feature and block tag flags are set. journal feature and block tag flags are set.
If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 is set, the journal block tag is If JBD2_FEATURE_INCOMPAT_CSUM_V3 is set, the journal block tag is
defined as ``struct journal_block_tag3_s``, which looks like the defined as ``struct journal_block_tag3_s``, which looks like the
following. The size is 16 or 32 bytes. following. The size is 16 or 32 bytes.
@ -380,24 +380,24 @@ following. The size is 16 or 32 bytes.
- Name - Name
- Descriptor - Descriptor
* - 0x0 * - 0x0
- \_\_be32 - __be32
- t\_blocknr - t_blocknr
- Lower 32-bits of the location of where the corresponding data block - Lower 32-bits of the location of where the corresponding data block
should end up on disk. should end up on disk.
* - 0x4 * - 0x4
- \_\_be32 - __be32
- t\_flags - t_flags
- Flags that go with the descriptor. See the table jbd2_tag_flags_ for - Flags that go with the descriptor. See the table jbd2_tag_flags_ for
more info. more info.
* - 0x8 * - 0x8
- \_\_be32 - __be32
- t\_blocknr\_high - t_blocknr_high
- Upper 32-bits of the location of where the corresponding data block - Upper 32-bits of the location of where the corresponding data block
should end up on disk. This is zero if JBD2\_FEATURE\_INCOMPAT\_64BIT is should end up on disk. This is zero if JBD2_FEATURE_INCOMPAT_64BIT is
not enabled. not enabled.
* - 0xC * - 0xC
- \_\_be32 - __be32
- t\_checksum - t_checksum
- Checksum of the journal UUID, the sequence number, and the data block. - Checksum of the journal UUID, the sequence number, and the data block.
* - * -
- -
@ -433,7 +433,7 @@ The journal tag flags are any combination of the following:
* - 0x8 * - 0x8
- This is the last tag in this descriptor block. - This is the last tag in this descriptor block.
If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 is NOT set, the journal block tag If JBD2_FEATURE_INCOMPAT_CSUM_V3 is NOT set, the journal block tag
is defined as ``struct journal_block_tag_s``, which looks like the is defined as ``struct journal_block_tag_s``, which looks like the
following. The size is 8, 12, 24, or 28 bytes: following. The size is 8, 12, 24, or 28 bytes:
@ -446,18 +446,18 @@ following. The size is 8, 12, 24, or 28 bytes:
- Name - Name
- Descriptor - Descriptor
* - 0x0 * - 0x0
- \_\_be32 - __be32
- t\_blocknr - t_blocknr
- Lower 32-bits of the location of where the corresponding data block - Lower 32-bits of the location of where the corresponding data block
should end up on disk. should end up on disk.
* - 0x4 * - 0x4
- \_\_be16 - __be16
- t\_checksum - t_checksum
- Checksum of the journal UUID, the sequence number, and the data block. - Checksum of the journal UUID, the sequence number, and the data block.
Note that only the lower 16 bits are stored. Note that only the lower 16 bits are stored.
* - 0x6 * - 0x6
- \_\_be16 - __be16
- t\_flags - t_flags
- Flags that go with the descriptor. See the table jbd2_tag_flags_ for - Flags that go with the descriptor. See the table jbd2_tag_flags_ for
more info. more info.
* - * -
@ -466,8 +466,8 @@ following. The size is 8, 12, 24, or 28 bytes:
- This next field is only present if the super block indicates support for - This next field is only present if the super block indicates support for
64-bit block numbers. 64-bit block numbers.
* - 0x8 * - 0x8
- \_\_be32 - __be32
- t\_blocknr\_high - t_blocknr_high
- Upper 32-bits of the location of where the corresponding data block - Upper 32-bits of the location of where the corresponding data block
should end up on disk. should end up on disk.
* - * -
@ -483,8 +483,8 @@ following. The size is 8, 12, 24, or 28 bytes:
``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that ``j_uuid`` field in ``struct journal_s``, but only tune2fs touches that
field. field.
If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or If JBD2_FEATURE_INCOMPAT_CSUM_V2 or
JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the block is a JBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the block is a
``struct jbd2_journal_block_tail``, which looks like this: ``struct jbd2_journal_block_tail``, which looks like this:
.. list-table:: .. list-table::
@ -496,8 +496,8 @@ JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the block is a
- Name - Name
- Descriptor - Descriptor
* - 0x0 * - 0x0
- \_\_be32 - __be32
- t\_checksum - t_checksum
- Checksum of the journal UUID + the descriptor block, with this field set - Checksum of the journal UUID + the descriptor block, with this field set
to zero. to zero.
@ -538,25 +538,25 @@ length, but use a full block:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- journal\_header\_t - journal_header_t
- r\_header - r_header
- Common block header. - Common block header.
* - 0xC * - 0xC
- \_\_be32 - __be32
- r\_count - r_count
- Number of bytes used in this block. - Number of bytes used in this block.
* - 0x10 * - 0x10
- \_\_be32 or \_\_be64 - __be32 or __be64
- blocks[0] - blocks[0]
- Blocks to revoke. - Blocks to revoke.
After r\_count is a linear array of block numbers that are effectively After r_count is a linear array of block numbers that are effectively
revoked by this transaction. The size of each block number is 8 bytes if revoked by this transaction. The size of each block number is 8 bytes if
the superblock advertises 64-bit block number support, or 4 bytes the superblock advertises 64-bit block number support, or 4 bytes
otherwise. otherwise.
If JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or If JBD2_FEATURE_INCOMPAT_CSUM_V2 or
JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 are set, the end of the revocation JBD2_FEATURE_INCOMPAT_CSUM_V3 are set, the end of the revocation
block is a ``struct jbd2_journal_revoke_tail``, which has this format: block is a ``struct jbd2_journal_revoke_tail``, which has this format:
.. list-table:: .. list-table::
@ -568,8 +568,8 @@ block is a ``struct jbd2_journal_revoke_tail``, which has this format:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_be32 - __be32
- r\_checksum - r_checksum
- Checksum of the journal UUID + revocation block - Checksum of the journal UUID + revocation block
Commit Block Commit Block
@ -592,38 +592,38 @@ bytes long (but uses a full block):
- Name - Name
- Descriptor - Descriptor
* - 0x0 * - 0x0
- journal\_header\_s - journal_header_s
- (open coded) - (open coded)
- Common block header. - Common block header.
* - 0xC * - 0xC
- unsigned char - unsigned char
- h\_chksum\_type - h_chksum_type
- The type of checksum to use to verify the integrity of the data blocks - The type of checksum to use to verify the integrity of the data blocks
in the transaction. See jbd2_checksum_type_ for more info. in the transaction. See jbd2_checksum_type_ for more info.
* - 0xD * - 0xD
- unsigned char - unsigned char
- h\_chksum\_size - h_chksum_size
- The number of bytes used by the checksum. Most likely 4. - The number of bytes used by the checksum. Most likely 4.
* - 0xE * - 0xE
- unsigned char - unsigned char
- h\_padding[2] - h_padding[2]
- -
* - 0x10 * - 0x10
- \_\_be32 - __be32
- h\_chksum[JBD2\_CHECKSUM\_BYTES] - h_chksum[JBD2_CHECKSUM_BYTES]
- 32 bytes of space to store checksums. If - 32 bytes of space to store checksums. If
JBD2\_FEATURE\_INCOMPAT\_CSUM\_V2 or JBD2\_FEATURE\_INCOMPAT\_CSUM\_V3 JBD2_FEATURE_INCOMPAT_CSUM_V2 or JBD2_FEATURE_INCOMPAT_CSUM_V3
are set, the first ``__be32`` is the checksum of the journal UUID and are set, the first ``__be32`` is the checksum of the journal UUID and
the entire commit block, with this field zeroed. If the entire commit block, with this field zeroed. If
JBD2\_FEATURE\_COMPAT\_CHECKSUM is set, the first ``__be32`` is the JBD2_FEATURE_COMPAT_CHECKSUM is set, the first ``__be32`` is the
crc32 of all the blocks already written to the transaction. crc32 of all the blocks already written to the transaction.
* - 0x30 * - 0x30
- \_\_be64 - __be64
- h\_commit\_sec - h_commit_sec
- The time that the transaction was committed, in seconds since the epoch. - The time that the transaction was committed, in seconds since the epoch.
* - 0x38 * - 0x38
- \_\_be32 - __be32
- h\_commit\_nsec - h_commit_nsec
- Nanoseconds component of the above timestamp. - Nanoseconds component of the above timestamp.
Fast commits Fast commits

View File

@ -7,8 +7,8 @@ Multiple mount protection (MMP) is a feature that protects the
filesystem against multiple hosts trying to use the filesystem filesystem against multiple hosts trying to use the filesystem
simultaneously. When a filesystem is opened (for mounting, or fsck, simultaneously. When a filesystem is opened (for mounting, or fsck,
etc.), the MMP code running on the node (call it node A) checks a etc.), the MMP code running on the node (call it node A) checks a
sequence number. If the sequence number is EXT4\_MMP\_SEQ\_CLEAN, the sequence number. If the sequence number is EXT4_MMP_SEQ_CLEAN, the
open continues. If the sequence number is EXT4\_MMP\_SEQ\_FSCK, then open continues. If the sequence number is EXT4_MMP_SEQ_FSCK, then
fsck is (hopefully) running, and open fails immediately. Otherwise, the fsck is (hopefully) running, and open fails immediately. Otherwise, the
open code will wait for twice the specified MMP check interval and check open code will wait for twice the specified MMP check interval and check
the sequence number again. If the sequence number has changed, then the the sequence number again. If the sequence number has changed, then the
@ -40,38 +40,38 @@ The MMP structure (``struct mmp_struct``) is as follows:
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- mmp\_magic - mmp_magic
- Magic number for MMP, 0x004D4D50 (“MMP”). - Magic number for MMP, 0x004D4D50 (“MMP”).
* - 0x4 * - 0x4
- \_\_le32 - __le32
- mmp\_seq - mmp_seq
- Sequence number, updated periodically. - Sequence number, updated periodically.
* - 0x8 * - 0x8
- \_\_le64 - __le64
- mmp\_time - mmp_time
- Time that the MMP block was last updated. - Time that the MMP block was last updated.
* - 0x10 * - 0x10
- char[64] - char[64]
- mmp\_nodename - mmp_nodename
- Hostname of the node that opened the filesystem. - Hostname of the node that opened the filesystem.
* - 0x50 * - 0x50
- char[32] - char[32]
- mmp\_bdevname - mmp_bdevname
- Block device name of the filesystem. - Block device name of the filesystem.
* - 0x70 * - 0x70
- \_\_le16 - __le16
- mmp\_check\_interval - mmp_check_interval
- The MMP re-check interval, in seconds. - The MMP re-check interval, in seconds.
* - 0x72 * - 0x72
- \_\_le16 - __le16
- mmp\_pad1 - mmp_pad1
- Zero. - Zero.
* - 0x74 * - 0x74
- \_\_le32[226] - __le32[226]
- mmp\_pad2 - mmp_pad2
- Zero. - Zero.
* - 0x3FC * - 0x3FC
- \_\_le32 - __le32
- mmp\_checksum - mmp_checksum
- Checksum of the MMP block. - Checksum of the MMP block.

View File

@ -7,7 +7,7 @@ An ext4 file system is split into a series of block groups. To reduce
performance difficulties due to fragmentation, the block allocator tries performance difficulties due to fragmentation, the block allocator tries
very hard to keep each file's blocks within the same group, thereby very hard to keep each file's blocks within the same group, thereby
reducing seek times. The size of a block group is specified in reducing seek times. The size of a block group is specified in
``sb.s_blocks_per_group`` blocks, though it can also calculated as 8 \* ``sb.s_blocks_per_group`` blocks, though it can also calculated as 8 *
``block_size_in_bytes``. With the default block size of 4KiB, each group ``block_size_in_bytes``. With the default block size of 4KiB, each group
will contain 32,768 blocks, for a length of 128MiB. The number of block will contain 32,768 blocks, for a length of 128MiB. The number of block
groups is the size of the device divided by the size of a block group. groups is the size of the device divided by the size of a block group.

View File

@ -34,7 +34,7 @@ ext4 reserves some inode for special features, as follows:
* - 10 * - 10
- Replica inode, used for some non-upstream feature? - Replica inode, used for some non-upstream feature?
* - 11 * - 11
- Traditional first non-reserved inode. Usually this is the lost+found directory. See s\_first\_ino in the superblock. - Traditional first non-reserved inode. Usually this is the lost+found directory. See s_first_ino in the superblock.
Note that there are also some inodes allocated from non-reserved inode numbers Note that there are also some inodes allocated from non-reserved inode numbers
for other filesystem features which are not referenced from standard directory for other filesystem features which are not referenced from standard directory
@ -47,9 +47,9 @@ hierarchy. These are generally reference from the superblock. They are:
* - Superblock field * - Superblock field
- Description - Description
* - s\_lpf\_ino * - s_lpf_ino
- Inode number of lost+found directory. - Inode number of lost+found directory.
* - s\_prj\_quota\_inum * - s_prj_quota_inum
- Inode number of quota file tracking project quotas - Inode number of quota file tracking project quotas
* - s\_orphan\_file\_inum * - s_orphan_file_inum
- Inode number of file tracking orphan inodes. - Inode number of file tracking orphan inodes.

View File

@ -7,7 +7,7 @@ The superblock records various information about the enclosing
filesystem, such as block counts, inode counts, supported features, filesystem, such as block counts, inode counts, supported features,
maintenance information, and more. maintenance information, and more.
If the sparse\_super feature flag is set, redundant copies of the If the sparse_super feature flag is set, redundant copies of the
superblock and group descriptors are kept only in the groups whose group superblock and group descriptors are kept only in the groups whose group
number is either 0 or a power of 3, 5, or 7. If the flag is not set, number is either 0 or a power of 3, 5, or 7. If the flag is not set,
redundant copies are kept in all groups. redundant copies are kept in all groups.
@ -27,107 +27,107 @@ The ext4 superblock is laid out as follows in
- Name - Name
- Description - Description
* - 0x0 * - 0x0
- \_\_le32 - __le32
- s\_inodes\_count - s_inodes_count
- Total inode count. - Total inode count.
* - 0x4 * - 0x4
- \_\_le32 - __le32
- s\_blocks\_count\_lo - s_blocks_count_lo
- Total block count. - Total block count.
* - 0x8 * - 0x8
- \_\_le32 - __le32
- s\_r\_blocks\_count\_lo - s_r_blocks_count_lo
- This number of blocks can only be allocated by the super-user. - This number of blocks can only be allocated by the super-user.
* - 0xC * - 0xC
- \_\_le32 - __le32
- s\_free\_blocks\_count\_lo - s_free_blocks_count_lo
- Free block count. - Free block count.
* - 0x10 * - 0x10
- \_\_le32 - __le32
- s\_free\_inodes\_count - s_free_inodes_count
- Free inode count. - Free inode count.
* - 0x14 * - 0x14
- \_\_le32 - __le32
- s\_first\_data\_block - s_first_data_block
- First data block. This must be at least 1 for 1k-block filesystems and - First data block. This must be at least 1 for 1k-block filesystems and
is typically 0 for all other block sizes. is typically 0 for all other block sizes.
* - 0x18 * - 0x18
- \_\_le32 - __le32
- s\_log\_block\_size - s_log_block_size
- Block size is 2 ^ (10 + s\_log\_block\_size). - Block size is 2 ^ (10 + s_log_block_size).
* - 0x1C * - 0x1C
- \_\_le32 - __le32
- s\_log\_cluster\_size - s_log_cluster_size
- Cluster size is 2 ^ (10 + s\_log\_cluster\_size) blocks if bigalloc is - Cluster size is 2 ^ (10 + s_log_cluster_size) blocks if bigalloc is
enabled. Otherwise s\_log\_cluster\_size must equal s\_log\_block\_size. enabled. Otherwise s_log_cluster_size must equal s_log_block_size.
* - 0x20 * - 0x20
- \_\_le32 - __le32
- s\_blocks\_per\_group - s_blocks_per_group
- Blocks per group. - Blocks per group.
* - 0x24 * - 0x24
- \_\_le32 - __le32
- s\_clusters\_per\_group - s_clusters_per_group
- Clusters per group, if bigalloc is enabled. Otherwise - Clusters per group, if bigalloc is enabled. Otherwise
s\_clusters\_per\_group must equal s\_blocks\_per\_group. s_clusters_per_group must equal s_blocks_per_group.
* - 0x28 * - 0x28
- \_\_le32 - __le32
- s\_inodes\_per\_group - s_inodes_per_group
- Inodes per group. - Inodes per group.
* - 0x2C * - 0x2C
- \_\_le32 - __le32
- s\_mtime - s_mtime
- Mount time, in seconds since the epoch. - Mount time, in seconds since the epoch.
* - 0x30 * - 0x30
- \_\_le32 - __le32
- s\_wtime - s_wtime
- Write time, in seconds since the epoch. - Write time, in seconds since the epoch.
* - 0x34 * - 0x34
- \_\_le16 - __le16
- s\_mnt\_count - s_mnt_count
- Number of mounts since the last fsck. - Number of mounts since the last fsck.
* - 0x36 * - 0x36
- \_\_le16 - __le16
- s\_max\_mnt\_count - s_max_mnt_count
- Number of mounts beyond which a fsck is needed. - Number of mounts beyond which a fsck is needed.
* - 0x38 * - 0x38
- \_\_le16 - __le16
- s\_magic - s_magic
- Magic signature, 0xEF53 - Magic signature, 0xEF53
* - 0x3A * - 0x3A
- \_\_le16 - __le16
- s\_state - s_state
- File system state. See super_state_ for more info. - File system state. See super_state_ for more info.
* - 0x3C * - 0x3C
- \_\_le16 - __le16
- s\_errors - s_errors
- Behaviour when detecting errors. See super_errors_ for more info. - Behaviour when detecting errors. See super_errors_ for more info.
* - 0x3E * - 0x3E
- \_\_le16 - __le16
- s\_minor\_rev\_level - s_minor_rev_level
- Minor revision level. - Minor revision level.
* - 0x40 * - 0x40
- \_\_le32 - __le32
- s\_lastcheck - s_lastcheck
- Time of last check, in seconds since the epoch. - Time of last check, in seconds since the epoch.
* - 0x44 * - 0x44
- \_\_le32 - __le32
- s\_checkinterval - s_checkinterval
- Maximum time between checks, in seconds. - Maximum time between checks, in seconds.
* - 0x48 * - 0x48
- \_\_le32 - __le32
- s\_creator\_os - s_creator_os
- Creator OS. See the table super_creator_ for more info. - Creator OS. See the table super_creator_ for more info.
* - 0x4C * - 0x4C
- \_\_le32 - __le32
- s\_rev\_level - s_rev_level
- Revision level. See the table super_revision_ for more info. - Revision level. See the table super_revision_ for more info.
* - 0x50 * - 0x50
- \_\_le16 - __le16
- s\_def\_resuid - s_def_resuid
- Default uid for reserved blocks. - Default uid for reserved blocks.
* - 0x52 * - 0x52
- \_\_le16 - __le16
- s\_def\_resgid - s_def_resgid
- Default gid for reserved blocks. - Default gid for reserved blocks.
* - * -
- -
@ -143,50 +143,50 @@ The ext4 superblock is laid out as follows in
about a feature in either the compatible or incompatible feature set, it about a feature in either the compatible or incompatible feature set, it
must abort and not try to meddle with things it doesn't understand... must abort and not try to meddle with things it doesn't understand...
* - 0x54 * - 0x54
- \_\_le32 - __le32
- s\_first\_ino - s_first_ino
- First non-reserved inode. - First non-reserved inode.
* - 0x58 * - 0x58
- \_\_le16 - __le16
- s\_inode\_size - s_inode_size
- Size of inode structure, in bytes. - Size of inode structure, in bytes.
* - 0x5A * - 0x5A
- \_\_le16 - __le16
- s\_block\_group\_nr - s_block_group_nr
- Block group # of this superblock. - Block group # of this superblock.
* - 0x5C * - 0x5C
- \_\_le32 - __le32
- s\_feature\_compat - s_feature_compat
- Compatible feature set flags. Kernel can still read/write this fs even - Compatible feature set flags. Kernel can still read/write this fs even
if it doesn't understand a flag; fsck should not do that. See the if it doesn't understand a flag; fsck should not do that. See the
super_compat_ table for more info. super_compat_ table for more info.
* - 0x60 * - 0x60
- \_\_le32 - __le32
- s\_feature\_incompat - s_feature_incompat
- Incompatible feature set. If the kernel or fsck doesn't understand one - Incompatible feature set. If the kernel or fsck doesn't understand one
of these bits, it should stop. See the super_incompat_ table for more of these bits, it should stop. See the super_incompat_ table for more
info. info.
* - 0x64 * - 0x64
- \_\_le32 - __le32
- s\_feature\_ro\_compat - s_feature_ro_compat
- Readonly-compatible feature set. If the kernel doesn't understand one of - Readonly-compatible feature set. If the kernel doesn't understand one of
these bits, it can still mount read-only. See the super_rocompat_ table these bits, it can still mount read-only. See the super_rocompat_ table
for more info. for more info.
* - 0x68 * - 0x68
- \_\_u8 - __u8
- s\_uuid[16] - s_uuid[16]
- 128-bit UUID for volume. - 128-bit UUID for volume.
* - 0x78 * - 0x78
- char - char
- s\_volume\_name[16] - s_volume_name[16]
- Volume label. - Volume label.
* - 0x88 * - 0x88
- char - char
- s\_last\_mounted[64] - s_last_mounted[64]
- Directory where filesystem was last mounted. - Directory where filesystem was last mounted.
* - 0xC8 * - 0xC8
- \_\_le32 - __le32
- s\_algorithm\_usage\_bitmap - s_algorithm_usage_bitmap
- For compression (Not used in e2fsprogs/Linux) - For compression (Not used in e2fsprogs/Linux)
* - * -
- -
@ -194,18 +194,18 @@ The ext4 superblock is laid out as follows in
- Performance hints. Directory preallocation should only happen if the - Performance hints. Directory preallocation should only happen if the
EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on. EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
* - 0xCC * - 0xCC
- \_\_u8 - __u8
- s\_prealloc\_blocks - s_prealloc_blocks
- #. of blocks to try to preallocate for ... files? (Not used in - #. of blocks to try to preallocate for ... files? (Not used in
e2fsprogs/Linux) e2fsprogs/Linux)
* - 0xCD * - 0xCD
- \_\_u8 - __u8
- s\_prealloc\_dir\_blocks - s_prealloc_dir_blocks
- #. of blocks to preallocate for directories. (Not used in - #. of blocks to preallocate for directories. (Not used in
e2fsprogs/Linux) e2fsprogs/Linux)
* - 0xCE * - 0xCE
- \_\_le16 - __le16
- s\_reserved\_gdt\_blocks - s_reserved_gdt_blocks
- Number of reserved GDT entries for future filesystem expansion. - Number of reserved GDT entries for future filesystem expansion.
* - * -
- -
@ -213,281 +213,281 @@ The ext4 superblock is laid out as follows in
- Journalling support is valid only if EXT4_FEATURE_COMPAT_HAS_JOURNAL is - Journalling support is valid only if EXT4_FEATURE_COMPAT_HAS_JOURNAL is
set. set.
* - 0xD0 * - 0xD0
- \_\_u8 - __u8
- s\_journal\_uuid[16] - s_journal_uuid[16]
- UUID of journal superblock - UUID of journal superblock
* - 0xE0 * - 0xE0
- \_\_le32 - __le32
- s\_journal\_inum - s_journal_inum
- inode number of journal file. - inode number of journal file.
* - 0xE4 * - 0xE4
- \_\_le32 - __le32
- s\_journal\_dev - s_journal_dev
- Device number of journal file, if the external journal feature flag is - Device number of journal file, if the external journal feature flag is
set. set.
* - 0xE8 * - 0xE8
- \_\_le32 - __le32
- s\_last\_orphan - s_last_orphan
- Start of list of orphaned inodes to delete. - Start of list of orphaned inodes to delete.
* - 0xEC * - 0xEC
- \_\_le32 - __le32
- s\_hash\_seed[4] - s_hash_seed[4]
- HTREE hash seed. - HTREE hash seed.
* - 0xFC * - 0xFC
- \_\_u8 - __u8
- s\_def\_hash\_version - s_def_hash_version
- Default hash algorithm to use for directory hashes. See super_def_hash_ - Default hash algorithm to use for directory hashes. See super_def_hash_
for more info. for more info.
* - 0xFD * - 0xFD
- \_\_u8 - __u8
- s\_jnl\_backup\_type - s_jnl_backup_type
- If this value is 0 or EXT3\_JNL\_BACKUP\_BLOCKS (1), then the - If this value is 0 or EXT3_JNL_BACKUP_BLOCKS (1), then the
``s_jnl_blocks`` field contains a duplicate copy of the inode's ``s_jnl_blocks`` field contains a duplicate copy of the inode's
``i_block[]`` array and ``i_size``. ``i_block[]`` array and ``i_size``.
* - 0xFE * - 0xFE
- \_\_le16 - __le16
- s\_desc\_size - s_desc_size
- Size of group descriptors, in bytes, if the 64bit incompat feature flag - Size of group descriptors, in bytes, if the 64bit incompat feature flag
is set. is set.
* - 0x100 * - 0x100
- \_\_le32 - __le32
- s\_default\_mount\_opts - s_default_mount_opts
- Default mount options. See the super_mountopts_ table for more info. - Default mount options. See the super_mountopts_ table for more info.
* - 0x104 * - 0x104
- \_\_le32 - __le32
- s\_first\_meta\_bg - s_first_meta_bg
- First metablock block group, if the meta\_bg feature is enabled. - First metablock block group, if the meta_bg feature is enabled.
* - 0x108 * - 0x108
- \_\_le32 - __le32
- s\_mkfs\_time - s_mkfs_time
- When the filesystem was created, in seconds since the epoch. - When the filesystem was created, in seconds since the epoch.
* - 0x10C * - 0x10C
- \_\_le32 - __le32
- s\_jnl\_blocks[17] - s_jnl_blocks[17]
- Backup copy of the journal inode's ``i_block[]`` array in the first 15 - Backup copy of the journal inode's ``i_block[]`` array in the first 15
elements and i\_size\_high and i\_size in the 16th and 17th elements, elements and i_size_high and i_size in the 16th and 17th elements,
respectively. respectively.
* - * -
- -
- -
- 64bit support is valid only if EXT4_FEATURE_COMPAT_64BIT is set. - 64bit support is valid only if EXT4_FEATURE_COMPAT_64BIT is set.
* - 0x150 * - 0x150
- \_\_le32 - __le32
- s\_blocks\_count\_hi - s_blocks_count_hi
- High 32-bits of the block count. - High 32-bits of the block count.
* - 0x154 * - 0x154
- \_\_le32 - __le32
- s\_r\_blocks\_count\_hi - s_r_blocks_count_hi
- High 32-bits of the reserved block count. - High 32-bits of the reserved block count.
* - 0x158 * - 0x158
- \_\_le32 - __le32
- s\_free\_blocks\_count\_hi - s_free_blocks_count_hi
- High 32-bits of the free block count. - High 32-bits of the free block count.
* - 0x15C * - 0x15C
- \_\_le16 - __le16
- s\_min\_extra\_isize - s_min_extra_isize
- All inodes have at least # bytes. - All inodes have at least # bytes.
* - 0x15E * - 0x15E
- \_\_le16 - __le16
- s\_want\_extra\_isize - s_want_extra_isize
- New inodes should reserve # bytes. - New inodes should reserve # bytes.
* - 0x160 * - 0x160
- \_\_le32 - __le32
- s\_flags - s_flags
- Miscellaneous flags. See the super_flags_ table for more info. - Miscellaneous flags. See the super_flags_ table for more info.
* - 0x164 * - 0x164
- \_\_le16 - __le16
- s\_raid\_stride - s_raid_stride
- RAID stride. This is the number of logical blocks read from or written - RAID stride. This is the number of logical blocks read from or written
to the disk before moving to the next disk. This affects the placement to the disk before moving to the next disk. This affects the placement
of filesystem metadata, which will hopefully make RAID storage faster. of filesystem metadata, which will hopefully make RAID storage faster.
* - 0x166 * - 0x166
- \_\_le16 - __le16
- s\_mmp\_interval - s_mmp_interval
- #. seconds to wait in multi-mount prevention (MMP) checking. In theory, - #. seconds to wait in multi-mount prevention (MMP) checking. In theory,
MMP is a mechanism to record in the superblock which host and device MMP is a mechanism to record in the superblock which host and device
have mounted the filesystem, in order to prevent multiple mounts. This have mounted the filesystem, in order to prevent multiple mounts. This
feature does not seem to be implemented... feature does not seem to be implemented...
* - 0x168 * - 0x168
- \_\_le64 - __le64
- s\_mmp\_block - s_mmp_block
- Block # for multi-mount protection data. - Block # for multi-mount protection data.
* - 0x170 * - 0x170
- \_\_le32 - __le32
- s\_raid\_stripe\_width - s_raid_stripe_width
- RAID stripe width. This is the number of logical blocks read from or - RAID stripe width. This is the number of logical blocks read from or
written to the disk before coming back to the current disk. This is used written to the disk before coming back to the current disk. This is used
by the block allocator to try to reduce the number of read-modify-write by the block allocator to try to reduce the number of read-modify-write
operations in a RAID5/6. operations in a RAID5/6.
* - 0x174 * - 0x174
- \_\_u8 - __u8
- s\_log\_groups\_per\_flex - s_log_groups_per_flex
- Size of a flexible block group is 2 ^ ``s_log_groups_per_flex``. - Size of a flexible block group is 2 ^ ``s_log_groups_per_flex``.
* - 0x175 * - 0x175
- \_\_u8 - __u8
- s\_checksum\_type - s_checksum_type
- Metadata checksum algorithm type. The only valid value is 1 (crc32c). - Metadata checksum algorithm type. The only valid value is 1 (crc32c).
* - 0x176 * - 0x176
- \_\_le16 - __le16
- s\_reserved\_pad - s_reserved_pad
- -
* - 0x178 * - 0x178
- \_\_le64 - __le64
- s\_kbytes\_written - s_kbytes_written
- Number of KiB written to this filesystem over its lifetime. - Number of KiB written to this filesystem over its lifetime.
* - 0x180 * - 0x180
- \_\_le32 - __le32
- s\_snapshot\_inum - s_snapshot_inum
- inode number of active snapshot. (Not used in e2fsprogs/Linux.) - inode number of active snapshot. (Not used in e2fsprogs/Linux.)
* - 0x184 * - 0x184
- \_\_le32 - __le32
- s\_snapshot\_id - s_snapshot_id
- Sequential ID of active snapshot. (Not used in e2fsprogs/Linux.) - Sequential ID of active snapshot. (Not used in e2fsprogs/Linux.)
* - 0x188 * - 0x188
- \_\_le64 - __le64
- s\_snapshot\_r\_blocks\_count - s_snapshot_r_blocks_count
- Number of blocks reserved for active snapshot's future use. (Not used in - Number of blocks reserved for active snapshot's future use. (Not used in
e2fsprogs/Linux.) e2fsprogs/Linux.)
* - 0x190 * - 0x190
- \_\_le32 - __le32
- s\_snapshot\_list - s_snapshot_list
- inode number of the head of the on-disk snapshot list. (Not used in - inode number of the head of the on-disk snapshot list. (Not used in
e2fsprogs/Linux.) e2fsprogs/Linux.)
* - 0x194 * - 0x194
- \_\_le32 - __le32
- s\_error\_count - s_error_count
- Number of errors seen. - Number of errors seen.
* - 0x198 * - 0x198
- \_\_le32 - __le32
- s\_first\_error\_time - s_first_error_time
- First time an error happened, in seconds since the epoch. - First time an error happened, in seconds since the epoch.
* - 0x19C * - 0x19C
- \_\_le32 - __le32
- s\_first\_error\_ino - s_first_error_ino
- inode involved in first error. - inode involved in first error.
* - 0x1A0 * - 0x1A0
- \_\_le64 - __le64
- s\_first\_error\_block - s_first_error_block
- Number of block involved of first error. - Number of block involved of first error.
* - 0x1A8 * - 0x1A8
- \_\_u8 - __u8
- s\_first\_error\_func[32] - s_first_error_func[32]
- Name of function where the error happened. - Name of function where the error happened.
* - 0x1C8 * - 0x1C8
- \_\_le32 - __le32
- s\_first\_error\_line - s_first_error_line
- Line number where error happened. - Line number where error happened.
* - 0x1CC * - 0x1CC
- \_\_le32 - __le32
- s\_last\_error\_time - s_last_error_time
- Time of most recent error, in seconds since the epoch. - Time of most recent error, in seconds since the epoch.
* - 0x1D0 * - 0x1D0
- \_\_le32 - __le32
- s\_last\_error\_ino - s_last_error_ino
- inode involved in most recent error. - inode involved in most recent error.
* - 0x1D4 * - 0x1D4
- \_\_le32 - __le32
- s\_last\_error\_line - s_last_error_line
- Line number where most recent error happened. - Line number where most recent error happened.
* - 0x1D8 * - 0x1D8
- \_\_le64 - __le64
- s\_last\_error\_block - s_last_error_block
- Number of block involved in most recent error. - Number of block involved in most recent error.
* - 0x1E0 * - 0x1E0
- \_\_u8 - __u8
- s\_last\_error\_func[32] - s_last_error_func[32]
- Name of function where the most recent error happened. - Name of function where the most recent error happened.
* - 0x200 * - 0x200
- \_\_u8 - __u8
- s\_mount\_opts[64] - s_mount_opts[64]
- ASCIIZ string of mount options. - ASCIIZ string of mount options.
* - 0x240 * - 0x240
- \_\_le32 - __le32
- s\_usr\_quota\_inum - s_usr_quota_inum
- Inode number of user `quota <quota>`__ file. - Inode number of user `quota <quota>`__ file.
* - 0x244 * - 0x244
- \_\_le32 - __le32
- s\_grp\_quota\_inum - s_grp_quota_inum
- Inode number of group `quota <quota>`__ file. - Inode number of group `quota <quota>`__ file.
* - 0x248 * - 0x248
- \_\_le32 - __le32
- s\_overhead\_blocks - s_overhead_blocks
- Overhead blocks/clusters in fs. (Huh? This field is always zero, which - Overhead blocks/clusters in fs. (Huh? This field is always zero, which
means that the kernel calculates it dynamically.) means that the kernel calculates it dynamically.)
* - 0x24C * - 0x24C
- \_\_le32 - __le32
- s\_backup\_bgs[2] - s_backup_bgs[2]
- Block groups containing superblock backups (if sparse\_super2) - Block groups containing superblock backups (if sparse_super2)
* - 0x254 * - 0x254
- \_\_u8 - __u8
- s\_encrypt\_algos[4] - s_encrypt_algos[4]
- Encryption algorithms in use. There can be up to four algorithms in use - Encryption algorithms in use. There can be up to four algorithms in use
at any time; valid algorithm codes are given in the super_encrypt_ table at any time; valid algorithm codes are given in the super_encrypt_ table
below. below.
* - 0x258 * - 0x258
- \_\_u8 - __u8
- s\_encrypt\_pw\_salt[16] - s_encrypt_pw_salt[16]
- Salt for the string2key algorithm for encryption. - Salt for the string2key algorithm for encryption.
* - 0x268 * - 0x268
- \_\_le32 - __le32
- s\_lpf\_ino - s_lpf_ino
- Inode number of lost+found - Inode number of lost+found
* - 0x26C * - 0x26C
- \_\_le32 - __le32
- s\_prj\_quota\_inum - s_prj_quota_inum
- Inode that tracks project quotas. - Inode that tracks project quotas.
* - 0x270 * - 0x270
- \_\_le32 - __le32
- s\_checksum\_seed - s_checksum_seed
- Checksum seed used for metadata\_csum calculations. This value is - Checksum seed used for metadata_csum calculations. This value is
crc32c(~0, $orig\_fs\_uuid). crc32c(~0, $orig_fs_uuid).
* - 0x274 * - 0x274
- \_\_u8 - __u8
- s\_wtime_hi - s_wtime_hi
- Upper 8 bits of the s_wtime field. - Upper 8 bits of the s_wtime field.
* - 0x275 * - 0x275
- \_\_u8 - __u8
- s\_mtime_hi - s_mtime_hi
- Upper 8 bits of the s_mtime field. - Upper 8 bits of the s_mtime field.
* - 0x276 * - 0x276
- \_\_u8 - __u8
- s\_mkfs_time_hi - s_mkfs_time_hi
- Upper 8 bits of the s_mkfs_time field. - Upper 8 bits of the s_mkfs_time field.
* - 0x277 * - 0x277
- \_\_u8 - __u8
- s\_lastcheck_hi - s_lastcheck_hi
- Upper 8 bits of the s_lastcheck_hi field. - Upper 8 bits of the s_lastcheck_hi field.
* - 0x278 * - 0x278
- \_\_u8 - __u8
- s\_first_error_time_hi - s_first_error_time_hi
- Upper 8 bits of the s_first_error_time_hi field. - Upper 8 bits of the s_first_error_time_hi field.
* - 0x279 * - 0x279
- \_\_u8 - __u8
- s\_last_error_time_hi - s_last_error_time_hi
- Upper 8 bits of the s_last_error_time_hi field. - Upper 8 bits of the s_last_error_time_hi field.
* - 0x27A * - 0x27A
- \_\_u8 - __u8
- s\_pad[2] - s_pad[2]
- Zero padding. - Zero padding.
* - 0x27C * - 0x27C
- \_\_le16 - __le16
- s\_encoding - s_encoding
- Filename charset encoding. - Filename charset encoding.
* - 0x27E * - 0x27E
- \_\_le16 - __le16
- s\_encoding_flags - s_encoding_flags
- Filename charset encoding flags. - Filename charset encoding flags.
* - 0x280 * - 0x280
- \_\_le32 - __le32
- s\_orphan\_file\_inum - s_orphan_file_inum
- Orphan file inode number. - Orphan file inode number.
* - 0x284 * - 0x284
- \_\_le32 - __le32
- s\_reserved[94] - s_reserved[94]
- Padding to the end of the block. - Padding to the end of the block.
* - 0x3FC * - 0x3FC
- \_\_le32 - __le32
- s\_checksum - s_checksum
- Superblock checksum. - Superblock checksum.
.. _super_state: .. _super_state:
@ -574,44 +574,44 @@ following:
* - Value * - Value
- Description - Description
* - 0x1 * - 0x1
- Directory preallocation (COMPAT\_DIR\_PREALLOC). - Directory preallocation (COMPAT_DIR_PREALLOC).
* - 0x2 * - 0x2
- “imagic inodes”. Not clear from the code what this does - “imagic inodes”. Not clear from the code what this does
(COMPAT\_IMAGIC\_INODES). (COMPAT_IMAGIC_INODES).
* - 0x4 * - 0x4
- Has a journal (COMPAT\_HAS\_JOURNAL). - Has a journal (COMPAT_HAS_JOURNAL).
* - 0x8 * - 0x8
- Supports extended attributes (COMPAT\_EXT\_ATTR). - Supports extended attributes (COMPAT_EXT_ATTR).
* - 0x10 * - 0x10
- Has reserved GDT blocks for filesystem expansion - Has reserved GDT blocks for filesystem expansion
(COMPAT\_RESIZE\_INODE). Requires RO\_COMPAT\_SPARSE\_SUPER. (COMPAT_RESIZE_INODE). Requires RO_COMPAT_SPARSE_SUPER.
* - 0x20 * - 0x20
- Has directory indices (COMPAT\_DIR\_INDEX). - Has directory indices (COMPAT_DIR_INDEX).
* - 0x40 * - 0x40
- “Lazy BG”. Not in Linux kernel, seems to have been for uninitialized - “Lazy BG”. Not in Linux kernel, seems to have been for uninitialized
block groups? (COMPAT\_LAZY\_BG) block groups? (COMPAT_LAZY_BG)
* - 0x80 * - 0x80
- “Exclude inode”. Not used. (COMPAT\_EXCLUDE\_INODE). - “Exclude inode”. Not used. (COMPAT_EXCLUDE_INODE).
* - 0x100 * - 0x100
- “Exclude bitmap”. Seems to be used to indicate the presence of - “Exclude bitmap”. Seems to be used to indicate the presence of
snapshot-related exclude bitmaps? Not defined in kernel or used in snapshot-related exclude bitmaps? Not defined in kernel or used in
e2fsprogs (COMPAT\_EXCLUDE\_BITMAP). e2fsprogs (COMPAT_EXCLUDE_BITMAP).
* - 0x200 * - 0x200
- Sparse Super Block, v2. If this flag is set, the SB field s\_backup\_bgs - Sparse Super Block, v2. If this flag is set, the SB field s_backup_bgs
points to the two block groups that contain backup superblocks points to the two block groups that contain backup superblocks
(COMPAT\_SPARSE\_SUPER2). (COMPAT_SPARSE_SUPER2).
* - 0x400 * - 0x400
- Fast commits supported. Although fast commits blocks are - Fast commits supported. Although fast commits blocks are
backward incompatible, fast commit blocks are not always backward incompatible, fast commit blocks are not always
present in the journal. If fast commit blocks are present in present in the journal. If fast commit blocks are present in
the journal, JBD2 incompat feature the journal, JBD2 incompat feature
(JBD2\_FEATURE\_INCOMPAT\_FAST\_COMMIT) gets (JBD2_FEATURE_INCOMPAT_FAST_COMMIT) gets
set (COMPAT\_FAST\_COMMIT). set (COMPAT_FAST_COMMIT).
* - 0x1000 * - 0x1000
- Orphan file allocated. This is the special file for more efficient - Orphan file allocated. This is the special file for more efficient
tracking of unlinked but still open inodes. When there may be any tracking of unlinked but still open inodes. When there may be any
entries in the file, we additionally set proper rocompat feature entries in the file, we additionally set proper rocompat feature
(RO\_COMPAT\_ORPHAN\_PRESENT). (RO_COMPAT_ORPHAN_PRESENT).
.. _super_incompat: .. _super_incompat:
@ -625,45 +625,45 @@ following:
* - Value * - Value
- Description - Description
* - 0x1 * - 0x1
- Compression (INCOMPAT\_COMPRESSION). - Compression (INCOMPAT_COMPRESSION).
* - 0x2 * - 0x2
- Directory entries record the file type. See ext4\_dir\_entry\_2 below - Directory entries record the file type. See ext4_dir_entry_2 below
(INCOMPAT\_FILETYPE). (INCOMPAT_FILETYPE).
* - 0x4 * - 0x4
- Filesystem needs recovery (INCOMPAT\_RECOVER). - Filesystem needs recovery (INCOMPAT_RECOVER).
* - 0x8 * - 0x8
- Filesystem has a separate journal device (INCOMPAT\_JOURNAL\_DEV). - Filesystem has a separate journal device (INCOMPAT_JOURNAL_DEV).
* - 0x10 * - 0x10
- Meta block groups. See the earlier discussion of this feature - Meta block groups. See the earlier discussion of this feature
(INCOMPAT\_META\_BG). (INCOMPAT_META_BG).
* - 0x40 * - 0x40
- Files in this filesystem use extents (INCOMPAT\_EXTENTS). - Files in this filesystem use extents (INCOMPAT_EXTENTS).
* - 0x80 * - 0x80
- Enable a filesystem size of 2^64 blocks (INCOMPAT\_64BIT). - Enable a filesystem size of 2^64 blocks (INCOMPAT_64BIT).
* - 0x100 * - 0x100
- Multiple mount protection (INCOMPAT\_MMP). - Multiple mount protection (INCOMPAT_MMP).
* - 0x200 * - 0x200
- Flexible block groups. See the earlier discussion of this feature - Flexible block groups. See the earlier discussion of this feature
(INCOMPAT\_FLEX\_BG). (INCOMPAT_FLEX_BG).
* - 0x400 * - 0x400
- Inodes can be used to store large extended attribute values - Inodes can be used to store large extended attribute values
(INCOMPAT\_EA\_INODE). (INCOMPAT_EA_INODE).
* - 0x1000 * - 0x1000
- Data in directory entry (INCOMPAT\_DIRDATA). (Not implemented?) - Data in directory entry (INCOMPAT_DIRDATA). (Not implemented?)
* - 0x2000 * - 0x2000
- Metadata checksum seed is stored in the superblock. This feature enables - Metadata checksum seed is stored in the superblock. This feature enables
the administrator to change the UUID of a metadata\_csum filesystem the administrator to change the UUID of a metadata_csum filesystem
while the filesystem is mounted; without it, the checksum definition while the filesystem is mounted; without it, the checksum definition
requires all metadata blocks to be rewritten (INCOMPAT\_CSUM\_SEED). requires all metadata blocks to be rewritten (INCOMPAT_CSUM_SEED).
* - 0x4000 * - 0x4000
- Large directory >2GB or 3-level htree (INCOMPAT\_LARGEDIR). Prior to - Large directory >2GB or 3-level htree (INCOMPAT_LARGEDIR). Prior to
this feature, directories could not be larger than 4GiB and could not this feature, directories could not be larger than 4GiB and could not
have an htree more than 2 levels deep. If this feature is enabled, have an htree more than 2 levels deep. If this feature is enabled,
directories can be larger than 4GiB and have a maximum htree depth of 3. directories can be larger than 4GiB and have a maximum htree depth of 3.
* - 0x8000 * - 0x8000
- Data in inode (INCOMPAT\_INLINE\_DATA). - Data in inode (INCOMPAT_INLINE_DATA).
* - 0x10000 * - 0x10000
- Encrypted inodes are present on the filesystem. (INCOMPAT\_ENCRYPT). - Encrypted inodes are present on the filesystem. (INCOMPAT_ENCRYPT).
.. _super_rocompat: .. _super_rocompat:
@ -678,54 +678,54 @@ the following:
- Description - Description
* - 0x1 * - 0x1
- Sparse superblocks. See the earlier discussion of this feature - Sparse superblocks. See the earlier discussion of this feature
(RO\_COMPAT\_SPARSE\_SUPER). (RO_COMPAT_SPARSE_SUPER).
* - 0x2 * - 0x2
- This filesystem has been used to store a file greater than 2GiB - This filesystem has been used to store a file greater than 2GiB
(RO\_COMPAT\_LARGE\_FILE). (RO_COMPAT_LARGE_FILE).
* - 0x4 * - 0x4
- Not used in kernel or e2fsprogs (RO\_COMPAT\_BTREE\_DIR). - Not used in kernel or e2fsprogs (RO_COMPAT_BTREE_DIR).
* - 0x8 * - 0x8
- This filesystem has files whose sizes are represented in units of - This filesystem has files whose sizes are represented in units of
logical blocks, not 512-byte sectors. This implies a very large file logical blocks, not 512-byte sectors. This implies a very large file
indeed! (RO\_COMPAT\_HUGE\_FILE) indeed! (RO_COMPAT_HUGE_FILE)
* - 0x10 * - 0x10
- Group descriptors have checksums. In addition to detecting corruption, - Group descriptors have checksums. In addition to detecting corruption,
this is useful for lazy formatting with uninitialized groups this is useful for lazy formatting with uninitialized groups
(RO\_COMPAT\_GDT\_CSUM). (RO_COMPAT_GDT_CSUM).
* - 0x20 * - 0x20
- Indicates that the old ext3 32,000 subdirectory limit no longer applies - Indicates that the old ext3 32,000 subdirectory limit no longer applies
(RO\_COMPAT\_DIR\_NLINK). A directory's i\_links\_count will be set to 1 (RO_COMPAT_DIR_NLINK). A directory's i_links_count will be set to 1
if it is incremented past 64,999. if it is incremented past 64,999.
* - 0x40 * - 0x40
- Indicates that large inodes exist on this filesystem - Indicates that large inodes exist on this filesystem
(RO\_COMPAT\_EXTRA\_ISIZE). (RO_COMPAT_EXTRA_ISIZE).
* - 0x80 * - 0x80
- This filesystem has a snapshot (RO\_COMPAT\_HAS\_SNAPSHOT). - This filesystem has a snapshot (RO_COMPAT_HAS_SNAPSHOT).
* - 0x100 * - 0x100
- `Quota <Quota>`__ (RO\_COMPAT\_QUOTA). - `Quota <Quota>`__ (RO_COMPAT_QUOTA).
* - 0x200 * - 0x200
- This filesystem supports “bigalloc”, which means that file extents are - This filesystem supports “bigalloc”, which means that file extents are
tracked in units of clusters (of blocks) instead of blocks tracked in units of clusters (of blocks) instead of blocks
(RO\_COMPAT\_BIGALLOC). (RO_COMPAT_BIGALLOC).
* - 0x400 * - 0x400
- This filesystem supports metadata checksumming. - This filesystem supports metadata checksumming.
(RO\_COMPAT\_METADATA\_CSUM; implies RO\_COMPAT\_GDT\_CSUM, though (RO_COMPAT_METADATA_CSUM; implies RO_COMPAT_GDT_CSUM, though
GDT\_CSUM must not be set) GDT_CSUM must not be set)
* - 0x800 * - 0x800
- Filesystem supports replicas. This feature is neither in the kernel nor - Filesystem supports replicas. This feature is neither in the kernel nor
e2fsprogs. (RO\_COMPAT\_REPLICA) e2fsprogs. (RO_COMPAT_REPLICA)
* - 0x1000 * - 0x1000
- Read-only filesystem image; the kernel will not mount this image - Read-only filesystem image; the kernel will not mount this image
read-write and most tools will refuse to write to the image. read-write and most tools will refuse to write to the image.
(RO\_COMPAT\_READONLY) (RO_COMPAT_READONLY)
* - 0x2000 * - 0x2000
- Filesystem tracks project quotas. (RO\_COMPAT\_PROJECT) - Filesystem tracks project quotas. (RO_COMPAT_PROJECT)
* - 0x8000 * - 0x8000
- Verity inodes may be present on the filesystem. (RO\_COMPAT\_VERITY) - Verity inodes may be present on the filesystem. (RO_COMPAT_VERITY)
* - 0x10000 * - 0x10000
- Indicates orphan file may have valid orphan entries and thus we need - Indicates orphan file may have valid orphan entries and thus we need
to clean them up when mounting the filesystem to clean them up when mounting the filesystem
(RO\_COMPAT\_ORPHAN\_PRESENT). (RO_COMPAT_ORPHAN_PRESENT).
.. _super_def_hash: .. _super_def_hash:
@ -761,36 +761,36 @@ The ``s_default_mount_opts`` field is any combination of the following:
* - Value * - Value
- Description - Description
* - 0x0001 * - 0x0001
- Print debugging info upon (re)mount. (EXT4\_DEFM\_DEBUG) - Print debugging info upon (re)mount. (EXT4_DEFM_DEBUG)
* - 0x0002 * - 0x0002
- New files take the gid of the containing directory (instead of the fsgid - New files take the gid of the containing directory (instead of the fsgid
of the current process). (EXT4\_DEFM\_BSDGROUPS) of the current process). (EXT4_DEFM_BSDGROUPS)
* - 0x0004 * - 0x0004
- Support userspace-provided extended attributes. (EXT4\_DEFM\_XATTR\_USER) - Support userspace-provided extended attributes. (EXT4_DEFM_XATTR_USER)
* - 0x0008 * - 0x0008
- Support POSIX access control lists (ACLs). (EXT4\_DEFM\_ACL) - Support POSIX access control lists (ACLs). (EXT4_DEFM_ACL)
* - 0x0010 * - 0x0010
- Do not support 32-bit UIDs. (EXT4\_DEFM\_UID16) - Do not support 32-bit UIDs. (EXT4_DEFM_UID16)
* - 0x0020 * - 0x0020
- All data and metadata are commited to the journal. - All data and metadata are commited to the journal.
(EXT4\_DEFM\_JMODE\_DATA) (EXT4_DEFM_JMODE_DATA)
* - 0x0040 * - 0x0040
- All data are flushed to the disk before metadata are committed to the - All data are flushed to the disk before metadata are committed to the
journal. (EXT4\_DEFM\_JMODE\_ORDERED) journal. (EXT4_DEFM_JMODE_ORDERED)
* - 0x0060 * - 0x0060
- Data ordering is not preserved; data may be written after the metadata - Data ordering is not preserved; data may be written after the metadata
has been written. (EXT4\_DEFM\_JMODE\_WBACK) has been written. (EXT4_DEFM_JMODE_WBACK)
* - 0x0100 * - 0x0100
- Disable write flushes. (EXT4\_DEFM\_NOBARRIER) - Disable write flushes. (EXT4_DEFM_NOBARRIER)
* - 0x0200 * - 0x0200
- Track which blocks in a filesystem are metadata and therefore should not - Track which blocks in a filesystem are metadata and therefore should not
be used as data blocks. This option will be enabled by default on 3.18, be used as data blocks. This option will be enabled by default on 3.18,
hopefully. (EXT4\_DEFM\_BLOCK\_VALIDITY) hopefully. (EXT4_DEFM_BLOCK_VALIDITY)
* - 0x0400 * - 0x0400
- Enable DISCARD support, where the storage device is told about blocks - Enable DISCARD support, where the storage device is told about blocks
becoming unused. (EXT4\_DEFM\_DISCARD) becoming unused. (EXT4_DEFM_DISCARD)
* - 0x0800 * - 0x0800
- Disable delayed allocation. (EXT4\_DEFM\_NODELALLOC) - Disable delayed allocation. (EXT4_DEFM_NODELALLOC)
.. _super_flags: .. _super_flags:
@ -820,12 +820,12 @@ The ``s_encrypt_algos`` list can contain any of the following:
* - Value * - Value
- Description - Description
* - 0 * - 0
- Invalid algorithm (ENCRYPTION\_MODE\_INVALID). - Invalid algorithm (ENCRYPTION_MODE_INVALID).
* - 1 * - 1
- 256-bit AES in XTS mode (ENCRYPTION\_MODE\_AES\_256\_XTS). - 256-bit AES in XTS mode (ENCRYPTION_MODE_AES_256_XTS).
* - 2 * - 2
- 256-bit AES in GCM mode (ENCRYPTION\_MODE\_AES\_256\_GCM). - 256-bit AES in GCM mode (ENCRYPTION_MODE_AES_256_GCM).
* - 3 * - 3
- 256-bit AES in CBC mode (ENCRYPTION\_MODE\_AES\_256\_CBC). - 256-bit AES in CBC mode (ENCRYPTION_MODE_AES_256_CBC).
Total size of the superblock is 1024 bytes. Total size of the superblock is 1024 bytes.

View File

@ -45,10 +45,12 @@ Name Alias Usage Preserved
``$r23``-``$r31`` ``$s0``-``$s8`` Static registers Yes ``$r23``-``$r31`` ``$s0``-``$s8`` Static registers Yes
================= =============== =================== ============ ================= =============== =================== ============
Note: The register ``$r21`` is reserved in the ELF psABI, but used by the Linux .. Note::
kernel for storing the percpu base address. It normally has no ABI name, but is The register ``$r21`` is reserved in the ELF psABI, but used by the Linux
called ``$u0`` in the kernel. You may also see ``$v0`` or ``$v1`` in some old code, kernel for storing the percpu base address. It normally has no ABI name,
however they are deprecated aliases of ``$a0`` and ``$a1`` respectively. but is called ``$u0`` in the kernel. You may also see ``$v0`` or ``$v1``
in some old code,however they are deprecated aliases of ``$a0`` and ``$a1``
respectively.
FPRs FPRs
---- ----
@ -69,8 +71,9 @@ Name Alias Usage Preserved
``$f24``-``$f31`` ``$fs0``-``$fs7`` Static registers Yes ``$f24``-``$f31`` ``$fs0``-``$fs7`` Static registers Yes
================= ================== =================== ============ ================= ================== =================== ============
Note: You may see ``$fv0`` or ``$fv1`` in some old code, however they are deprecated .. Note::
aliases of ``$fa0`` and ``$fa1`` respectively. You may see ``$fv0`` or ``$fv1`` in some old code, however they are
deprecated aliases of ``$fa0`` and ``$fa1`` respectively.
VRs VRs
---- ----

View File

@ -145,12 +145,16 @@ Documentation of Loongson's LS7A chipset:
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (in English) https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (in English)
Note: CPUINTC is CSR.ECFG/CSR.ESTAT and its interrupt controller described .. Note::
in Section 7.4 of "LoongArch Reference Manual, Vol 1"; LIOINTC is "Legacy I/O - CPUINTC is CSR.ECFG/CSR.ESTAT and its interrupt controller described
Interrupts" described in Section 11.1 of "Loongson 3A5000 Processor Reference in Section 7.4 of "LoongArch Reference Manual, Vol 1";
Manual"; EIOINTC is "Extended I/O Interrupts" described in Section 11.2 of - LIOINTC is "Legacy I/OInterrupts" described in Section 11.1 of
"Loongson 3A5000 Processor Reference Manual"; HTVECINTC is "HyperTransport "Loongson 3A5000 Processor Reference Manual";
Interrupts" described in Section 14.3 of "Loongson 3A5000 Processor Reference - EIOINTC is "Extended I/O Interrupts" described in Section 11.2 of
Manual"; PCH-PIC/PCH-MSI is "Interrupt Controller" described in Section 5 of "Loongson 3A5000 Processor Reference Manual";
"Loongson 7A1000 Bridge User Manual"; PCH-LPC is "LPC Interrupts" described in - HTVECINTC is "HyperTransport Interrupts" described in Section 14.3 of
Section 24.3 of "Loongson 7A1000 Bridge User Manual". "Loongson 3A5000 Processor Reference Manual";
- PCH-PIC/PCH-MSI is "Interrupt Controller" described in Section 5 of
"Loongson 7A1000 Bridge User Manual";
- PCH-LPC is "LPC Interrupts" described in Section 24.3 of
"Loongson 7A1000 Bridge User Manual".

View File

@ -46,10 +46,11 @@ LA64中每个寄存器为64位宽。 ``$r0`` 的内容总是固定为0而其
``$r23``-``$r31`` ``$s0``-``$s8`` 静态寄存器 是 ``$r23``-``$r31`` ``$s0``-``$s8`` 静态寄存器 是
================= =============== =================== ========== ================= =============== =================== ==========
注意:``$r21``寄存器在ELF psABI中保留未使用但是在Linux内核用于保存每CPU .. note::
变量基地址。该寄存器没有ABI命名不过在内核中称为``$u0``。在一些遗留代码 注意: ``$r21`` 寄存器在ELF psABI中保留未使用但是在Linux内核用于保
中有时可能见到``$v0````$v1``,它们是``$a0````$a1``的别名,属于已经废弃 存每CPU变量基地址。该寄存器没有ABI命名不过在内核中称为 ``$u0`` 。在
的用法。 一些遗留代码中有时可能见到 ``$v0````$v1`` ,它们是 ``$a0``
``$a1`` 的别名,属于已经废弃的用法。
浮点寄存器 浮点寄存器
---------- ----------
@ -68,8 +69,9 @@ LA64中每个寄存器为64位宽。 ``$r0`` 的内容总是固定为0而其
``$f24``-``$f31`` ``$fs0``-``$fs7`` 静态寄存器 是 ``$f24``-``$f31`` ``$fs0``-``$fs7`` 静态寄存器 是
================= ================== =================== ========== ================= ================== =================== ==========
注意:在一些遗留代码中有时可能见到 ``$v0````$v1`` ,它们是 ``$a0`` .. note::
``$a1`` 的别名,属于已经废弃的用法。 注意:在一些遗留代码中有时可能见到 ``$v0````$v1`` ,它们是
``$a0````$a1`` 的别名,属于已经废弃的用法。
向量寄存器 向量寄存器

View File

@ -147,9 +147,11 @@ PCH-LPC::
https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (英文版) https://github.com/loongson/LoongArch-Documentation/releases/latest/download/Loongson-7A1000-usermanual-2.00-EN.pdf (英文版)
CPUINTC即《龙芯架构参考手册卷一》第7.4节所描述的CSR.ECFG/CSR.ESTAT寄存器及其中断 .. note::
控制逻辑LIOINTC即《龙芯3A5000处理器使用手册》第11.1节所描述的“传统I/O中断”EIOINTC - CPUINTC即《龙芯架构参考手册卷一》第7.4节所描述的CSR.ECFG/CSR.ESTAT寄存器及其
即《龙芯3A5000处理器使用手册》第11.2节所描述的“扩展I/O中断”HTVECINTC即《龙芯3A5000 中断控制逻辑;
处理器使用手册》第14.3节所描述的“HyperTransport中断”PCH-PIC/PCH-MSI即《龙芯7A1000桥 - LIOINTC即《龙芯3A5000处理器使用手册》第11.1节所描述的“传统I/O中断”
片用户手册》第5章所描述的“中断控制器”PCH-LPC即《龙芯7A1000桥片用户手册》第24.3节所 - EIOINTC即《龙芯3A5000处理器使用手册》第11.2节所描述的“扩展I/O中断”
描述的“LPC中断”。 - HTVECINTC即《龙芯3A5000处理器使用手册》第14.3节所描述的“HyperTransport中断”
- PCH-PIC/PCH-MSI即《龙芯7A1000桥片用户手册》第5章所描述的“中断控制器”
- PCH-LPC即《龙芯7A1000桥片用户手册》第24.3节所描述的“LPC中断”。

View File

@ -3661,7 +3661,7 @@ BPF JIT for ARM
M: Shubham Bansal <illusionist.neo@gmail.com> M: Shubham Bansal <illusionist.neo@gmail.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
S: Maintained S: Odd Fixes
F: arch/arm/net/ F: arch/arm/net/
BPF JIT for ARM64 BPF JIT for ARM64
@ -3685,14 +3685,15 @@ BPF JIT for NFP NICs
M: Jakub Kicinski <kuba@kernel.org> M: Jakub Kicinski <kuba@kernel.org>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
S: Supported S: Odd Fixes
F: drivers/net/ethernet/netronome/nfp/bpf/ F: drivers/net/ethernet/netronome/nfp/bpf/
BPF JIT for POWERPC (32-BIT AND 64-BIT) BPF JIT for POWERPC (32-BIT AND 64-BIT)
M: Naveen N. Rao <naveen.n.rao@linux.ibm.com> M: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
M: Michael Ellerman <mpe@ellerman.id.au>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
S: Maintained S: Supported
F: arch/powerpc/net/ F: arch/powerpc/net/
BPF JIT for RISC-V (32-bit) BPF JIT for RISC-V (32-bit)
@ -3718,7 +3719,7 @@ M: Heiko Carstens <hca@linux.ibm.com>
M: Vasily Gorbik <gor@linux.ibm.com> M: Vasily Gorbik <gor@linux.ibm.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
S: Maintained S: Supported
F: arch/s390/net/ F: arch/s390/net/
X: arch/s390/net/pnet.c X: arch/s390/net/pnet.c
@ -3726,14 +3727,14 @@ BPF JIT for SPARC (32-BIT AND 64-BIT)
M: David S. Miller <davem@davemloft.net> M: David S. Miller <davem@davemloft.net>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
S: Maintained S: Odd Fixes
F: arch/sparc/net/ F: arch/sparc/net/
BPF JIT for X86 32-BIT BPF JIT for X86 32-BIT
M: Wang YanQing <udknight@gmail.com> M: Wang YanQing <udknight@gmail.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
S: Maintained S: Odd Fixes
F: arch/x86/net/bpf_jit_comp32.c F: arch/x86/net/bpf_jit_comp32.c
BPF JIT for X86 64-BIT BPF JIT for X86 64-BIT
@ -3756,6 +3757,19 @@ F: include/linux/bpf_lsm.h
F: kernel/bpf/bpf_lsm.c F: kernel/bpf/bpf_lsm.c
F: security/bpf/ F: security/bpf/
BPF L7 FRAMEWORK
M: John Fastabend <john.fastabend@gmail.com>
M: Jakub Sitnicki <jakub@cloudflare.com>
L: netdev@vger.kernel.org
L: bpf@vger.kernel.org
S: Maintained
F: include/linux/skmsg.h
F: net/core/skmsg.c
F: net/core/sock_map.c
F: net/ipv4/tcp_bpf.c
F: net/ipv4/udp_bpf.c
F: net/unix/unix_bpf.c
BPFTOOL BPFTOOL
M: Quentin Monnet <quentin@isovalent.com> M: Quentin Monnet <quentin@isovalent.com>
L: bpf@vger.kernel.org L: bpf@vger.kernel.org
@ -9275,6 +9289,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
F: Documentation/devicetree/bindings/i2c/i2c.txt F: Documentation/devicetree/bindings/i2c/i2c.txt
F: Documentation/i2c/ F: Documentation/i2c/
F: drivers/i2c/* F: drivers/i2c/*
F: include/dt-bindings/i2c/i2c.h
F: include/linux/i2c-dev.h F: include/linux/i2c-dev.h
F: include/linux/i2c-smbus.h F: include/linux/i2c-smbus.h
F: include/linux/i2c.h F: include/linux/i2c.h
@ -9290,6 +9305,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
F: Documentation/devicetree/bindings/i2c/ F: Documentation/devicetree/bindings/i2c/
F: drivers/i2c/algos/ F: drivers/i2c/algos/
F: drivers/i2c/busses/ F: drivers/i2c/busses/
F: include/dt-bindings/i2c/
I2C-TAOS-EVM DRIVER I2C-TAOS-EVM DRIVER
M: Jean Delvare <jdelvare@suse.com> M: Jean Delvare <jdelvare@suse.com>
@ -11095,20 +11111,6 @@ S: Maintained
F: include/net/l3mdev.h F: include/net/l3mdev.h
F: net/l3mdev F: net/l3mdev
L7 BPF FRAMEWORK
M: John Fastabend <john.fastabend@gmail.com>
M: Daniel Borkmann <daniel@iogearbox.net>
M: Jakub Sitnicki <jakub@cloudflare.com>
L: netdev@vger.kernel.org
L: bpf@vger.kernel.org
S: Maintained
F: include/linux/skmsg.h
F: net/core/skmsg.c
F: net/core/sock_map.c
F: net/ipv4/tcp_bpf.c
F: net/ipv4/udp_bpf.c
F: net/unix/unix_bpf.c
LANDLOCK SECURITY MODULE LANDLOCK SECURITY MODULE
M: Mickaël Salaün <mic@digikod.net> M: Mickaël Salaün <mic@digikod.net>
L: linux-security-module@vger.kernel.org L: linux-security-module@vger.kernel.org
@ -13951,7 +13953,6 @@ F: net/ipv6/tcp*.c
NETWORKING [TLS] NETWORKING [TLS]
M: Boris Pismenny <borisp@nvidia.com> M: Boris Pismenny <borisp@nvidia.com>
M: John Fastabend <john.fastabend@gmail.com> M: John Fastabend <john.fastabend@gmail.com>
M: Daniel Borkmann <daniel@iogearbox.net>
M: Jakub Kicinski <kuba@kernel.org> M: Jakub Kicinski <kuba@kernel.org>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Maintained
@ -14868,6 +14869,7 @@ F: include/dt-bindings/
OPENCOMPUTE PTP CLOCK DRIVER OPENCOMPUTE PTP CLOCK DRIVER
M: Jonathan Lemon <jonathan.lemon@gmail.com> M: Jonathan Lemon <jonathan.lemon@gmail.com>
M: Vadim Fedorenko <vadfed@fb.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/ptp/ptp_ocp.c F: drivers/ptp/ptp_ocp.c
@ -19304,7 +19306,7 @@ R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
R: Mika Westerberg <mika.westerberg@linux.intel.com> R: Mika Westerberg <mika.westerberg@linux.intel.com>
R: Jan Dabros <jsd@semihalf.com> R: Jan Dabros <jsd@semihalf.com>
L: linux-i2c@vger.kernel.org L: linux-i2c@vger.kernel.org
S: Maintained S: Supported
F: drivers/i2c/busses/i2c-designware-* F: drivers/i2c/busses/i2c-designware-*
SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER

View File

@ -2,7 +2,7 @@
VERSION = 5 VERSION = 5
PATCHLEVEL = 19 PATCHLEVEL = 19
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc2 EXTRAVERSION = -rc3
NAME = Superb Owl NAME = Superb Owl
# *DOCUMENTATION* # *DOCUMENTATION*

View File

@ -3101,7 +3101,6 @@ void cpu_set_feature(unsigned int num)
WARN_ON(num >= MAX_CPU_FEATURES); WARN_ON(num >= MAX_CPU_FEATURES);
elf_hwcap |= BIT(num); elf_hwcap |= BIT(num);
} }
EXPORT_SYMBOL_GPL(cpu_set_feature);
bool cpu_have_feature(unsigned int num) bool cpu_have_feature(unsigned int num)
{ {

View File

@ -102,7 +102,6 @@ SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
* x19-x29 per the AAPCS, and we created frame records upon entry, so we need * x19-x29 per the AAPCS, and we created frame records upon entry, so we need
* to restore x0-x8, x29, and x30. * to restore x0-x8, x29, and x30.
*/ */
ftrace_common_return:
/* Restore function arguments */ /* Restore function arguments */
ldp x0, x1, [sp] ldp x0, x1, [sp]
ldp x2, x3, [sp, #S_X2] ldp x2, x3, [sp, #S_X2]

View File

@ -77,6 +77,66 @@ static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr)
return NULL; return NULL;
} }
/*
* Find the address the callsite must branch to in order to reach '*addr'.
*
* Due to the limited range of 'BL' instructions, modules may be placed too far
* away to branch directly and must use a PLT.
*
* Returns true when '*addr' contains a reachable target address, or has been
* modified to contain a PLT address. Returns false otherwise.
*/
static bool ftrace_find_callable_addr(struct dyn_ftrace *rec,
struct module *mod,
unsigned long *addr)
{
unsigned long pc = rec->ip;
long offset = (long)*addr - (long)pc;
struct plt_entry *plt;
/*
* When the target is within range of the 'BL' instruction, use 'addr'
* as-is and branch to that directly.
*/
if (offset >= -SZ_128M && offset < SZ_128M)
return true;
/*
* When the target is outside of the range of a 'BL' instruction, we
* must use a PLT to reach it. We can only place PLTs for modules, and
* only when module PLT support is built-in.
*/
if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
return false;
/*
* 'mod' is only set at module load time, but if we end up
* dealing with an out-of-range condition, we can assume it
* is due to a module being loaded far away from the kernel.
*
* NOTE: __module_text_address() must be called with preemption
* disabled, but we can rely on ftrace_lock to ensure that 'mod'
* retains its validity throughout the remainder of this code.
*/
if (!mod) {
preempt_disable();
mod = __module_text_address(pc);
preempt_enable();
}
if (WARN_ON(!mod))
return false;
plt = get_ftrace_plt(mod, *addr);
if (!plt) {
pr_err("ftrace: no module PLT for %ps\n", (void *)*addr);
return false;
}
*addr = (unsigned long)plt;
return true;
}
/* /*
* Turn on the call to ftrace_caller() in instrumented function * Turn on the call to ftrace_caller() in instrumented function
*/ */
@ -84,41 +144,10 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{ {
unsigned long pc = rec->ip; unsigned long pc = rec->ip;
u32 old, new; u32 old, new;
long offset = (long)pc - (long)addr;
if (offset < -SZ_128M || offset >= SZ_128M) { if (!ftrace_find_callable_addr(rec, NULL, &addr))
struct module *mod;
struct plt_entry *plt;
if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
return -EINVAL; return -EINVAL;
/*
* On kernels that support module PLTs, the offset between the
* branch instruction and its target may legally exceed the
* range of an ordinary relative 'bl' opcode. In this case, we
* need to branch via a trampoline in the module.
*
* NOTE: __module_text_address() must be called with preemption
* disabled, but we can rely on ftrace_lock to ensure that 'mod'
* retains its validity throughout the remainder of this code.
*/
preempt_disable();
mod = __module_text_address(pc);
preempt_enable();
if (WARN_ON(!mod))
return -EINVAL;
plt = get_ftrace_plt(mod, addr);
if (!plt) {
pr_err("ftrace: no module PLT for %ps\n", (void *)addr);
return -EINVAL;
}
addr = (unsigned long)plt;
}
old = aarch64_insn_gen_nop(); old = aarch64_insn_gen_nop();
new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK);
@ -132,6 +161,11 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long pc = rec->ip; unsigned long pc = rec->ip;
u32 old, new; u32 old, new;
if (!ftrace_find_callable_addr(rec, NULL, &old_addr))
return -EINVAL;
if (!ftrace_find_callable_addr(rec, NULL, &addr))
return -EINVAL;
old = aarch64_insn_gen_branch_imm(pc, old_addr, old = aarch64_insn_gen_branch_imm(pc, old_addr,
AARCH64_INSN_BRANCH_LINK); AARCH64_INSN_BRANCH_LINK);
new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK); new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK);
@ -181,54 +215,15 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
unsigned long addr) unsigned long addr)
{ {
unsigned long pc = rec->ip; unsigned long pc = rec->ip;
bool validate = true;
u32 old = 0, new; u32 old = 0, new;
long offset = (long)pc - (long)addr;
if (offset < -SZ_128M || offset >= SZ_128M) { if (!ftrace_find_callable_addr(rec, mod, &addr))
u32 replaced;
if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
return -EINVAL; return -EINVAL;
/* old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK);
* 'mod' is only set at module load time, but if we end up
* dealing with an out-of-range condition, we can assume it
* is due to a module being loaded far away from the kernel.
*/
if (!mod) {
preempt_disable();
mod = __module_text_address(pc);
preempt_enable();
if (WARN_ON(!mod))
return -EINVAL;
}
/*
* The instruction we are about to patch may be a branch and
* link instruction that was redirected via a PLT entry. In
* this case, the normal validation will fail, but we can at
* least check that we are dealing with a branch and link
* instruction that points into the right module.
*/
if (aarch64_insn_read((void *)pc, &replaced))
return -EFAULT;
if (!aarch64_insn_is_bl(replaced) ||
!within_module(pc + aarch64_get_branch_offset(replaced),
mod))
return -EINVAL;
validate = false;
} else {
old = aarch64_insn_gen_branch_imm(pc, addr,
AARCH64_INSN_BRANCH_LINK);
}
new = aarch64_insn_gen_nop(); new = aarch64_insn_gen_nop();
return ftrace_modify_code(pc, old, new, validate); return ftrace_modify_code(pc, old, new, true);
} }
void arch_ftrace_update_code(int command) void arch_ftrace_update_code(int command)

View File

@ -303,14 +303,13 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
early_fixmap_init(); early_fixmap_init();
early_ioremap_init(); early_ioremap_init();
/*
* Initialise the static keys early as they may be enabled by the
* cpufeature code, early parameters, and DT setup.
*/
jump_label_init();
setup_machine_fdt(__fdt_pointer); setup_machine_fdt(__fdt_pointer);
/*
* Initialise the static keys early as they may be enabled by the
* cpufeature code and early parameters.
*/
jump_label_init();
parse_early_param(); parse_early_param();
/* /*

View File

@ -218,8 +218,6 @@ SYM_FUNC_ALIAS(__dma_flush_area, __pi___dma_flush_area)
*/ */
SYM_FUNC_START(__pi___dma_map_area) SYM_FUNC_START(__pi___dma_map_area)
add x1, x0, x1 add x1, x0, x1
cmp w2, #DMA_FROM_DEVICE
b.eq __pi_dcache_inval_poc
b __pi_dcache_clean_poc b __pi_dcache_clean_poc
SYM_FUNC_END(__pi___dma_map_area) SYM_FUNC_END(__pi___dma_map_area)
SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area) SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area)

View File

@ -101,6 +101,7 @@ SECTIONS
STABS_DEBUG STABS_DEBUG
DWARF_DEBUG DWARF_DEBUG
ELF_DETAILS
.gptab.sdata : { .gptab.sdata : {
*(.gptab.data) *(.gptab.data)

View File

@ -364,8 +364,13 @@ config RISCV_ISA_SVPBMT
select RISCV_ALTERNATIVE select RISCV_ALTERNATIVE
default y default y
help help
Adds support to dynamically detect the presence of the SVPBMT extension Adds support to dynamically detect the presence of the SVPBMT
(Supervisor-mode: page-based memory types) and enable its usage. ISA-extension (Supervisor-mode: page-based memory types) and
enable its usage.
The memory type for a page contains a combination of attributes
that indicate the cacheability, idempotency, and ordering
properties for access to that page.
The SVPBMT extension is only available on 64Bit cpus. The SVPBMT extension is only available on 64Bit cpus.

View File

@ -35,6 +35,7 @@ config ERRATA_SIFIVE_CIP_1200
config ERRATA_THEAD config ERRATA_THEAD
bool "T-HEAD errata" bool "T-HEAD errata"
depends on !XIP_KERNEL
select RISCV_ALTERNATIVE select RISCV_ALTERNATIVE
help help
All T-HEAD errata Kconfig depend on this Kconfig. Disabling All T-HEAD errata Kconfig depend on this Kconfig. Disabling

View File

@ -192,6 +192,15 @@
riscv,ndev = <186>; riscv,ndev = <186>;
}; };
pdma: dma-controller@3000000 {
compatible = "sifive,fu540-c000-pdma", "sifive,pdma0";
reg = <0x0 0x3000000 0x0 0x8000>;
interrupt-parent = <&plic>;
interrupts = <5 6>, <7 8>, <9 10>, <11 12>;
dma-channels = <4>;
#dma-cells = <1>;
};
clkcfg: clkcfg@20002000 { clkcfg: clkcfg@20002000 {
compatible = "microchip,mpfs-clkcfg"; compatible = "microchip,mpfs-clkcfg";
reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>;

View File

@ -293,7 +293,6 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
unsigned int stage) unsigned int stage)
{ {
u32 cpu_req_feature = cpufeature_probe(stage); u32 cpu_req_feature = cpufeature_probe(stage);
u32 cpu_apply_feature = 0;
struct alt_entry *alt; struct alt_entry *alt;
u32 tmp; u32 tmp;
@ -307,10 +306,8 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
} }
tmp = (1U << alt->errata_id); tmp = (1U << alt->errata_id);
if (cpu_req_feature & tmp) { if (cpu_req_feature & tmp)
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len); patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
cpu_apply_feature |= tmp;
}
} }
} }
#endif #endif

View File

@ -124,6 +124,51 @@ static u64 get_cc_mask(void)
return BIT_ULL(gpa_width - 1); return BIT_ULL(gpa_width - 1);
} }
/*
* The TDX module spec states that #VE may be injected for a limited set of
* reasons:
*
* - Emulation of the architectural #VE injection on EPT violation;
*
* - As a result of guest TD execution of a disallowed instruction,
* a disallowed MSR access, or CPUID virtualization;
*
* - A notification to the guest TD about anomalous behavior;
*
* The last one is opt-in and is not used by the kernel.
*
* The Intel Software Developer's Manual describes cases when instruction
* length field can be used in section "Information for VM Exits Due to
* Instruction Execution".
*
* For TDX, it ultimately means GET_VEINFO provides reliable instruction length
* information if #VE occurred due to instruction execution, but not for EPT
* violations.
*/
static int ve_instr_len(struct ve_info *ve)
{
switch (ve->exit_reason) {
case EXIT_REASON_HLT:
case EXIT_REASON_MSR_READ:
case EXIT_REASON_MSR_WRITE:
case EXIT_REASON_CPUID:
case EXIT_REASON_IO_INSTRUCTION:
/* It is safe to use ve->instr_len for #VE due instructions */
return ve->instr_len;
case EXIT_REASON_EPT_VIOLATION:
/*
* For EPT violations, ve->insn_len is not defined. For those,
* the kernel must decode instructions manually and should not
* be using this function.
*/
WARN_ONCE(1, "ve->instr_len is not defined for EPT violations");
return 0;
default:
WARN_ONCE(1, "Unexpected #VE-type: %lld\n", ve->exit_reason);
return ve->instr_len;
}
}
static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti) static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti)
{ {
struct tdx_hypercall_args args = { struct tdx_hypercall_args args = {
@ -147,7 +192,7 @@ static u64 __cpuidle __halt(const bool irq_disabled, const bool do_sti)
return __tdx_hypercall(&args, do_sti ? TDX_HCALL_ISSUE_STI : 0); return __tdx_hypercall(&args, do_sti ? TDX_HCALL_ISSUE_STI : 0);
} }
static bool handle_halt(void) static int handle_halt(struct ve_info *ve)
{ {
/* /*
* Since non safe halt is mainly used in CPU offlining * Since non safe halt is mainly used in CPU offlining
@ -158,9 +203,9 @@ static bool handle_halt(void)
const bool do_sti = false; const bool do_sti = false;
if (__halt(irq_disabled, do_sti)) if (__halt(irq_disabled, do_sti))
return false; return -EIO;
return true; return ve_instr_len(ve);
} }
void __cpuidle tdx_safe_halt(void) void __cpuidle tdx_safe_halt(void)
@ -180,7 +225,7 @@ void __cpuidle tdx_safe_halt(void)
WARN_ONCE(1, "HLT instruction emulation failed\n"); WARN_ONCE(1, "HLT instruction emulation failed\n");
} }
static bool read_msr(struct pt_regs *regs) static int read_msr(struct pt_regs *regs, struct ve_info *ve)
{ {
struct tdx_hypercall_args args = { struct tdx_hypercall_args args = {
.r10 = TDX_HYPERCALL_STANDARD, .r10 = TDX_HYPERCALL_STANDARD,
@ -194,14 +239,14 @@ static bool read_msr(struct pt_regs *regs)
* (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>". * (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>".
*/ */
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
return false; return -EIO;
regs->ax = lower_32_bits(args.r11); regs->ax = lower_32_bits(args.r11);
regs->dx = upper_32_bits(args.r11); regs->dx = upper_32_bits(args.r11);
return true; return ve_instr_len(ve);
} }
static bool write_msr(struct pt_regs *regs) static int write_msr(struct pt_regs *regs, struct ve_info *ve)
{ {
struct tdx_hypercall_args args = { struct tdx_hypercall_args args = {
.r10 = TDX_HYPERCALL_STANDARD, .r10 = TDX_HYPERCALL_STANDARD,
@ -215,10 +260,13 @@ static bool write_msr(struct pt_regs *regs)
* can be found in TDX Guest-Host-Communication Interface * can be found in TDX Guest-Host-Communication Interface
* (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>". * (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>".
*/ */
return !__tdx_hypercall(&args, 0); if (__tdx_hypercall(&args, 0))
return -EIO;
return ve_instr_len(ve);
} }
static bool handle_cpuid(struct pt_regs *regs) static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
{ {
struct tdx_hypercall_args args = { struct tdx_hypercall_args args = {
.r10 = TDX_HYPERCALL_STANDARD, .r10 = TDX_HYPERCALL_STANDARD,
@ -236,7 +284,7 @@ static bool handle_cpuid(struct pt_regs *regs)
*/ */
if (regs->ax < 0x40000000 || regs->ax > 0x4FFFFFFF) { if (regs->ax < 0x40000000 || regs->ax > 0x4FFFFFFF) {
regs->ax = regs->bx = regs->cx = regs->dx = 0; regs->ax = regs->bx = regs->cx = regs->dx = 0;
return true; return ve_instr_len(ve);
} }
/* /*
@ -245,7 +293,7 @@ static bool handle_cpuid(struct pt_regs *regs)
* (GHCI), section titled "VP.VMCALL<Instruction.CPUID>". * (GHCI), section titled "VP.VMCALL<Instruction.CPUID>".
*/ */
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT)) if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
return false; return -EIO;
/* /*
* As per TDX GHCI CPUID ABI, r12-r15 registers contain contents of * As per TDX GHCI CPUID ABI, r12-r15 registers contain contents of
@ -257,7 +305,7 @@ static bool handle_cpuid(struct pt_regs *regs)
regs->cx = args.r14; regs->cx = args.r14;
regs->dx = args.r15; regs->dx = args.r15;
return true; return ve_instr_len(ve);
} }
static bool mmio_read(int size, unsigned long addr, unsigned long *val) static bool mmio_read(int size, unsigned long addr, unsigned long *val)
@ -283,10 +331,10 @@ static bool mmio_write(int size, unsigned long addr, unsigned long val)
EPT_WRITE, addr, val); EPT_WRITE, addr, val);
} }
static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve) static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
{ {
unsigned long *reg, val, vaddr;
char buffer[MAX_INSN_SIZE]; char buffer[MAX_INSN_SIZE];
unsigned long *reg, val;
struct insn insn = {}; struct insn insn = {};
enum mmio_type mmio; enum mmio_type mmio;
int size, extend_size; int size, extend_size;
@ -294,34 +342,49 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve)
/* Only in-kernel MMIO is supported */ /* Only in-kernel MMIO is supported */
if (WARN_ON_ONCE(user_mode(regs))) if (WARN_ON_ONCE(user_mode(regs)))
return false; return -EFAULT;
if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE)) if (copy_from_kernel_nofault(buffer, (void *)regs->ip, MAX_INSN_SIZE))
return false; return -EFAULT;
if (insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64)) if (insn_decode(&insn, buffer, MAX_INSN_SIZE, INSN_MODE_64))
return false; return -EINVAL;
mmio = insn_decode_mmio(&insn, &size); mmio = insn_decode_mmio(&insn, &size);
if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED)) if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED))
return false; return -EINVAL;
if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) { if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) {
reg = insn_get_modrm_reg_ptr(&insn, regs); reg = insn_get_modrm_reg_ptr(&insn, regs);
if (!reg) if (!reg)
return false; return -EINVAL;
} }
ve->instr_len = insn.length; /*
* Reject EPT violation #VEs that split pages.
*
* MMIO accesses are supposed to be naturally aligned and therefore
* never cross page boundaries. Seeing split page accesses indicates
* a bug or a load_unaligned_zeropad() that stepped into an MMIO page.
*
* load_unaligned_zeropad() will recover using exception fixups.
*/
vaddr = (unsigned long)insn_get_addr_ref(&insn, regs);
if (vaddr / PAGE_SIZE != (vaddr + size - 1) / PAGE_SIZE)
return -EFAULT;
/* Handle writes first */ /* Handle writes first */
switch (mmio) { switch (mmio) {
case MMIO_WRITE: case MMIO_WRITE:
memcpy(&val, reg, size); memcpy(&val, reg, size);
return mmio_write(size, ve->gpa, val); if (!mmio_write(size, ve->gpa, val))
return -EIO;
return insn.length;
case MMIO_WRITE_IMM: case MMIO_WRITE_IMM:
val = insn.immediate.value; val = insn.immediate.value;
return mmio_write(size, ve->gpa, val); if (!mmio_write(size, ve->gpa, val))
return -EIO;
return insn.length;
case MMIO_READ: case MMIO_READ:
case MMIO_READ_ZERO_EXTEND: case MMIO_READ_ZERO_EXTEND:
case MMIO_READ_SIGN_EXTEND: case MMIO_READ_SIGN_EXTEND:
@ -334,15 +397,15 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve)
* decoded or handled properly. It was likely not using io.h * decoded or handled properly. It was likely not using io.h
* helpers or accessed MMIO accidentally. * helpers or accessed MMIO accidentally.
*/ */
return false; return -EINVAL;
default: default:
WARN_ONCE(1, "Unknown insn_decode_mmio() decode value?"); WARN_ONCE(1, "Unknown insn_decode_mmio() decode value?");
return false; return -EINVAL;
} }
/* Handle reads */ /* Handle reads */
if (!mmio_read(size, ve->gpa, &val)) if (!mmio_read(size, ve->gpa, &val))
return false; return -EIO;
switch (mmio) { switch (mmio) {
case MMIO_READ: case MMIO_READ:
@ -364,13 +427,13 @@ static bool handle_mmio(struct pt_regs *regs, struct ve_info *ve)
default: default:
/* All other cases has to be covered with the first switch() */ /* All other cases has to be covered with the first switch() */
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
return false; return -EINVAL;
} }
if (extend_size) if (extend_size)
memset(reg, extend_val, extend_size); memset(reg, extend_val, extend_size);
memcpy(reg, &val, size); memcpy(reg, &val, size);
return true; return insn.length;
} }
static bool handle_in(struct pt_regs *regs, int size, int port) static bool handle_in(struct pt_regs *regs, int size, int port)
@ -421,13 +484,14 @@ static bool handle_out(struct pt_regs *regs, int size, int port)
* *
* Return True on success or False on failure. * Return True on success or False on failure.
*/ */
static bool handle_io(struct pt_regs *regs, u32 exit_qual) static int handle_io(struct pt_regs *regs, struct ve_info *ve)
{ {
u32 exit_qual = ve->exit_qual;
int size, port; int size, port;
bool in; bool in, ret;
if (VE_IS_IO_STRING(exit_qual)) if (VE_IS_IO_STRING(exit_qual))
return false; return -EIO;
in = VE_IS_IO_IN(exit_qual); in = VE_IS_IO_IN(exit_qual);
size = VE_GET_IO_SIZE(exit_qual); size = VE_GET_IO_SIZE(exit_qual);
@ -435,9 +499,13 @@ static bool handle_io(struct pt_regs *regs, u32 exit_qual)
if (in) if (in)
return handle_in(regs, size, port); ret = handle_in(regs, size, port);
else else
return handle_out(regs, size, port); ret = handle_out(regs, size, port);
if (!ret)
return -EIO;
return ve_instr_len(ve);
} }
/* /*
@ -447,13 +515,19 @@ static bool handle_io(struct pt_regs *regs, u32 exit_qual)
__init bool tdx_early_handle_ve(struct pt_regs *regs) __init bool tdx_early_handle_ve(struct pt_regs *regs)
{ {
struct ve_info ve; struct ve_info ve;
int insn_len;
tdx_get_ve_info(&ve); tdx_get_ve_info(&ve);
if (ve.exit_reason != EXIT_REASON_IO_INSTRUCTION) if (ve.exit_reason != EXIT_REASON_IO_INSTRUCTION)
return false; return false;
return handle_io(regs, ve.exit_qual); insn_len = handle_io(regs, &ve);
if (insn_len < 0)
return false;
regs->ip += insn_len;
return true;
} }
void tdx_get_ve_info(struct ve_info *ve) void tdx_get_ve_info(struct ve_info *ve)
@ -486,54 +560,65 @@ void tdx_get_ve_info(struct ve_info *ve)
ve->instr_info = upper_32_bits(out.r10); ve->instr_info = upper_32_bits(out.r10);
} }
/* Handle the user initiated #VE */ /*
static bool virt_exception_user(struct pt_regs *regs, struct ve_info *ve) * Handle the user initiated #VE.
*
* On success, returns the number of bytes RIP should be incremented (>=0)
* or -errno on error.
*/
static int virt_exception_user(struct pt_regs *regs, struct ve_info *ve)
{ {
switch (ve->exit_reason) { switch (ve->exit_reason) {
case EXIT_REASON_CPUID: case EXIT_REASON_CPUID:
return handle_cpuid(regs); return handle_cpuid(regs, ve);
default: default:
pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
return false; return -EIO;
} }
} }
/* Handle the kernel #VE */ /*
static bool virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve) * Handle the kernel #VE.
*
* On success, returns the number of bytes RIP should be incremented (>=0)
* or -errno on error.
*/
static int virt_exception_kernel(struct pt_regs *regs, struct ve_info *ve)
{ {
switch (ve->exit_reason) { switch (ve->exit_reason) {
case EXIT_REASON_HLT: case EXIT_REASON_HLT:
return handle_halt(); return handle_halt(ve);
case EXIT_REASON_MSR_READ: case EXIT_REASON_MSR_READ:
return read_msr(regs); return read_msr(regs, ve);
case EXIT_REASON_MSR_WRITE: case EXIT_REASON_MSR_WRITE:
return write_msr(regs); return write_msr(regs, ve);
case EXIT_REASON_CPUID: case EXIT_REASON_CPUID:
return handle_cpuid(regs); return handle_cpuid(regs, ve);
case EXIT_REASON_EPT_VIOLATION: case EXIT_REASON_EPT_VIOLATION:
return handle_mmio(regs, ve); return handle_mmio(regs, ve);
case EXIT_REASON_IO_INSTRUCTION: case EXIT_REASON_IO_INSTRUCTION:
return handle_io(regs, ve->exit_qual); return handle_io(regs, ve);
default: default:
pr_warn("Unexpected #VE: %lld\n", ve->exit_reason); pr_warn("Unexpected #VE: %lld\n", ve->exit_reason);
return false; return -EIO;
} }
} }
bool tdx_handle_virt_exception(struct pt_regs *regs, struct ve_info *ve) bool tdx_handle_virt_exception(struct pt_regs *regs, struct ve_info *ve)
{ {
bool ret; int insn_len;
if (user_mode(regs)) if (user_mode(regs))
ret = virt_exception_user(regs, ve); insn_len = virt_exception_user(regs, ve);
else else
ret = virt_exception_kernel(regs, ve); insn_len = virt_exception_kernel(regs, ve);
if (insn_len < 0)
return false;
/* After successful #VE handling, move the IP */ /* After successful #VE handling, move the IP */
if (ret) regs->ip += insn_len;
regs->ip += ve->instr_len;
return ret; return true;
} }
static bool tdx_tlb_flush_required(bool private) static bool tdx_tlb_flush_required(bool private)

View File

@ -13,6 +13,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/apic.h> #include <asm/apic.h>
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/sev.h>
#include <asm/hypervisor.h> #include <asm/hypervisor.h>
#include <asm/hyperv-tlfs.h> #include <asm/hyperv-tlfs.h>
#include <asm/mshyperv.h> #include <asm/mshyperv.h>
@ -405,6 +406,11 @@ void __init hyperv_init(void)
} }
if (hv_isolation_type_snp()) { if (hv_isolation_type_snp()) {
/* Negotiate GHCB Version. */
if (!hv_ghcb_negotiate_protocol())
hv_ghcb_terminate(SEV_TERM_SET_GEN,
GHCB_SEV_ES_PROT_UNSUPPORTED);
hv_ghcb_pg = alloc_percpu(union hv_ghcb *); hv_ghcb_pg = alloc_percpu(union hv_ghcb *);
if (!hv_ghcb_pg) if (!hv_ghcb_pg)
goto free_vp_assist_page; goto free_vp_assist_page;

View File

@ -53,6 +53,8 @@ union hv_ghcb {
} hypercall; } hypercall;
} __packed __aligned(HV_HYP_PAGE_SIZE); } __packed __aligned(HV_HYP_PAGE_SIZE);
static u16 hv_ghcb_version __ro_after_init;
u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size) u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
{ {
union hv_ghcb *hv_ghcb; union hv_ghcb *hv_ghcb;
@ -96,12 +98,85 @@ u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size)
return status; return status;
} }
static inline u64 rd_ghcb_msr(void)
{
return __rdmsr(MSR_AMD64_SEV_ES_GHCB);
}
static inline void wr_ghcb_msr(u64 val)
{
native_wrmsrl(MSR_AMD64_SEV_ES_GHCB, val);
}
static enum es_result hv_ghcb_hv_call(struct ghcb *ghcb, u64 exit_code,
u64 exit_info_1, u64 exit_info_2)
{
/* Fill in protocol and format specifiers */
ghcb->protocol_version = hv_ghcb_version;
ghcb->ghcb_usage = GHCB_DEFAULT_USAGE;
ghcb_set_sw_exit_code(ghcb, exit_code);
ghcb_set_sw_exit_info_1(ghcb, exit_info_1);
ghcb_set_sw_exit_info_2(ghcb, exit_info_2);
VMGEXIT();
if (ghcb->save.sw_exit_info_1 & GENMASK_ULL(31, 0))
return ES_VMM_ERROR;
else
return ES_OK;
}
void hv_ghcb_terminate(unsigned int set, unsigned int reason)
{
u64 val = GHCB_MSR_TERM_REQ;
/* Tell the hypervisor what went wrong. */
val |= GHCB_SEV_TERM_REASON(set, reason);
/* Request Guest Termination from Hypvervisor */
wr_ghcb_msr(val);
VMGEXIT();
while (true)
asm volatile("hlt\n" : : : "memory");
}
bool hv_ghcb_negotiate_protocol(void)
{
u64 ghcb_gpa;
u64 val;
/* Save ghcb page gpa. */
ghcb_gpa = rd_ghcb_msr();
/* Do the GHCB protocol version negotiation */
wr_ghcb_msr(GHCB_MSR_SEV_INFO_REQ);
VMGEXIT();
val = rd_ghcb_msr();
if (GHCB_MSR_INFO(val) != GHCB_MSR_SEV_INFO_RESP)
return false;
if (GHCB_MSR_PROTO_MAX(val) < GHCB_PROTOCOL_MIN ||
GHCB_MSR_PROTO_MIN(val) > GHCB_PROTOCOL_MAX)
return false;
hv_ghcb_version = min_t(size_t, GHCB_MSR_PROTO_MAX(val),
GHCB_PROTOCOL_MAX);
/* Write ghcb page back after negotiating protocol. */
wr_ghcb_msr(ghcb_gpa);
VMGEXIT();
return true;
}
void hv_ghcb_msr_write(u64 msr, u64 value) void hv_ghcb_msr_write(u64 msr, u64 value)
{ {
union hv_ghcb *hv_ghcb; union hv_ghcb *hv_ghcb;
void **ghcb_base; void **ghcb_base;
unsigned long flags; unsigned long flags;
struct es_em_ctxt ctxt;
if (!hv_ghcb_pg) if (!hv_ghcb_pg)
return; return;
@ -120,8 +195,7 @@ void hv_ghcb_msr_write(u64 msr, u64 value)
ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value)); ghcb_set_rax(&hv_ghcb->ghcb, lower_32_bits(value));
ghcb_set_rdx(&hv_ghcb->ghcb, upper_32_bits(value)); ghcb_set_rdx(&hv_ghcb->ghcb, upper_32_bits(value));
if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt, if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 1, 0))
SVM_EXIT_MSR, 1, 0))
pr_warn("Fail to write msr via ghcb %llx.\n", msr); pr_warn("Fail to write msr via ghcb %llx.\n", msr);
local_irq_restore(flags); local_irq_restore(flags);
@ -133,7 +207,6 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
union hv_ghcb *hv_ghcb; union hv_ghcb *hv_ghcb;
void **ghcb_base; void **ghcb_base;
unsigned long flags; unsigned long flags;
struct es_em_ctxt ctxt;
/* Check size of union hv_ghcb here. */ /* Check size of union hv_ghcb here. */
BUILD_BUG_ON(sizeof(union hv_ghcb) != HV_HYP_PAGE_SIZE); BUILD_BUG_ON(sizeof(union hv_ghcb) != HV_HYP_PAGE_SIZE);
@ -152,8 +225,7 @@ void hv_ghcb_msr_read(u64 msr, u64 *value)
} }
ghcb_set_rcx(&hv_ghcb->ghcb, msr); ghcb_set_rcx(&hv_ghcb->ghcb, msr);
if (sev_es_ghcb_hv_call(&hv_ghcb->ghcb, false, &ctxt, if (hv_ghcb_hv_call(&hv_ghcb->ghcb, SVM_EXIT_MSR, 0, 0))
SVM_EXIT_MSR, 0, 0))
pr_warn("Fail to read msr via ghcb %llx.\n", msr); pr_warn("Fail to read msr via ghcb %llx.\n", msr);
else else
*value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax) *value = (u64)lower_32_bits(hv_ghcb->ghcb.save.rax)

View File

@ -4,9 +4,6 @@
#include <asm/e820/types.h> #include <asm/e820/types.h>
struct device;
struct resource;
extern struct e820_table *e820_table; extern struct e820_table *e820_table;
extern struct e820_table *e820_table_kexec; extern struct e820_table *e820_table_kexec;
extern struct e820_table *e820_table_firmware; extern struct e820_table *e820_table_firmware;
@ -46,8 +43,6 @@ extern void e820__register_nosave_regions(unsigned long limit_pfn);
extern int e820__get_entry_type(u64 start, u64 end); extern int e820__get_entry_type(u64 start, u64 end);
extern void remove_e820_regions(struct device *dev, struct resource *avail);
/* /*
* Returns true iff the specified range [start,end) is completely contained inside * Returns true iff the specified range [start,end) is completely contained inside
* the ISA region. * the ISA region.

View File

@ -323,7 +323,7 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \
(__efi64_split(phys), (desc)) (__efi64_split(phys), (desc))
#define __efi64_argmap_set_memory_space_descriptor(phys, size, flags) \ #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \
(__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) (__efi64_split(phys), __efi64_split(size), __efi64_split(flags))
/* /*

View File

@ -179,9 +179,13 @@ int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible);
#ifdef CONFIG_AMD_MEM_ENCRYPT #ifdef CONFIG_AMD_MEM_ENCRYPT
void hv_ghcb_msr_write(u64 msr, u64 value); void hv_ghcb_msr_write(u64 msr, u64 value);
void hv_ghcb_msr_read(u64 msr, u64 *value); void hv_ghcb_msr_read(u64 msr, u64 *value);
bool hv_ghcb_negotiate_protocol(void);
void hv_ghcb_terminate(unsigned int set, unsigned int reason);
#else #else
static inline void hv_ghcb_msr_write(u64 msr, u64 value) {} static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {} static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
static inline bool hv_ghcb_negotiate_protocol(void) { return false; }
static inline void hv_ghcb_terminate(unsigned int set, unsigned int reason) {}
#endif #endif
extern bool hv_isolation_type_snp(void); extern bool hv_isolation_type_snp(void);

View File

@ -69,6 +69,8 @@ void pcibios_scan_specific_bus(int busn);
/* pci-irq.c */ /* pci-irq.c */
struct pci_dev;
struct irq_info { struct irq_info {
u8 bus, devfn; /* Bus, device and function */ u8 bus, devfn; /* Bus, device and function */
struct { struct {
@ -246,3 +248,9 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val)
# define x86_default_pci_init_irq NULL # define x86_default_pci_init_irq NULL
# define x86_default_pci_fixup_irqs NULL # define x86_default_pci_fixup_irqs NULL
#endif #endif
#if defined(CONFIG_PCI) && defined(CONFIG_ACPI)
extern bool pci_use_e820;
#else
#define pci_use_e820 false
#endif

View File

@ -108,19 +108,16 @@ extern unsigned long _brk_end;
void *extend_brk(size_t size, size_t align); void *extend_brk(size_t size, size_t align);
/* /*
* Reserve space in the brk section. The name must be unique within the file, * Reserve space in the .brk section, which is a block of memory from which the
* and somewhat descriptive. The size is in bytes. * caller is allowed to allocate very early (before even memblock is available)
* by calling extend_brk(). All allocated memory will be eventually converted
* to memblock. Any leftover unallocated memory will be freed.
* *
* The allocation is done using inline asm (rather than using a section * The size is in bytes.
* attribute on a normal variable) in order to allow the use of @nobits, so
* that it doesn't take up any space in the vmlinux file.
*/ */
#define RESERVE_BRK(name, size) \ #define RESERVE_BRK(name, size) \
asm(".pushsection .brk_reservation,\"aw\",@nobits\n\t" \ __section(".bss..brk") __aligned(1) __used \
".brk." #name ":\n\t" \ static char __brk_##name[size]
".skip " __stringify(size) "\n\t" \
".size .brk." #name ", " __stringify(size) "\n\t" \
".popsection\n\t")
extern void probe_roms(void); extern void probe_roms(void);
#ifdef __i386__ #ifdef __i386__
@ -133,12 +130,19 @@ asmlinkage void __init x86_64_start_reservations(char *real_mode_data);
#endif /* __i386__ */ #endif /* __i386__ */
#endif /* _SETUP */ #endif /* _SETUP */
#else
#define RESERVE_BRK(name,sz) \ #else /* __ASSEMBLY */
.pushsection .brk_reservation,"aw",@nobits; \
.brk.name: \ .macro __RESERVE_BRK name, size
1: .skip sz; \ .pushsection .bss..brk, "aw"
.size .brk.name,.-1b; \ SYM_DATA_START(__brk_\name)
.skip \size
SYM_DATA_END(__brk_\name)
.popsection .popsection
.endm
#define RESERVE_BRK(name, size) __RESERVE_BRK name, size
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_SETUP_H */ #endif /* _ASM_X86_SETUP_H */

View File

@ -36,10 +36,6 @@ KCSAN_SANITIZE := n
OBJECT_FILES_NON_STANDARD_test_nx.o := y OBJECT_FILES_NON_STANDARD_test_nx.o := y
ifdef CONFIG_FRAME_POINTER
OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y
endif
# If instrumentation of this dir is enabled, boot hangs during first second. # If instrumentation of this dir is enabled, boot hangs during first second.
# Probably could be more selective here, but note that files related to irqs, # Probably could be more selective here, but note that files related to irqs,
# boot, dumpstack/stacktrace, etc are either non-interesting or can lead to # boot, dumpstack/stacktrace, etc are either non-interesting or can lead to

View File

@ -175,6 +175,7 @@ SYM_INNER_LABEL(ftrace_caller_end, SYM_L_GLOBAL)
jmp ftrace_epilogue jmp ftrace_epilogue
SYM_FUNC_END(ftrace_caller); SYM_FUNC_END(ftrace_caller);
STACK_FRAME_NON_STANDARD_FP(ftrace_caller)
SYM_FUNC_START(ftrace_epilogue) SYM_FUNC_START(ftrace_epilogue)
/* /*
@ -282,6 +283,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
jmp ftrace_epilogue jmp ftrace_epilogue
SYM_FUNC_END(ftrace_regs_caller) SYM_FUNC_END(ftrace_regs_caller)
STACK_FRAME_NON_STANDARD_FP(ftrace_regs_caller)
#else /* ! CONFIG_DYNAMIC_FTRACE */ #else /* ! CONFIG_DYNAMIC_FTRACE */
@ -311,10 +313,14 @@ trace:
jmp ftrace_stub jmp ftrace_stub
SYM_FUNC_END(__fentry__) SYM_FUNC_END(__fentry__)
EXPORT_SYMBOL(__fentry__) EXPORT_SYMBOL(__fentry__)
STACK_FRAME_NON_STANDARD_FP(__fentry__)
#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
SYM_FUNC_START(return_to_handler) SYM_CODE_START(return_to_handler)
UNWIND_HINT_EMPTY
ANNOTATE_NOENDBR
subq $16, %rsp subq $16, %rsp
/* Save the return values */ /* Save the return values */
@ -339,7 +345,6 @@ SYM_FUNC_START(return_to_handler)
int3 int3
.Ldo_rop: .Ldo_rop:
mov %rdi, (%rsp) mov %rdi, (%rsp)
UNWIND_HINT_FUNC
RET RET
SYM_FUNC_END(return_to_handler) SYM_CODE_END(return_to_handler)
#endif #endif

View File

@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/dev_printk.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/printk.h>
#include <asm/e820/api.h> #include <asm/e820/api.h>
#include <asm/pci_x86.h>
static void resource_clip(struct resource *res, resource_size_t start, static void resource_clip(struct resource *res, resource_size_t start,
resource_size_t end) resource_size_t end)
@ -24,14 +25,14 @@ static void resource_clip(struct resource *res, resource_size_t start,
res->start = end + 1; res->start = end + 1;
} }
void remove_e820_regions(struct device *dev, struct resource *avail) static void remove_e820_regions(struct resource *avail)
{ {
int i; int i;
struct e820_entry *entry; struct e820_entry *entry;
u64 e820_start, e820_end; u64 e820_start, e820_end;
struct resource orig = *avail; struct resource orig = *avail;
if (!(avail->flags & IORESOURCE_MEM)) if (!pci_use_e820)
return; return;
for (i = 0; i < e820_table->nr_entries; i++) { for (i = 0; i < e820_table->nr_entries; i++) {
@ -41,7 +42,7 @@ void remove_e820_regions(struct device *dev, struct resource *avail)
resource_clip(avail, e820_start, e820_end); resource_clip(avail, e820_start, e820_end);
if (orig.start != avail->start || orig.end != avail->end) { if (orig.start != avail->start || orig.end != avail->end) {
dev_info(dev, "clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n", pr_info("clipped %pR to %pR for e820 entry [mem %#010Lx-%#010Lx]\n",
&orig, avail, e820_start, e820_end); &orig, avail, e820_start, e820_end);
orig = *avail; orig = *avail;
} }
@ -55,6 +56,9 @@ void arch_remove_reservations(struct resource *avail)
* the low 1MB unconditionally, as this area is needed for some ISA * the low 1MB unconditionally, as this area is needed for some ISA
* cards requiring a memory range, e.g. the i82365 PCMCIA controller. * cards requiring a memory range, e.g. the i82365 PCMCIA controller.
*/ */
if (avail->flags & IORESOURCE_MEM) if (avail->flags & IORESOURCE_MEM) {
resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
remove_e820_regions(avail);
}
} }

View File

@ -67,11 +67,6 @@ RESERVE_BRK(dmi_alloc, 65536);
#endif #endif
/*
* Range of the BSS area. The size of the BSS area is determined
* at link time, with RESERVE_BRK() facility reserving additional
* chunks.
*/
unsigned long _brk_start = (unsigned long)__brk_base; unsigned long _brk_start = (unsigned long)__brk_base;
unsigned long _brk_end = (unsigned long)__brk_base; unsigned long _brk_end = (unsigned long)__brk_base;

View File

@ -385,10 +385,10 @@ SECTIONS
__end_of_kernel_reserve = .; __end_of_kernel_reserve = .;
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
.brk : AT(ADDR(.brk) - LOAD_OFFSET) { .brk (NOLOAD) : AT(ADDR(.brk) - LOAD_OFFSET) {
__brk_base = .; __brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */ . += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */ *(.bss..brk) /* areas brk users have reserved */
__brk_limit = .; __brk_limit = .;
} }

View File

@ -1420,8 +1420,9 @@ st: if (is_imm8(insn->off))
case BPF_JMP | BPF_CALL: case BPF_JMP | BPF_CALL:
func = (u8 *) __bpf_call_base + imm32; func = (u8 *) __bpf_call_base + imm32;
if (tail_call_reachable) { if (tail_call_reachable) {
/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */
EMIT3_off32(0x48, 0x8B, 0x85, EMIT3_off32(0x48, 0x8B, 0x85,
-(bpf_prog->aux->stack_depth + 8)); -round_up(bpf_prog->aux->stack_depth, 8) - 8);
if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7)) if (!imm32 || emit_call(&prog, func, image + addrs[i - 1] + 7))
return -EINVAL; return -EINVAL;
} else { } else {

View File

@ -8,7 +8,6 @@
#include <linux/pci-acpi.h> #include <linux/pci-acpi.h>
#include <asm/numa.h> #include <asm/numa.h>
#include <asm/pci_x86.h> #include <asm/pci_x86.h>
#include <asm/e820/api.h>
struct pci_root_info { struct pci_root_info {
struct acpi_pci_root_info common; struct acpi_pci_root_info common;
@ -20,7 +19,7 @@ struct pci_root_info {
#endif #endif
}; };
static bool pci_use_e820 = true; bool pci_use_e820 = true;
static bool pci_use_crs = true; static bool pci_use_crs = true;
static bool pci_ignore_seg; static bool pci_ignore_seg;
@ -387,11 +386,6 @@ static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
status = acpi_pci_probe_root_resources(ci); status = acpi_pci_probe_root_resources(ci);
if (pci_use_e820) {
resource_list_for_each_entry(entry, &ci->resources)
remove_e820_regions(&device->dev, entry->res);
}
if (pci_use_crs) { if (pci_use_crs) {
resource_list_for_each_entry_safe(entry, tmp, &ci->resources) resource_list_for_each_entry_safe(entry, tmp, &ci->resources)
if (resource_is_pcicfg_ioport(entry->res)) if (resource_is_pcicfg_ioport(entry->res))

View File

@ -7046,6 +7046,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
spin_unlock_irq(&bfqd->lock); spin_unlock_irq(&bfqd->lock);
#endif #endif
blk_stat_disable_accounting(bfqd->queue);
wbt_enable_default(bfqd->queue); wbt_enable_default(bfqd->queue);
kfree(bfqd); kfree(bfqd);
@ -7188,7 +7189,12 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
bfq_init_root_group(bfqd->root_group, bfqd); bfq_init_root_group(bfqd->root_group, bfqd);
bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group);
/* We dispatch from request queue wide instead of hw queue */
blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q);
wbt_disable_default(q); wbt_disable_default(q);
blk_stat_enable_accounting(q);
return 0; return 0;
out_free: out_free:

View File

@ -564,6 +564,7 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
int ret; int ret;
if (!e) { if (!e) {
blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q);
q->elevator = NULL; q->elevator = NULL;
q->nr_requests = q->tag_set->queue_depth; q->nr_requests = q->tag_set->queue_depth;
return 0; return 0;

View File

@ -579,6 +579,8 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
if (!blk_mq_hw_queue_mapped(data.hctx)) if (!blk_mq_hw_queue_mapped(data.hctx))
goto out_queue_exit; goto out_queue_exit;
cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask); cpu = cpumask_first_and(data.hctx->cpumask, cpu_online_mask);
if (cpu >= nr_cpu_ids)
goto out_queue_exit;
data.ctx = __blk_mq_get_ctx(q, cpu); data.ctx = __blk_mq_get_ctx(q, cpu);
if (!q->elevator) if (!q->elevator)
@ -2140,20 +2142,6 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
} }
EXPORT_SYMBOL(blk_mq_run_hw_queue); EXPORT_SYMBOL(blk_mq_run_hw_queue);
/*
* Is the request queue handled by an IO scheduler that does not respect
* hardware queues when dispatching?
*/
static bool blk_mq_has_sqsched(struct request_queue *q)
{
struct elevator_queue *e = q->elevator;
if (e && e->type->ops.dispatch_request &&
!(e->type->elevator_features & ELEVATOR_F_MQ_AWARE))
return true;
return false;
}
/* /*
* Return prefered queue to dispatch from (if any) for non-mq aware IO * Return prefered queue to dispatch from (if any) for non-mq aware IO
* scheduler. * scheduler.
@ -2186,7 +2174,7 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async)
unsigned long i; unsigned long i;
sq_hctx = NULL; sq_hctx = NULL;
if (blk_mq_has_sqsched(q)) if (blk_queue_sq_sched(q))
sq_hctx = blk_mq_get_sq_hctx(q); sq_hctx = blk_mq_get_sq_hctx(q);
queue_for_each_hw_ctx(q, hctx, i) { queue_for_each_hw_ctx(q, hctx, i) {
if (blk_mq_hctx_stopped(hctx)) if (blk_mq_hctx_stopped(hctx))
@ -2214,7 +2202,7 @@ void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs)
unsigned long i; unsigned long i;
sq_hctx = NULL; sq_hctx = NULL;
if (blk_mq_has_sqsched(q)) if (blk_queue_sq_sched(q))
sq_hctx = blk_mq_get_sq_hctx(q); sq_hctx = blk_mq_get_sq_hctx(q);
queue_for_each_hw_ctx(q, hctx, i) { queue_for_each_hw_ctx(q, hctx, i) {
if (blk_mq_hctx_stopped(hctx)) if (blk_mq_hctx_stopped(hctx))
@ -3443,6 +3431,7 @@ static void blk_mq_exit_hctx(struct request_queue *q,
if (blk_mq_hw_queue_mapped(hctx)) if (blk_mq_hw_queue_mapped(hctx))
blk_mq_tag_idle(hctx); blk_mq_tag_idle(hctx);
if (blk_queue_init_done(q))
blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx], blk_mq_clear_flush_rq_mapping(set->tags[hctx_idx],
set->queue_depth, flush_rq); set->queue_depth, flush_rq);
if (set->ops->exit_request) if (set->ops->exit_request)
@ -4438,12 +4427,14 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
if (!qe) if (!qe)
return false; return false;
/* q->elevator needs protection from ->sysfs_lock */
mutex_lock(&q->sysfs_lock);
INIT_LIST_HEAD(&qe->node); INIT_LIST_HEAD(&qe->node);
qe->q = q; qe->q = q;
qe->type = q->elevator->type; qe->type = q->elevator->type;
list_add(&qe->node, head); list_add(&qe->node, head);
mutex_lock(&q->sysfs_lock);
/* /*
* After elevator_switch_mq, the previous elevator_queue will be * After elevator_switch_mq, the previous elevator_queue will be
* released by elevator_release. The reference of the io scheduler * released by elevator_release. The reference of the io scheduler

View File

@ -421,6 +421,8 @@ static int kyber_init_sched(struct request_queue *q, struct elevator_type *e)
blk_stat_enable_accounting(q); blk_stat_enable_accounting(q);
blk_queue_flag_clear(QUEUE_FLAG_SQ_SCHED, q);
eq->elevator_data = kqd; eq->elevator_data = kqd;
q->elevator = eq; q->elevator = eq;
@ -1033,7 +1035,6 @@ static struct elevator_type kyber_sched = {
#endif #endif
.elevator_attrs = kyber_sched_attrs, .elevator_attrs = kyber_sched_attrs,
.elevator_name = "kyber", .elevator_name = "kyber",
.elevator_features = ELEVATOR_F_MQ_AWARE,
.elevator_owner = THIS_MODULE, .elevator_owner = THIS_MODULE,
}; };

View File

@ -642,6 +642,9 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e)
spin_lock_init(&dd->lock); spin_lock_init(&dd->lock);
spin_lock_init(&dd->zone_lock); spin_lock_init(&dd->zone_lock);
/* We dispatch from request queue wide instead of hw queue */
blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q);
q->elevator = eq; q->elevator = eq;
return 0; return 0;

View File

@ -3,8 +3,8 @@
# Makefile for the linux kernel signature checking certificates. # Makefile for the linux kernel signature checking certificates.
# #
obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o
obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),) ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),)

View File

@ -15,10 +15,9 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/uidgid.h> #include <linux/uidgid.h>
#include <linux/verification.h> #include <keys/asymmetric-type.h>
#include <keys/system_keyring.h> #include <keys/system_keyring.h>
#include "blacklist.h" #include "blacklist.h"
#include "common.h"
/* /*
* According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(), * According to crypto/asymmetric_keys/x509_cert_parser.c:x509_note_pkey_algo(),
@ -365,7 +364,8 @@ static __init int load_revocation_certificate_list(void)
if (revocation_certificate_list_size) if (revocation_certificate_list_size)
pr_notice("Loading compiled-in revocation X.509 certificates\n"); pr_notice("Loading compiled-in revocation X.509 certificates\n");
return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, return x509_load_certificate_list(revocation_certificate_list,
revocation_certificate_list_size,
blacklist_keyring); blacklist_keyring);
} }
late_initcall(load_revocation_certificate_list); late_initcall(load_revocation_certificate_list);

View File

@ -1,9 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _CERT_COMMON_H
#define _CERT_COMMON_H
int load_certificate_list(const u8 cert_list[], const unsigned long list_size,
const struct key *keyring);
#endif

View File

@ -16,7 +16,6 @@
#include <keys/asymmetric-type.h> #include <keys/asymmetric-type.h>
#include <keys/system_keyring.h> #include <keys/system_keyring.h>
#include <crypto/pkcs7.h> #include <crypto/pkcs7.h>
#include "common.h"
static struct key *builtin_trusted_keys; static struct key *builtin_trusted_keys;
#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
@ -183,7 +182,8 @@ __init int load_module_cert(struct key *keyring)
pr_notice("Loading compiled-in module X.509 certificates\n"); pr_notice("Loading compiled-in module X.509 certificates\n");
return load_certificate_list(system_certificate_list, module_cert_size, keyring); return x509_load_certificate_list(system_certificate_list,
module_cert_size, keyring);
} }
/* /*
@ -204,7 +204,7 @@ static __init int load_system_certificate_list(void)
size = system_certificate_list_size - module_cert_size; size = system_certificate_list_size - module_cert_size;
#endif #endif
return load_certificate_list(p, size, builtin_trusted_keys); return x509_load_certificate_list(p, size, builtin_trusted_keys);
} }
late_initcall(load_system_certificate_list); late_initcall(load_system_certificate_list);

View File

@ -15,6 +15,7 @@ source "crypto/async_tx/Kconfig"
# #
menuconfig CRYPTO menuconfig CRYPTO
tristate "Cryptographic API" tristate "Cryptographic API"
select LIB_MEMNEQ
help help
This option provides the core Cryptographic API. This option provides the core Cryptographic API.

View File

@ -4,7 +4,7 @@
# #
obj-$(CONFIG_CRYPTO) += crypto.o obj-$(CONFIG_CRYPTO) += crypto.o
crypto-y := api.o cipher.o compress.o memneq.o crypto-y := api.o cipher.o compress.o
obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o
obj-$(CONFIG_CRYPTO_FIPS) += fips.o obj-$(CONFIG_CRYPTO_FIPS) += fips.o

View File

@ -75,4 +75,14 @@ config SIGNED_PE_FILE_VERIFICATION
This option provides support for verifying the signature(s) on a This option provides support for verifying the signature(s) on a
signed PE binary. signed PE binary.
config FIPS_SIGNATURE_SELFTEST
bool "Run FIPS selftests on the X.509+PKCS7 signature verification"
help
This option causes some selftests to be run on the signature
verification code, using some built in data. This is required
for FIPS.
depends on KEYS
depends on ASYMMETRIC_KEY_TYPE
depends on PKCS7_MESSAGE_PARSER
endif # ASYMMETRIC_KEY_TYPE endif # ASYMMETRIC_KEY_TYPE

View File

@ -20,7 +20,9 @@ x509_key_parser-y := \
x509.asn1.o \ x509.asn1.o \
x509_akid.asn1.o \ x509_akid.asn1.o \
x509_cert_parser.o \ x509_cert_parser.o \
x509_loader.o \
x509_public_key.o x509_public_key.o
x509_key_parser-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += selftest.o
$(obj)/x509_cert_parser.o: \ $(obj)/x509_cert_parser.o: \
$(obj)/x509.asn1.h \ $(obj)/x509.asn1.h \

View File

@ -0,0 +1,224 @@
/* Self-testing for signature checking.
*
* Copyright (C) 2022 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#include <linux/kernel.h>
#include <linux/cred.h>
#include <linux/key.h>
#include <crypto/pkcs7.h>
#include "x509_parser.h"
struct certs_test {
const u8 *data;
size_t data_len;
const u8 *pkcs7;
size_t pkcs7_len;
};
/*
* Set of X.509 certificates to provide public keys for the tests. These will
* be loaded into a temporary keyring for the duration of the testing.
*/
static const __initconst u8 certs_selftest_keys[] = {
"\x30\x82\x05\x55\x30\x82\x03\x3d\xa0\x03\x02\x01\x02\x02\x14\x73"
"\x98\xea\x98\x2d\xd0\x2e\xa8\xb1\xcf\x57\xc7\xf2\x97\xb3\xe6\x1a"
"\xfc\x8c\x0a\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b"
"\x05\x00\x30\x34\x31\x32\x30\x30\x06\x03\x55\x04\x03\x0c\x29\x43"
"\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69\x66"
"\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x6c\x66\x2d\x74\x65\x73"
"\x74\x69\x6e\x67\x20\x6b\x65\x79\x30\x20\x17\x0d\x32\x32\x30\x35"
"\x31\x38\x32\x32\x33\x32\x34\x31\x5a\x18\x0f\x32\x31\x32\x32\x30"
"\x34\x32\x34\x32\x32\x33\x32\x34\x31\x5a\x30\x34\x31\x32\x30\x30"
"\x06\x03\x55\x04\x03\x0c\x29\x43\x65\x72\x74\x69\x66\x69\x63\x61"
"\x74\x65\x20\x76\x65\x72\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x20"
"\x73\x65\x6c\x66\x2d\x74\x65\x73\x74\x69\x6e\x67\x20\x6b\x65\x79"
"\x30\x82\x02\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01"
"\x01\x05\x00\x03\x82\x02\x0f\x00\x30\x82\x02\x0a\x02\x82\x02\x01"
"\x00\xcc\xac\x49\xdd\x3b\xca\xb0\x15\x7e\x84\x6a\xb2\x0a\x69\x5f"
"\x1c\x0a\x61\x82\x3b\x4f\x2c\xa3\x95\x2c\x08\x58\x4b\xb1\x5d\x99"
"\xe0\xc3\xc1\x79\xc2\xb3\xeb\xc0\x1e\x6d\x3e\x54\x1d\xbd\xb7\x92"
"\x7b\x4d\xb5\x95\x58\xb2\x52\x2e\xc6\x24\x4b\x71\x63\x80\x32\x77"
"\xa7\x38\x5e\xdb\x72\xae\x6e\x0d\xec\xfb\xb6\x6d\x01\x7f\xe9\x55"
"\x66\xdf\xbf\x1d\x76\x78\x02\x31\xe8\xe5\x07\xf8\xb7\x82\x5c\x0d"
"\xd4\xbb\xfb\xa2\x59\x0d\x2e\x3a\x78\x95\x3a\x8b\x46\x06\x47\x44"
"\x46\xd7\xcd\x06\x6a\x41\x13\xe3\x19\xf6\xbb\x6e\x38\xf4\x83\x01"
"\xa3\xbf\x4a\x39\x4f\xd7\x0a\xe9\x38\xb3\xf5\x94\x14\x4e\xdd\xf7"
"\x43\xfd\x24\xb2\x49\x3c\xa5\xf7\x7a\x7c\xd4\x45\x3d\x97\x75\x68"
"\xf1\xed\x4c\x42\x0b\x70\xca\x85\xf3\xde\xe5\x88\x2c\xc5\xbe\xb6"
"\x97\x34\xba\x24\x02\xcd\x8b\x86\x9f\xa9\x73\xca\x73\xcf\x92\x81"
"\xee\x75\x55\xbb\x18\x67\x5c\xff\x3f\xb5\xdd\x33\x1b\x0c\xe9\x78"
"\xdb\x5c\xcf\xaa\x5c\x43\x42\xdf\x5e\xa9\x6d\xec\xd7\xd7\xff\xe6"
"\xa1\x3a\x92\x1a\xda\xae\xf6\x8c\x6f\x7b\xd5\xb4\x6e\x06\xe9\x8f"
"\xe8\xde\x09\x31\x89\xed\x0e\x11\xa1\xfa\x8a\xe9\xe9\x64\x59\x62"
"\x53\xda\xd1\x70\xbe\x11\xd4\x99\x97\x11\xcf\x99\xde\x0b\x9d\x94"
"\x7e\xaa\xb8\x52\xea\x37\xdb\x90\x7e\x35\xbd\xd9\xfe\x6d\x0a\x48"
"\x70\x28\xdd\xd5\x0d\x7f\x03\x80\x93\x14\x23\x8f\xb9\x22\xcd\x7c"
"\x29\xfe\xf1\x72\xb5\x5c\x0b\x12\xcf\x9c\x15\xf6\x11\x4c\x7a\x45"
"\x25\x8c\x45\x0a\x34\xac\x2d\x9a\x81\xca\x0b\x13\x22\xcd\xeb\x1a"
"\x38\x88\x18\x97\x96\x08\x81\xaa\xcc\x8f\x0f\x8a\x32\x7b\x76\x68"
"\x03\x68\x43\xbf\x11\xba\x55\x60\xfd\x80\x1c\x0d\x9b\x69\xb6\x09"
"\x72\xbc\x0f\x41\x2f\x07\x82\xc6\xe3\xb2\x13\x91\xc4\x6d\x14\x95"
"\x31\xbe\x19\xbd\xbc\xed\xe1\x4c\x74\xa2\xe0\x78\x0b\xbb\x94\xec"
"\x4c\x53\x3a\xa2\xb5\x84\x1d\x4b\x65\x7e\xdc\xf7\xdb\x36\x7d\xbe"
"\x9e\x3b\x36\x66\x42\x66\x76\x35\xbf\xbe\xf0\xc1\x3c\x7c\xe9\x42"
"\x5c\x24\x53\x03\x05\xa8\x67\x24\x50\x02\x75\xff\x24\x46\x3b\x35"
"\x89\x76\xe6\x70\xda\xc5\x51\x8c\x9a\xe5\x05\xb0\x0b\xd0\x2d\xd4"
"\x7d\x57\x75\x94\x6b\xf9\x0a\xad\x0e\x41\x00\x15\xd0\x4f\xc0\x7f"
"\x90\x2d\x18\x48\x8f\x28\xfe\x5d\xa7\xcd\x99\x9e\xbd\x02\x6c\x8a"
"\x31\xf3\x1c\xc7\x4b\xe6\x93\xcd\x42\xa2\xe4\x68\x10\x47\x9d\xfc"
"\x21\x02\x03\x01\x00\x01\xa3\x5d\x30\x5b\x30\x0c\x06\x03\x55\x1d"
"\x13\x01\x01\xff\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
"\x04\x03\x02\x07\x80\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14"
"\xf5\x87\x03\xbb\x33\xce\x1b\x73\xee\x02\xec\xcd\xee\x5b\x88\x17"
"\x51\x8f\xe3\xdb\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80"
"\x14\xf5\x87\x03\xbb\x33\xce\x1b\x73\xee\x02\xec\xcd\xee\x5b\x88"
"\x17\x51\x8f\xe3\xdb\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01"
"\x01\x0b\x05\x00\x03\x82\x02\x01\x00\xc0\x2e\x12\x41\x7b\x73\x85"
"\x16\xc8\xdb\x86\x79\xe8\xf5\xcd\x44\xf4\xc6\xe2\x81\x23\x5e\x47"
"\xcb\xab\x25\xf1\x1e\x58\x3e\x31\x7f\x78\xad\x85\xeb\xfe\x14\x88"
"\x60\xf7\x7f\xd2\x26\xa2\xf4\x98\x2a\xfd\xba\x05\x0c\x20\x33\x12"
"\xcc\x4d\x14\x61\x64\x81\x93\xd3\x33\xed\xc8\xff\xf1\x78\xcc\x5f"
"\x51\x9f\x09\xd7\xbe\x0d\x5c\x74\xfd\x9b\xdf\x52\x4a\xc9\xa8\x71"
"\x25\x33\x04\x10\x67\x36\xd0\xb3\x0b\xc9\xa1\x40\x72\xae\x41\x7b"
"\x68\xe6\xe4\x7b\xd0\x28\xf7\x6d\xe7\x3f\x50\xfc\x91\x7c\x91\x56"
"\xd4\xdf\xa6\xbb\xe8\x4d\x1b\x58\xaa\x28\xfa\xc1\x19\xeb\x11\x2f"
"\x24\x8b\x7c\xc5\xa9\x86\x26\xaa\x6e\xb7\x9b\xd5\xf8\x06\xfb\x02"
"\x52\x7b\x9c\x9e\xa1\xe0\x07\x8b\x5e\xe4\xb8\x55\x29\xf6\x48\x52"
"\x1c\x1b\x54\x2d\x46\xd8\xe5\x71\xb9\x60\xd1\x45\xb5\x92\x89\x8a"
"\x63\x58\x2a\xb3\xc6\xb2\x76\xe2\x3c\x82\x59\x04\xae\x5a\xc4\x99"
"\x7b\x2e\x4b\x46\x57\xb8\x29\x24\xb2\xfd\xee\x2c\x0d\xa4\x83\xfa"
"\x65\x2a\x07\x35\x8b\x97\xcf\xbd\x96\x2e\xd1\x7e\x6c\xc2\x1e\x87"
"\xb6\x6c\x76\x65\xb5\xb2\x62\xda\x8b\xe9\x73\xe3\xdb\x33\xdd\x13"
"\x3a\x17\x63\x6a\x76\xde\x8d\x8f\xe0\x47\x61\x28\x3a\x83\xff\x8f"
"\xe7\xc7\xe0\x4a\xa3\xe5\x07\xcf\xe9\x8c\x35\x35\x2e\xe7\x80\x66"
"\x31\xbf\x91\x58\x0a\xe1\x25\x3d\x38\xd3\xa4\xf0\x59\x34\x47\x07"
"\x62\x0f\xbe\x30\xdd\x81\x88\x58\xf0\x28\xb0\x96\xe5\x82\xf8\x05"
"\xb7\x13\x01\xbc\xfa\xc6\x1f\x86\x72\xcc\xf9\xee\x8e\xd9\xd6\x04"
"\x8c\x24\x6c\xbf\x0f\x5d\x37\x39\xcf\x45\xc1\x93\x3a\xd2\xed\x5c"
"\x58\x79\x74\x86\x62\x30\x7e\x8e\xbb\xdd\x7a\xa9\xed\xca\x40\xcb"
"\x62\x47\xf4\xb4\x9f\x52\x7f\x72\x63\xa8\xf0\x2b\xaf\x45\x2a\x48"
"\x19\x6d\xe3\xfb\xf9\x19\x66\x69\xc8\xcc\x62\x87\x6c\x53\x2b\x2d"
"\x6e\x90\x6c\x54\x3a\x82\x25\x41\xcb\x18\x6a\xa4\x22\xa8\xa1\xc4"
"\x47\xd7\x81\x00\x1c\x15\x51\x0f\x1a\xaf\xef\x9f\xa6\x61\x8c\xbd"
"\x6b\x8b\xed\xe6\xac\x0e\xb6\x3a\x4c\x92\xe6\x0f\x91\x0a\x0f\x71"
"\xc7\xa0\xb9\x0d\x3a\x17\x5a\x6f\x35\xc8\xe7\x50\x4f\x46\xe8\x70"
"\x60\x48\x06\x82\x8b\x66\x58\xe6\x73\x91\x9c\x12\x3d\x35\x8e\x46"
"\xad\x5a\xf5\xb3\xdb\x69\x21\x04\xfd\xd3\x1c\xdf\x94\x9d\x56\xb0"
"\x0a\xd1\x95\x76\x8d\xec\x9e\xdd\x0b\x15\x97\x64\xad\xe5\xf2\x62"
"\x02\xfc\x9e\x5f\x56\x42\x39\x05\xb3"
};
/*
* Signed data and detached signature blobs that form the verification tests.
*/
static const __initconst u8 certs_selftest_1_data[] = {
"\x54\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x74\x65\x73"
"\x74\x20\x64\x61\x74\x61\x20\x75\x73\x65\x64\x20\x66\x6f\x72\x20"
"\x73\x65\x6c\x66\x2d\x74\x65\x73\x74\x69\x6e\x67\x20\x63\x65\x72"
"\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69\x66\x69\x63"
"\x61\x74\x69\x6f\x6e\x2e\x0a"
};
static const __initconst u8 certs_selftest_1_pkcs7[] = {
"\x30\x82\x02\xab\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02\xa0"
"\x82\x02\x9c\x30\x82\x02\x98\x02\x01\x01\x31\x0d\x30\x0b\x06\x09"
"\x60\x86\x48\x01\x65\x03\x04\x02\x01\x30\x0b\x06\x09\x2a\x86\x48"
"\x86\xf7\x0d\x01\x07\x01\x31\x82\x02\x75\x30\x82\x02\x71\x02\x01"
"\x01\x30\x4c\x30\x34\x31\x32\x30\x30\x06\x03\x55\x04\x03\x0c\x29"
"\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69"
"\x66\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x6c\x66\x2d\x74\x65"
"\x73\x74\x69\x6e\x67\x20\x6b\x65\x79\x02\x14\x73\x98\xea\x98\x2d"
"\xd0\x2e\xa8\xb1\xcf\x57\xc7\xf2\x97\xb3\xe6\x1a\xfc\x8c\x0a\x30"
"\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x30\x0d\x06\x09"
"\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x04\x82\x02\x00\xac"
"\xb0\xf2\x07\xd6\x99\x6d\xc0\xc0\xd9\x8d\x31\x0d\x7e\x04\xeb\xc3"
"\x88\x90\xc4\x58\x46\xd4\xe2\xa0\xa3\x25\xe3\x04\x50\x37\x85\x8c"
"\x91\xc6\xfc\xc5\xd4\x92\xfd\x05\xd8\xb8\xa3\xb8\xba\x89\x13\x00"
"\x88\x79\x99\x51\x6b\x5b\x28\x31\xc0\xb3\x1b\x7a\x68\x2c\x00\xdb"
"\x4b\x46\x11\xf3\xfa\x50\x8e\x19\x89\xa2\x4c\xda\x4c\x89\x01\x11"
"\x89\xee\xd3\xc8\xc1\xe7\xa7\xf6\xb2\xa2\xf8\x65\xb8\x35\x20\x33"
"\xba\x12\x62\xd5\xbd\xaa\x71\xe5\x5b\xc0\x6a\x32\xff\x6a\x2e\x23"
"\xef\x2b\xb6\x58\xb1\xfb\x5f\x82\x34\x40\x6d\x9f\xbc\x27\xac\x37"
"\x23\x99\xcf\x7d\x20\xb2\x39\x01\xc0\x12\xce\xd7\x5d\x2f\xb6\xab"
"\xb5\x56\x4f\xef\xf4\x72\x07\x58\x65\xa9\xeb\x1f\x75\x1c\x5f\x0c"
"\x88\xe0\xa4\xe2\xcd\x73\x2b\x9e\xb2\x05\x7e\x12\xf8\xd0\x66\x41"
"\xcc\x12\x63\xd4\xd6\xac\x9b\x1d\x14\x77\x8d\x1c\x57\xd5\x27\xc6"
"\x49\xa2\x41\x43\xf3\x59\x29\xe5\xcb\xd1\x75\xbc\x3a\x97\x2a\x72"
"\x22\x66\xc5\x3b\xc1\xba\xfc\x53\x18\x98\xe2\x21\x64\xc6\x52\x87"
"\x13\xd5\x7c\x42\xe8\xfb\x9c\x9a\x45\x32\xd5\xa5\x22\x62\x9d\xd4"
"\xcb\xa4\xfa\x77\xbb\x50\x24\x0b\x8b\x88\x99\x15\x56\xa9\x1e\x92"
"\xbf\x5d\x94\x77\xb6\xf1\x67\x01\x60\x06\x58\x5c\xdf\x18\x52\x79"
"\x37\x30\x93\x7d\x87\x04\xf1\xe0\x55\x59\x52\xf3\xc2\xb1\x1c\x5b"
"\x12\x7c\x49\x87\xfb\xf7\xed\xdd\x95\x71\xec\x4b\x1a\x85\x08\xb0"
"\xa0\x36\xc4\x7b\xab\x40\xe0\xf1\x98\xcc\xaf\x19\x40\x8f\x47\x6f"
"\xf0\x6c\x84\x29\x7f\x7f\x04\x46\xcb\x08\x0f\xe0\xc1\xc9\x70\x6e"
"\x95\x3b\xa4\xbc\x29\x2b\x53\x67\x45\x1b\x0d\xbc\x13\xa5\x76\x31"
"\xaf\xb9\xd0\xe0\x60\x12\xd2\xf4\xb7\x7c\x58\x7e\xf6\x2d\xbb\x24"
"\x14\x5a\x20\x24\xa8\x12\xdf\x25\xbd\x42\xce\x96\x7c\x2e\xba\x14"
"\x1b\x81\x9f\x18\x45\xa4\xc6\x70\x3e\x0e\xf0\xd3\x7b\x9c\x10\xbe"
"\xb8\x7a\x89\xc5\x9e\xd9\x97\xdf\xd7\xe7\xc6\x1d\xc0\x20\x6c\xb8"
"\x1e\x3a\x63\xb8\x39\x8e\x8e\x62\xd5\xd2\xb4\xcd\xff\x46\xfc\x8e"
"\xec\x07\x35\x0c\xff\xb0\x05\xe6\xf4\xe5\xfe\xa2\xe3\x0a\xe6\x36"
"\xa7\x4a\x7e\x62\x1d\xc4\x50\x39\x35\x4e\x28\xcb\x4a\xfb\x9d\xdb"
"\xdd\x23\xd6\x53\xb1\x74\x77\x12\xf7\x9c\xf0\x9a\x6b\xf7\xa9\x64"
"\x2d\x86\x21\x2a\xcf\xc6\x54\xf5\xc9\xad\xfa\xb5\x12\xb4\xf3\x51"
"\x77\x55\x3c\x6f\x0c\x32\xd3\x8c\x44\x39\x71\x25\xfe\x96\xd2"
};
/*
* List of tests to be run.
*/
#define TEST(data, pkcs7) { data, sizeof(data) - 1, pkcs7, sizeof(pkcs7) - 1 }
static const struct certs_test certs_tests[] __initconst = {
TEST(certs_selftest_1_data, certs_selftest_1_pkcs7),
};
int __init fips_signature_selftest(void)
{
struct key *keyring;
int ret, i;
pr_notice("Running certificate verification selftests\n");
keyring = keyring_alloc(".certs_selftest",
GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
(KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ |
KEY_USR_SEARCH,
KEY_ALLOC_NOT_IN_QUOTA,
NULL, NULL);
if (IS_ERR(keyring))
panic("Can't allocate certs selftest keyring: %ld\n",
PTR_ERR(keyring));
ret = x509_load_certificate_list(certs_selftest_keys,
sizeof(certs_selftest_keys) - 1, keyring);
if (ret < 0)
panic("Can't allocate certs selftest keyring: %d\n", ret);
for (i = 0; i < ARRAY_SIZE(certs_tests); i++) {
const struct certs_test *test = &certs_tests[i];
struct pkcs7_message *pkcs7;
pkcs7 = pkcs7_parse_message(test->pkcs7, test->pkcs7_len);
if (IS_ERR(pkcs7))
panic("Certs selftest %d: pkcs7_parse_message() = %d\n", i, ret);
pkcs7_supply_detached_data(pkcs7, test->data, test->data_len);
ret = pkcs7_verify(pkcs7, VERIFYING_MODULE_SIGNATURE);
if (ret < 0)
panic("Certs selftest %d: pkcs7_verify() = %d\n", i, ret);
ret = pkcs7_validate_trust(pkcs7, keyring);
if (ret < 0)
panic("Certs selftest %d: pkcs7_validate_trust() = %d\n", i, ret);
pkcs7_free_message(pkcs7);
}
key_put(keyring);
return 0;
}

View File

@ -2,9 +2,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/key.h> #include <linux/key.h>
#include "common.h" #include <keys/asymmetric-type.h>
int load_certificate_list(const u8 cert_list[], int x509_load_certificate_list(const u8 cert_list[],
const unsigned long list_size, const unsigned long list_size,
const struct key *keyring) const struct key *keyring)
{ {

View File

@ -40,6 +40,15 @@ struct x509_certificate {
bool blacklisted; bool blacklisted;
}; };
/*
* selftest.c
*/
#ifdef CONFIG_FIPS_SIGNATURE_SELFTEST
extern int __init fips_signature_selftest(void);
#else
static inline int fips_signature_selftest(void) { return 0; }
#endif
/* /*
* x509_cert_parser.c * x509_cert_parser.c
*/ */

View File

@ -244,9 +244,15 @@ static struct asymmetric_key_parser x509_key_parser = {
/* /*
* Module stuff * Module stuff
*/ */
extern int __init certs_selftest(void);
static int __init x509_key_init(void) static int __init x509_key_init(void)
{ {
return register_asymmetric_key_parser(&x509_key_parser); int ret;
ret = register_asymmetric_key_parser(&x509_key_parser);
if (ret < 0)
return ret;
return fips_signature_selftest();
} }
static void __exit x509_key_exit(void) static void __exit x509_key_exit(void)

View File

@ -8,6 +8,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/memory.h> #include <linux/memory.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/backing-dev.h>
#include "base.h" #include "base.h"
@ -20,6 +21,7 @@
void __init driver_init(void) void __init driver_init(void)
{ {
/* These are the core pieces */ /* These are the core pieces */
bdi_init(&noop_backing_dev_info);
devtmpfs_init(); devtmpfs_init();
devices_init(); devices_init();
buses_init(); buses_init();

View File

@ -1239,14 +1239,14 @@ error_cleanup_mc_io:
static int fsl_mc_bus_remove(struct platform_device *pdev) static int fsl_mc_bus_remove(struct platform_device *pdev)
{ {
struct fsl_mc *mc = platform_get_drvdata(pdev); struct fsl_mc *mc = platform_get_drvdata(pdev);
struct fsl_mc_io *mc_io;
if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev)) if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev))
return -EINVAL; return -EINVAL;
mc_io = mc->root_mc_bus_dev->mc_io;
fsl_mc_device_remove(mc->root_mc_bus_dev); fsl_mc_device_remove(mc->root_mc_bus_dev);
fsl_destroy_mc_io(mc_io);
fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
mc->root_mc_bus_dev->mc_io = NULL;
bus_unregister_notifier(&fsl_mc_bus_type, &fsl_mc_nb); bus_unregister_notifier(&fsl_mc_bus_type, &fsl_mc_nb);

View File

@ -1019,7 +1019,7 @@ static struct parport_driver lp_driver = {
static int __init lp_init(void) static int __init lp_init(void)
{ {
int i, err = 0; int i, err;
if (parport_nr[0] == LP_PARPORT_OFF) if (parport_nr[0] == LP_PARPORT_OFF)
return 0; return 0;

View File

@ -565,4 +565,3 @@ void __init hv_init_clocksource(void)
hv_sched_clock_offset = hv_read_reference_counter(); hv_sched_clock_offset = hv_read_reference_counter();
hv_setup_sched_clock(read_hv_sched_clock_msr); hv_setup_sched_clock(read_hv_sched_clock_msr);
} }
EXPORT_SYMBOL_GPL(hv_init_clocksource);

View File

@ -684,7 +684,7 @@ static int vmk80xx_alloc_usb_buffers(struct comedi_device *dev)
if (!devpriv->usb_rx_buf) if (!devpriv->usb_rx_buf)
return -ENOMEM; return -ENOMEM;
size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE); size = max(usb_endpoint_maxp(devpriv->ep_tx), MIN_BUF_SIZE);
devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
if (!devpriv->usb_tx_buf) if (!devpriv->usb_tx_buf)
return -ENOMEM; return -ENOMEM;

View File

@ -32,8 +32,11 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
{ {
struct vm_area_struct *vma = vmf->vma; struct vm_area_struct *vma = vmf->vma;
struct udmabuf *ubuf = vma->vm_private_data; struct udmabuf *ubuf = vma->vm_private_data;
pgoff_t pgoff = vmf->pgoff;
vmf->page = ubuf->pages[vmf->pgoff]; if (pgoff >= ubuf->pagecount)
return VM_FAULT_SIGBUS;
vmf->page = ubuf->pages[pgoff];
get_page(vmf->page); get_page(vmf->page);
return 0; return 0;
} }

View File

@ -1211,7 +1211,7 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2; struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2;
struct fw_card *card = client->device->card; struct fw_card *card = client->device->card;
struct timespec64 ts = {0, 0}; struct timespec64 ts = {0, 0};
u32 cycle_time; u32 cycle_time = 0;
int ret = 0; int ret = 0;
local_irq_disable(); local_irq_disable();

View File

@ -372,8 +372,7 @@ static ssize_t rom_index_show(struct device *dev,
struct fw_device *device = fw_device(dev->parent); struct fw_device *device = fw_device(dev->parent);
struct fw_unit *unit = fw_unit(dev); struct fw_unit *unit = fw_unit(dev);
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%td\n", unit->directory - device->config_rom);
(int)(unit->directory - device->config_rom));
} }
static struct device_attribute fw_unit_attributes[] = { static struct device_attribute fw_unit_attributes[] = {
@ -403,8 +402,7 @@ static ssize_t guid_show(struct device *dev,
int ret; int ret;
down_read(&fw_device_rwsem); down_read(&fw_device_rwsem);
ret = snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", ret = sysfs_emit(buf, "0x%08x%08x\n", device->config_rom[3], device->config_rom[4]);
device->config_rom[3], device->config_rom[4]);
up_read(&fw_device_rwsem); up_read(&fw_device_rwsem);
return ret; return ret;

View File

@ -26,8 +26,6 @@
#include <linux/sysfb.h> #include <linux/sysfb.h>
#include <video/vga.h> #include <video/vga.h>
#include <asm/efi.h>
enum { enum {
OVERRIDE_NONE = 0x0, OVERRIDE_NONE = 0x0,
OVERRIDE_BASE = 0x1, OVERRIDE_BASE = 0x1,

View File

@ -642,7 +642,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
atomic64_read(&adev->visible_pin_size), atomic64_read(&adev->visible_pin_size),
vram_gtt.vram_size); vram_gtt.vram_size);
vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size; vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size;
vram_gtt.gtt_size *= PAGE_SIZE;
vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size);
return copy_to_user(out, &vram_gtt, return copy_to_user(out, &vram_gtt,
min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0; min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0;
@ -675,7 +674,6 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
mem.cpu_accessible_vram.usable_heap_size * 3 / 4; mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
mem.gtt.total_heap_size = gtt_man->size; mem.gtt.total_heap_size = gtt_man->size;
mem.gtt.total_heap_size *= PAGE_SIZE;
mem.gtt.usable_heap_size = mem.gtt.total_heap_size - mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
atomic64_read(&adev->gart_pin_size); atomic64_read(&adev->gart_pin_size);
mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man); mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man);

View File

@ -2812,7 +2812,7 @@ static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = {
static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
{ {
u32 max_cll, min_cll, max, min, q, r; u32 max_avg, min_cll, max, min, q, r;
struct amdgpu_dm_backlight_caps *caps; struct amdgpu_dm_backlight_caps *caps;
struct amdgpu_display_manager *dm; struct amdgpu_display_manager *dm;
struct drm_connector *conn_base; struct drm_connector *conn_base;
@ -2842,7 +2842,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
caps = &dm->backlight_caps[i]; caps = &dm->backlight_caps[i];
caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps; caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps;
caps->aux_support = false; caps->aux_support = false;
max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll; max_avg = conn_base->hdr_sink_metadata.hdmi_type1.max_fall;
min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll;
if (caps->ext_caps->bits.oled == 1 /*|| if (caps->ext_caps->bits.oled == 1 /*||
@ -2870,8 +2870,8 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
* The results of the above expressions can be verified at * The results of the above expressions can be verified at
* pre_computed_values. * pre_computed_values.
*/ */
q = max_cll >> 5; q = max_avg >> 5;
r = max_cll % 32; r = max_avg % 32;
max = (1 << q) * pre_computed_values[r]; max = (1 << q) * pre_computed_values[r];
// min luminance: maxLum * (CV/255)^2 / 100 // min luminance: maxLum * (CV/255)^2 / 100

View File

@ -176,15 +176,15 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
}, { }, {
DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
DRM_COMPONENT_DRIVER DRM_COMPONENT_DRIVER
}, {
DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
DRM_COMPONENT_DRIVER
}, { }, {
DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP), DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP),
DRM_COMPONENT_DRIVER DRM_COMPONENT_DRIVER
}, { }, {
DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI), DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI),
DRM_COMPONENT_DRIVER DRM_COMPONENT_DRIVER
}, {
DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
DRM_COMPONENT_DRIVER
}, { }, {
DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI), DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
DRM_COMPONENT_DRIVER DRM_COMPONENT_DRIVER

View File

@ -26,6 +26,7 @@
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
/* Sysreg registers for MIC */ /* Sysreg registers for MIC */
#define DSD_CFG_MUX 0x1004 #define DSD_CFG_MUX 0x1004
@ -100,9 +101,7 @@ struct exynos_mic {
bool i80_mode; bool i80_mode;
struct videomode vm; struct videomode vm;
struct drm_encoder *encoder;
struct drm_bridge bridge; struct drm_bridge bridge;
struct drm_bridge *next_bridge;
bool enabled; bool enabled;
}; };
@ -229,8 +228,6 @@ static void mic_set_reg_on(struct exynos_mic *mic, bool enable)
writel(reg, mic->reg + MIC_OP); writel(reg, mic->reg + MIC_OP);
} }
static void mic_disable(struct drm_bridge *bridge) { }
static void mic_post_disable(struct drm_bridge *bridge) static void mic_post_disable(struct drm_bridge *bridge)
{ {
struct exynos_mic *mic = bridge->driver_private; struct exynos_mic *mic = bridge->driver_private;
@ -297,34 +294,30 @@ unlock:
mutex_unlock(&mic_mutex); mutex_unlock(&mic_mutex);
} }
static void mic_enable(struct drm_bridge *bridge) { }
static int mic_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct exynos_mic *mic = bridge->driver_private;
return drm_bridge_attach(bridge->encoder, mic->next_bridge,
&mic->bridge, flags);
}
static const struct drm_bridge_funcs mic_bridge_funcs = { static const struct drm_bridge_funcs mic_bridge_funcs = {
.disable = mic_disable,
.post_disable = mic_post_disable, .post_disable = mic_post_disable,
.mode_set = mic_mode_set, .mode_set = mic_mode_set,
.pre_enable = mic_pre_enable, .pre_enable = mic_pre_enable,
.enable = mic_enable,
.attach = mic_attach,
}; };
static int exynos_mic_bind(struct device *dev, struct device *master, static int exynos_mic_bind(struct device *dev, struct device *master,
void *data) void *data)
{ {
struct exynos_mic *mic = dev_get_drvdata(dev); struct exynos_mic *mic = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev,
EXYNOS_DISPLAY_TYPE_LCD);
struct drm_encoder *e, *encoder = NULL;
drm_for_each_encoder(e, drm_dev)
if (e->possible_crtcs == drm_crtc_mask(&crtc->base))
encoder = e;
if (!encoder)
return -ENODEV;
mic->bridge.driver_private = mic; mic->bridge.driver_private = mic;
return 0; return drm_bridge_attach(encoder, &mic->bridge, NULL, 0);
} }
static void exynos_mic_unbind(struct device *dev, struct device *master, static void exynos_mic_unbind(struct device *dev, struct device *master,
@ -388,7 +381,6 @@ static int exynos_mic_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct exynos_mic *mic; struct exynos_mic *mic;
struct device_node *remote;
struct resource res; struct resource res;
int ret, i; int ret, i;
@ -432,16 +424,6 @@ static int exynos_mic_probe(struct platform_device *pdev)
} }
} }
remote = of_graph_get_remote_node(dev->of_node, 1, 0);
mic->next_bridge = of_drm_find_bridge(remote);
if (IS_ERR(mic->next_bridge)) {
DRM_DEV_ERROR(dev, "mic: Failed to find next bridge\n");
ret = PTR_ERR(mic->next_bridge);
goto err;
}
of_node_put(remote);
platform_set_drvdata(pdev, mic); platform_set_drvdata(pdev, mic);
mic->bridge.funcs = &mic_bridge_funcs; mic->bridge.funcs = &mic_bridge_funcs;

View File

@ -999,7 +999,8 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
} }
} }
err = dma_resv_reserve_fences(vma->obj->base.resv, 1); /* Reserve enough slots to accommodate composite fences */
err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
if (err) if (err)
return err; return err;

View File

@ -785,6 +785,7 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
{ {
intel_wakeref_t wakeref; intel_wakeref_t wakeref;
intel_gt_sysfs_unregister(gt);
intel_rps_driver_unregister(&gt->rps); intel_rps_driver_unregister(&gt->rps);
intel_gsc_fini(&gt->gsc); intel_gsc_fini(&gt->gsc);

View File

@ -24,7 +24,7 @@ bool is_object_gt(struct kobject *kobj)
static struct intel_gt *kobj_to_gt(struct kobject *kobj) static struct intel_gt *kobj_to_gt(struct kobject *kobj)
{ {
return container_of(kobj, struct kobj_gt, base)->gt; return container_of(kobj, struct intel_gt, sysfs_gt);
} }
struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
@ -72,9 +72,9 @@ static struct attribute *id_attrs[] = {
}; };
ATTRIBUTE_GROUPS(id); ATTRIBUTE_GROUPS(id);
/* A kobject needs a release() method even if it does nothing */
static void kobj_gt_release(struct kobject *kobj) static void kobj_gt_release(struct kobject *kobj)
{ {
kfree(kobj);
} }
static struct kobj_type kobj_gt_type = { static struct kobj_type kobj_gt_type = {
@ -85,8 +85,6 @@ static struct kobj_type kobj_gt_type = {
void intel_gt_sysfs_register(struct intel_gt *gt) void intel_gt_sysfs_register(struct intel_gt *gt)
{ {
struct kobj_gt *kg;
/* /*
* We need to make things right with the * We need to make things right with the
* ABI compatibility. The files were originally * ABI compatibility. The files were originally
@ -98,25 +96,22 @@ void intel_gt_sysfs_register(struct intel_gt *gt)
if (gt_is_root(gt)) if (gt_is_root(gt))
intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt)); intel_gt_sysfs_pm_init(gt, gt_get_parent_obj(gt));
kg = kzalloc(sizeof(*kg), GFP_KERNEL); /* init and xfer ownership to sysfs tree */
if (!kg) if (kobject_init_and_add(&gt->sysfs_gt, &kobj_gt_type,
gt->i915->sysfs_gt, "gt%d", gt->info.id))
goto exit_fail; goto exit_fail;
kobject_init(&kg->base, &kobj_gt_type); intel_gt_sysfs_pm_init(gt, &gt->sysfs_gt);
kg->gt = gt;
/* xfer ownership to sysfs tree */
if (kobject_add(&kg->base, gt->i915->sysfs_gt, "gt%d", gt->info.id))
goto exit_kobj_put;
intel_gt_sysfs_pm_init(gt, &kg->base);
return; return;
exit_kobj_put:
kobject_put(&kg->base);
exit_fail: exit_fail:
kobject_put(&gt->sysfs_gt);
drm_warn(&gt->i915->drm, drm_warn(&gt->i915->drm,
"failed to initialize gt%d sysfs root\n", gt->info.id); "failed to initialize gt%d sysfs root\n", gt->info.id);
} }
void intel_gt_sysfs_unregister(struct intel_gt *gt)
{
kobject_put(&gt->sysfs_gt);
}

View File

@ -13,11 +13,6 @@
struct intel_gt; struct intel_gt;
struct kobj_gt {
struct kobject base;
struct intel_gt *gt;
};
bool is_object_gt(struct kobject *kobj); bool is_object_gt(struct kobject *kobj);
struct drm_i915_private *kobj_to_i915(struct kobject *kobj); struct drm_i915_private *kobj_to_i915(struct kobject *kobj);
@ -28,6 +23,7 @@ intel_gt_create_kobj(struct intel_gt *gt,
const char *name); const char *name);
void intel_gt_sysfs_register(struct intel_gt *gt); void intel_gt_sysfs_register(struct intel_gt *gt);
void intel_gt_sysfs_unregister(struct intel_gt *gt);
struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev, struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
const char *name); const char *name);

View File

@ -224,6 +224,9 @@ struct intel_gt {
} mocs; } mocs;
struct intel_pxp pxp; struct intel_pxp pxp;
/* gt/gtN sysfs */
struct kobject sysfs_gt;
}; };
enum intel_gt_scratch_field { enum intel_gt_scratch_field {

View File

@ -156,7 +156,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) }, [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) }, [INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
}; };
static const struct uc_fw_platform_requirement *fw_blobs; const struct uc_fw_platform_requirement *fw_blobs;
enum intel_platform p = INTEL_INFO(i915)->platform; enum intel_platform p = INTEL_INFO(i915)->platform;
u32 fw_count; u32 fw_count;
u8 rev = INTEL_REVID(i915); u8 rev = INTEL_REVID(i915);

View File

@ -166,7 +166,14 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
struct device *kdev = kobj_to_dev(kobj); struct device *kdev = kobj_to_dev(kobj);
struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
struct i915_gpu_coredump *gpu; struct i915_gpu_coredump *gpu;
ssize_t ret; ssize_t ret = 0;
/*
* FIXME: Concurrent clients triggering resets and reading + clearing
* dumps can cause inconsistent sysfs reads when a user calls in with a
* non-zero offset to complete a prior partial read but the
* gpu_coredump has been cleared or replaced.
*/
gpu = i915_first_error_state(i915); gpu = i915_first_error_state(i915);
if (IS_ERR(gpu)) { if (IS_ERR(gpu)) {
@ -178,9 +185,11 @@ static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
const char *str = "No error state collected\n"; const char *str = "No error state collected\n";
size_t len = strlen(str); size_t len = strlen(str);
if (off < len) {
ret = min_t(size_t, count, len - off); ret = min_t(size_t, count, len - off);
memcpy(buf, str + off, ret); memcpy(buf, str + off, ret);
} }
}
return ret; return ret;
} }
@ -259,4 +268,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
device_remove_bin_file(kdev, &dpf_attrs_1); device_remove_bin_file(kdev, &dpf_attrs_1);
device_remove_bin_file(kdev, &dpf_attrs); device_remove_bin_file(kdev, &dpf_attrs);
kobject_put(dev_priv->sysfs_gt);
} }

View File

@ -23,6 +23,7 @@
*/ */
#include <linux/sched/mm.h> #include <linux/sched/mm.h>
#include <linux/dma-fence-array.h>
#include <drm/drm_gem.h> #include <drm/drm_gem.h>
#include "display/intel_frontbuffer.h" #include "display/intel_frontbuffer.h"
@ -1823,6 +1824,21 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
if (unlikely(err)) if (unlikely(err))
return err; return err;
/*
* Reserve fences slot early to prevent an allocation after preparing
* the workload and associating fences with dma_resv.
*/
if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
struct dma_fence *curr;
int idx;
dma_fence_array_for_each(curr, idx, fence)
;
err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
if (unlikely(err))
return err;
}
if (flags & EXEC_OBJECT_WRITE) { if (flags & EXEC_OBJECT_WRITE) {
struct intel_frontbuffer *front; struct intel_frontbuffer *front;
@ -1832,31 +1848,23 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
i915_active_add_request(&front->write, rq); i915_active_add_request(&front->write, rq);
intel_frontbuffer_put(front); intel_frontbuffer_put(front);
} }
if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
if (unlikely(err))
return err;
} }
if (fence) { if (fence) {
dma_resv_add_fence(vma->obj->base.resv, fence, struct dma_fence *curr;
DMA_RESV_USAGE_WRITE); enum dma_resv_usage usage;
obj->write_domain = I915_GEM_DOMAIN_RENDER; int idx;
obj->read_domains = 0; obj->read_domains = 0;
} if (flags & EXEC_OBJECT_WRITE) {
usage = DMA_RESV_USAGE_WRITE;
obj->write_domain = I915_GEM_DOMAIN_RENDER;
} else { } else {
if (!(flags & __EXEC_OBJECT_NO_RESERVE)) { usage = DMA_RESV_USAGE_READ;
err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
if (unlikely(err))
return err;
} }
if (fence) { dma_fence_array_for_each(curr, idx, fence)
dma_resv_add_fence(vma->obj->base.resv, fence, dma_resv_add_fence(vma->obj->base.resv, curr, usage);
DMA_RESV_USAGE_READ);
obj->write_domain = 0;
}
} }
if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence) if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)

View File

@ -109,11 +109,11 @@ void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo,
return; return;
spin_lock(&bo->bdev->lru_lock); spin_lock(&bo->bdev->lru_lock);
if (bo->bulk_move && bo->resource) if (bo->resource)
ttm_lru_bulk_move_del(bo->bulk_move, bo->resource); ttm_resource_del_bulk_move(bo->resource, bo);
bo->bulk_move = bulk; bo->bulk_move = bulk;
if (bo->bulk_move && bo->resource) if (bo->resource)
ttm_lru_bulk_move_add(bo->bulk_move, bo->resource); ttm_resource_add_bulk_move(bo->resource, bo);
spin_unlock(&bo->bdev->lru_lock); spin_unlock(&bo->bdev->lru_lock);
} }
EXPORT_SYMBOL(ttm_bo_set_bulk_move); EXPORT_SYMBOL(ttm_bo_set_bulk_move);
@ -689,8 +689,11 @@ void ttm_bo_pin(struct ttm_buffer_object *bo)
{ {
dma_resv_assert_held(bo->base.resv); dma_resv_assert_held(bo->base.resv);
WARN_ON_ONCE(!kref_read(&bo->kref)); WARN_ON_ONCE(!kref_read(&bo->kref));
if (!(bo->pin_count++) && bo->bulk_move && bo->resource) spin_lock(&bo->bdev->lru_lock);
ttm_lru_bulk_move_del(bo->bulk_move, bo->resource); if (bo->resource)
ttm_resource_del_bulk_move(bo->resource, bo);
++bo->pin_count;
spin_unlock(&bo->bdev->lru_lock);
} }
EXPORT_SYMBOL(ttm_bo_pin); EXPORT_SYMBOL(ttm_bo_pin);
@ -707,8 +710,11 @@ void ttm_bo_unpin(struct ttm_buffer_object *bo)
if (WARN_ON_ONCE(!bo->pin_count)) if (WARN_ON_ONCE(!bo->pin_count))
return; return;
if (!(--bo->pin_count) && bo->bulk_move && bo->resource) spin_lock(&bo->bdev->lru_lock);
ttm_lru_bulk_move_add(bo->bulk_move, bo->resource); --bo->pin_count;
if (bo->resource)
ttm_resource_add_bulk_move(bo->resource, bo);
spin_unlock(&bo->bdev->lru_lock);
} }
EXPORT_SYMBOL(ttm_bo_unpin); EXPORT_SYMBOL(ttm_bo_unpin);

View File

@ -156,8 +156,12 @@ int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
ttm_resource_manager_for_each_res(man, &cursor, res) { ttm_resource_manager_for_each_res(man, &cursor, res) {
struct ttm_buffer_object *bo = res->bo; struct ttm_buffer_object *bo = res->bo;
uint32_t num_pages = PFN_UP(bo->base.size); uint32_t num_pages;
if (!bo)
continue;
num_pages = PFN_UP(bo->base.size);
ret = ttm_bo_swapout(bo, ctx, gfp_flags); ret = ttm_bo_swapout(bo, ctx, gfp_flags);
/* ttm_bo_swapout has dropped the lru_lock */ /* ttm_bo_swapout has dropped the lru_lock */
if (!ret) if (!ret)

View File

@ -91,7 +91,7 @@ static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos,
} }
/* Add the resource to a bulk_move cursor */ /* Add the resource to a bulk_move cursor */
void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk, static void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
struct ttm_resource *res) struct ttm_resource *res)
{ {
struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res);
@ -105,7 +105,7 @@ void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
} }
/* Remove the resource from a bulk_move range */ /* Remove the resource from a bulk_move range */
void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk, static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
struct ttm_resource *res) struct ttm_resource *res)
{ {
struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res);
@ -122,6 +122,22 @@ void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
} }
} }
/* Add the resource to a bulk move if the BO is configured for it */
void ttm_resource_add_bulk_move(struct ttm_resource *res,
struct ttm_buffer_object *bo)
{
if (bo->bulk_move && !bo->pin_count)
ttm_lru_bulk_move_add(bo->bulk_move, res);
}
/* Remove the resource from a bulk move if the BO is configured for it */
void ttm_resource_del_bulk_move(struct ttm_resource *res,
struct ttm_buffer_object *bo)
{
if (bo->bulk_move && !bo->pin_count)
ttm_lru_bulk_move_del(bo->bulk_move, res);
}
/* Move a resource to the LRU or bulk tail */ /* Move a resource to the LRU or bulk tail */
void ttm_resource_move_to_lru_tail(struct ttm_resource *res) void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
{ {
@ -169,15 +185,14 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
res->bus.is_iomem = false; res->bus.is_iomem = false;
res->bus.caching = ttm_cached; res->bus.caching = ttm_cached;
res->bo = bo; res->bo = bo;
INIT_LIST_HEAD(&res->lru);
man = ttm_manager_type(bo->bdev, place->mem_type); man = ttm_manager_type(bo->bdev, place->mem_type);
spin_lock(&bo->bdev->lru_lock); spin_lock(&bo->bdev->lru_lock);
man->usage += res->num_pages << PAGE_SHIFT; if (bo->pin_count)
if (bo->bulk_move) list_add_tail(&res->lru, &bo->bdev->pinned);
ttm_lru_bulk_move_add(bo->bulk_move, res);
else else
ttm_resource_move_to_lru_tail(res); list_add_tail(&res->lru, &man->lru[bo->priority]);
man->usage += res->num_pages << PAGE_SHIFT;
spin_unlock(&bo->bdev->lru_lock); spin_unlock(&bo->bdev->lru_lock);
} }
EXPORT_SYMBOL(ttm_resource_init); EXPORT_SYMBOL(ttm_resource_init);
@ -210,8 +225,16 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
{ {
struct ttm_resource_manager *man = struct ttm_resource_manager *man =
ttm_manager_type(bo->bdev, place->mem_type); ttm_manager_type(bo->bdev, place->mem_type);
int ret;
return man->func->alloc(man, bo, place, res_ptr); ret = man->func->alloc(man, bo, place, res_ptr);
if (ret)
return ret;
spin_lock(&bo->bdev->lru_lock);
ttm_resource_add_bulk_move(*res_ptr, bo);
spin_unlock(&bo->bdev->lru_lock);
return 0;
} }
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res) void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
@ -221,12 +244,9 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
if (!*res) if (!*res)
return; return;
if (bo->bulk_move) {
spin_lock(&bo->bdev->lru_lock); spin_lock(&bo->bdev->lru_lock);
ttm_lru_bulk_move_del(bo->bulk_move, *res); ttm_resource_del_bulk_move(*res, bo);
spin_unlock(&bo->bdev->lru_lock); spin_unlock(&bo->bdev->lru_lock);
}
man = ttm_manager_type(bo->bdev, (*res)->mem_type); man = ttm_manager_type(bo->bdev, (*res)->mem_type);
man->func->free(man, *res); man->func->free(man, *res);
*res = NULL; *res = NULL;

View File

@ -199,7 +199,8 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
if (!input_device->hid_desc) if (!input_device->hid_desc)
goto cleanup; goto cleanup;
input_device->report_desc_size = desc->desc[0].wDescriptorLength; input_device->report_desc_size = le16_to_cpu(
desc->desc[0].wDescriptorLength);
if (input_device->report_desc_size == 0) { if (input_device->report_desc_size == 0) {
input_device->dev_info_status = -EINVAL; input_device->dev_info_status = -EINVAL;
goto cleanup; goto cleanup;
@ -217,7 +218,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
memcpy(input_device->report_desc, memcpy(input_device->report_desc,
((unsigned char *)desc) + desc->bLength, ((unsigned char *)desc) + desc->bLength,
desc->desc[0].wDescriptorLength); le16_to_cpu(desc->desc[0].wDescriptorLength));
/* Send the ack */ /* Send the ack */
memset(&ack, 0, sizeof(struct mousevsc_prt_msg)); memset(&ack, 0, sizeof(struct mousevsc_prt_msg));

View File

@ -21,6 +21,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/hyperv.h> #include <linux/hyperv.h>
#include <asm/mshyperv.h> #include <asm/mshyperv.h>
#include <linux/sched/isolation.h>
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
@ -638,6 +639,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
*/ */
if (newchannel->offermsg.offer.sub_channel_index == 0) { if (newchannel->offermsg.offer.sub_channel_index == 0) {
mutex_unlock(&vmbus_connection.channel_mutex); mutex_unlock(&vmbus_connection.channel_mutex);
cpus_read_unlock();
/* /*
* Don't call free_channel(), because newchannel->kobj * Don't call free_channel(), because newchannel->kobj
* is not initialized yet. * is not initialized yet.
@ -728,16 +730,20 @@ static void init_vp_index(struct vmbus_channel *channel)
u32 i, ncpu = num_online_cpus(); u32 i, ncpu = num_online_cpus();
cpumask_var_t available_mask; cpumask_var_t available_mask;
struct cpumask *allocated_mask; struct cpumask *allocated_mask;
const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
u32 target_cpu; u32 target_cpu;
int numa_node; int numa_node;
if (!perf_chn || if (!perf_chn ||
!alloc_cpumask_var(&available_mask, GFP_KERNEL)) { !alloc_cpumask_var(&available_mask, GFP_KERNEL) ||
cpumask_empty(hk_mask)) {
/* /*
* If the channel is not a performance critical * If the channel is not a performance critical
* channel, bind it to VMBUS_CONNECT_CPU. * channel, bind it to VMBUS_CONNECT_CPU.
* In case alloc_cpumask_var() fails, bind it to * In case alloc_cpumask_var() fails, bind it to
* VMBUS_CONNECT_CPU. * VMBUS_CONNECT_CPU.
* If all the cpus are isolated, bind it to
* VMBUS_CONNECT_CPU.
*/ */
channel->target_cpu = VMBUS_CONNECT_CPU; channel->target_cpu = VMBUS_CONNECT_CPU;
if (perf_chn) if (perf_chn)
@ -758,17 +764,19 @@ static void init_vp_index(struct vmbus_channel *channel)
} }
allocated_mask = &hv_context.hv_numa_map[numa_node]; allocated_mask = &hv_context.hv_numa_map[numa_node];
if (cpumask_equal(allocated_mask, cpumask_of_node(numa_node))) { retry:
cpumask_xor(available_mask, allocated_mask, cpumask_of_node(numa_node));
cpumask_and(available_mask, available_mask, hk_mask);
if (cpumask_empty(available_mask)) {
/* /*
* We have cycled through all the CPUs in the node; * We have cycled through all the CPUs in the node;
* reset the allocated map. * reset the allocated map.
*/ */
cpumask_clear(allocated_mask); cpumask_clear(allocated_mask);
goto retry;
} }
cpumask_xor(available_mask, allocated_mask,
cpumask_of_node(numa_node));
target_cpu = cpumask_first(available_mask); target_cpu = cpumask_first(available_mask);
cpumask_set_cpu(target_cpu, allocated_mask); cpumask_set_cpu(target_cpu, allocated_mask);

View File

@ -394,7 +394,7 @@ kvp_send_key(struct work_struct *dummy)
in_msg = kvp_transaction.kvp_msg; in_msg = kvp_transaction.kvp_msg;
/* /*
* The key/value strings sent from the host are encoded in * The key/value strings sent from the host are encoded
* in utf16; convert it to utf8 strings. * in utf16; convert it to utf8 strings.
* The host assures us that the utf16 strings will not exceed * The host assures us that the utf16 strings will not exceed
* the max lengths specified. We will however, reserve room * the max lengths specified. We will however, reserve room

View File

@ -21,6 +21,7 @@
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/sched/isolation.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/delay.h> #include <linux/delay.h>
@ -1770,6 +1771,9 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
if (target_cpu >= nr_cpumask_bits) if (target_cpu >= nr_cpumask_bits)
return -EINVAL; return -EINVAL;
if (!cpumask_test_cpu(target_cpu, housekeeping_cpumask(HK_TYPE_MANAGED_IRQ)))
return -EINVAL;
/* No CPUs should come up or down during this. */ /* No CPUs should come up or down during this. */
cpus_read_lock(); cpus_read_lock();

View File

@ -259,7 +259,7 @@ static const struct ec_board_info board_info[] = {
}, },
{ {
.board_names = { .board_names = {
"ROG CROSSHAIR VIII FORMULA" "ROG CROSSHAIR VIII FORMULA",
"ROG CROSSHAIR VIII HERO", "ROG CROSSHAIR VIII HERO",
"ROG CROSSHAIR VIII HERO (WI-FI)", "ROG CROSSHAIR VIII HERO (WI-FI)",
}, },

View File

@ -1228,10 +1228,15 @@ EXPORT_SYMBOL_GPL(occ_setup);
void occ_shutdown(struct occ *occ) void occ_shutdown(struct occ *occ)
{ {
mutex_lock(&occ->lock);
occ_shutdown_sysfs(occ); occ_shutdown_sysfs(occ);
if (occ->hwmon) if (occ->hwmon)
hwmon_device_unregister(occ->hwmon); hwmon_device_unregister(occ->hwmon);
occ->hwmon = NULL;
mutex_unlock(&occ->lock);
} }
EXPORT_SYMBOL_GPL(occ_shutdown); EXPORT_SYMBOL_GPL(occ_shutdown);

View File

@ -477,9 +477,6 @@ int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare)
{ {
int ret; int ret;
if (IS_ERR(dev->clk))
return PTR_ERR(dev->clk);
if (prepare) { if (prepare) {
/* Optional interface clock */ /* Optional interface clock */
ret = clk_prepare_enable(dev->pclk); ret = clk_prepare_enable(dev->pclk);

View File

@ -320,8 +320,17 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
goto exit_reset; goto exit_reset;
} }
dev->clk = devm_clk_get(&pdev->dev, NULL); dev->clk = devm_clk_get_optional(&pdev->dev, NULL);
if (!i2c_dw_prepare_clk(dev, true)) { if (IS_ERR(dev->clk)) {
ret = PTR_ERR(dev->clk);
goto exit_reset;
}
ret = i2c_dw_prepare_clk(dev, true);
if (ret)
goto exit_reset;
if (dev->clk) {
u64 clk_khz; u64 clk_khz;
dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;

View File

@ -1420,17 +1420,22 @@ static int mtk_i2c_probe(struct platform_device *pdev)
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"Request I2C IRQ %d fail\n", irq); "Request I2C IRQ %d fail\n", irq);
return ret; goto err_bulk_unprepare;
} }
i2c_set_adapdata(&i2c->adap, i2c); i2c_set_adapdata(&i2c->adap, i2c);
ret = i2c_add_adapter(&i2c->adap); ret = i2c_add_adapter(&i2c->adap);
if (ret) if (ret)
return ret; goto err_bulk_unprepare;
platform_set_drvdata(pdev, i2c); platform_set_drvdata(pdev, i2c);
return 0; return 0;
err_bulk_unprepare:
clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
return ret;
} }
static int mtk_i2c_remove(struct platform_device *pdev) static int mtk_i2c_remove(struct platform_device *pdev)

Some files were not shown because too many files have changed in this diff Show More