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:
commit
93817be8b6
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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?)
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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. |
|
||||||
+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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).
|
||||||
|
@ -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.
|
||||||
|
@ -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).
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
----
|
----
|
||||||
|
@ -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".
|
||||||
|
@ -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`` 的别名,属于已经废弃的用法。
|
||||||
|
|
||||||
|
|
||||||
向量寄存器
|
向量寄存器
|
||||||
|
@ -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中断”。
|
||||||
|
46
MAINTAINERS
46
MAINTAINERS
@ -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
|
||||||
|
2
Makefile
2
Makefile
@ -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*
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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]
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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)
|
||||||
|
@ -101,6 +101,7 @@ SECTIONS
|
|||||||
|
|
||||||
STABS_DEBUG
|
STABS_DEBUG
|
||||||
DWARF_DEBUG
|
DWARF_DEBUG
|
||||||
|
ELF_DETAILS
|
||||||
|
|
||||||
.gptab.sdata : {
|
.gptab.sdata : {
|
||||||
*(.gptab.data)
|
*(.gptab.data)
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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>;
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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.
|
||||||
|
@ -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))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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),)
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 \
|
||||||
|
224
crypto/asymmetric_keys/selftest.c
Normal file
224
crypto/asymmetric_keys/selftest.c
Normal 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;
|
||||||
|
}
|
@ -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)
|
||||||
{
|
{
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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(>->rps);
|
intel_rps_driver_unregister(>->rps);
|
||||||
intel_gsc_fini(>->gsc);
|
intel_gsc_fini(>->gsc);
|
||||||
|
|
||||||
|
@ -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(>->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, >->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(>->sysfs_gt);
|
||||||
drm_warn(>->i915->drm,
|
drm_warn(>->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(>->sysfs_gt);
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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)",
|
||||||
},
|
},
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user