linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables
@ 2024-08-27  8:45 Sebastian Ene
  2024-08-27  8:45 ` [PATCH v9 1/5] KVM: arm64: Move pagetable definitions to common header Sebastian Ene
                   ` (5 more replies)
  0 siblings, 6 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-08-27  8:45 UTC (permalink / raw)
  To: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, sebastianene, shahuang, suzuki.poulose, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

Hi,


This series extends the ptdump support to allow dumping the guest
stage-2 pagetables. When CONFIG_PTDUMP_STAGE2_DEBUGFS is enabled, ptdump
registers the new following files under debugfs:
- /sys/debug/kvm/<guest_id>/stage2_page_tables
- /sys/debug/kvm/<guest_id>/stage2_levels
- /sys/debug/kvm/<guest_id>/ipa_range

This allows userspace tools (eg. cat) to dump the stage-2 pagetables by
reading the 'stage2_page_tables' file.
The output format has the following fields:
<IPA range> <size> <level> <access permissions> <mem_attributes>

Below is the output of a guest stage-2 pagetable dump running under Qemu.
After a VM is created, the following files are available:

# cat /sys/kernel/debug/kvm/256-4/stage2_levels 
4
# cat /sys/kernel/debug/kvm/256-4/ipa_range 
44
# cat /sys/kernel/debug/kvm/256-4/stage2_page_tables 
---[ Guest IPA ]---
0x0000000000000000-0x0000000001000000          16M 2
0x0000000001000000-0x0000000001020000         128K 3
0x0000000001020000-0x0000000001021000           4K 3   R W X AF    
0x0000000001021000-0x0000000001200000        1916K 3
0x0000000001200000-0x0000000040000000        1006M 2
0x0000000040000000-0x0000000080000000           1G 0
0x0000000080000000-0x0000000081200000          18M 2   R W   AF BLK
0x0000000081200000-0x0000000081a00000           8M 2   R W X AF BLK
0x0000000081a00000-0x0000000081c00000           2M 2   R W   AF BLK
0x0000000081c00000-0x0000000082200000           6M 2   R W X AF BLK
0x0000000082200000-0x0000000082400000           2M 2   R W   AF BLK
0x0000000082400000-0x0000000082800000           4M 2   R W X AF BLK
0x0000000082800000-0x0000000082a00000           2M 2   R W   AF BLK
0x0000000082a00000-0x0000000082c00000           2M 2
0x0000000082c00000-0x0000000083200000           6M 2   R W X AF BLK
0x0000000083200000-0x0000000083400000           2M 2
0x0000000083400000-0x0000000083a00000           6M 2   R W X AF BLK
0x0000000083a00000-0x000000008fe00000         196M 2
0x000000008fe00000-0x0000000090000000           2M 2   R W   AF BLK
0x0000000090000000-0x0000000099400000         148M 2
0x0000000099400000-0x0000000099600000           2M 2   R W X AF BLK
0x0000000099600000-0x000000009b600000          32M 2
0x000000009b600000-0x000000009be00000           8M 2   R W X AF BLK
0x000000009be00000-0x000000009c000000           2M 2   R W   AF BLK
0x000000009c000000-0x00000000c0000000         576M 2

Changelog:
v8 -> current:
 * squashed the last 3 patches and separated the Kconfig change as the
   last patch.
 * updated the commit message of the 3rd patch
 * printing level numbers instead of names as suggested by Mark
 * fixed one return code to ERR_PTR(-ENOMEM) as spotted by Vincent
 * dropped a barely empty header 'kvm_ptdump.h'
 * general cosmetic changes 

v7 -> v8:
 * applied Will's feedback and prefixed the exported structure names
   with ptdump_
 * dropped PTE_CONT and PTE_NG attribute parsing from Oliver's
   suggestion
 * fixed spurious BLK annotation reported by Vincent
 * repurposed `stage2_levels` debugfs file to show the number of the
   levels
 * tried changing the order of the patches:
   "5/6 Initialize the ptdump parser with stage-2 attributes" before
   exposing the debugfs file but ended up keeping the same order
   as this depends on the later one.

 v6 -> v7:
 * Reworded commit for this patch : [PATCH v6 2/6] arm64: ptdump: Expose
   the attribute parsing functionality
 * fixed minor conflicts in the struct pg_state definition
 * moved the kvm_ptdump_guest_registration in the
 * kvm_arch_create_vm_debugfs
 * reset the parse state before walking the pagetables
 * copy the level name to the pg_level buffer

 v5 -> v6:
 * don't return an error if the kvm_arch_create_vm_debugfs fails to
   initialize (ref.
https://lore.kernel.org/all/20240216155941.2029458-1-oliver.upton@linux.dev/)  
 * fix use-after-free suggested by getting a reference to the
   KVM struct while manipulating the debugfs files
   and put the reference on the file close.
 * do all the allocations at once for the ptdump parser state tracking
   and simplify the initialization.
 * move the ptdump parser state initialization as part of the file_open
 * create separate files for printing the guest stage-2 pagetable
   configuration such as: the start level of the pagetable walk and the
   number of bits used for the IPA space representation.
 * fixed the wrong header format for the newly added file
 * include missing patch which hasn't been posted on the v5:
   "KVM-arm64-Move-pagetable-definitions-to-common-heade.patch" 

 
Links to previous versions:
v8:
https://lore.kernel.org/all/20240816123906.3683425-1-sebastianene@google.com/  
v7:
https://lore.kernel.org/all/20240621123230.1085265-1-sebastianene@google.com/
v6:
https://lore.kernel.org/all/20240220151035.327199-1-sebastianene@google.com/
v5:
https://lore.kernel.org/all/20240207144832.1017815-2-sebastianene@google.com/

Thanks,
Sebastian

Sebastian Ene (5):
  KVM: arm64: Move pagetable definitions to common header
  arm64: ptdump: Expose the attribute parsing functionality
  arm64: ptdump: Use the ptdump description from a local context
  KVM: arm64: Register ptdump with debugfs on guest creation
  KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config

 arch/arm64/include/asm/kvm_host.h    |   6 +
 arch/arm64/include/asm/kvm_pgtable.h |  42 +++++
 arch/arm64/include/asm/ptdump.h      |  42 ++++-
 arch/arm64/kvm/Kconfig               |  17 ++
 arch/arm64/kvm/Makefile              |   1 +
 arch/arm64/kvm/arm.c                 |   1 +
 arch/arm64/kvm/hyp/pgtable.c         |  42 -----
 arch/arm64/kvm/ptdump.c              | 247 +++++++++++++++++++++++++++
 arch/arm64/mm/ptdump.c               |  66 ++-----
 9 files changed, 373 insertions(+), 91 deletions(-)
 create mode 100644 arch/arm64/kvm/ptdump.c

-- 
2.46.0.295.g3b9ea8a38a-goog



^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v9 1/5] KVM: arm64: Move pagetable definitions to common header
  2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
@ 2024-08-27  8:45 ` Sebastian Ene
  2024-08-27  8:45 ` [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality Sebastian Ene
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-08-27  8:45 UTC (permalink / raw)
  To: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, sebastianene, shahuang, suzuki.poulose, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

In preparation for using the stage-2 definitions in ptdump, move some of
these macros in the common header.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 42 ++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/pgtable.c         | 42 ----------------------------
 2 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 19278dfe7978..03f4c3d7839c 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -59,6 +59,48 @@ typedef u64 kvm_pte_t;
 
 #define KVM_PHYS_INVALID		(-1ULL)
 
+#define KVM_PTE_LEAF_ATTR_LO		GENMASK(11, 2)
+
+#define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX	GENMASK(4, 2)
+#define KVM_PTE_LEAF_ATTR_LO_S1_AP	GENMASK(7, 6)
+#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RO		\
+	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 2 : 3; })
+#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RW		\
+	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 0 : 1; })
+#define KVM_PTE_LEAF_ATTR_LO_S1_SH	GENMASK(9, 8)
+#define KVM_PTE_LEAF_ATTR_LO_S1_SH_IS	3
+#define KVM_PTE_LEAF_ATTR_LO_S1_AF	BIT(10)
+
+#define KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR	GENMASK(5, 2)
+#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R	BIT(6)
+#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W	BIT(7)
+#define KVM_PTE_LEAF_ATTR_LO_S2_SH	GENMASK(9, 8)
+#define KVM_PTE_LEAF_ATTR_LO_S2_SH_IS	3
+#define KVM_PTE_LEAF_ATTR_LO_S2_AF	BIT(10)
+
+#define KVM_PTE_LEAF_ATTR_HI		GENMASK(63, 50)
+
+#define KVM_PTE_LEAF_ATTR_HI_SW		GENMASK(58, 55)
+
+#define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)
+
+#define KVM_PTE_LEAF_ATTR_HI_S2_XN	BIT(54)
+
+#define KVM_PTE_LEAF_ATTR_HI_S1_GP	BIT(50)
+
+#define KVM_PTE_LEAF_ATTR_S2_PERMS	(KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
+					 KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
+					 KVM_PTE_LEAF_ATTR_HI_S2_XN)
+
+#define KVM_INVALID_PTE_OWNER_MASK	GENMASK(9, 2)
+#define KVM_MAX_OWNER_ID		1
+
+/*
+ * Used to indicate a pte for which a 'break-before-make' sequence is in
+ * progress.
+ */
+#define KVM_INVALID_PTE_LOCKED		BIT(10)
+
 static inline bool kvm_pte_valid(kvm_pte_t pte)
 {
 	return pte & KVM_PTE_VALID;
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 9e2bbee77491..c3e9d77bba23 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -17,48 +17,6 @@
 #define KVM_PTE_TYPE_PAGE		1
 #define KVM_PTE_TYPE_TABLE		1
 
-#define KVM_PTE_LEAF_ATTR_LO		GENMASK(11, 2)
-
-#define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX	GENMASK(4, 2)
-#define KVM_PTE_LEAF_ATTR_LO_S1_AP	GENMASK(7, 6)
-#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RO		\
-	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 2 : 3; })
-#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RW		\
-	({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 0 : 1; })
-#define KVM_PTE_LEAF_ATTR_LO_S1_SH	GENMASK(9, 8)
-#define KVM_PTE_LEAF_ATTR_LO_S1_SH_IS	3
-#define KVM_PTE_LEAF_ATTR_LO_S1_AF	BIT(10)
-
-#define KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR	GENMASK(5, 2)
-#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R	BIT(6)
-#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W	BIT(7)
-#define KVM_PTE_LEAF_ATTR_LO_S2_SH	GENMASK(9, 8)
-#define KVM_PTE_LEAF_ATTR_LO_S2_SH_IS	3
-#define KVM_PTE_LEAF_ATTR_LO_S2_AF	BIT(10)
-
-#define KVM_PTE_LEAF_ATTR_HI		GENMASK(63, 50)
-
-#define KVM_PTE_LEAF_ATTR_HI_SW		GENMASK(58, 55)
-
-#define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)
-
-#define KVM_PTE_LEAF_ATTR_HI_S2_XN	BIT(54)
-
-#define KVM_PTE_LEAF_ATTR_HI_S1_GP	BIT(50)
-
-#define KVM_PTE_LEAF_ATTR_S2_PERMS	(KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
-					 KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
-					 KVM_PTE_LEAF_ATTR_HI_S2_XN)
-
-#define KVM_INVALID_PTE_OWNER_MASK	GENMASK(9, 2)
-#define KVM_MAX_OWNER_ID		1
-
-/*
- * Used to indicate a pte for which a 'break-before-make' sequence is in
- * progress.
- */
-#define KVM_INVALID_PTE_LOCKED		BIT(10)
-
 struct kvm_pgtable_walk_data {
 	struct kvm_pgtable_walker	*walker;
 
-- 
2.46.0.295.g3b9ea8a38a-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality
  2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
  2024-08-27  8:45 ` [PATCH v9 1/5] KVM: arm64: Move pagetable definitions to common header Sebastian Ene
@ 2024-08-27  8:45 ` Sebastian Ene
  2024-08-30 12:28   ` Marc Zyngier
  2024-08-27  8:45 ` [PATCH v9 3/5] arm64: ptdump: Use the ptdump description from a local context Sebastian Ene
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: Sebastian Ene @ 2024-08-27  8:45 UTC (permalink / raw)
  To: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, sebastianene, shahuang, suzuki.poulose, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

Reuse the descriptor parsing functionality to keep the same output format
as the original ptdump code. In order for this to happen, move the state
tracking objects into a common header.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/include/asm/ptdump.h | 41 +++++++++++++++++++++++-
 arch/arm64/mm/ptdump.c          | 55 +++++++--------------------------
 2 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 5b1701c76d1c..bd5d3ee3e8dc 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -9,6 +9,7 @@
 
 #include <linux/mm_types.h>
 #include <linux/seq_file.h>
+#include <linux/ptdump.h>
 
 struct addr_marker {
 	unsigned long start_address;
@@ -21,14 +22,52 @@ struct ptdump_info {
 	unsigned long			base_addr;
 };
 
+struct ptdump_prot_bits {
+	u64		mask;
+	u64		val;
+	const char	*set;
+	const char	*clear;
+};
+
+struct ptdump_pg_level {
+	const struct ptdump_prot_bits *bits;
+	char name[4];
+	int num;
+	u64 mask;
+};
+
+/*
+ * The page dumper groups page table entries of the same type into a single
+ * description. It uses pg_state to track the range information while
+ * iterating over the pte entries. When the continuity is broken it then
+ * dumps out a description of the range.
+ */
+struct ptdump_pg_state {
+	struct ptdump_state ptdump;
+	struct seq_file *seq;
+	const struct addr_marker *marker;
+	const struct mm_struct *mm;
+	unsigned long start_address;
+	int level;
+	u64 current_prot;
+	bool check_wx;
+	unsigned long wx_pages;
+	unsigned long uxn_pages;
+};
+
 void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+	       u64 val);
 #ifdef CONFIG_PTDUMP_DEBUGFS
 #define EFI_RUNTIME_MAP_END	DEFAULT_MAP_WINDOW_64
 void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
 #else
 static inline void ptdump_debugfs_register(struct ptdump_info *info,
 					   const char *name) { }
-#endif
+#endif /* CONFIG_PTDUMP_DEBUGFS */
+#else
+static inline void note_page(void *pt_st, unsigned long addr,
+			     int level, u64 val) { }
 #endif /* CONFIG_PTDUMP_CORE */
 
 #endif /* __ASM_PTDUMP_H */
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index 6986827e0d64..404751fd30fe 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -38,33 +38,7 @@
 		seq_printf(m, fmt);	\
 })
 
-/*
- * The page dumper groups page table entries of the same type into a single
- * description. It uses pg_state to track the range information while
- * iterating over the pte entries. When the continuity is broken it then
- * dumps out a description of the range.
- */
-struct pg_state {
-	struct ptdump_state ptdump;
-	struct seq_file *seq;
-	const struct addr_marker *marker;
-	const struct mm_struct *mm;
-	unsigned long start_address;
-	int level;
-	u64 current_prot;
-	bool check_wx;
-	unsigned long wx_pages;
-	unsigned long uxn_pages;
-};
-
-struct prot_bits {
-	u64		mask;
-	u64		val;
-	const char	*set;
-	const char	*clear;
-};
-
-static const struct prot_bits pte_bits[] = {
+static const struct ptdump_prot_bits pte_bits[] = {
 	{
 		.mask	= PTE_VALID,
 		.val	= PTE_VALID,
@@ -143,14 +117,7 @@ static const struct prot_bits pte_bits[] = {
 	}
 };
 
-struct pg_level {
-	const struct prot_bits *bits;
-	char name[4];
-	int num;
-	u64 mask;
-};
-
-static struct pg_level pg_level[] __ro_after_init = {
+static struct ptdump_pg_level pg_level[] __ro_after_init = {
 	{ /* pgd */
 		.name	= "PGD",
 		.bits	= pte_bits,
@@ -174,7 +141,7 @@ static struct pg_level pg_level[] __ro_after_init = {
 	},
 };
 
-static void dump_prot(struct pg_state *st, const struct prot_bits *bits,
+static void dump_prot(struct ptdump_pg_state *st, const struct ptdump_prot_bits *bits,
 			size_t num)
 {
 	unsigned i;
@@ -192,7 +159,7 @@ static void dump_prot(struct pg_state *st, const struct prot_bits *bits,
 	}
 }
 
-static void note_prot_uxn(struct pg_state *st, unsigned long addr)
+static void note_prot_uxn(struct ptdump_pg_state *st, unsigned long addr)
 {
 	if (!st->check_wx)
 		return;
@@ -206,7 +173,7 @@ static void note_prot_uxn(struct pg_state *st, unsigned long addr)
 	st->uxn_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_prot_wx(struct pg_state *st, unsigned long addr)
+static void note_prot_wx(struct ptdump_pg_state *st, unsigned long addr)
 {
 	if (!st->check_wx)
 		return;
@@ -221,10 +188,10 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
 	st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
-		      u64 val)
+void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+	       u64 val)
 {
-	struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
+	struct ptdump_pg_state *st = container_of(pt_st, struct ptdump_pg_state, ptdump);
 	static const char units[] = "KMGTPE";
 	u64 prot = 0;
 
@@ -286,12 +253,12 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 {
 	unsigned long end = ~0UL;
-	struct pg_state st;
+	struct ptdump_pg_state st;
 
 	if (info->base_addr < TASK_SIZE_64)
 		end = TASK_SIZE_64;
 
-	st = (struct pg_state){
+	st = (struct ptdump_pg_state){
 		.seq = s,
 		.marker = info->markers,
 		.mm = info->mm,
@@ -324,7 +291,7 @@ static struct ptdump_info kernel_ptdump_info __ro_after_init = {
 
 bool ptdump_check_wx(void)
 {
-	struct pg_state st = {
+	struct ptdump_pg_state st = {
 		.seq = NULL,
 		.marker = (struct addr_marker[]) {
 			{ 0, NULL},
-- 
2.46.0.295.g3b9ea8a38a-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v9 3/5] arm64: ptdump: Use the ptdump description from a local context
  2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
  2024-08-27  8:45 ` [PATCH v9 1/5] KVM: arm64: Move pagetable definitions to common header Sebastian Ene
  2024-08-27  8:45 ` [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality Sebastian Ene
@ 2024-08-27  8:45 ` Sebastian Ene
  2024-08-27  8:45 ` [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation Sebastian Ene
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-08-27  8:45 UTC (permalink / raw)
  To: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, sebastianene, shahuang, suzuki.poulose, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

Rename the attributes description array to allow the parsing method
to use the description from a local context. To be able to do this,
store a pointer to the description array in the state structure. This
will allow for the later introduced callers (stage_2 ptdump) to specify
their own page table description format to the ptdump parser.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/include/asm/ptdump.h |  1 +
 arch/arm64/mm/ptdump.c          | 13 ++++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index bd5d3ee3e8dc..71a7ed01153a 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -44,6 +44,7 @@ struct ptdump_pg_level {
  */
 struct ptdump_pg_state {
 	struct ptdump_state ptdump;
+	struct ptdump_pg_level *pg_level;
 	struct seq_file *seq;
 	const struct addr_marker *marker;
 	const struct mm_struct *mm;
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index 404751fd30fe..ca53ef274a8b 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -117,7 +117,7 @@ static const struct ptdump_prot_bits pte_bits[] = {
 	}
 };
 
-static struct ptdump_pg_level pg_level[] __ro_after_init = {
+static struct ptdump_pg_level kernel_pg_levels[] __ro_after_init = {
 	{ /* pgd */
 		.name	= "PGD",
 		.bits	= pte_bits,
@@ -192,6 +192,7 @@ void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 	       u64 val)
 {
 	struct ptdump_pg_state *st = container_of(pt_st, struct ptdump_pg_state, ptdump);
+	struct ptdump_pg_level *pg_level = st->pg_level;
 	static const char units[] = "KMGTPE";
 	u64 prot = 0;
 
@@ -262,6 +263,7 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 		.seq = s,
 		.marker = info->markers,
 		.mm = info->mm,
+		.pg_level = &kernel_pg_levels[0],
 		.level = -1,
 		.ptdump = {
 			.note_page = note_page,
@@ -279,10 +281,10 @@ static void __init ptdump_initialize(void)
 {
 	unsigned i, j;
 
-	for (i = 0; i < ARRAY_SIZE(pg_level); i++)
-		if (pg_level[i].bits)
-			for (j = 0; j < pg_level[i].num; j++)
-				pg_level[i].mask |= pg_level[i].bits[j].mask;
+	for (i = 0; i < ARRAY_SIZE(kernel_pg_levels); i++)
+		if (kernel_pg_levels[i].bits)
+			for (j = 0; j < kernel_pg_levels[i].num; j++)
+				kernel_pg_levels[i].mask |= kernel_pg_levels[i].bits[j].mask;
 }
 
 static struct ptdump_info kernel_ptdump_info __ro_after_init = {
@@ -297,6 +299,7 @@ bool ptdump_check_wx(void)
 			{ 0, NULL},
 			{ -1, NULL},
 		},
+		.pg_level = &kernel_pg_levels[0],
 		.level = -1,
 		.check_wx = true,
 		.ptdump = {
-- 
2.46.0.295.g3b9ea8a38a-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
                   ` (2 preceding siblings ...)
  2024-08-27  8:45 ` [PATCH v9 3/5] arm64: ptdump: Use the ptdump description from a local context Sebastian Ene
@ 2024-08-27  8:45 ` Sebastian Ene
  2024-08-30 10:24   ` Vincent Donnefort
  2024-08-27  8:45 ` [PATCH v9 5/5] KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config Sebastian Ene
  2024-08-30 14:44 ` [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Marc Zyngier
  5 siblings, 1 reply; 20+ messages in thread
From: Sebastian Ene @ 2024-08-27  8:45 UTC (permalink / raw)
  To: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, sebastianene, shahuang, suzuki.poulose, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

While arch/*/mem/ptdump handles the kernel pagetable dumping code,
introduce KVM/ptdump to show the guest stage-2 pagetables. The
separation is necessary because most of the definitions from the
stage-2 pagetable reside in the KVM path and we will be invoking
functionality specific to KVM.

When a guest is created, register a new file entry under the guest
debugfs dir which allows userspace to show the contents of the guest
stage-2 pagetables when accessed.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/include/asm/kvm_host.h |   6 +
 arch/arm64/kvm/Makefile           |   1 +
 arch/arm64/kvm/arm.c              |   1 +
 arch/arm64/kvm/ptdump.c           | 247 ++++++++++++++++++++++++++++++
 4 files changed, 255 insertions(+)
 create mode 100644 arch/arm64/kvm/ptdump.c

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a33f5996ca9f..4acd589f086b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -1473,4 +1473,10 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
 		(pa + pi + pa3) == 1;					\
 	})
 
+#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
+void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
+#else
+static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
+#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 86a629aaf0a1..e4233b323a73 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -27,6 +27,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
 kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
+kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
 
 always-y := hyp_constants.h hyp-constants.s
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 9bef7638342e..b9fd928d3477 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -228,6 +228,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 void kvm_arch_create_vm_debugfs(struct kvm *kvm)
 {
 	kvm_sys_regs_create_debugfs(kvm);
+	kvm_s2_ptdump_create_debugfs(kvm);
 }
 
 static void kvm_destroy_mpidr_data(struct kvm *kvm)
diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
new file mode 100644
index 000000000000..e72a928d4445
--- /dev/null
+++ b/arch/arm64/kvm/ptdump.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Debug helper used to dump the stage-2 pagetables of the system and their
+ * associated permissions.
+ *
+ * Copyright (C) Google, 2024
+ * Author: Sebastian Ene <sebastianene@google.com>
+ */
+#include <linux/debugfs.h>
+#include <linux/kvm_host.h>
+#include <linux/seq_file.h>
+
+#include <asm/kvm_pgtable.h>
+#include <asm/kvm_host.h>
+#include <asm/ptdump.h>
+
+
+#define MARKERS_LEN		(2)
+#define KVM_PGTABLE_MAX_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
+
+struct kvm_ptdump_guest_state {
+	struct kvm		*kvm;
+	struct ptdump_pg_state	parser_state;
+	struct addr_marker	ipa_marker[MARKERS_LEN];
+	struct ptdump_pg_level	level[KVM_PGTABLE_MAX_LEVELS];
+	struct ptdump_range	range[MARKERS_LEN];
+};
+
+static const struct ptdump_prot_bits stage2_pte_bits[] = {
+	{
+		.mask	= PTE_VALID,
+		.val	= PTE_VALID,
+		.set	= " ",
+		.clear	= "F",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
+		.set	= "R",
+		.clear	= " ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
+		.set	= "W",
+		.clear	= " ",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
+		.val	= PTE_VALID,
+		.set	= " ",
+		.clear	= "X",
+	}, {
+		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
+		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
+		.set	= "AF",
+		.clear	= "  ",
+	}, {
+		.mask	= PTE_TABLE_BIT | PTE_VALID,
+		.val	= PTE_VALID,
+		.set	= "BLK",
+		.clear	= "   ",
+	},
+};
+
+static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
+			      enum kvm_pgtable_walk_flags visit)
+{
+	struct ptdump_pg_state *st = ctx->arg;
+	struct ptdump_state *pt_st = &st->ptdump;
+
+	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
+
+	return 0;
+}
+
+static int kvm_ptdump_build_levels(struct ptdump_pg_level *level, u32 start_lvl)
+{
+	u32 i;
+	u64 mask;
+
+	if (WARN_ON_ONCE(start_lvl >= KVM_PGTABLE_LAST_LEVEL))
+		return -EINVAL;
+
+	mask = 0;
+	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
+		mask |= stage2_pte_bits[i].mask;
+
+	for (i = start_lvl; i < KVM_PGTABLE_MAX_LEVELS; i++) {
+		snprintf(level[i].name, sizeof(level[i].name), "%d", i);
+
+		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
+		level[i].bits	= stage2_pte_bits;
+		level[i].mask	= mask;
+	}
+
+	return 0;
+}
+
+static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm)
+{
+	struct kvm_ptdump_guest_state *st;
+	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
+	struct kvm_pgtable *pgtable = mmu->pgt;
+	int ret;
+
+	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
+	if (!st)
+		return ERR_PTR(-ENOMEM);
+
+	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
+	if (ret) {
+		kfree(st);
+		return ERR_PTR(ret);
+	}
+
+	st->ipa_marker[0].name		= "Guest IPA";
+	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
+	st->range[0].end		= BIT(pgtable->ia_bits);
+
+	st->kvm				= kvm;
+	st->parser_state = (struct ptdump_pg_state) {
+		.marker		= &st->ipa_marker[0],
+		.level		= -1,
+		.pg_level	= &st->level[0],
+		.ptdump.range	= &st->range[0],
+		.start_address	= 0,
+	};
+
+	return st;
+}
+
+static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)
+{
+	int ret;
+	struct kvm_ptdump_guest_state *st = m->private;
+	struct kvm *kvm = st->kvm;
+	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
+	struct ptdump_pg_state *parser_state = &st->parser_state;
+	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
+		.cb	= kvm_ptdump_visitor,
+		.arg	= parser_state,
+		.flags	= KVM_PGTABLE_WALK_LEAF,
+	};
+
+	parser_state->seq = m;
+
+	write_lock(&kvm->mmu_lock);
+	ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker);
+	write_unlock(&kvm->mmu_lock);
+
+	return ret;
+}
+
+static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+	struct kvm_ptdump_guest_state *st;
+	int ret;
+
+	if (!kvm_get_kvm_safe(kvm))
+		return -ENOENT;
+
+	st = kvm_ptdump_parser_create(kvm);
+	if (IS_ERR(st)) {
+		ret = PTR_ERR(st);
+		goto free_with_kvm_ref;
+	}
+
+	ret = single_open(file, kvm_ptdump_guest_show, st);
+	if (!ret)
+		return 0;
+
+	kfree(st);
+free_with_kvm_ref:
+	kvm_put_kvm(kvm);
+	return ret;
+}
+
+static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+	void *st = ((struct seq_file *)file->private_data)->private;
+
+	kfree(st);
+	kvm_put_kvm(kvm);
+
+	return single_release(m, file);
+}
+
+static const struct file_operations kvm_ptdump_guest_fops = {
+	.open		= kvm_ptdump_guest_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= kvm_ptdump_guest_close,
+};
+
+static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
+{
+	const struct file *file = m->file;
+	struct kvm_pgtable *pgtable = m->private;
+
+	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
+		seq_printf(m, "%2u\n", pgtable->ia_bits);
+	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
+		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
+	return 0;
+}
+
+static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+	struct kvm_pgtable *pgtable;
+	int ret;
+
+	if (!kvm_get_kvm_safe(kvm))
+		return -ENOENT;
+
+	pgtable = kvm->arch.mmu.pgt;
+
+	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
+	if (ret < 0)
+		kvm_put_kvm(kvm);
+	return ret;
+}
+
+static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
+{
+	struct kvm *kvm = m->i_private;
+
+	kvm_put_kvm(kvm);
+	return single_release(m, file);
+}
+
+static const struct file_operations kvm_pgtable_debugfs_fops = {
+	.open		= kvm_pgtable_debugfs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= kvm_pgtable_debugfs_close,
+};
+
+void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
+{
+	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
+			    kvm, &kvm_ptdump_guest_fops);
+	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
+			    &kvm_pgtable_debugfs_fops);
+	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
+			    kvm, &kvm_pgtable_debugfs_fops);
+}
-- 
2.46.0.295.g3b9ea8a38a-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v9 5/5] KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config
  2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
                   ` (3 preceding siblings ...)
  2024-08-27  8:45 ` [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation Sebastian Ene
@ 2024-08-27  8:45 ` Sebastian Ene
  2024-08-30 10:26   ` Vincent Donnefort
  2024-08-30 14:44 ` [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Marc Zyngier
  5 siblings, 1 reply; 20+ messages in thread
From: Sebastian Ene @ 2024-08-27  8:45 UTC (permalink / raw)
  To: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, sebastianene, shahuang, suzuki.poulose, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

When this config is enabled, it exposes the stage-2 pagetable layout
through a debugfs file.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/kvm/Kconfig | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 8304eb342be9..ead632ad01b4 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -66,4 +66,21 @@ config PROTECTED_NVHE_STACKTRACE
 
 	  If unsure, or not using protected nVHE (pKVM), say N.
 
+config PTDUMP_STAGE2_DEBUGFS
+	bool "Present the stage-2 pagetables to debugfs"
+	depends on KVM
+	depends on DEBUG_KERNEL
+	depends on DEBUG_FS
+	depends on GENERIC_PTDUMP
+	select PTDUMP_CORE
+	default n
+	help
+	  Say Y here if you want to show the stage-2 kernel pagetables
+	  layout in a debugfs file. This information is only useful for kernel developers
+	  who are working in architecture specific areas of the kernel.
+	  It is probably not a good idea to enable this feature in a production
+	  kernel.
+
+	  If in doubt, say N.
+
 endif # VIRTUALIZATION
-- 
2.46.0.295.g3b9ea8a38a-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-08-27  8:45 ` [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation Sebastian Ene
@ 2024-08-30 10:24   ` Vincent Donnefort
  2024-08-30 14:11     ` Marc Zyngier
  2024-09-02  5:31     ` Sebastian Ene
  0 siblings, 2 replies; 20+ messages in thread
From: Vincent Donnefort @ 2024-08-30 10:24 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

Hi Seb,

Thanks for the respin.

On Tue, Aug 27, 2024 at 08:45:47AM +0000, Sebastian Ene wrote:
> While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> introduce KVM/ptdump to show the guest stage-2 pagetables. The
> separation is necessary because most of the definitions from the
> stage-2 pagetable reside in the KVM path and we will be invoking
> functionality specific to KVM.
> 
> When a guest is created, register a new file entry under the guest
> debugfs dir which allows userspace to show the contents of the guest
> stage-2 pagetables when accessed.
> 
> Signed-off-by: Sebastian Ene <sebastianene@google.com>

I only have some nits, otherwise:

Reviewed-by: Vincent Donnefort <vdonnefort@google.com>

> ---
>  arch/arm64/include/asm/kvm_host.h |   6 +
>  arch/arm64/kvm/Makefile           |   1 +
>  arch/arm64/kvm/arm.c              |   1 +
>  arch/arm64/kvm/ptdump.c           | 247 ++++++++++++++++++++++++++++++
>  4 files changed, 255 insertions(+)
>  create mode 100644 arch/arm64/kvm/ptdump.c
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index a33f5996ca9f..4acd589f086b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -1473,4 +1473,10 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
>  		(pa + pi + pa3) == 1;					\
>  	})
>  
> +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
> +#else
> +static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
> +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> +
>  #endif /* __ARM64_KVM_HOST_H__ */
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index 86a629aaf0a1..e4233b323a73 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -27,6 +27,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
>  
>  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
>  kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
> +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
>  
>  always-y := hyp_constants.h hyp-constants.s
>  
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 9bef7638342e..b9fd928d3477 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -228,6 +228,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>  void kvm_arch_create_vm_debugfs(struct kvm *kvm)
>  {
>  	kvm_sys_regs_create_debugfs(kvm);
> +	kvm_s2_ptdump_create_debugfs(kvm);
>  }
>  
>  static void kvm_destroy_mpidr_data(struct kvm *kvm)
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> new file mode 100644
> index 000000000000..e72a928d4445
> --- /dev/null
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -0,0 +1,247 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Debug helper used to dump the stage-2 pagetables of the system and their
> + * associated permissions.
> + *
> + * Copyright (C) Google, 2024
> + * Author: Sebastian Ene <sebastianene@google.com>
> + */
> +#include <linux/debugfs.h>
> +#include <linux/kvm_host.h>
> +#include <linux/seq_file.h>
> +
> +#include <asm/kvm_pgtable.h>
> +#include <asm/kvm_host.h>

nit: I believe you wanted to follow the alphabetical order, if that is the case,
kvm_host.h then kvm_pgtable.h

> +#include <asm/ptdump.h>
> +
> +

nit: don't think double empty are a rule, I would remove it.

> +#define MARKERS_LEN		(2)

nit: The brackets are not necessary for MARKERS_LEN.

> +#define KVM_PGTABLE_MAX_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
> +
> +struct kvm_ptdump_guest_state {
> +	struct kvm		*kvm;
> +	struct ptdump_pg_state	parser_state;
> +	struct addr_marker	ipa_marker[MARKERS_LEN];
> +	struct ptdump_pg_level	level[KVM_PGTABLE_MAX_LEVELS];
> +	struct ptdump_range	range[MARKERS_LEN];
> +};
> +
> +static const struct ptdump_prot_bits stage2_pte_bits[] = {
> +	{
> +		.mask	= PTE_VALID,
> +		.val	= PTE_VALID,
> +		.set	= " ",
> +		.clear	= "F",

This is effectively never used because an invalid PTE is 0 and note_page() won't
print it. This probably can be removed?

> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> +		.set	= "R",
> +		.clear	= " ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> +		.set	= "W",
> +		.clear	= " ",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> +		.val	= PTE_VALID,
> +		.set	= " ",
> +		.clear	= "X",
> +	}, {
> +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> +		.set	= "AF",
> +		.clear	= "  ",
> +	}, {
> +		.mask	= PTE_TABLE_BIT | PTE_VALID,
> +		.val	= PTE_VALID,
> +		.set	= "BLK",
> +		.clear	= "   ",
> +	},
> +};
> +
> +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> +			      enum kvm_pgtable_walk_flags visit)
> +{
> +	struct ptdump_pg_state *st = ctx->arg;
> +	struct ptdump_state *pt_st = &st->ptdump;
> +
> +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> +
> +	return 0;
> +}
> +
> +static int kvm_ptdump_build_levels(struct ptdump_pg_level *level, u32 start_lvl)
> +{
> +	u32 i;
> +	u64 mask;
> +
> +	if (WARN_ON_ONCE(start_lvl >= KVM_PGTABLE_LAST_LEVEL))
> +		return -EINVAL;
> +
> +	mask = 0;
> +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> +		mask |= stage2_pte_bits[i].mask;
> +
> +	for (i = start_lvl; i < KVM_PGTABLE_MAX_LEVELS; i++) {
> +		snprintf(level[i].name, sizeof(level[i].name), "%d", i);

%u, i being unsigned.

> +
> +		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
> +		level[i].bits	= stage2_pte_bits;
> +		level[i].mask	= mask;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm)
> +{
> +	struct kvm_ptdump_guest_state *st;
> +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> +	struct kvm_pgtable *pgtable = mmu->pgt;
> +	int ret;
> +
> +	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
> +	if (!st)
> +		return ERR_PTR(-ENOMEM);
> +
> +	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
> +	if (ret) {
> +		kfree(st);
> +		return ERR_PTR(ret);
> +	}
> +
> +	st->ipa_marker[0].name		= "Guest IPA";
> +	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
> +	st->range[0].end		= BIT(pgtable->ia_bits);
> +
> +	st->kvm				= kvm;
> +	st->parser_state = (struct ptdump_pg_state) {
> +		.marker		= &st->ipa_marker[0],
> +		.level		= -1,
> +		.pg_level	= &st->level[0],
> +		.ptdump.range	= &st->range[0],
> +		.start_address	= 0,
> +	};
> +
> +	return st;
> +}
> +
> +static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)
> +{
> +	int ret;
> +	struct kvm_ptdump_guest_state *st = m->private;
> +	struct kvm *kvm = st->kvm;
> +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> +	struct ptdump_pg_state *parser_state = &st->parser_state;
> +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> +		.cb	= kvm_ptdump_visitor,
> +		.arg	= parser_state,
> +		.flags	= KVM_PGTABLE_WALK_LEAF,
> +	};
> +
> +	parser_state->seq = m;
> +
> +	write_lock(&kvm->mmu_lock);
> +	ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker);
> +	write_unlock(&kvm->mmu_lock);
> +
> +	return ret;
> +}
> +
> +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> +{
> +	struct kvm *kvm = m->i_private;
> +	struct kvm_ptdump_guest_state *st;
> +	int ret;
> +
> +	if (!kvm_get_kvm_safe(kvm))
> +		return -ENOENT;
> +
> +	st = kvm_ptdump_parser_create(kvm);
> +	if (IS_ERR(st)) {
> +		ret = PTR_ERR(st);
> +		goto free_with_kvm_ref;
> +	}
> +
> +	ret = single_open(file, kvm_ptdump_guest_show, st);
> +	if (!ret)
> +		return 0;
> +
> +	kfree(st);
> +free_with_kvm_ref:

nit: I believe kfree understands IS_ERR() so you could have a simple "err:"
label covering all the error path.

> +	kvm_put_kvm(kvm);
> +	return ret;
> +}
> +
> +static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
> +{
> +	struct kvm *kvm = m->i_private;
> +	void *st = ((struct seq_file *)file->private_data)->private;
> +
> +	kfree(st);
> +	kvm_put_kvm(kvm);
> +
> +	return single_release(m, file);
> +}
> +
> +static const struct file_operations kvm_ptdump_guest_fops = {
> +	.open		= kvm_ptdump_guest_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= kvm_ptdump_guest_close,
> +};
> +
> +static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
> +{
> +	const struct file *file = m->file;
> +	struct kvm_pgtable *pgtable = m->private;
> +
> +	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
> +		seq_printf(m, "%2u\n", pgtable->ia_bits);
> +	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
> +		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);

nit: KVM_PGTABLE_MAX_LEVELS - pgtable->start_level ?

> +	return 0;
> +}
> +
> +static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
> +{
> +	struct kvm *kvm = m->i_private;
> +	struct kvm_pgtable *pgtable;
> +	int ret;
> +
> +	if (!kvm_get_kvm_safe(kvm))
> +		return -ENOENT;
> +
> +	pgtable = kvm->arch.mmu.pgt;
> +
> +	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
> +	if (ret < 0)
> +		kvm_put_kvm(kvm);
> +	return ret;
> +}
> +
> +static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
> +{
> +	struct kvm *kvm = m->i_private;
> +
> +	kvm_put_kvm(kvm);
> +	return single_release(m, file);
> +}
> +
> +static const struct file_operations kvm_pgtable_debugfs_fops = {
> +	.open		= kvm_pgtable_debugfs_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= kvm_pgtable_debugfs_close,
> +};
> +
> +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
> +{
> +	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
> +			    kvm, &kvm_ptdump_guest_fops);
> +	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
> +			    &kvm_pgtable_debugfs_fops);
> +	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
> +			    kvm, &kvm_pgtable_debugfs_fops);
> +}
> -- 
> 2.46.0.295.g3b9ea8a38a-goog
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 5/5] KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config
  2024-08-27  8:45 ` [PATCH v9 5/5] KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config Sebastian Ene
@ 2024-08-30 10:26   ` Vincent Donnefort
  0 siblings, 0 replies; 20+ messages in thread
From: Vincent Donnefort @ 2024-08-30 10:26 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Tue, Aug 27, 2024 at 08:45:48AM +0000, Sebastian Ene wrote:
> When this config is enabled, it exposes the stage-2 pagetable layout
> through a debugfs file.
> 
> Signed-off-by: Sebastian Ene <sebastianene@google.com>

It doesn't feel like having a separated patch for Kconfig brings anything and
I would have squashed it with the previous change.

Otherwise:

Reviewed-by: Vincent Donnefort <vdonnefort@google.com>

> ---
>  arch/arm64/kvm/Kconfig | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
> index 8304eb342be9..ead632ad01b4 100644
> --- a/arch/arm64/kvm/Kconfig
> +++ b/arch/arm64/kvm/Kconfig
> @@ -66,4 +66,21 @@ config PROTECTED_NVHE_STACKTRACE
>  
>  	  If unsure, or not using protected nVHE (pKVM), say N.
>  
> +config PTDUMP_STAGE2_DEBUGFS
> +	bool "Present the stage-2 pagetables to debugfs"
> +	depends on KVM
> +	depends on DEBUG_KERNEL
> +	depends on DEBUG_FS
> +	depends on GENERIC_PTDUMP
> +	select PTDUMP_CORE
> +	default n
> +	help
> +	  Say Y here if you want to show the stage-2 kernel pagetables
> +	  layout in a debugfs file. This information is only useful for kernel developers
> +	  who are working in architecture specific areas of the kernel.
> +	  It is probably not a good idea to enable this feature in a production
> +	  kernel.
> +
> +	  If in doubt, say N.
> +
>  endif # VIRTUALIZATION
> -- 
> 2.46.0.295.g3b9ea8a38a-goog
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality
  2024-08-27  8:45 ` [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality Sebastian Ene
@ 2024-08-30 12:28   ` Marc Zyngier
  2024-09-02  5:36     ` Sebastian Ene
  0 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2024-08-30 12:28 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Tue, 27 Aug 2024 09:45:45 +0100,
Sebastian Ene <sebastianene@google.com> wrote:
> 
> Reuse the descriptor parsing functionality to keep the same output format
> as the original ptdump code.

This sentence seems either out of place or missing something, because
this change it not reusing anything...

> In order for this to happen, move the state
> tracking objects into a common header.

... but instead doing this ^^^.

I propose to rewrite the commit message as:

"Adding a new page-table dumper for stage-2 requires parsing the page
tables, and reusing the descriptor parsing functionality would help
keeping the same output format as the original ptdump code.

In order for this to happen, move the state tracking object
definitions into a common header."

Shout if you object to it!

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-08-30 10:24   ` Vincent Donnefort
@ 2024-08-30 14:11     ` Marc Zyngier
  2024-09-02  5:27       ` Sebastian Ene
  2024-09-02 11:13       ` Vincent Donnefort
  2024-09-02  5:31     ` Sebastian Ene
  1 sibling, 2 replies; 20+ messages in thread
From: Marc Zyngier @ 2024-08-30 14:11 UTC (permalink / raw)
  To: Vincent Donnefort, Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, mark.rutland, oliver.upton, rananta, ryan.roberts,
	shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Fri, 30 Aug 2024 11:24:53 +0100,
Vincent Donnefort <vdonnefort@google.com> wrote:
> 
> Hi Seb,
> 
> Thanks for the respin.
> 
> On Tue, Aug 27, 2024 at 08:45:47AM +0000, Sebastian Ene wrote:
> > While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> > introduce KVM/ptdump to show the guest stage-2 pagetables. The
> > separation is necessary because most of the definitions from the
> > stage-2 pagetable reside in the KVM path and we will be invoking
> > functionality specific to KVM.
> > 
> > When a guest is created, register a new file entry under the guest
> > debugfs dir which allows userspace to show the contents of the guest
> > stage-2 pagetables when accessed.
> > 
> > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> 
> I only have some nits, otherwise:
> 
> Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> 
> > ---
> >  arch/arm64/include/asm/kvm_host.h |   6 +
> >  arch/arm64/kvm/Makefile           |   1 +
> >  arch/arm64/kvm/arm.c              |   1 +
> >  arch/arm64/kvm/ptdump.c           | 247 ++++++++++++++++++++++++++++++
> >  4 files changed, 255 insertions(+)
> >  create mode 100644 arch/arm64/kvm/ptdump.c
> > 
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index a33f5996ca9f..4acd589f086b 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -1473,4 +1473,10 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
> >  		(pa + pi + pa3) == 1;					\
> >  	})
> >  
> > +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> > +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
> > +#else
> > +static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
> > +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> > +
> >  #endif /* __ARM64_KVM_HOST_H__ */
> > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> > index 86a629aaf0a1..e4233b323a73 100644
> > --- a/arch/arm64/kvm/Makefile
> > +++ b/arch/arm64/kvm/Makefile
> > @@ -27,6 +27,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
> >  
> >  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
> >  kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
> > +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
> >  
> >  always-y := hyp_constants.h hyp-constants.s
> >  
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 9bef7638342e..b9fd928d3477 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -228,6 +228,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> >  void kvm_arch_create_vm_debugfs(struct kvm *kvm)
> >  {
> >  	kvm_sys_regs_create_debugfs(kvm);
> > +	kvm_s2_ptdump_create_debugfs(kvm);
> >  }
> >  
> >  static void kvm_destroy_mpidr_data(struct kvm *kvm)
> > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> > new file mode 100644
> > index 000000000000..e72a928d4445
> > --- /dev/null
> > +++ b/arch/arm64/kvm/ptdump.c
> > @@ -0,0 +1,247 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Debug helper used to dump the stage-2 pagetables of the system and their
> > + * associated permissions.
> > + *
> > + * Copyright (C) Google, 2024
> > + * Author: Sebastian Ene <sebastianene@google.com>
> > + */
> > +#include <linux/debugfs.h>
> > +#include <linux/kvm_host.h>
> > +#include <linux/seq_file.h>
> > +
> > +#include <asm/kvm_pgtable.h>
> > +#include <asm/kvm_host.h>
> 
> nit: I believe you wanted to follow the alphabetical order, if that is the case,
> kvm_host.h then kvm_pgtable.h
> 
> > +#include <asm/ptdump.h>
> > +
> > +
> 
> nit: don't think double empty are a rule, I would remove it.
> 
> > +#define MARKERS_LEN		(2)
> 
> nit: The brackets are not necessary for MARKERS_LEN.
> 
> > +#define KVM_PGTABLE_MAX_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
> > +
> > +struct kvm_ptdump_guest_state {
> > +	struct kvm		*kvm;
> > +	struct ptdump_pg_state	parser_state;
> > +	struct addr_marker	ipa_marker[MARKERS_LEN];
> > +	struct ptdump_pg_level	level[KVM_PGTABLE_MAX_LEVELS];
> > +	struct ptdump_range	range[MARKERS_LEN];
> > +};
> > +
> > +static const struct ptdump_prot_bits stage2_pte_bits[] = {
> > +	{
> > +		.mask	= PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= " ",
> > +		.clear	= "F",
> 
> This is effectively never used because an invalid PTE is 0 and note_page() won't
> print it. This probably can be removed?

Yeah, I can't see how we are going to trigger that one given that
PTE_VALID must be set, and that we only print something if the bit is
clear.

Seb?

>
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > +		.set	= "R",
> > +		.clear	= " ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > +		.set	= "W",
> > +		.clear	= " ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= " ",
> > +		.clear	= "X",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > +		.set	= "AF",
> > +		.clear	= "  ",
> > +	}, {
> > +		.mask	= PTE_TABLE_BIT | PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= "BLK",
> > +		.clear	= "   ",
> > +	},
> > +};
> > +
> > +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> > +			      enum kvm_pgtable_walk_flags visit)
> > +{
> > +	struct ptdump_pg_state *st = ctx->arg;
> > +	struct ptdump_state *pt_st = &st->ptdump;
> > +
> > +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> > +
> > +	return 0;
> > +}
> > +
> > +static int kvm_ptdump_build_levels(struct ptdump_pg_level *level, u32 start_lvl)
> > +{
> > +	u32 i;
> > +	u64 mask;
> > +
> > +	if (WARN_ON_ONCE(start_lvl >= KVM_PGTABLE_LAST_LEVEL))
> > +		return -EINVAL;
> > +
> > +	mask = 0;
> > +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> > +		mask |= stage2_pte_bits[i].mask;
> > +
> > +	for (i = start_lvl; i < KVM_PGTABLE_MAX_LEVELS; i++) {
> > +		snprintf(level[i].name, sizeof(level[i].name), "%d", i);
> 
> %u, i being unsigned.
> 
> > +
> > +		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
> > +		level[i].bits	= stage2_pte_bits;
> > +		level[i].mask	= mask;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm)
> > +{
> > +	struct kvm_ptdump_guest_state *st;
> > +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> > +	struct kvm_pgtable *pgtable = mmu->pgt;
> > +	int ret;
> > +
> > +	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
> > +	if (!st)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
> > +	if (ret) {
> > +		kfree(st);
> > +		return ERR_PTR(ret);
> > +	}
> > +
> > +	st->ipa_marker[0].name		= "Guest IPA";
> > +	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
> > +	st->range[0].end		= BIT(pgtable->ia_bits);
> > +
> > +	st->kvm				= kvm;
> > +	st->parser_state = (struct ptdump_pg_state) {
> > +		.marker		= &st->ipa_marker[0],
> > +		.level		= -1,
> > +		.pg_level	= &st->level[0],
> > +		.ptdump.range	= &st->range[0],
> > +		.start_address	= 0,
> > +	};
> > +
> > +	return st;
> > +}
> > +
> > +static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)
> > +{
> > +	int ret;
> > +	struct kvm_ptdump_guest_state *st = m->private;
> > +	struct kvm *kvm = st->kvm;
> > +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> > +	struct ptdump_pg_state *parser_state = &st->parser_state;
> > +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> > +		.cb	= kvm_ptdump_visitor,
> > +		.arg	= parser_state,
> > +		.flags	= KVM_PGTABLE_WALK_LEAF,
> > +	};
> > +
> > +	parser_state->seq = m;
> > +
> > +	write_lock(&kvm->mmu_lock);
> > +	ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker);
> > +	write_unlock(&kvm->mmu_lock);
> > +
> > +	return ret;
> > +}
> > +
> > +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +	struct kvm_ptdump_guest_state *st;
> > +	int ret;
> > +
> > +	if (!kvm_get_kvm_safe(kvm))
> > +		return -ENOENT;
> > +
> > +	st = kvm_ptdump_parser_create(kvm);
> > +	if (IS_ERR(st)) {
> > +		ret = PTR_ERR(st);
> > +		goto free_with_kvm_ref;
> > +	}
> > +
> > +	ret = single_open(file, kvm_ptdump_guest_show, st);
> > +	if (!ret)
> > +		return 0;
> > +
> > +	kfree(st);
> > +free_with_kvm_ref:
> 
> nit: I believe kfree understands IS_ERR() so you could have a simple "err:"
> label covering all the error path.

I couldn't find such handling in kfree(). Could you point be to it?

> 
> > +	kvm_put_kvm(kvm);
> > +	return ret;
> > +}
> > +
> > +static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +	void *st = ((struct seq_file *)file->private_data)->private;
> > +
> > +	kfree(st);
> > +	kvm_put_kvm(kvm);
> > +
> > +	return single_release(m, file);
> > +}
> > +
> > +static const struct file_operations kvm_ptdump_guest_fops = {
> > +	.open		= kvm_ptdump_guest_open,
> > +	.read		= seq_read,
> > +	.llseek		= seq_lseek,
> > +	.release	= kvm_ptdump_guest_close,
> > +};
> > +
> > +static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
> > +{
> > +	const struct file *file = m->file;
> > +	struct kvm_pgtable *pgtable = m->private;
> > +
> > +	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))

I really dislike this sort of construct, and I'd rather we pick the
correct callback by construction rather than relying on a string
comparison. See below for a suggestion.

> > +		seq_printf(m, "%2u\n", pgtable->ia_bits);
> > +	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
> > +		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
> 
> nit: KVM_PGTABLE_MAX_LEVELS - pgtable->start_level ?
> 
> > +	return 0;
> > +}
> > +
> > +static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +	struct kvm_pgtable *pgtable;
> > +	int ret;
> > +
> > +	if (!kvm_get_kvm_safe(kvm))
> > +		return -ENOENT;
> > +
> > +	pgtable = kvm->arch.mmu.pgt;
> > +
> > +	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
> > +	if (ret < 0)
> > +		kvm_put_kvm(kvm);
> > +	return ret;
> > +}
> > +
> > +static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +
> > +	kvm_put_kvm(kvm);
> > +	return single_release(m, file);
> > +}
> > +
> > +static const struct file_operations kvm_pgtable_debugfs_fops = {
> > +	.open		= kvm_pgtable_debugfs_open,
> > +	.read		= seq_read,
> > +	.llseek		= seq_lseek,
> > +	.release	= kvm_pgtable_debugfs_close,
> > +};
> > +
> > +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
> > +{
> > +	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
> > +			    kvm, &kvm_ptdump_guest_fops);
> > +	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
> > +			    &kvm_pgtable_debugfs_fops);
> > +	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
> > +			    kvm, &kvm_pgtable_debugfs_fops);
> > +}

I'd expect something like this instead:

diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
index e72a928d4445..c11ea355aa51 100644
--- a/arch/arm64/kvm/ptdump.c
+++ b/arch/arm64/kvm/ptdump.c
@@ -192,19 +191,24 @@ static const struct file_operations kvm_ptdump_guest_fops = {
 	.release	= kvm_ptdump_guest_close,
 };
 
-static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
+static int kvm_pgtable_range_show(struct seq_file *m, void *unused)
+{
+	struct kvm_pgtable *pgtable = m->private;
+
+	seq_printf(m, "%2u\n", pgtable->ia_bits);
+	return 0;
+}
+
+static int kvm_pgtable_levels_show(struct seq_file *m, void *unused)
 {
-	const struct file *file = m->file;
 	struct kvm_pgtable *pgtable = m->private;
 
-	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
-		seq_printf(m, "%2u\n", pgtable->ia_bits);
-	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
-		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
+	seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
 	return 0;
 }
 
-static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
+static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file,
+				    int (*show)(struct seq_file *, void *))
 {
 	struct kvm *kvm = m->i_private;
 	struct kvm_pgtable *pgtable;
@@ -215,12 +219,22 @@ static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
 
 	pgtable = kvm->arch.mmu.pgt;
 
-	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
+	ret = single_open(file, show, pgtable);
 	if (ret < 0)
 		kvm_put_kvm(kvm);
 	return ret;
 }
 
+static int kvm_pgtable_range_open(struct inode *m, struct file *file)
+{
+	return kvm_pgtable_debugfs_open(m, file, kvm_pgtable_range_show);
+}
+
+static int kvm_pgtable_levels_open(struct inode *m, struct file *file)
+{
+	return kvm_pgtable_debugfs_open(m, file, kvm_pgtable_levels_show);
+}
+
 static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
 {
 	struct kvm *kvm = m->i_private;
@@ -229,8 +243,15 @@ static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
 	return single_release(m, file);
 }
 
-static const struct file_operations kvm_pgtable_debugfs_fops = {
-	.open		= kvm_pgtable_debugfs_open,
+static const struct file_operations kvm_pgtable_range_fops = {
+	.open		= kvm_pgtable_range_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= kvm_pgtable_debugfs_close,
+};
+
+static const struct file_operations kvm_pgtable_levels_fops = {
+	.open		= kvm_pgtable_levels_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= kvm_pgtable_debugfs_close,
@@ -241,7 +262,7 @@ void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
 	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
 			    kvm, &kvm_ptdump_guest_fops);
 	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
-			    &kvm_pgtable_debugfs_fops);
+			    &kvm_pgtable_range_fops);
 	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
-			    kvm, &kvm_pgtable_debugfs_fops);
+			    kvm, &kvm_pgtable_levels_fops);
 }


Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables
  2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
                   ` (4 preceding siblings ...)
  2024-08-27  8:45 ` [PATCH v9 5/5] KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config Sebastian Ene
@ 2024-08-30 14:44 ` Marc Zyngier
  2024-08-30 15:00   ` Marc Zyngier
  5 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2024-08-30 14:44 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

Hi Seb,

On Tue, 27 Aug 2024 09:45:43 +0100,
Sebastian Ene <sebastianene@google.com> wrote:
> 
> Hi,
> 
> 
> This series extends the ptdump support to allow dumping the guest
> stage-2 pagetables. When CONFIG_PTDUMP_STAGE2_DEBUGFS is enabled, ptdump
> registers the new following files under debugfs:
> - /sys/debug/kvm/<guest_id>/stage2_page_tables
> - /sys/debug/kvm/<guest_id>/stage2_levels
> - /sys/debug/kvm/<guest_id>/ipa_range
> 
> This allows userspace tools (eg. cat) to dump the stage-2 pagetables by
> reading the 'stage2_page_tables' file.
> The output format has the following fields:
> <IPA range> <size> <level> <access permissions> <mem_attributes>
> 
> Below is the output of a guest stage-2 pagetable dump running under Qemu.
> After a VM is created, the following files are available:
> 
> # cat /sys/kernel/debug/kvm/256-4/stage2_levels 
> 4
> # cat /sys/kernel/debug/kvm/256-4/ipa_range 
> 44
> # cat /sys/kernel/debug/kvm/256-4/stage2_page_tables 
> ---[ Guest IPA ]---
> 0x0000000000000000-0x0000000001000000          16M 2
> 0x0000000001000000-0x0000000001020000         128K 3
> 0x0000000001020000-0x0000000001021000           4K 3   R W X AF    
> 0x0000000001021000-0x0000000001200000        1916K 3
> 0x0000000001200000-0x0000000040000000        1006M 2
> 0x0000000040000000-0x0000000080000000           1G 0
> 0x0000000080000000-0x0000000081200000          18M 2   R W   AF BLK
> 0x0000000081200000-0x0000000081a00000           8M 2   R W X AF BLK
> 0x0000000081a00000-0x0000000081c00000           2M 2   R W   AF BLK
> 0x0000000081c00000-0x0000000082200000           6M 2   R W X AF BLK
> 0x0000000082200000-0x0000000082400000           2M 2   R W   AF BLK
> 0x0000000082400000-0x0000000082800000           4M 2   R W X AF BLK
> 0x0000000082800000-0x0000000082a00000           2M 2   R W   AF BLK
> 0x0000000082a00000-0x0000000082c00000           2M 2
> 0x0000000082c00000-0x0000000083200000           6M 2   R W X AF BLK
> 0x0000000083200000-0x0000000083400000           2M 2
> 0x0000000083400000-0x0000000083a00000           6M 2   R W X AF BLK
> 0x0000000083a00000-0x000000008fe00000         196M 2
> 0x000000008fe00000-0x0000000090000000           2M 2   R W   AF BLK
> 0x0000000090000000-0x0000000099400000         148M 2
> 0x0000000099400000-0x0000000099600000           2M 2   R W X AF BLK
> 0x0000000099600000-0x000000009b600000          32M 2
> 0x000000009b600000-0x000000009be00000           8M 2   R W X AF BLK
> 0x000000009be00000-0x000000009c000000           2M 2   R W   AF BLK
> 0x000000009c000000-0x00000000c0000000         576M 2

I've been giving this a go on my test systems with 16k pages, and it
doesn't really work as advertised:

root@babette:/sys/kernel/debug/kvm# cat 2573-13/stage2_*
2
---[ Guest IPA ]---
0x0000000000000000-0x0000000008000000         128M 
0x0000000008000000-0x00000000090a0000       17024K 3
0x00000000090a0000-0x00000000090a4000          16K 3   R W X AF    
0x00000000090a4000-0x000000000a000000       15728K 3

Only 16kB mapped? This is a full Linux guest running the Debian
installer, and just the kernel is about 20MB (the VM has 4GB of RAM,
and is using QEMU as the VMM)

So clearly something isn't playing as expected. Also, this '128M'
without a level being displayed makes me wonder. It is probably the
QEMU flash, but then the rest of the addresses don't make much sense
(RAM on QEMU is at 1GB, not at 128MB.

On another system with kvmtool, I get something similar:

root@duodenum:/home/maz# cat /sys/kernel/debug/kvm/*/stage2_*
2
---[ Guest IPA ]---
0x0000000000000000-0x0000000001020000       16512K 3
0x0000000001020000-0x0000000001024000          16K 3   R W X AF    
0x0000000001024000-0x0000000002000000       16240K 3

and kvmtool places the RAM at 2GB. Clearly not what we're seeing here.

Could you please verify this?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables
  2024-08-30 14:44 ` [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Marc Zyngier
@ 2024-08-30 15:00   ` Marc Zyngier
  2024-09-02  6:11     ` Sebastian Ene
  0 siblings, 1 reply; 20+ messages in thread
From: Marc Zyngier @ 2024-08-30 15:00 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Fri, 30 Aug 2024 15:44:39 +0100,
Marc Zyngier <maz@kernel.org> wrote:
> 
> Hi Seb,

[...]

> I've been giving this a go on my test systems with 16k pages, and it
> doesn't really work as advertised:
> 
> root@babette:/sys/kernel/debug/kvm# cat 2573-13/stage2_*
> 2
> ---[ Guest IPA ]---
> 0x0000000000000000-0x0000000008000000         128M 
> 0x0000000008000000-0x00000000090a0000       17024K 3
> 0x00000000090a0000-0x00000000090a4000          16K 3   R W X AF    
> 0x00000000090a4000-0x000000000a000000       15728K 3
> 
> Only 16kB mapped? This is a full Linux guest running the Debian
> installer, and just the kernel is about 20MB (the VM has 4GB of RAM,
> and is using QEMU as the VMM)
> 
> So clearly something isn't playing as expected. Also, this '128M'
> without a level being displayed makes me wonder. It is probably the
> QEMU flash, but then the rest of the addresses don't make much sense
> (RAM on QEMU is at 1GB, not at 128MB.
> 
> On another system with kvmtool, I get something similar:
> 
> root@duodenum:/home/maz# cat /sys/kernel/debug/kvm/*/stage2_*
> 2
> ---[ Guest IPA ]---
> 0x0000000000000000-0x0000000001020000       16512K 3
> 0x0000000001020000-0x0000000001024000          16K 3   R W X AF    
> 0x0000000001024000-0x0000000002000000       16240K 3
> 
> and kvmtool places the RAM at 2GB. Clearly not what we're seeing here.
> 
> Could you please verify this?

For the record, on a 4kB host, I get much more plausible results:

root@big-leg-emma:/home/maz# cat /sys/kernel/debug/kvm/632-12/stage2_*
3
---[ Guest IPA ]---
0x0000000000000000-0x0000000000200000           2M 2   R     AF BLK
0x0000000000200000-0x0000000040000000        1022M 2
0x0000000040000000-0x0000000040200000           2M 2   R W X AF BLK
0x0000000040200000-0x0000000044000000          62M 2
0x0000000044000000-0x0000000044200000           2M 2   R W X AF BLK
0x0000000044200000-0x0000000047600000          52M 2
0x0000000047600000-0x0000000047800000           2M 2   R W   AF BLK
0x0000000047800000-0x0000000047e00000           6M 2   R W X AF BLK
0x0000000047e00000-0x0000000048000000           2M 2   R W   AF BLK
0x0000000048000000-0x00000000b9c00000        1820M 2
0x00000000b9c00000-0x00000000b9e00000           2M 2   R W X AF BLK
0x00000000b9e00000-0x00000000bb800000          26M 2
0x00000000bb800000-0x00000000bba00000           2M 2   R W X AF BLK
0x00000000bba00000-0x00000000bbe00000           4M 2   R W   AF BLK
0x00000000bbe00000-0x00000000bc200000           4M 2   R W X AF BLK
0x00000000bc200000-0x00000000bc800000           6M 2   R W   AF BLK
0x00000000bc800000-0x00000000be400000          28M 2
0x00000000be400000-0x00000000bf800000          20M 2   R W X AF BLK
0x00000000bf800000-0x00000000bfe00000           6M 2   R W   AF BLK
0x00000000bfe00000-0x00000000c0000000           2M 2   R W X AF BLK

So 16kB is the one that needs investigating, and I strongly suspect
that 64kB is in the same boat...

Thanks,

	M. (signing off for the day)

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-08-30 14:11     ` Marc Zyngier
@ 2024-09-02  5:27       ` Sebastian Ene
  2024-09-02 11:13       ` Vincent Donnefort
  1 sibling, 0 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-09-02  5:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Vincent Donnefort, akpm, alexghiti, ankita, ardb, catalin.marinas,
	christophe.leroy, james.morse, mark.rutland, oliver.upton,
	rananta, ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui,
	kvmarm, linux-arm-kernel, linux-kernel, kernel-team

On Fri, Aug 30, 2024 at 03:11:34PM +0100, Marc Zyngier wrote:
> On Fri, 30 Aug 2024 11:24:53 +0100,
> Vincent Donnefort <vdonnefort@google.com> wrote:
> > 
> > Hi Seb,
> > 
> > Thanks for the respin.
> > 
> > On Tue, Aug 27, 2024 at 08:45:47AM +0000, Sebastian Ene wrote:
> > > While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> > > introduce KVM/ptdump to show the guest stage-2 pagetables. The
> > > separation is necessary because most of the definitions from the
> > > stage-2 pagetable reside in the KVM path and we will be invoking
> > > functionality specific to KVM.
> > > 
> > > When a guest is created, register a new file entry under the guest
> > > debugfs dir which allows userspace to show the contents of the guest
> > > stage-2 pagetables when accessed.
> > > 
> > > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> > 
> > I only have some nits, otherwise:
> > 
> > Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> > 
> > > ---
> > >  arch/arm64/include/asm/kvm_host.h |   6 +
> > >  arch/arm64/kvm/Makefile           |   1 +
> > >  arch/arm64/kvm/arm.c              |   1 +
> > >  arch/arm64/kvm/ptdump.c           | 247 ++++++++++++++++++++++++++++++
> > >  4 files changed, 255 insertions(+)
> > >  create mode 100644 arch/arm64/kvm/ptdump.c
> > > 
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index a33f5996ca9f..4acd589f086b 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -1473,4 +1473,10 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
> > >  		(pa + pi + pa3) == 1;					\
> > >  	})
> > >  
> > > +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> > > +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
> > > +#else
> > > +static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
> > > +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> > > +
> > >  #endif /* __ARM64_KVM_HOST_H__ */
> > > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> > > index 86a629aaf0a1..e4233b323a73 100644
> > > --- a/arch/arm64/kvm/Makefile
> > > +++ b/arch/arm64/kvm/Makefile
> > > @@ -27,6 +27,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
> > >  
> > >  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
> > >  kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
> > > +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
> > >  
> > >  always-y := hyp_constants.h hyp-constants.s
> > >  
> > > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > > index 9bef7638342e..b9fd928d3477 100644
> > > --- a/arch/arm64/kvm/arm.c
> > > +++ b/arch/arm64/kvm/arm.c
> > > @@ -228,6 +228,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> > >  void kvm_arch_create_vm_debugfs(struct kvm *kvm)
> > >  {
> > >  	kvm_sys_regs_create_debugfs(kvm);
> > > +	kvm_s2_ptdump_create_debugfs(kvm);
> > >  }
> > >  
> > >  static void kvm_destroy_mpidr_data(struct kvm *kvm)
> > > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> > > new file mode 100644
> > > index 000000000000..e72a928d4445
> > > --- /dev/null
> > > +++ b/arch/arm64/kvm/ptdump.c
> > > @@ -0,0 +1,247 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * Debug helper used to dump the stage-2 pagetables of the system and their
> > > + * associated permissions.
> > > + *
> > > + * Copyright (C) Google, 2024
> > > + * Author: Sebastian Ene <sebastianene@google.com>
> > > + */
> > > +#include <linux/debugfs.h>
> > > +#include <linux/kvm_host.h>
> > > +#include <linux/seq_file.h>
> > > +
> > > +#include <asm/kvm_pgtable.h>
> > > +#include <asm/kvm_host.h>
> > 
> > nit: I believe you wanted to follow the alphabetical order, if that is the case,
> > kvm_host.h then kvm_pgtable.h
> > 
> > > +#include <asm/ptdump.h>
> > > +
> > > +
> > 
> > nit: don't think double empty are a rule, I would remove it.
> > 
> > > +#define MARKERS_LEN		(2)
> > 
> > nit: The brackets are not necessary for MARKERS_LEN.
> > 
> > > +#define KVM_PGTABLE_MAX_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
> > > +
> > > +struct kvm_ptdump_guest_state {
> > > +	struct kvm		*kvm;
> > > +	struct ptdump_pg_state	parser_state;
> > > +	struct addr_marker	ipa_marker[MARKERS_LEN];
> > > +	struct ptdump_pg_level	level[KVM_PGTABLE_MAX_LEVELS];
> > > +	struct ptdump_range	range[MARKERS_LEN];
> > > +};
> > > +
> > > +static const struct ptdump_prot_bits stage2_pte_bits[] = {
> > > +	{
> > > +		.mask	= PTE_VALID,
> > > +		.val	= PTE_VALID,
> > > +		.set	= " ",
> > > +		.clear	= "F",
> > 
> > This is effectively never used because an invalid PTE is 0 and note_page() won't
> > print it. This probably can be removed?
> 
> Yeah, I can't see how we are going to trigger that one given that
> PTE_VALID must be set, and that we only print something if the bit is
> clear.
> 
> Seb?

When (pte_prot & mask == val) we print .set (which is empty), otherwise we
print .clear (This is from dump_prot). Invalid non-zero PTEs should be
printed in this case.

> 
> >
> > > +	}, {
> > > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > > +		.set	= "R",
> > > +		.clear	= " ",
> > > +	}, {
> > > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > > +		.set	= "W",
> > > +		.clear	= " ",
> > > +	}, {
> > > +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> > > +		.val	= PTE_VALID,
> > > +		.set	= " ",
> > > +		.clear	= "X",
> > > +	}, {
> > > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > > +		.set	= "AF",
> > > +		.clear	= "  ",
> > > +	}, {
> > > +		.mask	= PTE_TABLE_BIT | PTE_VALID,
> > > +		.val	= PTE_VALID,
> > > +		.set	= "BLK",
> > > +		.clear	= "   ",
> > > +	},
> > > +};
> > > +
> > > +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> > > +			      enum kvm_pgtable_walk_flags visit)
> > > +{
> > > +	struct ptdump_pg_state *st = ctx->arg;
> > > +	struct ptdump_state *pt_st = &st->ptdump;
> > > +
> > > +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int kvm_ptdump_build_levels(struct ptdump_pg_level *level, u32 start_lvl)
> > > +{
> > > +	u32 i;
> > > +	u64 mask;
> > > +
> > > +	if (WARN_ON_ONCE(start_lvl >= KVM_PGTABLE_LAST_LEVEL))
> > > +		return -EINVAL;
> > > +
> > > +	mask = 0;
> > > +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> > > +		mask |= stage2_pte_bits[i].mask;
> > > +
> > > +	for (i = start_lvl; i < KVM_PGTABLE_MAX_LEVELS; i++) {
> > > +		snprintf(level[i].name, sizeof(level[i].name), "%d", i);
> > 
> > %u, i being unsigned.
> > 
> > > +
> > > +		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
> > > +		level[i].bits	= stage2_pte_bits;
> > > +		level[i].mask	= mask;
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm)
> > > +{
> > > +	struct kvm_ptdump_guest_state *st;
> > > +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> > > +	struct kvm_pgtable *pgtable = mmu->pgt;
> > > +	int ret;
> > > +
> > > +	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
> > > +	if (!st)
> > > +		return ERR_PTR(-ENOMEM);
> > > +
> > > +	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
> > > +	if (ret) {
> > > +		kfree(st);
> > > +		return ERR_PTR(ret);
> > > +	}
> > > +
> > > +	st->ipa_marker[0].name		= "Guest IPA";
> > > +	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
> > > +	st->range[0].end		= BIT(pgtable->ia_bits);
> > > +
> > > +	st->kvm				= kvm;
> > > +	st->parser_state = (struct ptdump_pg_state) {
> > > +		.marker		= &st->ipa_marker[0],
> > > +		.level		= -1,
> > > +		.pg_level	= &st->level[0],
> > > +		.ptdump.range	= &st->range[0],
> > > +		.start_address	= 0,
> > > +	};
> > > +
> > > +	return st;
> > > +}
> > > +
> > > +static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)
> > > +{
> > > +	int ret;
> > > +	struct kvm_ptdump_guest_state *st = m->private;
> > > +	struct kvm *kvm = st->kvm;
> > > +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> > > +	struct ptdump_pg_state *parser_state = &st->parser_state;
> > > +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> > > +		.cb	= kvm_ptdump_visitor,
> > > +		.arg	= parser_state,
> > > +		.flags	= KVM_PGTABLE_WALK_LEAF,
> > > +	};
> > > +
> > > +	parser_state->seq = m;
> > > +
> > > +	write_lock(&kvm->mmu_lock);
> > > +	ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker);
> > > +	write_unlock(&kvm->mmu_lock);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> > > +{
> > > +	struct kvm *kvm = m->i_private;
> > > +	struct kvm_ptdump_guest_state *st;
> > > +	int ret;
> > > +
> > > +	if (!kvm_get_kvm_safe(kvm))
> > > +		return -ENOENT;
> > > +
> > > +	st = kvm_ptdump_parser_create(kvm);
> > > +	if (IS_ERR(st)) {
> > > +		ret = PTR_ERR(st);
> > > +		goto free_with_kvm_ref;
> > > +	}
> > > +
> > > +	ret = single_open(file, kvm_ptdump_guest_show, st);
> > > +	if (!ret)
> > > +		return 0;
> > > +
> > > +	kfree(st);
> > > +free_with_kvm_ref:
> > 
> > nit: I believe kfree understands IS_ERR() so you could have a simple "err:"
> > label covering all the error path.
> 
> I couldn't find such handling in kfree(). Could you point be to it?
> 
> > 
> > > +	kvm_put_kvm(kvm);
> > > +	return ret;
> > > +}
> > > +
> > > +static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
> > > +{
> > > +	struct kvm *kvm = m->i_private;
> > > +	void *st = ((struct seq_file *)file->private_data)->private;
> > > +
> > > +	kfree(st);
> > > +	kvm_put_kvm(kvm);
> > > +
> > > +	return single_release(m, file);
> > > +}
> > > +
> > > +static const struct file_operations kvm_ptdump_guest_fops = {
> > > +	.open		= kvm_ptdump_guest_open,
> > > +	.read		= seq_read,
> > > +	.llseek		= seq_lseek,
> > > +	.release	= kvm_ptdump_guest_close,
> > > +};
> > > +
> > > +static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
> > > +{
> > > +	const struct file *file = m->file;
> > > +	struct kvm_pgtable *pgtable = m->private;
> > > +
> > > +	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
> 
> I really dislike this sort of construct, and I'd rather we pick the
> correct callback by construction rather than relying on a string
> comparison. See below for a suggestion.
> 

Thanks for the feedback and for the suggestion. Let me try to re-write
this as indicated.

> > > +		seq_printf(m, "%2u\n", pgtable->ia_bits);
> > > +	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
> > > +		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
> > 
> > nit: KVM_PGTABLE_MAX_LEVELS - pgtable->start_level ?
> > 
> > > +	return 0;
> > > +}
> > > +
> > > +static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
> > > +{
> > > +	struct kvm *kvm = m->i_private;
> > > +	struct kvm_pgtable *pgtable;
> > > +	int ret;
> > > +
> > > +	if (!kvm_get_kvm_safe(kvm))
> > > +		return -ENOENT;
> > > +
> > > +	pgtable = kvm->arch.mmu.pgt;
> > > +
> > > +	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
> > > +	if (ret < 0)
> > > +		kvm_put_kvm(kvm);
> > > +	return ret;
> > > +}
> > > +
> > > +static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
> > > +{
> > > +	struct kvm *kvm = m->i_private;
> > > +
> > > +	kvm_put_kvm(kvm);
> > > +	return single_release(m, file);
> > > +}
> > > +
> > > +static const struct file_operations kvm_pgtable_debugfs_fops = {
> > > +	.open		= kvm_pgtable_debugfs_open,
> > > +	.read		= seq_read,
> > > +	.llseek		= seq_lseek,
> > > +	.release	= kvm_pgtable_debugfs_close,
> > > +};
> > > +
> > > +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
> > > +{
> > > +	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
> > > +			    kvm, &kvm_ptdump_guest_fops);
> > > +	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
> > > +			    &kvm_pgtable_debugfs_fops);
> > > +	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
> > > +			    kvm, &kvm_pgtable_debugfs_fops);
> > > +}
> 
> I'd expect something like this instead:
> 
> diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> index e72a928d4445..c11ea355aa51 100644
> --- a/arch/arm64/kvm/ptdump.c
> +++ b/arch/arm64/kvm/ptdump.c
> @@ -192,19 +191,24 @@ static const struct file_operations kvm_ptdump_guest_fops = {
>  	.release	= kvm_ptdump_guest_close,
>  };
>  
> -static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
> +static int kvm_pgtable_range_show(struct seq_file *m, void *unused)
> +{
> +	struct kvm_pgtable *pgtable = m->private;
> +
> +	seq_printf(m, "%2u\n", pgtable->ia_bits);
> +	return 0;
> +}
> +
> +static int kvm_pgtable_levels_show(struct seq_file *m, void *unused)
>  {
> -	const struct file *file = m->file;
>  	struct kvm_pgtable *pgtable = m->private;
>  
> -	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
> -		seq_printf(m, "%2u\n", pgtable->ia_bits);
> -	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
> -		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
> +	seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
>  	return 0;
>  }
>  
> -static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
> +static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file,
> +				    int (*show)(struct seq_file *, void *))
>  {
>  	struct kvm *kvm = m->i_private;
>  	struct kvm_pgtable *pgtable;
> @@ -215,12 +219,22 @@ static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
>  
>  	pgtable = kvm->arch.mmu.pgt;
>  
> -	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
> +	ret = single_open(file, show, pgtable);
>  	if (ret < 0)
>  		kvm_put_kvm(kvm);
>  	return ret;
>  }
>  
> +static int kvm_pgtable_range_open(struct inode *m, struct file *file)
> +{
> +	return kvm_pgtable_debugfs_open(m, file, kvm_pgtable_range_show);
> +}
> +
> +static int kvm_pgtable_levels_open(struct inode *m, struct file *file)
> +{
> +	return kvm_pgtable_debugfs_open(m, file, kvm_pgtable_levels_show);
> +}
> +
>  static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
>  {
>  	struct kvm *kvm = m->i_private;
> @@ -229,8 +243,15 @@ static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
>  	return single_release(m, file);
>  }
>  
> -static const struct file_operations kvm_pgtable_debugfs_fops = {
> -	.open		= kvm_pgtable_debugfs_open,
> +static const struct file_operations kvm_pgtable_range_fops = {
> +	.open		= kvm_pgtable_range_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= kvm_pgtable_debugfs_close,
> +};
> +
> +static const struct file_operations kvm_pgtable_levels_fops = {
> +	.open		= kvm_pgtable_levels_open,
>  	.read		= seq_read,
>  	.llseek		= seq_lseek,
>  	.release	= kvm_pgtable_debugfs_close,
> @@ -241,7 +262,7 @@ void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
>  	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
>  			    kvm, &kvm_ptdump_guest_fops);
>  	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
> -			    &kvm_pgtable_debugfs_fops);
> +			    &kvm_pgtable_range_fops);
>  	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
> -			    kvm, &kvm_pgtable_debugfs_fops);
> +			    kvm, &kvm_pgtable_levels_fops);
>  }
> 
> 
> Thanks,
> 
> 	M.
> 

Thanks,
Seb


> -- 
> Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-08-30 10:24   ` Vincent Donnefort
  2024-08-30 14:11     ` Marc Zyngier
@ 2024-09-02  5:31     ` Sebastian Ene
  1 sibling, 0 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-09-02  5:31 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, mark.rutland, maz, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Fri, Aug 30, 2024 at 11:24:53AM +0100, Vincent Donnefort wrote:
> Hi Seb,
> 
> Thanks for the respin.
> 
> On Tue, Aug 27, 2024 at 08:45:47AM +0000, Sebastian Ene wrote:
> > While arch/*/mem/ptdump handles the kernel pagetable dumping code,
> > introduce KVM/ptdump to show the guest stage-2 pagetables. The
> > separation is necessary because most of the definitions from the
> > stage-2 pagetable reside in the KVM path and we will be invoking
> > functionality specific to KVM.
> > 
> > When a guest is created, register a new file entry under the guest
> > debugfs dir which allows userspace to show the contents of the guest
> > stage-2 pagetables when accessed.
> > 
> > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> 
> I only have some nits, otherwise:

Hello Vincent,

> 
> Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> 

Thanks for giving me consistent feedback on the series. I will
incorporate your latest suggestions in my patch series and add the tag.

> > ---
> >  arch/arm64/include/asm/kvm_host.h |   6 +
> >  arch/arm64/kvm/Makefile           |   1 +
> >  arch/arm64/kvm/arm.c              |   1 +
> >  arch/arm64/kvm/ptdump.c           | 247 ++++++++++++++++++++++++++++++
> >  4 files changed, 255 insertions(+)
> >  create mode 100644 arch/arm64/kvm/ptdump.c
> > 
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index a33f5996ca9f..4acd589f086b 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -1473,4 +1473,10 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
> >  		(pa + pi + pa3) == 1;					\
> >  	})
> >  
> > +#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
> > +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
> > +#else
> > +static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
> > +#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
> > +
> >  #endif /* __ARM64_KVM_HOST_H__ */
> > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> > index 86a629aaf0a1..e4233b323a73 100644
> > --- a/arch/arm64/kvm/Makefile
> > +++ b/arch/arm64/kvm/Makefile
> > @@ -27,6 +27,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
> >  
> >  kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o pmu.o
> >  kvm-$(CONFIG_ARM64_PTR_AUTH)  += pauth.o
> > +kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) += ptdump.o
> >  
> >  always-y := hyp_constants.h hyp-constants.s
> >  
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 9bef7638342e..b9fd928d3477 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -228,6 +228,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> >  void kvm_arch_create_vm_debugfs(struct kvm *kvm)
> >  {
> >  	kvm_sys_regs_create_debugfs(kvm);
> > +	kvm_s2_ptdump_create_debugfs(kvm);
> >  }
> >  
> >  static void kvm_destroy_mpidr_data(struct kvm *kvm)
> > diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
> > new file mode 100644
> > index 000000000000..e72a928d4445
> > --- /dev/null
> > +++ b/arch/arm64/kvm/ptdump.c
> > @@ -0,0 +1,247 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Debug helper used to dump the stage-2 pagetables of the system and their
> > + * associated permissions.
> > + *
> > + * Copyright (C) Google, 2024
> > + * Author: Sebastian Ene <sebastianene@google.com>
> > + */
> > +#include <linux/debugfs.h>
> > +#include <linux/kvm_host.h>
> > +#include <linux/seq_file.h>
> > +
> > +#include <asm/kvm_pgtable.h>
> > +#include <asm/kvm_host.h>
> 
> nit: I believe you wanted to follow the alphabetical order, if that is the case,
> kvm_host.h then kvm_pgtable.h
> 
> > +#include <asm/ptdump.h>
> > +
> > +
> 
> nit: don't think double empty are a rule, I would remove it.
> 

Ack.

> > +#define MARKERS_LEN		(2)
> 
> nit: The brackets are not necessary for MARKERS_LEN.
> 
> > +#define KVM_PGTABLE_MAX_LEVELS	(KVM_PGTABLE_LAST_LEVEL + 1)
> > +
> > +struct kvm_ptdump_guest_state {
> > +	struct kvm		*kvm;
> > +	struct ptdump_pg_state	parser_state;
> > +	struct addr_marker	ipa_marker[MARKERS_LEN];
> > +	struct ptdump_pg_level	level[KVM_PGTABLE_MAX_LEVELS];
> > +	struct ptdump_range	range[MARKERS_LEN];
> > +};
> > +
> > +static const struct ptdump_prot_bits stage2_pte_bits[] = {
> > +	{
> > +		.mask	= PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= " ",
> > +		.clear	= "F",
> 
> This is effectively never used because an invalid PTE is 0 and note_page() won't
> print it. This probably can be removed?
> 

Please see my previous reply to this. I would keep it around as it
should print out non-zero invalid PTEs.

> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | PTE_VALID,
> > +		.set	= "R",
> > +		.clear	= " ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | PTE_VALID,
> > +		.set	= "W",
> > +		.clear	= " ",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_HI_S2_XN | PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= " ",
> > +		.clear	= "X",
> > +	}, {
> > +		.mask	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > +		.val	= KVM_PTE_LEAF_ATTR_LO_S2_AF | PTE_VALID,
> > +		.set	= "AF",
> > +		.clear	= "  ",
> > +	}, {
> > +		.mask	= PTE_TABLE_BIT | PTE_VALID,
> > +		.val	= PTE_VALID,
> > +		.set	= "BLK",
> > +		.clear	= "   ",
> > +	},
> > +};
> > +
> > +static int kvm_ptdump_visitor(const struct kvm_pgtable_visit_ctx *ctx,
> > +			      enum kvm_pgtable_walk_flags visit)
> > +{
> > +	struct ptdump_pg_state *st = ctx->arg;
> > +	struct ptdump_state *pt_st = &st->ptdump;
> > +
> > +	note_page(pt_st, ctx->addr, ctx->level, ctx->old);
> > +
> > +	return 0;
> > +}
> > +
> > +static int kvm_ptdump_build_levels(struct ptdump_pg_level *level, u32 start_lvl)
> > +{
> > +	u32 i;
> > +	u64 mask;
> > +
> > +	if (WARN_ON_ONCE(start_lvl >= KVM_PGTABLE_LAST_LEVEL))
> > +		return -EINVAL;
> > +
> > +	mask = 0;
> > +	for (i = 0; i < ARRAY_SIZE(stage2_pte_bits); i++)
> > +		mask |= stage2_pte_bits[i].mask;
> > +
> > +	for (i = start_lvl; i < KVM_PGTABLE_MAX_LEVELS; i++) {
> > +		snprintf(level[i].name, sizeof(level[i].name), "%d", i);
> 
> %u, i being unsigned.

Ack.

> 
> > +
> > +		level[i].num	= ARRAY_SIZE(stage2_pte_bits);
> > +		level[i].bits	= stage2_pte_bits;
> > +		level[i].mask	= mask;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm)
> > +{
> > +	struct kvm_ptdump_guest_state *st;
> > +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> > +	struct kvm_pgtable *pgtable = mmu->pgt;
> > +	int ret;
> > +
> > +	st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
> > +	if (!st)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
> > +	if (ret) {
> > +		kfree(st);
> > +		return ERR_PTR(ret);
> > +	}
> > +
> > +	st->ipa_marker[0].name		= "Guest IPA";
> > +	st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
> > +	st->range[0].end		= BIT(pgtable->ia_bits);
> > +
> > +	st->kvm				= kvm;
> > +	st->parser_state = (struct ptdump_pg_state) {
> > +		.marker		= &st->ipa_marker[0],
> > +		.level		= -1,
> > +		.pg_level	= &st->level[0],
> > +		.ptdump.range	= &st->range[0],
> > +		.start_address	= 0,
> > +	};
> > +
> > +	return st;
> > +}
> > +
> > +static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)
> > +{
> > +	int ret;
> > +	struct kvm_ptdump_guest_state *st = m->private;
> > +	struct kvm *kvm = st->kvm;
> > +	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
> > +	struct ptdump_pg_state *parser_state = &st->parser_state;
> > +	struct kvm_pgtable_walker walker = (struct kvm_pgtable_walker) {
> > +		.cb	= kvm_ptdump_visitor,
> > +		.arg	= parser_state,
> > +		.flags	= KVM_PGTABLE_WALK_LEAF,
> > +	};
> > +
> > +	parser_state->seq = m;
> > +
> > +	write_lock(&kvm->mmu_lock);
> > +	ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker);
> > +	write_unlock(&kvm->mmu_lock);
> > +
> > +	return ret;
> > +}
> > +
> > +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +	struct kvm_ptdump_guest_state *st;
> > +	int ret;
> > +
> > +	if (!kvm_get_kvm_safe(kvm))
> > +		return -ENOENT;
> > +
> > +	st = kvm_ptdump_parser_create(kvm);
> > +	if (IS_ERR(st)) {
> > +		ret = PTR_ERR(st);
> > +		goto free_with_kvm_ref;
> > +	}
> > +
> > +	ret = single_open(file, kvm_ptdump_guest_show, st);
> > +	if (!ret)
> > +		return 0;
> > +
> > +	kfree(st);
> > +free_with_kvm_ref:
> 
> nit: I believe kfree understands IS_ERR() so you could have a simple "err:"
> label covering all the error path.
> 
> > +	kvm_put_kvm(kvm);
> > +	return ret;
> > +}
> > +
> > +static int kvm_ptdump_guest_close(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +	void *st = ((struct seq_file *)file->private_data)->private;
> > +
> > +	kfree(st);
> > +	kvm_put_kvm(kvm);
> > +
> > +	return single_release(m, file);
> > +}
> > +
> > +static const struct file_operations kvm_ptdump_guest_fops = {
> > +	.open		= kvm_ptdump_guest_open,
> > +	.read		= seq_read,
> > +	.llseek		= seq_lseek,
> > +	.release	= kvm_ptdump_guest_close,
> > +};
> > +
> > +static int kvm_pgtable_debugfs_show(struct seq_file *m, void *unused)
> > +{
> > +	const struct file *file = m->file;
> > +	struct kvm_pgtable *pgtable = m->private;
> > +
> > +	if (!strcmp(file_dentry(file)->d_iname, "ipa_range"))
> > +		seq_printf(m, "%2u\n", pgtable->ia_bits);
> > +	else if (!strcmp(file_dentry(file)->d_iname, "stage2_levels"))
> > +		seq_printf(m, "%1d\n", KVM_PGTABLE_LAST_LEVEL - pgtable->start_level + 1);
> 
> nit: KVM_PGTABLE_MAX_LEVELS - pgtable->start_level ?

Yes, we can use this one.

> 
> > +	return 0;
> > +}
> > +
> > +static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +	struct kvm_pgtable *pgtable;
> > +	int ret;
> > +
> > +	if (!kvm_get_kvm_safe(kvm))
> > +		return -ENOENT;
> > +
> > +	pgtable = kvm->arch.mmu.pgt;
> > +
> > +	ret = single_open(file, kvm_pgtable_debugfs_show, pgtable);
> > +	if (ret < 0)
> > +		kvm_put_kvm(kvm);
> > +	return ret;
> > +}
> > +
> > +static int kvm_pgtable_debugfs_close(struct inode *m, struct file *file)
> > +{
> > +	struct kvm *kvm = m->i_private;
> > +
> > +	kvm_put_kvm(kvm);
> > +	return single_release(m, file);
> > +}
> > +
> > +static const struct file_operations kvm_pgtable_debugfs_fops = {
> > +	.open		= kvm_pgtable_debugfs_open,
> > +	.read		= seq_read,
> > +	.llseek		= seq_lseek,
> > +	.release	= kvm_pgtable_debugfs_close,
> > +};
> > +
> > +void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
> > +{
> > +	debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
> > +			    kvm, &kvm_ptdump_guest_fops);
> > +	debugfs_create_file("ipa_range", 0400, kvm->debugfs_dentry, kvm,
> > +			    &kvm_pgtable_debugfs_fops);
> > +	debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
> > +			    kvm, &kvm_pgtable_debugfs_fops);
> > +}
> > -- 
> > 2.46.0.295.g3b9ea8a38a-goog
> > 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality
  2024-08-30 12:28   ` Marc Zyngier
@ 2024-09-02  5:36     ` Sebastian Ene
  0 siblings, 0 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-09-02  5:36 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Fri, Aug 30, 2024 at 01:28:36PM +0100, Marc Zyngier wrote:
> On Tue, 27 Aug 2024 09:45:45 +0100,
> Sebastian Ene <sebastianene@google.com> wrote:
> > 
> > Reuse the descriptor parsing functionality to keep the same output format
> > as the original ptdump code.

Hello Mark,

> 
> This sentence seems either out of place or missing something, because
> this change it not reusing anything...
> 
> > In order for this to happen, move the state
> > tracking objects into a common header.
> 
> ... but instead doing this ^^^.
> 
> I propose to rewrite the commit message as:
> 
> "Adding a new page-table dumper for stage-2 requires parsing the page
> tables, and reusing the descriptor parsing functionality would help
> keeping the same output format as the original ptdump code.
> 
> In order for this to happen, move the state tracking object
> definitions into a common header."

Thanks for the feedback, I think the re-wording works much better and
I'll make use of it.

> 
> Shout if you object to it!
> 
> Thanks,
> 
> 	M.
>

Seb

> -- 
> Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables
  2024-08-30 15:00   ` Marc Zyngier
@ 2024-09-02  6:11     ` Sebastian Ene
  2024-09-02  7:08       ` Sebastian Ene
  0 siblings, 1 reply; 20+ messages in thread
From: Sebastian Ene @ 2024-09-02  6:11 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Fri, Aug 30, 2024 at 04:00:11PM +0100, Marc Zyngier wrote:
> On Fri, 30 Aug 2024 15:44:39 +0100,
> Marc Zyngier <maz@kernel.org> wrote:

Hello Marc,

> > 
> > Hi Seb,
> 
> [...]
> 
> > I've been giving this a go on my test systems with 16k pages, and it
> > doesn't really work as advertised:
> > 
> > root@babette:/sys/kernel/debug/kvm# cat 2573-13/stage2_*
> > 2
> > ---[ Guest IPA ]---
> > 0x0000000000000000-0x0000000008000000         128M 
> > 0x0000000008000000-0x00000000090a0000       17024K 3
> > 0x00000000090a0000-0x00000000090a4000          16K 3   R W X AF    
> > 0x00000000090a4000-0x000000000a000000       15728K 3
> > 
> > Only 16kB mapped? This is a full Linux guest running the Debian
> > installer, and just the kernel is about 20MB (the VM has 4GB of RAM,
> > and is using QEMU as the VMM)
> > 
> > So clearly something isn't playing as expected. Also, this '128M'
> > without a level being displayed makes me wonder. It is probably the
> > QEMU flash, but then the rest of the addresses don't make much sense
> > (RAM on QEMU is at 1GB, not at 128MB.
> > 
> > On another system with kvmtool, I get something similar:
> > 
> > root@duodenum:/home/maz# cat /sys/kernel/debug/kvm/*/stage2_*
> > 2
> > ---[ Guest IPA ]---
> > 0x0000000000000000-0x0000000001020000       16512K 3
> > 0x0000000001020000-0x0000000001024000          16K 3   R W X AF    
> > 0x0000000001024000-0x0000000002000000       16240K 3
> > 
> > and kvmtool places the RAM at 2GB. Clearly not what we're seeing here.
> > 
> > Could you please verify this?

Ughh, this doesn't look right. I will give it a spin with a different
granule, thanks for bringing me to attention. I will look first at
mm/ptdump.c if it works as intended.
 

> 
> For the record, on a 4kB host, I get much more plausible results:
> 
> root@big-leg-emma:/home/maz# cat /sys/kernel/debug/kvm/632-12/stage2_*
> 3
> ---[ Guest IPA ]---
> 0x0000000000000000-0x0000000000200000           2M 2   R     AF BLK
> 0x0000000000200000-0x0000000040000000        1022M 2
> 0x0000000040000000-0x0000000040200000           2M 2   R W X AF BLK
> 0x0000000040200000-0x0000000044000000          62M 2
> 0x0000000044000000-0x0000000044200000           2M 2   R W X AF BLK
> 0x0000000044200000-0x0000000047600000          52M 2
> 0x0000000047600000-0x0000000047800000           2M 2   R W   AF BLK
> 0x0000000047800000-0x0000000047e00000           6M 2   R W X AF BLK
> 0x0000000047e00000-0x0000000048000000           2M 2   R W   AF BLK
> 0x0000000048000000-0x00000000b9c00000        1820M 2
> 0x00000000b9c00000-0x00000000b9e00000           2M 2   R W X AF BLK
> 0x00000000b9e00000-0x00000000bb800000          26M 2
> 0x00000000bb800000-0x00000000bba00000           2M 2   R W X AF BLK
> 0x00000000bba00000-0x00000000bbe00000           4M 2   R W   AF BLK
> 0x00000000bbe00000-0x00000000bc200000           4M 2   R W X AF BLK
> 0x00000000bc200000-0x00000000bc800000           6M 2   R W   AF BLK
> 0x00000000bc800000-0x00000000be400000          28M 2
> 0x00000000be400000-0x00000000bf800000          20M 2   R W X AF BLK
> 0x00000000bf800000-0x00000000bfe00000           6M 2   R W   AF BLK
> 0x00000000bfe00000-0x00000000c0000000           2M 2   R W X AF BLK
> 
> So 16kB is the one that needs investigating, and I strongly suspect
> that 64kB is in the same boat...
> 
> Thanks,
> 
> 	M. (signing off for the day)
> 

Thanks,
Sebastian

> -- 
> Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables
  2024-09-02  6:11     ` Sebastian Ene
@ 2024-09-02  7:08       ` Sebastian Ene
  2024-09-02  8:22         ` Marc Zyngier
  0 siblings, 1 reply; 20+ messages in thread
From: Sebastian Ene @ 2024-09-02  7:08 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Mon, Sep 02, 2024 at 06:11:04AM +0000, Sebastian Ene wrote:
> On Fri, Aug 30, 2024 at 04:00:11PM +0100, Marc Zyngier wrote:
> > On Fri, 30 Aug 2024 15:44:39 +0100,
> > Marc Zyngier <maz@kernel.org> wrote:

Hello Marc,


I tried with a 16Kb host under VHE on Qemu starting a 4kb guest with
kvmtool:

root@seb-qemu-pkvm-host:~#  zcat /proc/config.gz | grep
"CONFIG_ARM64_[164K]*_PAGES=y"
CONFIG_ARM64_16K_PAGES=y
root@seb-qemu-pkvm-host:~# cat
/sys/kernel/debug/kvm/263-4/stage2*
2
---[ Guest IPA ]---
0x0000000000000000-0x0000000001020000       16512K 3
0x0000000001020000-0x0000000001024000          16K 3   R W X AF    
0x0000000001024000-0x0000000002000000       16240K 3
0x0000000002000000-0x0000000080000000        2016M 2
0x0000000080000000-0x0000000084000000          64M 2   R W   AF BLK
0x0000000084000000-0x000000008e000000         160M 2
0x000000008e000000-0x0000000090000000          32M 2   R W   AF BLK
0x0000000090000000-0x0000000098000000         128M 2
0x0000000098000000-0x000000009a000000          32M 2   R W X AF BLK
0x000000009a000000-0x000000009c000000          32M 2   R W   AF BLK

This looks quite right I guess and I wonder how can I repro what you are seeing ?
What kvm-arm.mode is the host running into ?

Thanks,
Seb

> 
> Hello Marc,
> 
> > > 
> > > Hi Seb,
> > 
> > [...]
> > 
> > > I've been giving this a go on my test systems with 16k pages, and it
> > > doesn't really work as advertised:
> > > 
> > > root@babette:/sys/kernel/debug/kvm# cat 2573-13/stage2_*
> > > 2
> > > ---[ Guest IPA ]---
> > > 0x0000000000000000-0x0000000008000000         128M 
> > > 0x0000000008000000-0x00000000090a0000       17024K 3
> > > 0x00000000090a0000-0x00000000090a4000          16K 3   R W X AF    
> > > 0x00000000090a4000-0x000000000a000000       15728K 3
> > > 
> > > Only 16kB mapped? This is a full Linux guest running the Debian
> > > installer, and just the kernel is about 20MB (the VM has 4GB of RAM,
> > > and is using QEMU as the VMM)
> > > 
> > > So clearly something isn't playing as expected. Also, this '128M'
> > > without a level being displayed makes me wonder. It is probably the
> > > QEMU flash, but then the rest of the addresses don't make much sense
> > > (RAM on QEMU is at 1GB, not at 128MB.
> > > 
> > > On another system with kvmtool, I get something similar:
> > > 
> > > root@duodenum:/home/maz# cat /sys/kernel/debug/kvm/*/stage2_*
> > > 2
> > > ---[ Guest IPA ]---
> > > 0x0000000000000000-0x0000000001020000       16512K 3
> > > 0x0000000001020000-0x0000000001024000          16K 3   R W X AF    
> > > 0x0000000001024000-0x0000000002000000       16240K 3
> > > 
> > > and kvmtool places the RAM at 2GB. Clearly not what we're seeing here.
> > > 
> > > Could you please verify this?
> 
> Ughh, this doesn't look right. I will give it a spin with a different
> granule, thanks for bringing me to attention. I will look first at
> mm/ptdump.c if it works as intended.
>  
> 
> > 
> > For the record, on a 4kB host, I get much more plausible results:
> > 
> > root@big-leg-emma:/home/maz# cat /sys/kernel/debug/kvm/632-12/stage2_*
> > 3
> > ---[ Guest IPA ]---
> > 0x0000000000000000-0x0000000000200000           2M 2   R     AF BLK
> > 0x0000000000200000-0x0000000040000000        1022M 2
> > 0x0000000040000000-0x0000000040200000           2M 2   R W X AF BLK
> > 0x0000000040200000-0x0000000044000000          62M 2
> > 0x0000000044000000-0x0000000044200000           2M 2   R W X AF BLK
> > 0x0000000044200000-0x0000000047600000          52M 2
> > 0x0000000047600000-0x0000000047800000           2M 2   R W   AF BLK
> > 0x0000000047800000-0x0000000047e00000           6M 2   R W X AF BLK
> > 0x0000000047e00000-0x0000000048000000           2M 2   R W   AF BLK
> > 0x0000000048000000-0x00000000b9c00000        1820M 2
> > 0x00000000b9c00000-0x00000000b9e00000           2M 2   R W X AF BLK
> > 0x00000000b9e00000-0x00000000bb800000          26M 2
> > 0x00000000bb800000-0x00000000bba00000           2M 2   R W X AF BLK
> > 0x00000000bba00000-0x00000000bbe00000           4M 2   R W   AF BLK
> > 0x00000000bbe00000-0x00000000bc200000           4M 2   R W X AF BLK
> > 0x00000000bc200000-0x00000000bc800000           6M 2   R W   AF BLK
> > 0x00000000bc800000-0x00000000be400000          28M 2
> > 0x00000000be400000-0x00000000bf800000          20M 2   R W X AF BLK
> > 0x00000000bf800000-0x00000000bfe00000           6M 2   R W   AF BLK
> > 0x00000000bfe00000-0x00000000c0000000           2M 2   R W X AF BLK
> > 
> > So 16kB is the one that needs investigating, and I strongly suspect
> > that 64kB is in the same boat...
> > 
> > Thanks,
> > 
> > 	M. (signing off for the day)
> > 
> 
> Thanks,
> Sebastian
> 
> > -- 
> > Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables
  2024-09-02  7:08       ` Sebastian Ene
@ 2024-09-02  8:22         ` Marc Zyngier
  0 siblings, 0 replies; 20+ messages in thread
From: Marc Zyngier @ 2024-09-02  8:22 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: akpm, alexghiti, ankita, ardb, catalin.marinas, christophe.leroy,
	james.morse, vdonnefort, mark.rutland, oliver.upton, rananta,
	ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Mon, 02 Sep 2024 08:08:24 +0100,
Sebastian Ene <sebastianene@google.com> wrote:
> 
> On Mon, Sep 02, 2024 at 06:11:04AM +0000, Sebastian Ene wrote:
> > On Fri, Aug 30, 2024 at 04:00:11PM +0100, Marc Zyngier wrote:
> > > On Fri, 30 Aug 2024 15:44:39 +0100,
> > > Marc Zyngier <maz@kernel.org> wrote:
> 
> Hello Marc,
> 
> 
> I tried with a 16Kb host under VHE on Qemu starting a 4kb guest with
> kvmtool:
> 
> root@seb-qemu-pkvm-host:~#  zcat /proc/config.gz | grep
> "CONFIG_ARM64_[164K]*_PAGES=y"
> CONFIG_ARM64_16K_PAGES=y

VA bits? I'm using 47 bits, which may or may not have an impact.

> root@seb-qemu-pkvm-host:~# cat
> /sys/kernel/debug/kvm/263-4/stage2*
> 2
> ---[ Guest IPA ]---
> 0x0000000000000000-0x0000000001020000       16512K 3
> 0x0000000001020000-0x0000000001024000          16K 3   R W X AF    
> 0x0000000001024000-0x0000000002000000       16240K 3
> 0x0000000002000000-0x0000000080000000        2016M 2
> 0x0000000080000000-0x0000000084000000          64M 2   R W   AF BLK
> 0x0000000084000000-0x000000008e000000         160M 2
> 0x000000008e000000-0x0000000090000000          32M 2   R W   AF BLK
> 0x0000000090000000-0x0000000098000000         128M 2
> 0x0000000098000000-0x000000009a000000          32M 2   R W X AF BLK
> 0x000000009a000000-0x000000009c000000          32M 2   R W   AF BLK
> 
> This looks quite right I guess and I wonder how can I repro what you are seeing ?
> What kvm-arm.mode is the host running into ?

I tried both VHE (Apple M1) and nVHE (ThunderX), and they show similar
results.

Minimised configuration below.

	M.

CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_AUDIT=y
CONFIG_GENERIC_IRQ_DEBUGFS=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set
CONFIG_PREEMPT=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_NUMA_BALANCING=y
CONFIG_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_KALLSYMS_ALL=y
CONFIG_PROFILING=y
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_APPLE=y
CONFIG_ARCH_K3=y
CONFIG_ARCH_HISI=y
CONFIG_ARCH_MEDIATEK=y
CONFIG_ARCH_MESON=y
CONFIG_ARCH_MVEBU=y
CONFIG_ARCH_QCOM=y
CONFIG_ARCH_RENESAS=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_ARCH_SEATTLE=y
CONFIG_ARCH_SYNQUACER=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_THUNDER=y
CONFIG_ARCH_THUNDER2=y
CONFIG_ARCH_UNIPHIER=y
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_XGENE=y
CONFIG_ARCH_ZYNQMP=y
CONFIG_ARM64_ERRATUM_834220=y
CONFIG_ARM64_ERRATUM_2441007=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_1542419=y
# CONFIG_ARM64_ERRATUM_2051678 is not set
# CONFIG_ARM64_ERRATUM_2077057 is not set
CONFIG_ARM64_ERRATUM_2441009=y
CONFIG_ARM64_16K_PAGES=y
CONFIG_ARM64_VA_BITS_47=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_NR_CPUS=256
CONFIG_NUMA=y
CONFIG_NODES_SHIFT=2
CONFIG_XEN=y
CONFIG_COMPAT=y
CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y
CONFIG_CP15_BARRIER_EMULATION=y
CONFIG_SETEND_EMULATION=y
CONFIG_ARM64_PMEM=y
CONFIG_ARM64_PSEUDO_NMI=y
CONFIG_RANDOMIZE_BASE=y
CONFIG_ARM64_ACPI_PARKING_PROTOCOL=y
CONFIG_HIBERNATION=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPUFREQ_DT=m
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_ARM_ARMADA_37XX_CPUFREQ=m
CONFIG_ARM_ARMADA_8K_CPUFREQ=m
# CONFIG_ARM_TEGRA20_CPUFREQ is not set
CONFIG_ARM_TEGRA186_CPUFREQ=y
CONFIG_ACPI_CPPC_CPUFREQ=m
CONFIG_ACPI=y
CONFIG_ACPI_TAD=m
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_PCI_SLOT=y
CONFIG_ACPI_BGRT=y
CONFIG_ACPI_NFIT=m
CONFIG_ACPI_APEI=y
CONFIG_ACPI_APEI_GHES=y
CONFIG_ACPI_APEI_PCIEAER=y
CONFIG_ACPI_APEI_MEMORY_FAILURE=y
CONFIG_ACPI_APEI_EINJ=m
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_ALL is not set
CONFIG_MODULE_SIG_SHA256=y
CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_WBT=y
CONFIG_BLK_SED_OPAL=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_KARMA_PARTITION=y
CONFIG_MQ_IOSCHED_KYBER=m
CONFIG_IOSCHED_BFQ=m
CONFIG_BINFMT_MISC=m
CONFIG_ZSWAP=y
CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
CONFIG_Z3FOLD=m
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
# CONFIG_COMPAT_BRK is not set
CONFIG_KSM=y
CONFIG_MEMORY_FAILURE=y
CONFIG_HWPOISON_INJECT=m
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_CMA=y
CONFIG_CMA_AREAS=7
CONFIG_USERFAULTFD=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=m
CONFIG_UNIX_DIAG=m
CONFIG_XFRM_USER=m
CONFIG_XFRM_INTERFACE=m
CONFIG_XFRM_SUB_POLICY=y
CONFIG_NET_KEY=m
CONFIG_NET_KEY_MIGRATE=y
CONFIG_SMC=m
CONFIG_SMC_DIAG=m
CONFIG_XDP_SOCKETS=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_NET_IPIP=m
CONFIG_NET_IPGRE_DEMUX=m
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_NET_IPVTI=m
CONFIG_NET_FOU_IP_TUNNELS=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_ESP_OFFLOAD=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_DIAG=m
CONFIG_INET_UDP_DIAG=m
CONFIG_INET_RAW_DIAG=m
CONFIG_INET_DIAG_DESTROY=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_HSTCP=m
CONFIG_TCP_CONG_HYBLA=m
CONFIG_TCP_CONG_NV=m
CONFIG_TCP_CONG_SCALABLE=m
CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_TCP_CONG_DCTCP=m
CONFIG_TCP_CONG_CDG=m
CONFIG_TCP_CONG_BBR=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_ESP_OFFLOAD=m
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_MIP6=y
CONFIG_IPV6_ILA=m
CONFIG_IPV6_VTI=m
CONFIG_IPV6_SIT=m
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_GRE=m
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_IPV6_SEG6_HMAC=y
CONFIG_NETWORK_SECMARK=y
CONFIG_NETFILTER=y
CONFIG_BRIDGE_NETFILTER=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_ZONES=y
CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CONNTRACK_AMANDA=m
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_H323=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
CONFIG_NF_CONNTRACK_SNMP=m
CONFIG_NF_CONNTRACK_PPTP=m
CONFIG_NF_CONNTRACK_SANE=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NF_CT_NETLINK_HELPER=m
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_TABLES=m
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=m
CONFIG_NFT_CT=m
CONFIG_NFT_FLOW_OFFLOAD=m
CONFIG_NFT_CONNLIMIT=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_MASQ=m
CONFIG_NFT_REDIR=m
CONFIG_NFT_NAT=m
CONFIG_NFT_TUNNEL=m
CONFIG_NFT_QUEUE=m
CONFIG_NFT_QUOTA=m
CONFIG_NFT_REJECT=m
CONFIG_NFT_COMPAT=m
CONFIG_NFT_HASH=m
CONFIG_NFT_FIB_INET=m
CONFIG_NFT_SOCKET=m
CONFIG_NFT_OSF=m
CONFIG_NFT_TPROXY=m
CONFIG_NFT_DUP_NETDEV=m
CONFIG_NFT_FWD_NETDEV=m
CONFIG_NFT_FIB_NETDEV=m
CONFIG_NF_FLOW_TABLE_INET=m
CONFIG_NF_FLOW_TABLE=m
CONFIG_NETFILTER_XTABLES_COMPAT=y
CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_HMARK=m
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LED=m
CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
CONFIG_NETFILTER_XT_TARGET_TEE=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
CONFIG_NETFILTER_XT_MATCH_BPF=m
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_CPU=m
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_NFACCT=m
CONFIG_NETFILTER_XT_MATCH_OSF=m
CONFIG_NETFILTER_XT_MATCH_OWNER=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
CONFIG_NETFILTER_XT_MATCH_REALM=m
CONFIG_NETFILTER_XT_MATCH_RECENT=m
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=m
CONFIG_IP_SET=m
CONFIG_IP_SET_BITMAP_IP=m
CONFIG_IP_SET_BITMAP_IPMAC=m
CONFIG_IP_SET_BITMAP_PORT=m
CONFIG_IP_SET_HASH_IP=m
CONFIG_IP_SET_HASH_IPMARK=m
CONFIG_IP_SET_HASH_IPPORT=m
CONFIG_IP_SET_HASH_IPPORTIP=m
CONFIG_IP_SET_HASH_IPPORTNET=m
CONFIG_IP_SET_HASH_IPMAC=m
CONFIG_IP_SET_HASH_MAC=m
CONFIG_IP_SET_HASH_NETPORTNET=m
CONFIG_IP_SET_HASH_NET=m
CONFIG_IP_SET_HASH_NETNET=m
CONFIG_IP_SET_HASH_NETPORT=m
CONFIG_IP_SET_HASH_NETIFACE=m
CONFIG_IP_SET_LIST_SET=m
CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_FO=m
CONFIG_IP_VS_OVF=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_MH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_PE_SIP=m
CONFIG_NFT_DUP_IPV4=m
CONFIG_NFT_FIB_IPV4=m
CONFIG_NF_TABLES_ARP=y
CONFIG_NF_LOG_ARP=m
CONFIG_NF_LOG_IPV4=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_SYNPROXY=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NFT_DUP_IPV6=m
CONFIG_NFT_FIB_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_RPFILTER=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_TARGET_SYNPROXY=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NFT_BRIDGE_REJECT=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_IP_DCCP=m
CONFIG_SCTP_COOKIE_HMAC_SHA1=y
CONFIG_RDS=m
CONFIG_RDS_RDMA=m
CONFIG_RDS_TCP=m
CONFIG_TIPC=m
CONFIG_TIPC_MEDIA_IB=y
CONFIG_ATM=m
CONFIG_ATM_CLIP=m
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
CONFIG_L2TP=m
CONFIG_L2TP_DEBUGFS=m
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=m
CONFIG_L2TP_ETH=m
CONFIG_BRIDGE=m
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_NET_DSA=m
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_LLC2=m
CONFIG_ATALK=m
CONFIG_PHONET=m
CONFIG_6LOWPAN=m
CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m
CONFIG_6LOWPAN_GHC_UDP=m
CONFIG_6LOWPAN_GHC_ICMPV6=m
CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m
CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m
CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m
CONFIG_IEEE802154=m
CONFIG_IEEE802154_6LOWPAN=m
CONFIG_MAC802154=m
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFB=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_CBS=m
CONFIG_NET_SCH_ETF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_DRR=m
CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_SCH_SKBPRIO=m
CONFIG_NET_SCH_CHOKE=m
CONFIG_NET_SCH_QFQ=m
CONFIG_NET_SCH_CODEL=m
CONFIG_NET_SCH_FQ_CODEL=m
CONFIG_NET_SCH_CAKE=m
CONFIG_NET_SCH_FQ=m
CONFIG_NET_SCH_HHF=m
CONFIG_NET_SCH_PIE=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_SCH_PLUG=m
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_FLOWER=m
CONFIG_NET_CLS_MATCHALL=m
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=m
CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=m
CONFIG_NET_EMATCH_TEXT=m
CONFIG_NET_EMATCH_CANID=m
CONFIG_NET_EMATCH_IPSET=m
CONFIG_NET_EMATCH_IPT=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_ACT_SAMPLE=m
CONFIG_NET_ACT_NAT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_NET_ACT_CSUM=m
CONFIG_NET_ACT_VLAN=m
CONFIG_NET_ACT_BPF=m
CONFIG_NET_ACT_CONNMARK=m
CONFIG_NET_ACT_SKBMOD=m
CONFIG_NET_ACT_IFE=m
CONFIG_NET_ACT_TUNNEL_KEY=m
CONFIG_NET_IFE_SKBMARK=m
CONFIG_NET_IFE_SKBPRIO=m
CONFIG_NET_IFE_SKBTCINDEX=m
CONFIG_DCB=y
CONFIG_BATMAN_ADV=m
# CONFIG_BATMAN_ADV_BATMAN_V is not set
CONFIG_BATMAN_ADV_NC=y
CONFIG_OPENVSWITCH=m
CONFIG_VSOCKETS=m
CONFIG_VIRTIO_VSOCKETS=m
CONFIG_NETLINK_DIAG=m
CONFIG_NET_MPLS_GSO=y
CONFIG_MPLS_ROUTING=m
CONFIG_MPLS_IPTUNNEL=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_NET_PKTGEN=m
CONFIG_NET_DROP_MONITOR=y
CONFIG_CAN=m
CONFIG_BT=m
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=m
CONFIG_BT_6LOWPAN=m
CONFIG_BT_LEDS=y
CONFIG_BT_HCIBTUSB=m
CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
CONFIG_BT_HCIBTSDIO=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_NOKIA=m
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_ATH3K=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_INTEL=y
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_HCIUART_RTL=y
CONFIG_BT_HCIUART_QCA=y
CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIUART_MRVL=y
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_BT_ATH3K=m
CONFIG_BT_MTKUART=m
CONFIG_BT_QCOMSMD=m
CONFIG_AF_RXRPC_IPV6=y
CONFIG_RXKAD=y
CONFIG_CFG80211=m
CONFIG_MAC80211=m
CONFIG_MAC80211_MESH=y
CONFIG_RFKILL=m
CONFIG_RFKILL_INPUT=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_NET_9P_XEN=m
CONFIG_NET_9P_RDMA=m
CONFIG_NFC=m
CONFIG_NFC_DIGITAL=m
CONFIG_NFC_SIM=m
CONFIG_NFC_PORT100=m
CONFIG_NFC_PN533_USB=m
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_PCIEAER=y
CONFIG_PCIEAER_INJECT=m
CONFIG_PCIE_DPC=y
CONFIG_PCIE_PTM=y
CONFIG_PCIE_EDR=y
CONFIG_PCI_REALLOC_ENABLE_AUTO=y
CONFIG_PCI_STUB=m
CONFIG_PCI_PF_STUB=m
CONFIG_PCI_IOV=y
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
CONFIG_HOTPLUG_PCI_ACPI_IBM=m
CONFIG_HOTPLUG_PCI_CPCI=y
CONFIG_HOTPLUG_PCI_SHPC=y
CONFIG_PCI_AARDVARK=y
CONFIG_PCIE_APPLE=y
CONFIG_PCI_HOST_THUNDER_PEM=y
CONFIG_PCI_HOST_THUNDER_ECAM=y
CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCI_TEGRA=y
CONFIG_PCIE_RCAR_HOST=y
CONFIG_PCIE_ROCKCHIP_HOST=y
CONFIG_PCI_XGENE=y
CONFIG_PCIE_XILINX=y
CONFIG_PCIE_XILINX_NWL=y
CONFIG_PCI_MESON=y
CONFIG_PCI_HISI=y
CONFIG_PCIE_KIRIN=y
CONFIG_PCIE_ARMADA_8K=y
CONFIG_PCIE_TEGRA194_HOST=m
CONFIG_PCIE_QCOM=y
CONFIG_PCI_SW_SWITCHTEC=y
CONFIG_DEVTMPFS=y
CONFIG_HISILICON_LPC=y
CONFIG_TEGRA_ACONNECT=y
CONFIG_CONNECTOR=y
CONFIG_DMI_SYSFS=y
CONFIG_FW_CFG_SYSFS=m
CONFIG_SYSFB_SIMPLEFB=y
CONFIG_GOOGLE_FIRMWARE=y
CONFIG_GOOGLE_COREBOOT_TABLE=m
CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=m
CONFIG_EFI_VARS_PSTORE=m
CONFIG_EFI_BOOTLOADER_CONTROL=m
CONFIG_EFI_CAPSULE_LOADER=m
CONFIG_GNSS=m
CONFIG_GNSS_SIRF_SERIAL=m
CONFIG_GNSS_UBX_SERIAL=m
CONFIG_MTD=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m
CONFIG_MTD_OOPS=m
CONFIG_MTD_SWAP=m
CONFIG_MTD_PLATRAM=m
CONFIG_MTD_DATAFLASH=m
CONFIG_MTD_SST25L=m
CONFIG_MTD_ONENAND=m
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y
CONFIG_MTD_LPDDR=m
CONFIG_MTD_SPI_NOR=m
CONFIG_SPI_HISI_SFC=m
CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_BLOCK=y
CONFIG_OF_OVERLAY=y
CONFIG_PARPORT=m
CONFIG_PARPORT_1284=y
# CONFIG_PNP_DEBUG_MESSAGES is not set
CONFIG_BLK_DEV_NULL_BLK=m
CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m
CONFIG_ZRAM=m
CONFIG_ZRAM_WRITEBACK=y
CONFIG_ZRAM_MEMORY_TRACKING=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_DRBD=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_ATA_OVER_ETH=m
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_NVME=m
CONFIG_NVME_MULTIPATH=y
CONFIG_NVME_RDMA=m
CONFIG_NVME_FC=m
CONFIG_NVME_APPLE=m
CONFIG_NVME_TARGET=m
CONFIG_NVME_TARGET_RDMA=m
CONFIG_NVME_TARGET_FC=m
CONFIG_AD525X_DPOT=m
CONFIG_AD525X_DPOT_I2C=m
CONFIG_AD525X_DPOT_SPI=m
CONFIG_ICS932S401=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_QCOM_COINCELL=m
CONFIG_APDS9802ALS=m
CONFIG_ISL29003=m
CONFIG_ISL29020=m
CONFIG_SENSORS_TSL2550=m
CONFIG_SENSORS_BH1770=m
CONFIG_SENSORS_APDS990X=m
CONFIG_HMC6352=m
CONFIG_DS1682=m
CONFIG_C2PORT=m
CONFIG_EEPROM_AT24=m
CONFIG_EEPROM_AT25=m
CONFIG_EEPROM_MAX6875=m
CONFIG_TI_ST=m
CONFIG_SENSORS_LIS3_I2C=m
CONFIG_MISC_RTSX_PCI=m
CONFIG_MISC_RTSX_USB=m
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m
CONFIG_CHR_DEV_SCH=m
CONFIG_SCSI_ENCLOSURE=m
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_SAS_ATA=y
CONFIG_ISCSI_TCP=m
CONFIG_SCSI_CXGB3_ISCSI=m
CONFIG_SCSI_CXGB4_ISCSI=m
CONFIG_SCSI_BNX2_ISCSI=m
CONFIG_SCSI_BNX2X_FCOE=m
CONFIG_BE2ISCSI=m
CONFIG_BLK_DEV_3W_XXXX_RAID=m
CONFIG_SCSI_HPSA=m
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_3W_SAS=m
CONFIG_SCSI_ACARD=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
CONFIG_SCSI_AIC79XX=m
CONFIG_AIC79XX_RESET_DELAY_MS=15000
CONFIG_SCSI_AIC94XX=m
# CONFIG_AIC94XX_DEBUG is not set
CONFIG_SCSI_HISI_SAS=m
CONFIG_SCSI_HISI_SAS_PCI=m
CONFIG_SCSI_MVSAS=m
# CONFIG_SCSI_MVSAS_DEBUG is not set
CONFIG_SCSI_MVUMI=m
CONFIG_SCSI_ADVANSYS=m
CONFIG_SCSI_ESAS2R=m
CONFIG_MEGARAID_SAS=m
CONFIG_SCSI_MPT2SAS=m
CONFIG_SCSI_SMARTPQI=m
CONFIG_SCSI_HPTIOP=m
CONFIG_XEN_SCSI_FRONTEND=m
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
CONFIG_FCOE=m
CONFIG_SCSI_SNIC=m
CONFIG_SCSI_DMX3191D=m
CONFIG_SCSI_STEX=m
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_QLA_FC=m
CONFIG_TCM_QLA2XXX=m
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_QEDI=m
CONFIG_QEDF=m
CONFIG_SCSI_LPFC=m
CONFIG_SCSI_WD719X=m
CONFIG_SCSI_PMCRAID=m
CONFIG_SCSI_PM8001=m
CONFIG_SCSI_BFA_FC=m
CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_CHELSIO_FCOE=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_HP_SW=m
CONFIG_SCSI_DH_EMC=m
CONFIG_SCSI_DH_ALUA=m
CONFIG_ATA=m
CONFIG_SATA_ZPODD=y
CONFIG_SATA_AHCI=m
CONFIG_SATA_MOBILE_LPM_POLICY=0
CONFIG_SATA_AHCI_PLATFORM=m
CONFIG_AHCI_CEVA=m
CONFIG_AHCI_MVEBU=m
CONFIG_AHCI_TEGRA=m
CONFIG_AHCI_XGENE=m
CONFIG_SATA_AHCI_SEATTLE=m
CONFIG_SATA_ACARD_AHCI=m
CONFIG_SATA_SIL24=m
CONFIG_PDC_ADMA=m
CONFIG_SATA_QSTOR=m
CONFIG_SATA_SX4=m
CONFIG_ATA_PIIX=m
CONFIG_SATA_MV=m
CONFIG_SATA_NV=m
CONFIG_SATA_PROMISE=m
CONFIG_SATA_SIL=m
CONFIG_SATA_SIS=m
CONFIG_SATA_SVW=m
CONFIG_SATA_ULI=m
CONFIG_SATA_VIA=m
CONFIG_SATA_VITESSE=m
CONFIG_PATA_ARTOP=m
CONFIG_PATA_ATP867X=m
CONFIG_PATA_CMD64X=m
CONFIG_PATA_IT8213=m
CONFIG_PATA_IT821X=m
CONFIG_PATA_JMICRON=m
CONFIG_PATA_MARVELL=m
CONFIG_PATA_NINJA32=m
CONFIG_PATA_RDC=m
CONFIG_PATA_SCH=m
CONFIG_PATA_TOSHIBA=m
CONFIG_ATA_GENERIC=m
CONFIG_MD=y
CONFIG_BCACHE=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_DM_CACHE=m
CONFIG_DM_WRITECACHE=m
CONFIG_DM_ERA=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m
CONFIG_DM_MULTIPATH_ST=m
CONFIG_DM_DELAY=m
CONFIG_DM_UEVENT=y
CONFIG_DM_FLAKEY=m
CONFIG_DM_VERITY=m
CONFIG_DM_SWITCH=m
CONFIG_DM_LOG_WRITES=m
CONFIG_DM_INTEGRITY=m
CONFIG_DM_ZONED=m
CONFIG_TARGET_CORE=m
CONFIG_TCM_IBLOCK=m
CONFIG_TCM_FILEIO=m
CONFIG_TCM_PSCSI=m
CONFIG_TCM_USER2=m
CONFIG_LOOPBACK_TARGET=m
CONFIG_TCM_FC=m
CONFIG_ISCSI_TARGET=m
CONFIG_ISCSI_TARGET_CXGB4=m
CONFIG_SBP_TARGET=m
CONFIG_FUSION=y
CONFIG_FUSION_SPI=m
CONFIG_FUSION_FC=m
CONFIG_FUSION_SAS=m
CONFIG_FUSION_CTL=m
CONFIG_FIREWIRE=m
CONFIG_FIREWIRE_OHCI=m
CONFIG_FIREWIRE_SBP2=m
CONFIG_FIREWIRE_NET=m
CONFIG_FIREWIRE_NOSY=m
CONFIG_BONDING=m
CONFIG_DUMMY=m
CONFIG_EQUALIZER=m
CONFIG_IFB=m
CONFIG_NET_TEAM=m
CONFIG_NET_TEAM_MODE_BROADCAST=m
CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
CONFIG_NET_TEAM_MODE_RANDOM=m
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
CONFIG_NET_TEAM_MODE_LOADBALANCE=m
CONFIG_MACVLAN=m
CONFIG_MACVTAP=m
CONFIG_IPVLAN=m
CONFIG_IPVTAP=m
CONFIG_VXLAN=m
CONFIG_GENEVE=m
CONFIG_GTP=m
CONFIG_MACSEC=m
CONFIG_NETCONSOLE=m
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_VIRTIO_NET=y
CONFIG_NLMON=m
CONFIG_NET_VRF=m
CONFIG_VSOCKMON=m
CONFIG_ATM_DUMMY=m
CONFIG_ATM_NICSTAR=m
CONFIG_ATM_NICSTAR_USE_SUNI=y
CONFIG_ATM_NICSTAR_USE_IDT77105=y
CONFIG_ATM_IA=m
CONFIG_ATM_FORE200E=m
CONFIG_ATM_SOLOS=m
CONFIG_NET_DSA_MV88E6060=m
CONFIG_NET_DSA_MV88E6XXX=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
CONFIG_ADAPTEC_STARFIRE=m
CONFIG_ET131X=m
CONFIG_ACENIC=m
CONFIG_ENA_ETHERNET=m
CONFIG_PCNET32=m
CONFIG_AMD_XGBE=m
CONFIG_AMD_XGBE_DCB=y
CONFIG_NET_XGENE=m
CONFIG_NET_XGENE_V2=m
CONFIG_AQTION=m
CONFIG_EMAC_ROCKCHIP=m
CONFIG_ATL2=m
CONFIG_ATL1=m
CONFIG_ATL1E=m
CONFIG_ATL1C=m
CONFIG_ALX=m
CONFIG_BCMGENET=m
CONFIG_TIGON3=y
CONFIG_BNX2X=m
CONFIG_BNXT=m
CONFIG_BNXT_DCB=y
CONFIG_MACB=m
CONFIG_THUNDER_NIC_PF=m
CONFIG_THUNDER_NIC_VF=m
CONFIG_CAVIUM_PTP=y
CONFIG_LIQUIDIO=m
CONFIG_LIQUIDIO_VF=m
CONFIG_CHELSIO_T1=m
CONFIG_CHELSIO_T1_1G=y
CONFIG_CHELSIO_T4_DCB=y
CONFIG_CHELSIO_T4_FCOE=y
CONFIG_CHELSIO_T4VF=m
CONFIG_ENIC=m
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=m
CONFIG_TULIP_NAPI=y
CONFIG_TULIP_NAPI_HW_MITIGATION=y
CONFIG_WINBOND_840=m
CONFIG_DM9102=m
CONFIG_ULI526X=m
CONFIG_DL2K=m
CONFIG_SUNDANCE=m
CONFIG_HIX5HD2_GMAC=m
CONFIG_HISI_FEMAC=m
CONFIG_HIP04_ETH=m
CONFIG_HNS_DSAF=m
CONFIG_HNS_ENET=m
CONFIG_HNS3=m
CONFIG_HNS3_DCB=y
CONFIG_HNS3_HCLGEVF=m
CONFIG_HINIC=m
CONFIG_E100=m
CONFIG_E1000=m
CONFIG_E1000E=m
CONFIG_IGB=m
CONFIG_IGBVF=m
CONFIG_IXGBE=m
CONFIG_IXGBE_DCB=y
CONFIG_IXGBEVF=m
CONFIG_I40E=m
CONFIG_I40E_DCB=y
CONFIG_I40EVF=m
CONFIG_ICE=m
CONFIG_JME=m
CONFIG_MVNETA=m
CONFIG_MVPP2=m
CONFIG_SKGE=m
CONFIG_SKGE_GENESIS=y
CONFIG_SKY2=m
CONFIG_MLX4_EN=m
CONFIG_MLX5_CORE=m
CONFIG_MLX5_FPGA=y
CONFIG_MLX5_CORE_EN=y
CONFIG_MLX5_CORE_IPOIB=y
CONFIG_MLXFW=m
CONFIG_KSZ884X_PCI=m
CONFIG_LAN743X=m
CONFIG_MYRI10GE=m
CONFIG_FEALNX=m
CONFIG_NATSEMI=m
CONFIG_NS83820=m
CONFIG_S2IO=m
CONFIG_NFP=m
CONFIG_NE2K_PCI=m
CONFIG_HAMACHI=m
CONFIG_YELLOWFIN=m
CONFIG_QLA3XXX=m
CONFIG_QLCNIC=m
CONFIG_NETXEN_NIC=m
CONFIG_QED=m
CONFIG_QEDE=m
CONFIG_BNA=m
CONFIG_QCOM_EMAC=m
CONFIG_R6040=m
CONFIG_8139CP=m
CONFIG_8139TOO=m
# CONFIG_8139TOO_PIO is not set
CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
CONFIG_R8169=m
# CONFIG_NET_VENDOR_SEEQ is not set
CONFIG_SC92031=m
CONFIG_SIS190=m
CONFIG_SFC=m
CONFIG_SFC_FALCON=m
CONFIG_SMC91X=m
CONFIG_EPIC100=m
CONFIG_SMSC911X=m
CONFIG_SMSC9420=m
CONFIG_SNI_NETSEC=m
CONFIG_STMMAC_ETH=m
CONFIG_DWMAC_DWC_QOS_ETH=m
CONFIG_CASSINI=m
CONFIG_NIU=m
CONFIG_TEHUTI=m
CONFIG_TLAN=m
CONFIG_VIA_VELOCITY=m
CONFIG_FDDI=y
CONFIG_DEFXX=m
CONFIG_SKFP=m
CONFIG_LED_TRIGGER_PHY=y
CONFIG_SFP=m
CONFIG_AMD_PHY=m
CONFIG_MESON_GXL_PHY=m
CONFIG_AQUANTIA_PHY=m
CONFIG_BROADCOM_PHY=m
CONFIG_BCM87XX_PHY=m
CONFIG_CICADA_PHY=m
CONFIG_CORTINA_PHY=m
CONFIG_DAVICOM_PHY=m
CONFIG_ICPLUS_PHY=m
CONFIG_LXT_PHY=m
CONFIG_LSI_ET1011C_PHY=m
CONFIG_MARVELL_10G_PHY=m
CONFIG_MICREL_PHY=m
CONFIG_MICROCHIP_T1_PHY=m
CONFIG_MICROSEMI_PHY=m
CONFIG_NATIONAL_PHY=m
CONFIG_AT803X_PHY=m
CONFIG_QSEMI_PHY=m
CONFIG_RENESAS_PHY=m
CONFIG_ROCKCHIP_PHY=m
CONFIG_STE10XP=m
CONFIG_TERANETICS_PHY=m
CONFIG_DP83822_PHY=m
CONFIG_DP83TC811_PHY=m
CONFIG_DP83848_PHY=m
CONFIG_DP83867_PHY=m
CONFIG_VITESSE_PHY=m
CONFIG_CAN_VCAN=m
CONFIG_CAN_VXCAN=m
CONFIG_CAN_SLCAN=m
CONFIG_CAN_PEAK_PCIEFD=m
CONFIG_CAN_SJA1000=m
CONFIG_CAN_EMS_PCI=m
CONFIG_CAN_KVASER_PCI=m
CONFIG_CAN_PEAK_PCI=m
CONFIG_CAN_PLX_PCI=m
CONFIG_CAN_SOFTING=m
CONFIG_CAN_8DEV_USB=m
CONFIG_CAN_EMS_USB=m
CONFIG_CAN_GS_USB=m
CONFIG_CAN_KVASER_USB=m
CONFIG_CAN_MCBA_USB=m
CONFIG_CAN_PEAK_USB=m
CONFIG_CAN_UCAN=m
CONFIG_MDIO_HISI_FEMAC=m
CONFIG_MDIO_BUS_MUX_MMIOREG=m
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOATM=m
CONFIG_PPPOE=m
CONFIG_PPTP=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
CONFIG_USB_NET_DRIVERS=m
CONFIG_USB_CATC=m
CONFIG_USB_KAWETH=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_CDC_EEM=m
CONFIG_USB_NET_HUAWEI_CDC_NCM=m
CONFIG_USB_NET_CDC_MBIM=m
CONFIG_USB_NET_DM9601=m
CONFIG_USB_NET_SR9700=m
CONFIG_USB_NET_SR9800=m
CONFIG_USB_NET_SMSC75XX=m
CONFIG_USB_NET_SMSC95XX=m
CONFIG_USB_NET_GL620A=m
CONFIG_USB_NET_PLUSB=m
CONFIG_USB_NET_MCS7830=m
CONFIG_USB_NET_RNDIS_HOST=m
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_CX82310_ETH=m
CONFIG_USB_NET_KALMIA=m
CONFIG_USB_NET_QMI_WWAN=m
CONFIG_USB_HSO=m
CONFIG_USB_NET_INT51X1=m
CONFIG_USB_CDC_PHONET=m
CONFIG_USB_IPHETH=m
CONFIG_USB_SIERRA_NET=m
CONFIG_USB_VL600=m
CONFIG_USB_NET_CH9200=m
CONFIG_ADM8211=m
CONFIG_ATH5K=m
CONFIG_ATH9K=m
CONFIG_ATH9K_CHANNEL_CONTEXT=y
CONFIG_ATH9K_HTC=m
CONFIG_CARL9170=m
CONFIG_ATH6KL=m
CONFIG_ATH6KL_SDIO=m
CONFIG_ATH6KL_USB=m
CONFIG_AR5523=m
CONFIG_WIL6210=m
CONFIG_WIL6210_TRACING=y
CONFIG_ATH10K=m
CONFIG_ATH10K_PCI=m
CONFIG_ATH10K_USB=m
CONFIG_WCN36XX=m
CONFIG_AT76C50X_USB=m
CONFIG_B43=m
CONFIG_B43_SDIO=y
CONFIG_B43LEGACY=m
CONFIG_BRCMSMAC=m
CONFIG_BRCMFMAC=m
CONFIG_BRCMFMAC_USB=y
CONFIG_BRCMFMAC_PCIE=y
CONFIG_IPW2200=m
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y
CONFIG_IWL4965=m
CONFIG_IWL3945=m
CONFIG_IWLWIFI=m
CONFIG_IWLDVM=m
CONFIG_IWLMVM=m
# CONFIG_IWLWIFI_DEVICE_TRACING is not set
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
CONFIG_P54_PCI=m
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_MESH=y
CONFIG_LIBERTAS_THINFIRM=m
CONFIG_LIBERTAS_THINFIRM_USB=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_PCIE=m
CONFIG_MWL8K=m
CONFIG_MT7601U=m
CONFIG_MT76x0U=m
CONFIG_MT76x2E=m
CONFIG_MT76x2U=m
CONFIG_RT2X00=m
CONFIG_RT2400PCI=m
CONFIG_RT2500PCI=m
CONFIG_RT61PCI=m
CONFIG_RT2800PCI=m
CONFIG_RT2500USB=m
CONFIG_RT73USB=m
CONFIG_RT2800USB=m
CONFIG_RT2800USB_RT3573=y
CONFIG_RT2800USB_RT53XX=y
CONFIG_RT2800USB_RT55XX=y
CONFIG_RTL8180=m
CONFIG_RTL8187=m
CONFIG_RTL8192CE=m
CONFIG_RTL8192SE=m
CONFIG_RTL8192DE=m
CONFIG_RTL8723AE=m
CONFIG_RTL8723BE=m
CONFIG_RTL8188EE=m
CONFIG_RTL8192EE=m
CONFIG_RTL8821AE=m
CONFIG_RTL8192CU=m
# CONFIG_RTLWIFI_DEBUG is not set
CONFIG_RTL8XXXU=m
CONFIG_RSI_91X=m
# CONFIG_RSI_SDIO is not set
CONFIG_WL1251=m
CONFIG_WL1251_SPI=m
CONFIG_WL1251_SDIO=m
CONFIG_WL12XX=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SPI=m
CONFIG_WLCORE_SDIO=m
CONFIG_ZD1211RW=m
CONFIG_MAC80211_HWSIM=m
CONFIG_IEEE802154_FAKELB=m
CONFIG_IEEE802154_AT86RF230=m
CONFIG_IEEE802154_MRF24J40=m
CONFIG_IEEE802154_CC2520=m
CONFIG_IEEE802154_ATUSB=m
CONFIG_IEEE802154_ADF7242=m
CONFIG_IEEE802154_HWSIM=m
CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XEN_NETDEV_BACKEND=m
CONFIG_INPUT_SPARSEKMAP=m
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_JOYDEV=m
CONFIG_INPUT_EVDEV=m
CONFIG_KEYBOARD_ADP5588=m
CONFIG_KEYBOARD_QT2160=m
CONFIG_KEYBOARD_GPIO=m
CONFIG_KEYBOARD_LM8323=m
CONFIG_KEYBOARD_MAX7359=m
CONFIG_KEYBOARD_TEGRA=m
CONFIG_KEYBOARD_OPENCORES=m
CONFIG_KEYBOARD_STOWAWAY=m
CONFIG_KEYBOARD_CROS_EC=m
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_PS2_SENTELIC=y
CONFIG_MOUSE_ELAN_I2C=m
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_MOUSE_SYNAPTICS_USB=m
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=m
CONFIG_TABLET_USB_AIPTEK=m
CONFIG_TABLET_USB_HANWANG=m
CONFIG_TABLET_USB_KBTAB=m
CONFIG_TABLET_USB_PEGASUS=m
CONFIG_TABLET_SERIAL_WACOM4=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_TOUCHSCREEN_AD7877=m
CONFIG_TOUCHSCREEN_AD7879=m
CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y
CONFIG_TOUCHSCREEN_DYNAPRO=m
CONFIG_TOUCHSCREEN_HAMPSHIRE=m
CONFIG_TOUCHSCREEN_EETI=m
CONFIG_TOUCHSCREEN_FUJITSU=m
CONFIG_TOUCHSCREEN_GOODIX=m
CONFIG_TOUCHSCREEN_GUNZE=m
CONFIG_TOUCHSCREEN_ELAN=m
CONFIG_TOUCHSCREEN_ELO=m
CONFIG_TOUCHSCREEN_WACOM_W8001=m
CONFIG_TOUCHSCREEN_MCS5000=m
CONFIG_TOUCHSCREEN_MTOUCH=m
CONFIG_TOUCHSCREEN_INEXIO=m
CONFIG_TOUCHSCREEN_PENMOUNT=m
CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
CONFIG_TOUCHSCREEN_TOUCHWIN=m
CONFIG_TOUCHSCREEN_WM97XX=m
CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
CONFIG_TOUCHSCREEN_TOUCHIT213=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_TOUCHSCREEN_SUR40=m
CONFIG_TOUCHSCREEN_TPS6507X=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PM8941_PWRKEY=m
CONFIG_INPUT_ATI_REMOTE2=m
CONFIG_INPUT_KEYSPAN_REMOTE=m
CONFIG_INPUT_POWERMATE=m
CONFIG_INPUT_YEALINK=m
CONFIG_INPUT_CM109=m
CONFIG_INPUT_AXP20X_PEK=m
CONFIG_INPUT_UINPUT=m
CONFIG_INPUT_HISI_POWERKEY=m
CONFIG_RMI4_F34=y
CONFIG_RMI4_F55=y
CONFIG_SERIO_ALTERA_PS2=m
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_EXAR=m
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_AMBA_PL010=y
CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_MESON=y
CONFIG_SERIAL_MESON_CONSOLE=y
CONFIG_SERIAL_SAMSUNG=y
CONFIG_SERIAL_SAMSUNG_CONSOLE=y
CONFIG_SERIAL_TEGRA=y
CONFIG_SERIAL_TEGRA_TCU=y
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_SERIAL_RP2=m
CONFIG_SERIAL_MVEBU_UART=y
CONFIG_N_GSM=m
CONFIG_NOZOMI=m
CONFIG_SERIAL_DEV_BUS=y
CONFIG_TTY_PRINTK=m
CONFIG_VIRTIO_CONSOLE=y
CONFIG_IPMI_HANDLER=m
CONFIG_IPMI_DEVICE_INTERFACE=m
CONFIG_IPMI_SSIF=m
CONFIG_IPMI_WATCHDOG=m
CONFIG_IPMI_POWEROFF=m
# CONFIG_HW_RANDOM_OMAP is not set
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_HW_RANDOM_CN10K=m
CONFIG_TCG_TPM=m
CONFIG_TCG_TIS_SPI=m
CONFIG_TCG_TIS_I2C_INFINEON=m
CONFIG_TCG_VTPM_PROXY=m
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_ISCH=m
CONFIG_I2C_DESIGNWARE_PLATFORM=m
CONFIG_I2C_GPIO=m
CONFIG_I2C_MESON=m
CONFIG_I2C_MV64XXX=m
CONFIG_I2C_OCORES=m
CONFIG_I2C_PCA_PLATFORM=m
CONFIG_I2C_PXA=m
CONFIG_I2C_QUP=m
CONFIG_I2C_RK3X=m
CONFIG_I2C_SIMTEC=m
CONFIG_I2C_SYNQUACER=m
CONFIG_I2C_TEGRA=y
CONFIG_I2C_THUNDERX=m
CONFIG_I2C_XLP9XX=m
CONFIG_I2C_DIOLAN_U2C=m
CONFIG_I2C_ROBOTFUZZ_OSIF=m
CONFIG_I2C_TAOS_EVM=m
CONFIG_I2C_TINY_USB=m
CONFIG_I2C_VIPERBOARD=m
CONFIG_I2C_CROS_EC_TUNNEL=m
CONFIG_I2C_XGENE_SLIMPRO=m
CONFIG_SPI=y
CONFIG_SPI_ARMADA_3700=m
CONFIG_SPI_BUTTERFLY=m
CONFIG_SPI_LM70_LLP=m
CONFIG_SPI_MESON_SPICC=m
CONFIG_SPI_MESON_SPIFC=m
CONFIG_SPI_ROCKCHIP=m
CONFIG_SPI_QUP=m
CONFIG_SPI_TEGRA114=m
CONFIG_SPI_TEGRA20_SFLASH=m
CONFIG_SPI_TEGRA20_SLINK=m
CONFIG_SPI_THUNDERX=m
CONFIG_SPI_XLP=m
CONFIG_SPI_SPIDEV=y
CONFIG_SPMI=y
CONFIG_PPS_CLIENT_LDISC=m
CONFIG_PPS_CLIENT_PARPORT=m
CONFIG_PINCTRL_AMD=y
CONFIG_PINCTRL_APPLE_GPIO=y
CONFIG_PINCTRL_AXP209=m
CONFIG_PINCTRL_MAX77620=y
CONFIG_PINCTRL_SINGLE=y
# CONFIG_PINCTRL_MT8195 is not set
CONFIG_PINCTRL_MSM=y
CONFIG_PINCTRL_MSM8916=y
CONFIG_PINCTRL_MSM8996=y
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
CONFIG_PINCTRL_QCOM_SSBI_PMIC=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_EXAR=m
CONFIG_GPIO_MB86S7X=m
CONFIG_GPIO_PL061=y
CONFIG_GPIO_XGENE=y
CONFIG_GPIO_XGENE_SB=m
CONFIG_GPIO_XLP=y
CONFIG_GPIO_ZYNQ=m
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_MAX77620=y
CONFIG_GPIO_PCI_IDIO_16=m
CONFIG_GPIO_PCIE_IDIO_24=m
CONFIG_GPIO_VIPERBOARD=m
CONFIG_W1=m
CONFIG_W1_MASTER_DS2490=m
CONFIG_W1_MASTER_DS2482=m
CONFIG_W1_MASTER_GPIO=m
CONFIG_W1_SLAVE_THERM=m
CONFIG_W1_SLAVE_SMEM=m
CONFIG_W1_SLAVE_DS2405=m
CONFIG_W1_SLAVE_DS2408=m
CONFIG_W1_SLAVE_DS2413=m
CONFIG_W1_SLAVE_DS2406=m
CONFIG_W1_SLAVE_DS2423=m
CONFIG_W1_SLAVE_DS2805=m
CONFIG_W1_SLAVE_DS2431=m
CONFIG_W1_SLAVE_DS2433=m
CONFIG_W1_SLAVE_DS2438=m
CONFIG_W1_SLAVE_DS2780=m
CONFIG_W1_SLAVE_DS2781=m
CONFIG_W1_SLAVE_DS28E04=m
CONFIG_W1_SLAVE_DS28E17=m
CONFIG_POWER_RESET_HISI=y
CONFIG_POWER_RESET_MSM=y
CONFIG_POWER_RESET_VEXPRESS=y
CONFIG_POWER_RESET_XGENE=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
CONFIG_BATTERY_DS2760=m
CONFIG_BATTERY_SBS=m
CONFIG_BATTERY_BQ27XXX=m
# CONFIG_BATTERY_BQ27XXX_I2C is not set
CONFIG_CHARGER_AXP20X=m
CONFIG_BATTERY_AXP20X=m
CONFIG_AXP20X_POWER=m
CONFIG_CHARGER_QCOM_SMBB=m
CONFIG_CHARGER_CROS_USBPD=m
CONFIG_CHARGER_CROS_PCHG=m
CONFIG_SENSORS_AD7414=m
CONFIG_SENSORS_AD7418=m
CONFIG_SENSORS_ADM1029=m
CONFIG_SENSORS_ADM9240=m
CONFIG_SENSORS_ADT7411=m
CONFIG_SENSORS_ADT7462=m
CONFIG_SENSORS_ADT7470=m
CONFIG_SENSORS_ADT7475=m
CONFIG_SENSORS_ASC7621=m
CONFIG_SENSORS_ATXP1=m
CONFIG_SENSORS_DS620=m
CONFIG_SENSORS_I5K_AMB=m
CONFIG_SENSORS_F71882FG=m
CONFIG_SENSORS_F75375S=m
CONFIG_SENSORS_FTSTEUTATES=m
CONFIG_SENSORS_G760A=m
CONFIG_SENSORS_IBMAEM=m
CONFIG_SENSORS_IBMPEX=m
CONFIG_SENSORS_JC42=m
CONFIG_SENSORS_LINEAGE=m
CONFIG_SENSORS_LTC4151=m
CONFIG_SENSORS_LTC4215=m
CONFIG_SENSORS_LTC4245=m
CONFIG_SENSORS_LTC4261=m
CONFIG_SENSORS_MAX1111=m
CONFIG_SENSORS_MAX16065=m
CONFIG_SENSORS_MAX1668=m
CONFIG_SENSORS_MAX6639=m
CONFIG_SENSORS_MAX6650=m
CONFIG_SENSORS_ADCXX=m
CONFIG_SENSORS_LM70=m
CONFIG_SENSORS_LM73=m
CONFIG_SENSORS_LM93=m
CONFIG_SENSORS_LM95241=m
CONFIG_SENSORS_LM95245=m
CONFIG_SENSORS_PC87427=m
CONFIG_SENSORS_NTC_THERMISTOR=m
CONFIG_SENSORS_NCT6683=m
CONFIG_SENSORS_NCT6775=m
CONFIG_SENSORS_NCT7802=m
CONFIG_SENSORS_NCT7904=m
CONFIG_SENSORS_NPCM7XX=m
CONFIG_SENSORS_PWM_FAN=m
CONFIG_SENSORS_SHT21=m
CONFIG_SENSORS_DME1737=m
CONFIG_SENSORS_EMC1403=m
CONFIG_SENSORS_EMC2103=m
CONFIG_SENSORS_EMC6W201=m
CONFIG_SENSORS_SMSC47M192=m
CONFIG_SENSORS_SCH5627=m
CONFIG_SENSORS_ADS7828=m
CONFIG_SENSORS_ADS7871=m
CONFIG_SENSORS_AMC6821=m
CONFIG_SENSORS_INA3221=m
CONFIG_SENSORS_THMC50=m
CONFIG_SENSORS_TMP102=m
CONFIG_SENSORS_TMP401=m
CONFIG_SENSORS_TMP421=m
CONFIG_SENSORS_VT1211=m
CONFIG_SENSORS_VT8231=m
CONFIG_SENSORS_W83773G=m
CONFIG_SENSORS_W83791D=m
CONFIG_SENSORS_W83792D=m
CONFIG_SENSORS_W83793=m
CONFIG_SENSORS_W83795=m
CONFIG_SENSORS_W83L786NG=m
CONFIG_SENSORS_W83627EHF=m
CONFIG_SENSORS_XGENE=m
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_CPU_THERMAL=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_HISI_THERMAL=m
CONFIG_ROCKCHIP_THERMAL=m
CONFIG_ARMADA_THERMAL=m
CONFIG_MTK_THERMAL=y
CONFIG_TEGRA_SOCTHERM=y
CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_QCOM_SPMI_TEMP_ALARM=m
CONFIG_KHADAS_MCU_FAN_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_SYSFS=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m
CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_GPIO_WATCHDOG=m
CONFIG_WDAT_WDT=m
CONFIG_ARM_SP805_WATCHDOG=m
CONFIG_ARM_SBSA_WATCHDOG=m
CONFIG_ARMADA_37XX_WATCHDOG=m
CONFIG_DW_WATCHDOG=m
CONFIG_SUNXI_WATCHDOG=m
CONFIG_TEGRA_WATCHDOG=m
CONFIG_QCOM_WDT=m
CONFIG_MESON_GXBB_WATCHDOG=m
CONFIG_MESON_WATCHDOG=m
# CONFIG_MEDIATEK_WATCHDOG is not set
CONFIG_APPLE_WATCHDOG=y
CONFIG_XEN_WDT=m
CONFIG_MFD_AXP20X_RSB=m
CONFIG_MFD_HI655X_PMIC=m
CONFIG_MFD_MAX77620=y
CONFIG_MFD_VIPERBOARD=m
CONFIG_MFD_QCOM_RPM=m
CONFIG_MFD_SPMI_PMIC=m
CONFIG_MFD_SUN6I_PRCM=y
CONFIG_MFD_KHADAS_MCU=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_AXP20X=m
CONFIG_REGULATOR_FAN53555=m
CONFIG_REGULATOR_GPIO=m
CONFIG_REGULATOR_HI655X=m
CONFIG_REGULATOR_MAX77620=m
CONFIG_REGULATOR_PWM=m
CONFIG_REGULATOR_QCOM_RPM=m
CONFIG_REGULATOR_QCOM_SMD_RPM=m
CONFIG_REGULATOR_QCOM_SPMI=m
CONFIG_REGULATOR_VCTRL=m
CONFIG_RC_CORE=m
CONFIG_LIRC=y
CONFIG_RC_DECODERS=y
CONFIG_IR_IMON_DECODER=m
CONFIG_IR_JVC_DECODER=m
CONFIG_IR_MCE_KBD_DECODER=m
CONFIG_IR_NEC_DECODER=m
CONFIG_IR_RC5_DECODER=m
CONFIG_IR_RC6_DECODER=m
CONFIG_IR_SANYO_DECODER=m
CONFIG_IR_SHARP_DECODER=m
CONFIG_IR_SONY_DECODER=m
CONFIG_IR_XMP_DECODER=m
CONFIG_RC_DEVICES=y
CONFIG_IR_ENE=m
CONFIG_IR_IGORPLUGUSB=m
CONFIG_IR_IGUANA=m
CONFIG_IR_IMON=m
CONFIG_IR_IMON_RAW=m
CONFIG_IR_MCEUSB=m
CONFIG_IR_REDRAT3=m
CONFIG_IR_STREAMZAP=m
CONFIG_IR_TTUSBIR=m
CONFIG_RC_ATI_REMOTE=m
CONFIG_RC_LOOPBACK=m
CONFIG_CEC_TEGRA=m
CONFIG_USB_PULSE8_CEC=m
CONFIG_USB_RAINSHADOW_CEC=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_USB_GSPCA=m
CONFIG_USB_GSPCA_BENQ=m
CONFIG_USB_GSPCA_CONEX=m
CONFIG_USB_GSPCA_CPIA1=m
CONFIG_USB_GSPCA_DTCS033=m
CONFIG_USB_GSPCA_ETOMS=m
CONFIG_USB_GSPCA_FINEPIX=m
CONFIG_USB_GSPCA_JEILINJ=m
CONFIG_USB_GSPCA_JL2005BCD=m
CONFIG_USB_GSPCA_KINECT=m
CONFIG_USB_GSPCA_KONICA=m
CONFIG_USB_GSPCA_MARS=m
CONFIG_USB_GSPCA_MR97310A=m
CONFIG_USB_GSPCA_NW80X=m
CONFIG_USB_GSPCA_OV519=m
CONFIG_USB_GSPCA_OV534=m
CONFIG_USB_GSPCA_OV534_9=m
CONFIG_USB_GSPCA_PAC207=m
CONFIG_USB_GSPCA_PAC7302=m
CONFIG_USB_GSPCA_PAC7311=m
CONFIG_USB_GSPCA_SE401=m
CONFIG_USB_GSPCA_SN9C2028=m
CONFIG_USB_GSPCA_SN9C20X=m
CONFIG_USB_GSPCA_SONIXB=m
CONFIG_USB_GSPCA_SONIXJ=m
CONFIG_USB_GSPCA_SPCA1528=m
CONFIG_USB_GSPCA_SPCA500=m
CONFIG_USB_GSPCA_SPCA501=m
CONFIG_USB_GSPCA_SPCA505=m
CONFIG_USB_GSPCA_SPCA506=m
CONFIG_USB_GSPCA_SPCA508=m
CONFIG_USB_GSPCA_SPCA561=m
CONFIG_USB_GSPCA_SQ905=m
CONFIG_USB_GSPCA_SQ905C=m
CONFIG_USB_GSPCA_SQ930X=m
CONFIG_USB_GSPCA_STK014=m
CONFIG_USB_GSPCA_STK1135=m
CONFIG_USB_GSPCA_STV0680=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
CONFIG_USB_GSPCA_TOPRO=m
CONFIG_USB_GSPCA_TOUPTEK=m
CONFIG_USB_GSPCA_TV8532=m
CONFIG_USB_GSPCA_VC032X=m
CONFIG_USB_GSPCA_VICAM=m
CONFIG_USB_GSPCA_XIRLINK_CIT=m
CONFIG_USB_GSPCA_ZC3XX=m
CONFIG_USB_GL860=m
CONFIG_USB_M5602=m
CONFIG_USB_STV06XX=m
CONFIG_USB_PWC=m
CONFIG_USB_S2255=m
CONFIG_VIDEO_USBTV=m
CONFIG_USB_VIDEO_CLASS=m
CONFIG_VIDEO_GO7007=m
CONFIG_VIDEO_GO7007_USB=m
CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m
CONFIG_VIDEO_HDPVR=m
CONFIG_VIDEO_PVRUSB2=m
CONFIG_VIDEO_STK1160=m
CONFIG_VIDEO_AU0828=m
CONFIG_VIDEO_AU0828_RC=y
CONFIG_VIDEO_CX231XX=m
CONFIG_VIDEO_CX231XX_ALSA=m
CONFIG_VIDEO_CX231XX_DVB=m
CONFIG_DVB_AS102=m
CONFIG_DVB_B2C2_FLEXCOP_USB=m
CONFIG_DVB_USB_V2=m
CONFIG_DVB_USB_AF9015=m
CONFIG_DVB_USB_AF9035=m
CONFIG_DVB_USB_ANYSEE=m
CONFIG_DVB_USB_AU6610=m
CONFIG_DVB_USB_AZ6007=m
CONFIG_DVB_USB_CE6230=m
CONFIG_DVB_USB_DVBSKY=m
CONFIG_DVB_USB_EC168=m
CONFIG_DVB_USB_GL861=m
CONFIG_DVB_USB_LME2510=m
CONFIG_DVB_USB_MXL111SF=m
CONFIG_DVB_USB_RTL28XXU=m
CONFIG_DVB_USB_ZD1301=m
CONFIG_DVB_USB=m
CONFIG_DVB_USB_A800=m
CONFIG_DVB_USB_AF9005=m
CONFIG_DVB_USB_AF9005_REMOTE=m
CONFIG_DVB_USB_AZ6027=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_USB_CXUSB=m
CONFIG_DVB_USB_DIB0700=m
CONFIG_DVB_USB_DIBUSB_MB=m
CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y
CONFIG_DVB_USB_DIBUSB_MC=m
CONFIG_DVB_USB_DIGITV=m
CONFIG_DVB_USB_DTT200U=m
CONFIG_DVB_USB_DTV5100=m
CONFIG_DVB_USB_DW2102=m
CONFIG_DVB_USB_GP8PSK=m
CONFIG_DVB_USB_M920X=m
CONFIG_DVB_USB_NOVA_T_USB2=m
CONFIG_DVB_USB_OPERA1=m
CONFIG_DVB_USB_PCTV452E=m
CONFIG_DVB_USB_TECHNISAT_USB2=m
CONFIG_DVB_USB_TTUSB2=m
CONFIG_DVB_USB_UMT_010=m
CONFIG_DVB_USB_VP702X=m
CONFIG_DVB_USB_VP7045=m
CONFIG_SMS_USB_DRV=m
CONFIG_DVB_TTUSB_BUDGET=m
CONFIG_DVB_TTUSB_DEC=m
CONFIG_VIDEO_EM28XX=m
CONFIG_VIDEO_EM28XX_V4L2=m
CONFIG_VIDEO_EM28XX_ALSA=m
CONFIG_VIDEO_EM28XX_DVB=m
CONFIG_USB_AIRSPY=m
CONFIG_USB_HACKRF=m
CONFIG_USB_MSI2500=m
CONFIG_MEDIA_PCI_SUPPORT=y
CONFIG_VIDEO_SOLO6X10=m
CONFIG_VIDEO_TW5864=m
CONFIG_VIDEO_TW68=m
CONFIG_VIDEO_TW686X=m
CONFIG_VIDEO_DT3155=m
CONFIG_VIDEO_IVTV=m
CONFIG_VIDEO_IVTV_ALSA=m
CONFIG_VIDEO_FB_IVTV=m
CONFIG_VIDEO_HEXIUM_GEMINI=m
CONFIG_VIDEO_HEXIUM_ORION=m
CONFIG_VIDEO_MXB=m
CONFIG_VIDEO_BT848=m
CONFIG_DVB_BT8XX=m
CONFIG_VIDEO_CX18=m
CONFIG_VIDEO_CX18_ALSA=m
CONFIG_VIDEO_CX23885=m
CONFIG_MEDIA_ALTERA_CI=m
CONFIG_VIDEO_CX88=m
CONFIG_VIDEO_CX88_ALSA=m
CONFIG_VIDEO_CX88_BLACKBIRD=m
CONFIG_VIDEO_CX88_DVB=m
CONFIG_VIDEO_SAA7134=m
CONFIG_VIDEO_SAA7134_ALSA=m
CONFIG_VIDEO_SAA7134_DVB=m
CONFIG_VIDEO_SAA7164=m
CONFIG_DVB_B2C2_FLEXCOP_PCI=m
CONFIG_DVB_DDBRIDGE=m
CONFIG_DVB_DM1105=m
CONFIG_MANTIS_CORE=m
CONFIG_DVB_MANTIS=m
CONFIG_DVB_HOPPER=m
CONFIG_DVB_NETUP_UNIDVB=m
CONFIG_DVB_NGENE=m
CONFIG_DVB_PLUTO2=m
CONFIG_DVB_PT1=m
CONFIG_DVB_PT3=m
CONFIG_DVB_SMIPCIE=m
CONFIG_DVB_BUDGET_CORE=m
CONFIG_DVB_BUDGET=m
CONFIG_DVB_BUDGET_CI=m
CONFIG_DVB_BUDGET_AV=m
CONFIG_RADIO_SHARK=m
CONFIG_RADIO_SHARK2=m
CONFIG_USB_KEENE=m
CONFIG_USB_MA901=m
CONFIG_USB_MR800=m
CONFIG_USB_RAREMONO=m
CONFIG_RADIO_SI470X=m
CONFIG_USB_SI470X=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_VIDEO_CAFE_CCIC=m
CONFIG_SMS_SDIO_DRV=m
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIVID=m
CONFIG_VIDEO_VIVID_CEC=y
CONFIG_DVB_FIREDTV=m
CONFIG_DVB_DUMMY_FE=m
CONFIG_DRM=m
CONFIG_DRM_LOAD_EDID_FIRMWARE=y
# CONFIG_DRM_I2C_CH7006 is not set
# CONFIG_DRM_I2C_SIL164 is not set
CONFIG_DRM_HDLCD=m
CONFIG_DRM_MALI_DISPLAY=m
CONFIG_DRM_RADEON=m
CONFIG_DRM_AMDGPU=m
CONFIG_DRM_AMDGPU_SI=y
CONFIG_DRM_AMDGPU_CIK=y
CONFIG_DRM_NOUVEAU=m
CONFIG_DRM_VGEM=m
CONFIG_DRM_ROCKCHIP=m
CONFIG_ROCKCHIP_ANALOGIX_DP=y
CONFIG_ROCKCHIP_CDN_DP=y
CONFIG_ROCKCHIP_DW_HDMI=y
CONFIG_ROCKCHIP_DW_MIPI_DSI=y
CONFIG_DRM_UDL=m
CONFIG_DRM_AST=m
CONFIG_DRM_SUN4I=m
# CONFIG_DRM_SUN6I_DSI is not set
# CONFIG_DRM_SUN8I_MIXER is not set
CONFIG_DRM_QXL=m
CONFIG_DRM_VIRTIO_GPU=m
CONFIG_DRM_MSM=m
CONFIG_DRM_TEGRA=m
CONFIG_DRM_TEGRA_STAGING=y
CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_I2C_ADV7511=m
CONFIG_DRM_I2C_ADV7511_AUDIO=y
# CONFIG_DRM_DW_HDMI_I2S_AUDIO is not set
CONFIG_DRM_HISI_HIBMC=m
CONFIG_DRM_HISI_KIRIN=m
CONFIG_DRM_MESON=m
CONFIG_DRM_BOCHS=m
CONFIG_DRM_CIRRUS_QEMU=m
CONFIG_DRM_PANFROST=m
CONFIG_FB=y
CONFIG_FB_EFI=y
CONFIG_FB_S3=m
CONFIG_FB_3DFX=m
CONFIG_FB_VT8623=m
CONFIG_FB_ARK=m
CONFIG_FB_PM3=m
CONFIG_FB_SMSCUFX=m
CONFIG_FB_UDL=m
CONFIG_FB_MB862XX=m
CONFIG_FB_SIMPLE=y
CONFIG_FIRMWARE_EDID=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=m
CONFIG_BACKLIGHT_LP855X=m
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_SOUND=m
CONFIG_SND=m
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_HRTIMER=m
CONFIG_SND_SEQUENCER=m
CONFIG_SND_SEQ_DUMMY=m
CONFIG_SND_ALOOP=m
CONFIG_SND_MTS64=m
CONFIG_SND_PORTMAN2X4=m
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AD1889=m
CONFIG_SND_OXYGEN=m
CONFIG_SND_CTXFI=m
CONFIG_SND_DARLA20=m
CONFIG_SND_GINA20=m
CONFIG_SND_LAYLA20=m
CONFIG_SND_DARLA24=m
CONFIG_SND_GINA24=m
CONFIG_SND_LAYLA24=m
CONFIG_SND_MONA=m
CONFIG_SND_MIA=m
CONFIG_SND_ECHO3G=m
CONFIG_SND_INDIGO=m
CONFIG_SND_INDIGOIO=m
CONFIG_SND_INDIGODJ=m
CONFIG_SND_INDIGOIOX=m
CONFIG_SND_INDIGODJX=m
CONFIG_SND_HDSPM=m
CONFIG_SND_LOLA=m
CONFIG_SND_LX6464ES=m
CONFIG_SND_PCXHR=m
CONFIG_SND_RIPTIDE=m
CONFIG_SND_VIRTUOSO=m
CONFIG_SND_HDA_INTEL=m
CONFIG_SND_HDA_TEGRA=m
CONFIG_SND_HDA_HWDEP=y
CONFIG_SND_HDA_INPUT_BEEP=y
CONFIG_SND_HDA_PATCH_LOADER=y
CONFIG_SND_HDA_CODEC_REALTEK=m
CONFIG_SND_HDA_CODEC_ANALOG=m
CONFIG_SND_HDA_CODEC_SIGMATEL=m
CONFIG_SND_HDA_CODEC_VIA=m
CONFIG_SND_HDA_CODEC_HDMI=m
CONFIG_SND_HDA_CODEC_CIRRUS=m
CONFIG_SND_HDA_CODEC_CONEXANT=m
CONFIG_SND_HDA_CODEC_CA0110=m
CONFIG_SND_HDA_CODEC_CA0132=m
CONFIG_SND_HDA_CODEC_CMEDIA=m
CONFIG_SND_HDA_CODEC_SI3054=m
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=1
CONFIG_SND_HDA_PREALLOC_SIZE=2048
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_USB_UA101=m
CONFIG_SND_USB_CAIAQ=m
CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_6FIRE=m
CONFIG_SND_USB_HIFACE=m
CONFIG_SND_BCD2000=m
CONFIG_SND_USB_POD=m
CONFIG_SND_USB_PODHD=m
CONFIG_SND_USB_TONEPORT=m
CONFIG_SND_USB_VARIAX=m
CONFIG_SND_DICE=m
CONFIG_SND_OXFW=m
CONFIG_SND_ISIGHT=m
CONFIG_SND_FIREWORKS=m
CONFIG_SND_BEBOB=m
CONFIG_SND_FIREWIRE_DIGI00X=m
CONFIG_SND_FIREWIRE_TASCAM=m
CONFIG_SND_FIREWIRE_MOTU=m
CONFIG_SND_FIREFACE=m
CONFIG_SND_SOC=m
CONFIG_SND_I2S_HI6210_I2S=m
CONFIG_SND_MESON_AXG_SOUND_CARD=m
# CONFIG_SND_MESON_G12A_TOACODEC is not set
CONFIG_SND_SOC_QCOM=m
CONFIG_SND_SOC_APQ8016_SBC=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
CONFIG_SND_SOC_ROCKCHIP_RT5645=m
CONFIG_SND_SOC_RK3399_GRU_SOUND=m
CONFIG_SND_SOC_TEGRA=m
CONFIG_SND_SOC_TEGRA20_SPDIF=m
CONFIG_SND_SOC_TEGRA186_DSPK=m
CONFIG_SND_SOC_TEGRA_RT5640=m
CONFIG_SND_SOC_TEGRA_WM8753=m
CONFIG_SND_SOC_TEGRA_WM8903=m
CONFIG_SND_SOC_TEGRA_TRIMSLICE=m
CONFIG_SND_SOC_TEGRA_ALC5632=m
CONFIG_SND_SOC_TEGRA_MAX98090=m
CONFIG_SND_SOC_TEGRA_RT5677=m
# CONFIG_SND_SOC_SPDIF is not set
CONFIG_SND_XEN_FRONTEND=m
CONFIG_HID_BATTERY_STRENGTH=y
CONFIG_HIDRAW=y
CONFIG_UHID=y
CONFIG_HID_A4TECH=m
CONFIG_HID_ACCUTOUCH=m
CONFIG_HID_ACRUX=m
CONFIG_HID_ACRUX_FF=y
CONFIG_HID_APPLE=m
CONFIG_HID_ASUS=m
CONFIG_HID_AUREAL=m
CONFIG_HID_BELKIN=m
CONFIG_HID_BETOP_FF=m
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
CONFIG_HID_CORSAIR=m
CONFIG_HID_COUGAR=m
CONFIG_HID_PRODIKEYS=m
CONFIG_HID_CMEDIA=m
CONFIG_HID_CP2112=m
CONFIG_HID_CYPRESS=m
CONFIG_HID_DRAGONRISE=m
CONFIG_DRAGONRISE_FF=y
CONFIG_HID_EMS_FF=m
CONFIG_HID_ELAN=m
CONFIG_HID_ELECOM=m
CONFIG_HID_ELO=m
CONFIG_HID_EZKEY=m
CONFIG_HID_GEMBIRD=m
CONFIG_HID_HOLTEK=m
CONFIG_HOLTEK_FF=y
CONFIG_HID_KEYTOUCH=m
CONFIG_HID_KYE=m
CONFIG_HID_UCLOGIC=m
CONFIG_HID_WALTOP=m
CONFIG_HID_GYRATION=m
CONFIG_HID_ICADE=m
CONFIG_HID_ITE=m
CONFIG_HID_JABRA=m
CONFIG_HID_TWINHAN=m
CONFIG_HID_KENSINGTON=m
CONFIG_HID_LCPOWER=m
CONFIG_HID_LENOVO=m
CONFIG_HID_LOGITECH=m
CONFIG_HID_LOGITECH_DJ=m
CONFIG_LOGITECH_FF=y
CONFIG_LOGIRUMBLEPAD2_FF=y
CONFIG_LOGIG940_FF=y
CONFIG_HID_MAGICMOUSE=m
CONFIG_HID_MAYFLASH=m
CONFIG_HID_REDRAGON=m
CONFIG_HID_MICROSOFT=m
CONFIG_HID_MONTEREY=m
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NTI=m
CONFIG_HID_NTRIG=m
CONFIG_HID_ORTEK=m
CONFIG_HID_PANTHERLORD=m
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PENMOUNT=m
CONFIG_HID_PETALYNX=m
CONFIG_HID_PICOLCD=m
CONFIG_HID_PICOLCD_FB=y
CONFIG_HID_PICOLCD_BACKLIGHT=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PICOLCD_CIR=y
CONFIG_HID_PLANTRONICS=m
CONFIG_HID_PRIMAX=m
CONFIG_HID_RETRODE=m
CONFIG_HID_ROCCAT=m
CONFIG_HID_SAITEK=m
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SONY=m
CONFIG_SONY_FF=y
CONFIG_HID_SPEEDLINK=m
CONFIG_HID_STEAM=m
CONFIG_HID_STEELSERIES=m
CONFIG_HID_SUNPLUS=m
CONFIG_HID_RMI=m
CONFIG_HID_GREENASIA=m
CONFIG_GREENASIA_FF=y
CONFIG_HID_SMARTJOYPLUS=m
CONFIG_SMARTJOYPLUS_FF=y
CONFIG_HID_TIVO=m
CONFIG_HID_TOPSEED=m
CONFIG_HID_THINGM=m
CONFIG_HID_THRUSTMASTER=m
CONFIG_THRUSTMASTER_FF=y
CONFIG_HID_UDRAW_PS3=m
CONFIG_HID_WACOM=m
CONFIG_HID_WIIMOTE=m
CONFIG_HID_XINMO=m
CONFIG_HID_ZEROPLUS=m
CONFIG_ZEROPLUS_FF=y
CONFIG_HID_ZYDACRON=m
CONFIG_HID_SENSOR_HUB=m
CONFIG_HID_SENSOR_CUSTOM_SENSOR=m
CONFIG_HID_ALPS=m
CONFIG_USB_HID=m
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y
CONFIG_USB_LED_TRIG=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_OTG=y
CONFIG_USB_OTG_FSM=m
CONFIG_USB_LEDS_TRIGGER_USBPORT=m
CONFIG_USB_MON=m
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_TEGRA=m
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_TEGRA=m
CONFIG_USB_EHCI_HCD_PLATFORM=m
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PLATFORM=m
CONFIG_USB_PRINTER=m
CONFIG_USB_TMC=m
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_REALTEK=m
CONFIG_USB_STORAGE_DATAFAB=m
CONFIG_USB_STORAGE_FREECOM=m
CONFIG_USB_STORAGE_ISD200=m
CONFIG_USB_STORAGE_USBAT=m
CONFIG_USB_STORAGE_SDDR09=m
CONFIG_USB_STORAGE_SDDR55=m
CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_STORAGE_ALAUDA=m
CONFIG_USB_STORAGE_ONETOUCH=m
CONFIG_USB_STORAGE_KARMA=m
CONFIG_USB_STORAGE_CYPRESS_ATACB=m
CONFIG_USB_STORAGE_ENE_UB6250=m
CONFIG_USB_UAS=y
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
CONFIG_USBIP_CORE=m
CONFIG_USBIP_VHCI_HCD=m
CONFIG_USBIP_VHCI_HC_PORTS=15
CONFIG_USBIP_VHCI_NR_HCS=8
CONFIG_USBIP_HOST=m
CONFIG_USBIP_VUDC=m
CONFIG_USB_MUSB_HDRC=m
CONFIG_USB_MUSB_SUNXI=m
CONFIG_USB_DWC3=m
CONFIG_USB_DWC3_ULPI=y
CONFIG_USB_DWC2=m
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_ISP1760=m
CONFIG_USB_SERIAL=m
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_SIMPLE=m
CONFIG_USB_SERIAL_AIRCABLE=m
CONFIG_USB_SERIAL_ARK3116=m
CONFIG_USB_SERIAL_BELKIN=m
CONFIG_USB_SERIAL_CH341=m
CONFIG_USB_SERIAL_WHITEHEAT=m
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
CONFIG_USB_SERIAL_CP210X=m
CONFIG_USB_SERIAL_CYPRESS_M8=m
CONFIG_USB_SERIAL_EMPEG=m
CONFIG_USB_SERIAL_FTDI_SIO=m
CONFIG_USB_SERIAL_VISOR=m
CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
CONFIG_USB_SERIAL_F81232=m
CONFIG_USB_SERIAL_F8153X=m
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IUU=m
CONFIG_USB_SERIAL_KEYSPAN_PDA=m
CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_SERIAL_METRO=m
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MXUPORT=m
CONFIG_USB_SERIAL_NAVMAN=m
CONFIG_USB_SERIAL_PL2303=m
CONFIG_USB_SERIAL_OTI6858=m
CONFIG_USB_SERIAL_QCAUX=m
CONFIG_USB_SERIAL_QUALCOMM=m
CONFIG_USB_SERIAL_SPCP8X5=m
CONFIG_USB_SERIAL_SAFE=m
CONFIG_USB_SERIAL_SIERRAWIRELESS=m
CONFIG_USB_SERIAL_SYMBOL=m
CONFIG_USB_SERIAL_TI=m
CONFIG_USB_SERIAL_CYBERJACK=m
CONFIG_USB_SERIAL_OPTION=m
CONFIG_USB_SERIAL_OMNINET=m
CONFIG_USB_SERIAL_OPTICON=m
CONFIG_USB_SERIAL_XSENS_MT=m
CONFIG_USB_SERIAL_WISHBONE=m
CONFIG_USB_SERIAL_SSU100=m
CONFIG_USB_SERIAL_QT2=m
CONFIG_USB_SERIAL_UPD78F0730=m
CONFIG_USB_SERIAL_DEBUG=m
CONFIG_USB_EMI62=m
CONFIG_USB_EMI26=m
CONFIG_USB_ADUTUX=m
CONFIG_USB_SEVSEG=m
CONFIG_USB_LEGOTOWER=m
CONFIG_USB_LCD=m
CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_APPLEDISPLAY=m
CONFIG_USB_SISUSBVGA=m
CONFIG_USB_LD=m
CONFIG_USB_TRANCEVIBRATOR=m
CONFIG_USB_IOWARRIOR=m
CONFIG_USB_TEST=m
CONFIG_USB_EHSET_TEST_FIXTURE=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
CONFIG_USB_HSIC_USB3503=m
CONFIG_USB_CHAOSKEY=m
CONFIG_NOP_USB_XCEIV=m
CONFIG_USB_TEGRA_PHY=y
CONFIG_USB_NET2280=m
CONFIG_USB_TEGRA_XUDC=m
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_PHONET=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_UAC1=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_CONFIGFS_F_PRINTER=y
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
CONFIG_USB_FUNCTIONFS=m
CONFIG_USB_FUNCTIONFS_ETH=y
CONFIG_USB_FUNCTIONFS_RNDIS=y
CONFIG_USB_FUNCTIONFS_GENERIC=y
CONFIG_USB_G_SERIAL=m
CONFIG_TYPEC=m
CONFIG_TYPEC_TCPM=m
CONFIG_TYPEC_TCPCI=m
CONFIG_TYPEC_RT1711H=m
CONFIG_TYPEC_FUSB302=m
CONFIG_TYPEC_UCSI=m
CONFIG_UCSI_CCG=m
CONFIG_UCSI_ACPI=m
CONFIG_TYPEC_TPS6598X=m
CONFIG_TYPEC_HD3SS3220=m
CONFIG_TYPEC_MUX_PI3USB30532=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=256
CONFIG_SDIO_UART=m
CONFIG_MMC_ARMMMCI=m
CONFIG_MMC_SDHCI=m
CONFIG_MMC_SDHCI_PCI=m
CONFIG_MMC_SDHCI_ACPI=m
CONFIG_MMC_SDHCI_PLTFM=m
CONFIG_MMC_SDHCI_OF_ARASAN=m
CONFIG_MMC_SDHCI_TEGRA=m
CONFIG_MMC_SDHCI_F_SDH30=m
CONFIG_MMC_MESON_GX=m
CONFIG_MMC_MESON_MX_SDIO=m
CONFIG_MMC_SDHCI_MSM=m
CONFIG_MMC_TIFM_SD=m
CONFIG_MMC_SPI=m
CONFIG_MMC_CB710=m
CONFIG_MMC_VIA_SDMMC=m
CONFIG_MMC_DW=m
CONFIG_MMC_DW_K3=m
CONFIG_MMC_DW_ROCKCHIP=m
CONFIG_MMC_VUB300=m
CONFIG_MMC_USHC=m
CONFIG_MMC_REALTEK_PCI=m
CONFIG_MMC_REALTEK_USB=m
CONFIG_MMC_SUNXI=m
CONFIG_MMC_TOSHIBA_PCI=m
CONFIG_MMC_SDHCI_XENON=m
CONFIG_SCSI_UFSHCD=m
CONFIG_SCSI_UFSHCD_PCI=m
CONFIG_MEMSTICK=m
CONFIG_MSPRO_BLOCK=m
CONFIG_MEMSTICK_TIFM_MS=m
CONFIG_MEMSTICK_JMICRON_38X=m
CONFIG_MEMSTICK_R592=m
CONFIG_MEMSTICK_REALTEK_USB=m
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
CONFIG_LEDS_GPIO=m
CONFIG_LEDS_LP3944=m
CONFIG_LEDS_PCA955X=m
CONFIG_LEDS_DAC124S085=m
CONFIG_LEDS_PWM=m
CONFIG_LEDS_REGULATOR=m
CONFIG_LEDS_BD2802=m
CONFIG_LEDS_LT3593=m
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_DISK=y
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_TRIGGER_CAMERA=m
CONFIG_LEDS_TRIGGER_PANIC=y
CONFIG_ACCESSIBILITY=y
CONFIG_A11Y_BRAILLE_CONSOLE=y
CONFIG_SPEAKUP=m
CONFIG_SPEAKUP_SYNTH_ACNTSA=m
CONFIG_SPEAKUP_SYNTH_APOLLO=m
CONFIG_SPEAKUP_SYNTH_AUDPTR=m
CONFIG_SPEAKUP_SYNTH_BNS=m
CONFIG_SPEAKUP_SYNTH_DECTLK=m
CONFIG_SPEAKUP_SYNTH_DECEXT=m
CONFIG_SPEAKUP_SYNTH_LTLK=m
CONFIG_SPEAKUP_SYNTH_SOFT=m
CONFIG_SPEAKUP_SYNTH_SPKOUT=m
CONFIG_SPEAKUP_SYNTH_TXPRT=m
CONFIG_SPEAKUP_SYNTH_DUMMY=m
CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_MAD=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_CXGB4=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_MLX5_INFINIBAND=m
CONFIG_INFINIBAND_MTHCA=m
CONFIG_INFINIBAND_OCRDMA=m
CONFIG_INFINIBAND_QEDR=m
CONFIG_RDMA_RXE=m
CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_SRPT=m
CONFIG_INFINIBAND_ISER=m
CONFIG_INFINIBAND_ISERT=m
CONFIG_EDAC=y
CONFIG_EDAC_THUNDERX=m
CONFIG_EDAC_XGENE=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_DS1307=y
CONFIG_RTC_DRV_HYM8563=m
CONFIG_RTC_DRV_MAX77686=y
CONFIG_RTC_DRV_PCF85363=m
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_EFI=y
CONFIG_RTC_DRV_CROS_EC=m
CONFIG_RTC_DRV_PL031=y
CONFIG_RTC_DRV_SUN6I=y
CONFIG_RTC_DRV_MV=m
CONFIG_RTC_DRV_ARMADA38X=m
CONFIG_RTC_DRV_PM8XXX=m
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_DRV_XGENE=y
CONFIG_DMADEVICES=y
CONFIG_DMA_SUN6I=m
CONFIG_K3_DMA=m
CONFIG_MV_XOR=y
CONFIG_MV_XOR_V2=y
CONFIG_PL330_DMA=m
CONFIG_TEGRA20_APB_DMA=y
CONFIG_TEGRA210_ADMA=y
CONFIG_XGENE_DMA=m
CONFIG_QCOM_BAM_DMA=m
CONFIG_QCOM_HIDMA_MGMT=m
CONFIG_QCOM_HIDMA=m
CONFIG_ASYNC_TX_DMA=y
CONFIG_UIO_CIF=m
CONFIG_UIO_AEC=m
CONFIG_UIO_SERCOS3=m
CONFIG_UIO_PCI_GENERIC=m
CONFIG_UIO_NETX=m
CONFIG_UIO_MF624=m
CONFIG_VFIO=m
CONFIG_VFIO_NOIOMMU=y
CONFIG_VFIO_PCI=m
CONFIG_VIRT_DRIVERS=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VHOST_NET=m
CONFIG_VHOST_SCSI=m
CONFIG_VHOST_VSOCK=m
CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XENFS=m
CONFIG_XEN_SCSI_BACKEND=m
CONFIG_STAGING=y
CONFIG_RTL8723BS=m
CONFIG_R8712U=m
CONFIG_CHROME_PLATFORMS=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_I2C=m
CONFIG_CROS_EC_SPI=m
CONFIG_CROS_KBD_LED_BACKLIGHT=m
CONFIG_CLK_SP810=y
# CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set
# CONFIG_COMMON_CLK_MT8183_CAMSYS is not set
# CONFIG_COMMON_CLK_MT8183_IMGSYS is not set
# CONFIG_COMMON_CLK_MT8183_IPU_CORE0 is not set
# CONFIG_COMMON_CLK_MT8183_IPU_CORE1 is not set
# CONFIG_COMMON_CLK_MT8183_IPU_ADL is not set
# CONFIG_COMMON_CLK_MT8183_IPU_CONN is not set
# CONFIG_COMMON_CLK_MT8183_MFGCFG is not set
# CONFIG_COMMON_CLK_MT8183_MMSYS is not set
# CONFIG_COMMON_CLK_MT8183_VDECSYS is not set
# CONFIG_COMMON_CLK_MT8183_VENCSYS is not set
# CONFIG_COMMON_CLK_MT8192_AUDSYS is not set
# CONFIG_COMMON_CLK_MT8192_CAMSYS is not set
# CONFIG_COMMON_CLK_MT8192_IMGSYS is not set
# CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP is not set
# CONFIG_COMMON_CLK_MT8192_IPESYS is not set
# CONFIG_COMMON_CLK_MT8192_MDPSYS is not set
# CONFIG_COMMON_CLK_MT8192_MFGCFG is not set
# CONFIG_COMMON_CLK_MT8192_MMSYS is not set
# CONFIG_COMMON_CLK_MT8192_MSDC is not set
# CONFIG_COMMON_CLK_MT8192_SCP_ADSP is not set
# CONFIG_COMMON_CLK_MT8192_VDECSYS is not set
# CONFIG_COMMON_CLK_MT8192_VENCSYS is not set
# CONFIG_COMMON_CLK_AXG_AUDIO is not set
CONFIG_COMMON_CLK_QCOM=y
CONFIG_QCOM_A53PLL=y
CONFIG_QCOM_CLK_APCS_MSM8916=m
CONFIG_QCOM_CLK_RPM=m
CONFIG_QCOM_CLK_SMD_RPM=m
CONFIG_MSM_GCC_8916=y
CONFIG_MSM_MMCC_8996=y
# CONFIG_COMMON_CLK_ZYNQMP is not set
CONFIG_ARMADA_37XX_RWTM_MBOX=m
CONFIG_QCOM_APCS_IPC=m
CONFIG_XGENE_SLIMPRO_MBOX=m
CONFIG_ROCKCHIP_IOMMU=y
CONFIG_TEGRA_IOMMU_SMMU=y
CONFIG_ARM_SMMU=y
# CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is not set
CONFIG_ARM_SMMU_V3=y
CONFIG_QCOM_IOMMU=y
CONFIG_RPMSG_QCOM_GLINK_RPM=m
CONFIG_QCOM_COMMAND_DB=y
CONFIG_QCOM_GSBI=m
CONFIG_QCOM_SMD_RPM=m
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_ROCKCHIP_IODOMAIN=m
CONFIG_ARCH_TEGRA_132_SOC=y
CONFIG_ARCH_TEGRA_210_SOC=y
CONFIG_ARCH_TEGRA_186_SOC=y
CONFIG_ARCH_TEGRA_194_SOC=y
CONFIG_ROCKCHIP_PM_DOMAINS=y
CONFIG_ARM_TEGRA_DEVFREQ=m
CONFIG_ARM_RK3399_DMC_DEVFREQ=m
CONFIG_EXTCON_QCOM_SPMI_MISC=m
CONFIG_EXTCON_USB_GPIO=m
CONFIG_EXTCON_USBC_CROS_EC=m
CONFIG_MEMORY=y
CONFIG_IIO=m
CONFIG_HID_SENSOR_ACCEL_3D=m
CONFIG_IIO_CROS_EC_ACCEL_LEGACY=m
CONFIG_AXP20X_ADC=m
CONFIG_AXP288_ADC=m
CONFIG_QCOM_SPMI_IADC=m
CONFIG_QCOM_SPMI_VADC=m
CONFIG_ROCKCHIP_SARADC=m
CONFIG_VIPERBOARD_ADC=m
CONFIG_IIO_CROS_EC_SENSORS_CORE=m
CONFIG_IIO_CROS_EC_SENSORS=m
CONFIG_AD5446=m
CONFIG_HID_SENSOR_GYRO_3D=m
CONFIG_DHT11=m
CONFIG_ACPI_ALS=m
CONFIG_BH1780=m
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
CONFIG_HID_SENSOR_ALS=m
CONFIG_HID_SENSOR_PROX=m
CONFIG_HID_SENSOR_MAGNETOMETER_3D=m
CONFIG_HID_SENSOR_INCLINOMETER_3D=m
CONFIG_HID_SENSOR_DEVICE_ROTATION=m
CONFIG_IIO_CROS_EC_BARO=m
CONFIG_HID_SENSOR_PRESS=m
CONFIG_PWM=y
CONFIG_PWM_CROS_EC=m
CONFIG_PWM_MESON=m
CONFIG_PWM_ROCKCHIP=m
CONFIG_PWM_SUN4I=m
CONFIG_PWM_TEGRA=m
CONFIG_QCOM_PDC=y
# CONFIG_RESET_MESON_AUDIO_ARB is not set
CONFIG_PHY_XGENE=m
CONFIG_PHY_SUN4I_USB=m
CONFIG_PHY_MESON8B_USB2=m
CONFIG_PHY_HI6220_USB=m
CONFIG_PHY_MVEBU_CP110_COMPHY=m
CONFIG_PHY_MVEBU_CP110_UTMI=m
CONFIG_PHY_QCOM_APQ8064_SATA=m
CONFIG_PHY_QCOM_IPQ806X_SATA=m
CONFIG_PHY_QCOM_QMP=m
CONFIG_PHY_QCOM_QUSB2=m
CONFIG_PHY_QCOM_USB_HS=m
CONFIG_PHY_QCOM_USB_HSIC=m
CONFIG_PHY_ROCKCHIP_DP=m
CONFIG_PHY_ROCKCHIP_EMMC=m
CONFIG_PHY_ROCKCHIP_INNO_USB2=m
CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m
CONFIG_PHY_ROCKCHIP_PCIE=m
CONFIG_PHY_ROCKCHIP_TYPEC=m
CONFIG_PHY_ROCKCHIP_USB=m
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_ARM_CCI_PMU=y
CONFIG_ARM_CCN=y
CONFIG_QCOM_L2_PMU=y
CONFIG_QCOM_L3_PMU=y
CONFIG_XGENE_PMU=y
CONFIG_APPLE_M1_CPU_PMU=y
CONFIG_HISI_PMU=y
CONFIG_DAX=y
CONFIG_DEV_DAX=m
CONFIG_NVMEM_SUNXI_SID=m
CONFIG_TEE=m
CONFIG_OPTEE=m
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_REISERFS_FS=m
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_XFS_FS=m
CONFIG_XFS_QUOTA=y
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_GFS2_FS=m
CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_OCFS2_FS=m
CONFIG_NILFS2_FS=m
CONFIG_F2FS_FS=m
CONFIG_F2FS_FS_SECURITY=y
CONFIG_FANOTIFY=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_AUTOFS_FS=m
CONFIG_FUSE_FS=m
CONFIG_CUSE=m
CONFIG_OVERLAY_FS=m
CONFIG_FSCACHE_STATS=y
CONFIG_CACHEFILES=m
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
CONFIG_FAT_DEFAULT_UTF8=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y
CONFIG_ORANGEFS_FS=m
CONFIG_ADFS_FS=m
CONFIG_AFFS_FS=m
CONFIG_ECRYPT_FS=m
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_JFFS2_FS=m
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_LZO=y
CONFIG_UBIFS_FS=m
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_SQUASHFS=m
CONFIG_SQUASHFS_XATTR=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_VXFS_FS=m
CONFIG_MINIX_FS=m
CONFIG_OMFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_QNX6FS_FS=m
CONFIG_ROMFS_FS=m
CONFIG_ROMFS_BACKED_BY_BOTH=y
CONFIG_PSTORE_RAM=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_NFS_FS=m
CONFIG_NFS_V2=m
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=m
CONFIG_NFS_SWAP=y
CONFIG_NFS_V4_1=y
CONFIG_NFS_V4_2=y
CONFIG_NFS_FSCACHE=y
# CONFIG_NFS_V4_2_READ_PLUS is not set
CONFIG_NFSD=m
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_BLOCKLAYOUT=y
# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set
CONFIG_SUNRPC_DEBUG=y
CONFIG_CEPH_FS=m
CONFIG_CEPH_FSCACHE=y
CONFIG_CEPH_FS_POSIX_ACL=y
CONFIG_CIFS=m
# CONFIG_CIFS_STATS2 is not set
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_FSCACHE=y
CONFIG_CODA_FS=m
CONFIG_AFS_FS=m
CONFIG_AFS_FSCACHE=y
CONFIG_9P_FS=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=m
CONFIG_NLS_CODEPAGE_857=m
CONFIG_NLS_CODEPAGE_860=m
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=m
CONFIG_NLS_CODEPAGE_865=m
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_CODEPAGE_950=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_MAC_ROMAN=m
CONFIG_NLS_MAC_CELTIC=m
CONFIG_NLS_MAC_CENTEURO=m
CONFIG_NLS_MAC_CROATIAN=m
CONFIG_NLS_MAC_CYRILLIC=m
CONFIG_NLS_MAC_GAELIC=m
CONFIG_NLS_MAC_GREEK=m
CONFIG_NLS_MAC_ICELAND=m
CONFIG_NLS_MAC_INUIT=m
CONFIG_NLS_MAC_ROMANIAN=m
CONFIG_NLS_MAC_TURKISH=m
CONFIG_DLM=m
CONFIG_DLM_DEBUG=y
CONFIG_KEY_DH_OPERATIONS=y
# CONFIG_SECURITYFS is not set
CONFIG_LSM="yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo"
CONFIG_INIT_STACK_NONE=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_USER=m
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_PCRYPT=m
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_BLAKE2B=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_XXHASH=m
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_LZ4=m
CONFIG_CRYPTO_LZ4HC=m
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_USER_API_AEAD=m
CONFIG_CRYPTO_GHASH_ARM64_CE=m
CONFIG_CRYPTO_SHA1_ARM64_CE=m
CONFIG_CRYPTO_SHA2_ARM64_CE=m
CONFIG_CRYPTO_AES_ARM64=m
CONFIG_CRYPTO_AES_ARM64_CE_CCM=m
CONFIG_CAVIUM_CPT=m
CONFIG_CRYPTO_DEV_NITROX_CNN55XX=m
CONFIG_CRYPTO_DEV_MARVELL_CESA=m
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCOM_RNG=m
CONFIG_CRYPTO_DEV_ROCKCHIP=m
CONFIG_CRYPTO_DEV_CHELSIO=m
CONFIG_CRYPTO_DEV_VIRTIO=m
CONFIG_CRYPTO_DEV_SAFEXCEL=m
CONFIG_CRYPTO_DEV_AMLOGIC_GXL=y
CONFIG_MODULE_SIG_KEY=""
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
# CONFIG_XZ_DEC_X86 is not set
# CONFIG_XZ_DEC_POWERPC is not set
# CONFIG_XZ_DEC_ARM is not set
# CONFIG_XZ_DEC_ARMTHUMB is not set
# CONFIG_XZ_DEC_SPARC is not set
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=64
CONFIG_PRINTK_TIME=y
CONFIG_BOOT_PRINTK_DELAY=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_HEADERS_INSTALL=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x01b6
CONFIG_PAGE_EXTENSION=y
CONFIG_PAGE_POISONING=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_SOFTLOCKUP_DETECTOR=y
CONFIG_SCHEDSTATS=y
CONFIG_DEBUG_LIST=y
# CONFIG_RCU_TRACE is not set
CONFIG_STACK_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_TRACER_SNAPSHOT=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_SAMPLES=y
CONFIG_SAMPLE_UHID=y
CONFIG_IO_STRICT_DEVMEM=y
CONFIG_NOTIFIER_ERROR_INJECTION=m
CONFIG_FUNCTION_ERROR_INJECTION=y
CONFIG_TEST_BPF=m
CONFIG_TEST_FIRMWARE=m
CONFIG_TEST_STATIC_KEYS=m

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-08-30 14:11     ` Marc Zyngier
  2024-09-02  5:27       ` Sebastian Ene
@ 2024-09-02 11:13       ` Vincent Donnefort
  2024-09-02 13:45         ` Sebastian Ene
  1 sibling, 1 reply; 20+ messages in thread
From: Vincent Donnefort @ 2024-09-02 11:13 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Sebastian Ene, akpm, alexghiti, ankita, ardb, catalin.marinas,
	christophe.leroy, james.morse, mark.rutland, oliver.upton,
	rananta, ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui,
	kvmarm, linux-arm-kernel, linux-kernel, kernel-team

[...]

> > > +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> > > +{
> > > +	struct kvm *kvm = m->i_private;
> > > +	struct kvm_ptdump_guest_state *st;
> > > +	int ret;
> > > +
> > > +	if (!kvm_get_kvm_safe(kvm))
> > > +		return -ENOENT;
> > > +
> > > +	st = kvm_ptdump_parser_create(kvm);
> > > +	if (IS_ERR(st)) {
> > > +		ret = PTR_ERR(st);
> > > +		goto free_with_kvm_ref;
> > > +	}
> > > +
> > > +	ret = single_open(file, kvm_ptdump_guest_show, st);
> > > +	if (!ret)
> > > +		return 0;
> > > +
> > > +	kfree(st);
> > > +free_with_kvm_ref:
> > 
> > nit: I believe kfree understands IS_ERR() so you could have a simple "err:"
> > label covering all the error path.
> 
> I couldn't find such handling in kfree(). Could you point be to it?

My aplogies, I was confused by the DEFINE_FREE(kfree ...) for __free(). kfree()
only checks for null ptr.

Although, I wonder if the naming "free_with_kvm_ref" isn't an artifact from
previous code? Nothing is freeed here. So perhaps err_with_kvm_ref? which could
be shorten as this is the only label?

[...]


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation
  2024-09-02 11:13       ` Vincent Donnefort
@ 2024-09-02 13:45         ` Sebastian Ene
  0 siblings, 0 replies; 20+ messages in thread
From: Sebastian Ene @ 2024-09-02 13:45 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: Marc Zyngier, akpm, alexghiti, ankita, ardb, catalin.marinas,
	christophe.leroy, james.morse, mark.rutland, oliver.upton,
	rananta, ryan.roberts, shahuang, suzuki.poulose, will, yuzenghui,
	kvmarm, linux-arm-kernel, linux-kernel, kernel-team

On Mon, Sep 02, 2024 at 12:13:12PM +0100, Vincent Donnefort wrote:
> [...]
> 
> > > > +static int kvm_ptdump_guest_open(struct inode *m, struct file *file)
> > > > +{
> > > > +	struct kvm *kvm = m->i_private;
> > > > +	struct kvm_ptdump_guest_state *st;
> > > > +	int ret;
> > > > +
> > > > +	if (!kvm_get_kvm_safe(kvm))
> > > > +		return -ENOENT;
> > > > +
> > > > +	st = kvm_ptdump_parser_create(kvm);
> > > > +	if (IS_ERR(st)) {
> > > > +		ret = PTR_ERR(st);
> > > > +		goto free_with_kvm_ref;
> > > > +	}
> > > > +
> > > > +	ret = single_open(file, kvm_ptdump_guest_show, st);
> > > > +	if (!ret)
> > > > +		return 0;
> > > > +
> > > > +	kfree(st);
> > > > +free_with_kvm_ref:
> > > 
> > > nit: I believe kfree understands IS_ERR() so you could have a simple "err:"
> > > label covering all the error path.
> > 
> > I couldn't find such handling in kfree(). Could you point be to it?
> 
> My aplogies, I was confused by the DEFINE_FREE(kfree ...) for __free(). kfree()
> only checks for null ptr.
> 
> Although, I wonder if the naming "free_with_kvm_ref" isn't an artifact from
> previous code? Nothing is freeed here. So perhaps err_with_kvm_ref? which could
> be shorten as this is the only label?
> 
> [...]

Yes, I guess that works better. Thanks for checking,

Seb


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2024-09-02 13:47 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-27  8:45 [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Sebastian Ene
2024-08-27  8:45 ` [PATCH v9 1/5] KVM: arm64: Move pagetable definitions to common header Sebastian Ene
2024-08-27  8:45 ` [PATCH v9 2/5] arm64: ptdump: Expose the attribute parsing functionality Sebastian Ene
2024-08-30 12:28   ` Marc Zyngier
2024-09-02  5:36     ` Sebastian Ene
2024-08-27  8:45 ` [PATCH v9 3/5] arm64: ptdump: Use the ptdump description from a local context Sebastian Ene
2024-08-27  8:45 ` [PATCH v9 4/5] KVM: arm64: Register ptdump with debugfs on guest creation Sebastian Ene
2024-08-30 10:24   ` Vincent Donnefort
2024-08-30 14:11     ` Marc Zyngier
2024-09-02  5:27       ` Sebastian Ene
2024-09-02 11:13       ` Vincent Donnefort
2024-09-02 13:45         ` Sebastian Ene
2024-09-02  5:31     ` Sebastian Ene
2024-08-27  8:45 ` [PATCH v9 5/5] KVM: arm64: Introduce the PTDUMP_STAGE2_DEBUGFS config Sebastian Ene
2024-08-30 10:26   ` Vincent Donnefort
2024-08-30 14:44 ` [PATCH v9 0/5] arm64: ptdump: View the second stage page-tables Marc Zyngier
2024-08-30 15:00   ` Marc Zyngier
2024-09-02  6:11     ` Sebastian Ene
2024-09-02  7:08       ` Sebastian Ene
2024-09-02  8:22         ` Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).