All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 kvmtool 00/13] arm64: Allow the user to set RAM base address
@ 2022-05-25 11:23 ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The series can be found at [1]. It is loosely based on the patches that
allow the user to define the VM memory layout (RAM + MMIO) [2]. I've
cherry-picked a handful of patches from that series, the rest I wrote from
scratch since there have been several changes to the way guest memory is
handled. I've chosen to focus on specifying the RAM layout with only one
RAM bank and leave the rest for a later series because this was relatively
easy to accomplish, while still being very useful.

Because this series comes after almost three year of changes to kvmtool,
I've decided to drop all the Reviewed-by tags. Thanks to Andre and Suzuki
for reviewing the previous patches, it has been very much appreciated.

What this series does: for arm64, the user can now specify the base address
for RAM:

$ ./lkvm run -m1G@2G .. # Equivalent to ./lkvm run -m1024

The memory units are B (bytes), K (kilobytes), M (megabytes), G
(gigabytes), T (terrabytes), P (petabytes).

Want to put RAM at the top of the physical address range? Easy:

$ ./lkvm run -m2G@1022G .. # Assumes the maximum is 40 bits of IPA

There one limitation on the RAM base address: it must not overlap with the
MMIO range that kvmtool uses, which lives below 2GB.

Why this is useful, in my opinion:

1. Testing how a payload handles different memory layouts without the need
to hack kvmtool or find the hardware that implements the desired layout.

2. It can serve as a development tool for adding support for larger PA
ranges for Linux and KVM (currently capped at 48 bits for 4k/16k pages), or
other payloads.

Summary of the series
======================

* The series starts with refactoring how kvm->cfg.ram_size is validated
  and used, followed by several cleanups in the arm and arm64 code.

* Then patch #9 ("builtin_run: Allow standard size specifiers for memory")
  introduced the ability to specify the measurement unit for memory. I
  believe that typing the equivalent of 2TB in megabytes isn't appealing
  for anyone.

* More cleanups in the arm/arm64 code follow, which are needed for patch
  #13 ("arm64: Allow the user to specify the RAM base address"). This is
  where the ability to specify the RAM base address is introduced.

Testing
=======

I tried to do better at testing the series:

- Built each patch for all architectures (found a compilation error this
  way, patch incoming).

- Ran an x86 kernel with and without setting the amount of RAM using the
  memory specifiers; tested that setting the RAM address results in an
  error.

- Ran an arm64 kernel without setting the size, with setting the size and
  with setting the size and address; tried different addresses (2G, 3G,
  256G); also tested that going below 2G or above the maximum IPA correctly
  results in an error.

- Ran all arm64 kvm-unit-test tests with various combinations of memory
  size and address.

- Ran all arm kvm-unit-tests on an arm64 host with various combinations of
  memory size and address (found another bug, the patch will be sent
  shortly).

Changelog
=========

Since v2:

* Patch #2 ("sizes.h: Make all sizes 64bit") is new (reported by Andre).

* Casted nr_pages to u64 in host_ram_size() to avoid overflows when multiplied
  by page_size on 32-bit systems with more than 2GB of RAM (Andre).

* Initialize ram_addr before parsing the command line options because the
  default was at address 0, which is invalid for arm64 (Andre).

* Fix check for RAM top above 4GB for aarch32 guests.

Since v1:

* Rebased on top of current HEAD (commit 4639b72f61a3 ("arm64: Add
  --vcpu-affinity command line argument")).

* Removed the last 3 patches that touched the --firmware-address command line
  argument. They weren't necessary for this series, I'll resend them after this
  series gets merged.

* Moved patch #8 ("builtin_run: Allow standard size specifiers for memory")
  later in the series (was #6).

[1] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/arm-allow-the-user-to-define-ram-address-v3
[2] https://lkml.kernel.org/kvm/1569245722-23375-1-git-send-email-alexandru.elisei@arm.com/

Alexandru Elisei (10):
  Use MB for megabytes consistently
  sizes.h: Make all sizes 64bit
  builtin-run: Always use RAM size in bytes
  builtin-run: Rework RAM size validation
  builtin-run: Add arch hook to validate VM configuration
  arm/arm64: Fail if RAM size is too large for 32-bit guests
  arm/arm64: Kill the ARM_MAX_MEMORY() macro
  arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro
  Introduce kvm__arch_default_ram_address()
  arm64: Allow the user to specify the RAM base address

Julien Grall (2):
  kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters
  arm/arm64: Consolidate RAM initialization in kvm__init_ram()

Suzuki K Poulose (1):
  builtin_run: Allow standard size specifiers for memory

 Documentation/kvmtool.1            |   4 +-
 Makefile                           |   1 +
 arm/aarch32/include/kvm/kvm-arch.h |   2 -
 arm/aarch32/kvm.c                  |  14 ++++
 arm/aarch64/include/kvm/kvm-arch.h |  18 +----
 arm/aarch64/kvm.c                  |  22 +++++-
 arm/include/arm-common/kvm-arch.h  |   1 -
 arm/kvm.c                          |  60 +++++++-------
 builtin-run.c                      | 122 +++++++++++++++++++++++++----
 include/kvm/kvm-config.h           |   8 +-
 include/kvm/kvm.h                  |  18 ++++-
 include/linux/sizes.h              |  66 ++++++++--------
 kvm.c                              |   2 +-
 mips/kvm.c                         |  16 +++-
 powerpc/kvm.c                      |  14 +++-
 riscv/kvm.c                        |  16 +++-
 x86/kvm.c                          |  13 ++-
 17 files changed, 285 insertions(+), 112 deletions(-)
 create mode 100644 arm/aarch32/kvm.c

-- 
2.35.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 00/13] arm64: Allow the user to set RAM base address
@ 2022-05-25 11:23 ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The series can be found at [1]. It is loosely based on the patches that
allow the user to define the VM memory layout (RAM + MMIO) [2]. I've
cherry-picked a handful of patches from that series, the rest I wrote from
scratch since there have been several changes to the way guest memory is
handled. I've chosen to focus on specifying the RAM layout with only one
RAM bank and leave the rest for a later series because this was relatively
easy to accomplish, while still being very useful.

Because this series comes after almost three year of changes to kvmtool,
I've decided to drop all the Reviewed-by tags. Thanks to Andre and Suzuki
for reviewing the previous patches, it has been very much appreciated.

What this series does: for arm64, the user can now specify the base address
for RAM:

$ ./lkvm run -m1G@2G .. # Equivalent to ./lkvm run -m1024

The memory units are B (bytes), K (kilobytes), M (megabytes), G
(gigabytes), T (terrabytes), P (petabytes).

Want to put RAM at the top of the physical address range? Easy:

$ ./lkvm run -m2G@1022G .. # Assumes the maximum is 40 bits of IPA

There one limitation on the RAM base address: it must not overlap with the
MMIO range that kvmtool uses, which lives below 2GB.

Why this is useful, in my opinion:

1. Testing how a payload handles different memory layouts without the need
to hack kvmtool or find the hardware that implements the desired layout.

2. It can serve as a development tool for adding support for larger PA
ranges for Linux and KVM (currently capped at 48 bits for 4k/16k pages), or
other payloads.

Summary of the series
======================

* The series starts with refactoring how kvm->cfg.ram_size is validated
  and used, followed by several cleanups in the arm and arm64 code.

* Then patch #9 ("builtin_run: Allow standard size specifiers for memory")
  introduced the ability to specify the measurement unit for memory. I
  believe that typing the equivalent of 2TB in megabytes isn't appealing
  for anyone.

* More cleanups in the arm/arm64 code follow, which are needed for patch
  #13 ("arm64: Allow the user to specify the RAM base address"). This is
  where the ability to specify the RAM base address is introduced.

Testing
=======

I tried to do better at testing the series:

- Built each patch for all architectures (found a compilation error this
  way, patch incoming).

- Ran an x86 kernel with and without setting the amount of RAM using the
  memory specifiers; tested that setting the RAM address results in an
  error.

- Ran an arm64 kernel without setting the size, with setting the size and
  with setting the size and address; tried different addresses (2G, 3G,
  256G); also tested that going below 2G or above the maximum IPA correctly
  results in an error.

- Ran all arm64 kvm-unit-test tests with various combinations of memory
  size and address.

- Ran all arm kvm-unit-tests on an arm64 host with various combinations of
  memory size and address (found another bug, the patch will be sent
  shortly).

Changelog
=========

Since v2:

* Patch #2 ("sizes.h: Make all sizes 64bit") is new (reported by Andre).

* Casted nr_pages to u64 in host_ram_size() to avoid overflows when multiplied
  by page_size on 32-bit systems with more than 2GB of RAM (Andre).

* Initialize ram_addr before parsing the command line options because the
  default was at address 0, which is invalid for arm64 (Andre).

* Fix check for RAM top above 4GB for aarch32 guests.

Since v1:

* Rebased on top of current HEAD (commit 4639b72f61a3 ("arm64: Add
  --vcpu-affinity command line argument")).

* Removed the last 3 patches that touched the --firmware-address command line
  argument. They weren't necessary for this series, I'll resend them after this
  series gets merged.

* Moved patch #8 ("builtin_run: Allow standard size specifiers for memory")
  later in the series (was #6).

[1] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/arm-allow-the-user-to-define-ram-address-v3
[2] https://lkml.kernel.org/kvm/1569245722-23375-1-git-send-email-alexandru.elisei@arm.com/

Alexandru Elisei (10):
  Use MB for megabytes consistently
  sizes.h: Make all sizes 64bit
  builtin-run: Always use RAM size in bytes
  builtin-run: Rework RAM size validation
  builtin-run: Add arch hook to validate VM configuration
  arm/arm64: Fail if RAM size is too large for 32-bit guests
  arm/arm64: Kill the ARM_MAX_MEMORY() macro
  arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro
  Introduce kvm__arch_default_ram_address()
  arm64: Allow the user to specify the RAM base address

Julien Grall (2):
  kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters
  arm/arm64: Consolidate RAM initialization in kvm__init_ram()

Suzuki K Poulose (1):
  builtin_run: Allow standard size specifiers for memory

 Documentation/kvmtool.1            |   4 +-
 Makefile                           |   1 +
 arm/aarch32/include/kvm/kvm-arch.h |   2 -
 arm/aarch32/kvm.c                  |  14 ++++
 arm/aarch64/include/kvm/kvm-arch.h |  18 +----
 arm/aarch64/kvm.c                  |  22 +++++-
 arm/include/arm-common/kvm-arch.h  |   1 -
 arm/kvm.c                          |  60 +++++++-------
 builtin-run.c                      | 122 +++++++++++++++++++++++++----
 include/kvm/kvm-config.h           |   8 +-
 include/kvm/kvm.h                  |  18 ++++-
 include/linux/sizes.h              |  66 ++++++++--------
 kvm.c                              |   2 +-
 mips/kvm.c                         |  16 +++-
 powerpc/kvm.c                      |  14 +++-
 riscv/kvm.c                        |  16 +++-
 x86/kvm.c                          |  13 ++-
 17 files changed, 285 insertions(+), 112 deletions(-)
 create mode 100644 arm/aarch32/kvm.c

-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 01/13] Use MB for megabytes consistently
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The help text for the -m/--mem argument states that the guest memory size
is in MiB (mebibyte). MiB is the same thing as MB (megabyte), and indeed
this is how MB is used throughout kvmtool.

Replace MiB with MB, so people don't get the wrong idea and start
believing that for kvmtool a MB is 10^6 bytes instead of 2^20.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 Documentation/kvmtool.1 | 4 ++--
 builtin-run.c           | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/kvmtool.1 b/Documentation/kvmtool.1
index 2b8c274dc3ff..25d46f8f51f9 100644
--- a/Documentation/kvmtool.1
+++ b/Documentation/kvmtool.1
@@ -10,7 +10,7 @@ kvmtool is a userland tool for creating and controlling KVM guests.
 .SH "KVMTOOL COMMANDS"
 .sp
 .PP
-.B run -k <kernel\-image> [\-c <cores>] [\-m <MiB>] [\-p <command line>]
+.B run -k <kernel\-image> [\-c <cores>] [\-m <MB>] [\-p <command line>]
 .br
 .B [\-i <initrd>] [\-d <image file>] [\-\-console serial|virtio|hv]
 .br
@@ -30,7 +30,7 @@ The number of virtual CPUs to run.
 .sp
 .B \-m, \-\-mem <n>
 .RS 4
-Virtual machine memory size in MiB.
+Virtual machine memory size in MB.
 .RE
 .sp
 .B \-p, \-\-params <parameters>
diff --git a/builtin-run.c b/builtin-run.c
index 9a1a0c1fa6fb..0126c9fbcba6 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -97,7 +97,7 @@ void kvm_run_set_wrapper_sandbox(void)
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
 	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
-		" size in MiB."),					\
+		" size in MB."),					\
 	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
 			" image or rootfs directory", img_name_parser,	\
 			kvm),						\
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 01/13] Use MB for megabytes consistently
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The help text for the -m/--mem argument states that the guest memory size
is in MiB (mebibyte). MiB is the same thing as MB (megabyte), and indeed
this is how MB is used throughout kvmtool.

Replace MiB with MB, so people don't get the wrong idea and start
believing that for kvmtool a MB is 10^6 bytes instead of 2^20.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 Documentation/kvmtool.1 | 4 ++--
 builtin-run.c           | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/kvmtool.1 b/Documentation/kvmtool.1
index 2b8c274dc3ff..25d46f8f51f9 100644
--- a/Documentation/kvmtool.1
+++ b/Documentation/kvmtool.1
@@ -10,7 +10,7 @@ kvmtool is a userland tool for creating and controlling KVM guests.
 .SH "KVMTOOL COMMANDS"
 .sp
 .PP
-.B run -k <kernel\-image> [\-c <cores>] [\-m <MiB>] [\-p <command line>]
+.B run -k <kernel\-image> [\-c <cores>] [\-m <MB>] [\-p <command line>]
 .br
 .B [\-i <initrd>] [\-d <image file>] [\-\-console serial|virtio|hv]
 .br
@@ -30,7 +30,7 @@ The number of virtual CPUs to run.
 .sp
 .B \-m, \-\-mem <n>
 .RS 4
-Virtual machine memory size in MiB.
+Virtual machine memory size in MB.
 .RE
 .sp
 .B \-p, \-\-params <parameters>
diff --git a/builtin-run.c b/builtin-run.c
index 9a1a0c1fa6fb..0126c9fbcba6 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -97,7 +97,7 @@ void kvm_run_set_wrapper_sandbox(void)
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
 	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
-		" size in MiB."),					\
+		" size in MB."),					\
 	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
 			" image or rootfs directory", img_name_parser,	\
 			kvm),						\
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Append ULL to all of the size definitions to make them 64bit and avoid
overflows.

Reported-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 include/linux/sizes.h | 64 +++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index ce3e8150c174..b2b5c457cf1c 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -8,40 +8,40 @@
 #ifndef __LINUX_SIZES_H__
 #define __LINUX_SIZES_H__
 
-#define SZ_1				0x00000001
-#define SZ_2				0x00000002
-#define SZ_4				0x00000004
-#define SZ_8				0x00000008
-#define SZ_16				0x00000010
-#define SZ_32				0x00000020
-#define SZ_64				0x00000040
-#define SZ_128				0x00000080
-#define SZ_256				0x00000100
-#define SZ_512				0x00000200
+#define SZ_1				0x00000001ULL
+#define SZ_2				0x00000002ULL
+#define SZ_4				0x00000004ULL
+#define SZ_8				0x00000008ULL
+#define SZ_16				0x00000010ULL
+#define SZ_32				0x00000020ULL
+#define SZ_64				0x00000040ULL
+#define SZ_128				0x00000080ULL
+#define SZ_256				0x00000100ULL
+#define SZ_512				0x00000200ULL
 
-#define SZ_1K				0x00000400
-#define SZ_2K				0x00000800
-#define SZ_4K				0x00001000
-#define SZ_8K				0x00002000
-#define SZ_16K				0x00004000
-#define SZ_32K				0x00008000
-#define SZ_64K				0x00010000
-#define SZ_128K				0x00020000
-#define SZ_256K				0x00040000
-#define SZ_512K				0x00080000
+#define SZ_1K				0x00000400ULL
+#define SZ_2K				0x00000800ULL
+#define SZ_4K				0x00001000ULL
+#define SZ_8K				0x00002000ULL
+#define SZ_16K				0x00004000ULL
+#define SZ_32K				0x00008000ULL
+#define SZ_64K				0x00010000ULL
+#define SZ_128K				0x00020000ULL
+#define SZ_256K				0x00040000ULL
+#define SZ_512K				0x00080000ULL
 
-#define SZ_1M				0x00100000
-#define SZ_2M				0x00200000
-#define SZ_4M				0x00400000
-#define SZ_8M				0x00800000
-#define SZ_16M				0x01000000
-#define SZ_32M				0x02000000
-#define SZ_64M				0x04000000
-#define SZ_128M				0x08000000
-#define SZ_256M				0x10000000
-#define SZ_512M				0x20000000
+#define SZ_1M				0x00100000ULL
+#define SZ_2M				0x00200000ULL
+#define SZ_4M				0x00400000ULL
+#define SZ_8M				0x00800000ULL
+#define SZ_16M				0x01000000ULL
+#define SZ_32M				0x02000000ULL
+#define SZ_64M				0x04000000ULL
+#define SZ_128M				0x08000000ULL
+#define SZ_256M				0x10000000ULL
+#define SZ_512M				0x20000000ULL
 
-#define SZ_1G				0x40000000
-#define SZ_2G				0x80000000
+#define SZ_1G				0x40000000ULL
+#define SZ_2G				0x80000000ULL
 
 #endif /* __LINUX_SIZES_H__ */
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Append ULL to all of the size definitions to make them 64bit and avoid
overflows.

Reported-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 include/linux/sizes.h | 64 +++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index ce3e8150c174..b2b5c457cf1c 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -8,40 +8,40 @@
 #ifndef __LINUX_SIZES_H__
 #define __LINUX_SIZES_H__
 
-#define SZ_1				0x00000001
-#define SZ_2				0x00000002
-#define SZ_4				0x00000004
-#define SZ_8				0x00000008
-#define SZ_16				0x00000010
-#define SZ_32				0x00000020
-#define SZ_64				0x00000040
-#define SZ_128				0x00000080
-#define SZ_256				0x00000100
-#define SZ_512				0x00000200
+#define SZ_1				0x00000001ULL
+#define SZ_2				0x00000002ULL
+#define SZ_4				0x00000004ULL
+#define SZ_8				0x00000008ULL
+#define SZ_16				0x00000010ULL
+#define SZ_32				0x00000020ULL
+#define SZ_64				0x00000040ULL
+#define SZ_128				0x00000080ULL
+#define SZ_256				0x00000100ULL
+#define SZ_512				0x00000200ULL
 
-#define SZ_1K				0x00000400
-#define SZ_2K				0x00000800
-#define SZ_4K				0x00001000
-#define SZ_8K				0x00002000
-#define SZ_16K				0x00004000
-#define SZ_32K				0x00008000
-#define SZ_64K				0x00010000
-#define SZ_128K				0x00020000
-#define SZ_256K				0x00040000
-#define SZ_512K				0x00080000
+#define SZ_1K				0x00000400ULL
+#define SZ_2K				0x00000800ULL
+#define SZ_4K				0x00001000ULL
+#define SZ_8K				0x00002000ULL
+#define SZ_16K				0x00004000ULL
+#define SZ_32K				0x00008000ULL
+#define SZ_64K				0x00010000ULL
+#define SZ_128K				0x00020000ULL
+#define SZ_256K				0x00040000ULL
+#define SZ_512K				0x00080000ULL
 
-#define SZ_1M				0x00100000
-#define SZ_2M				0x00200000
-#define SZ_4M				0x00400000
-#define SZ_8M				0x00800000
-#define SZ_16M				0x01000000
-#define SZ_32M				0x02000000
-#define SZ_64M				0x04000000
-#define SZ_128M				0x08000000
-#define SZ_256M				0x10000000
-#define SZ_512M				0x20000000
+#define SZ_1M				0x00100000ULL
+#define SZ_2M				0x00200000ULL
+#define SZ_4M				0x00400000ULL
+#define SZ_8M				0x00800000ULL
+#define SZ_16M				0x01000000ULL
+#define SZ_32M				0x02000000ULL
+#define SZ_64M				0x04000000ULL
+#define SZ_128M				0x08000000ULL
+#define SZ_256M				0x10000000ULL
+#define SZ_512M				0x20000000ULL
 
-#define SZ_1G				0x40000000
-#define SZ_2G				0x80000000
+#define SZ_1G				0x40000000ULL
+#define SZ_2G				0x80000000ULL
 
 #endif /* __LINUX_SIZES_H__ */
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 03/13] builtin-run: Always use RAM size in bytes
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The user can specify the virtual machine memory size in MB, which is saved
in cfg->ram_size. kvmtool validates it against the host memory size,
converted from bytes to MB. ram_size is then converted to bytes, and this
is how it is used throughout the rest of kvmtool.

To avoid any confusion about the unit of measurement, especially once the
user is allowed to specify the unit of measurement, always use ram_size in
bytes.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 builtin-run.c            | 19 ++++++++++---------
 include/kvm/kvm-config.h |  7 ++++---
 include/kvm/kvm.h        |  2 +-
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index 0126c9fbcba6..4fc7cbed1d17 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -36,6 +36,7 @@
 
 #include <linux/types.h>
 #include <linux/err.h>
+#include <linux/sizes.h>
 
 #include <sys/utsname.h>
 #include <sys/types.h>
@@ -264,7 +265,7 @@ static u64 host_ram_size(void)
 		return 0;
 	}
 
-	return (nr_pages * page_size) >> MB_SHIFT;
+	return (u64)nr_pages * page_size;
 }
 
 /*
@@ -278,11 +279,11 @@ static u64 get_ram_size(int nr_cpus)
 	u64 available;
 	u64 ram_size;
 
-	ram_size	= 64 * (nr_cpus + 3);
+	ram_size	= SZ_64M * (nr_cpus + 3);
 
 	available	= host_ram_size() * RAM_SIZE_RATIO;
 	if (!available)
-		available = MIN_RAM_SIZE_MB;
+		available = MIN_RAM_SIZE;
 
 	if (ram_size > available)
 		ram_size	= available;
@@ -595,13 +596,13 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	if (!kvm->cfg.ram_size)
 		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
+	else
+		kvm->cfg.ram_size <<= MB_SHIFT;
 
 	if (kvm->cfg.ram_size > host_ram_size())
 		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-			(unsigned long long)kvm->cfg.ram_size,
-			(unsigned long long)host_ram_size());
-
-	kvm->cfg.ram_size <<= MB_SHIFT;
+			(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
+			(unsigned long long)host_ram_size() >> MB_SHIFT);
 
 	if (!kvm->cfg.dev)
 		kvm->cfg.dev = DEFAULT_KVM_DEV;
@@ -676,12 +677,12 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 	if (kvm->cfg.kernel_filename) {
 		printf("  # %s run -k %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
 		       kvm->cfg.kernel_filename,
-		       (unsigned long long)kvm->cfg.ram_size / 1024 / 1024,
+		       (unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
 		       kvm->cfg.nrcpus, kvm->cfg.guest_name);
 	} else if (kvm->cfg.firmware_filename) {
 		printf("  # %s run --firmware %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
 		       kvm->cfg.firmware_filename,
-		       (unsigned long long)kvm->cfg.ram_size / 1024 / 1024,
+		       (unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
 		       kvm->cfg.nrcpus, kvm->cfg.guest_name);
 	}
 
diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
index 6a5720c4c7d4..31bc89520d52 100644
--- a/include/kvm/kvm-config.h
+++ b/include/kvm/kvm-config.h
@@ -5,6 +5,8 @@
 #include "kvm/vfio.h"
 #include "kvm/kvm-config-arch.h"
 
+#include <linux/sizes.h>
+
 #define DEFAULT_KVM_DEV		"/dev/kvm"
 #define DEFAULT_CONSOLE		"serial"
 #define DEFAULT_NETWORK		"user"
@@ -15,14 +17,13 @@
 #define DEFAULT_SCRIPT		"none"
 #define DEFAULT_SANDBOX_FILENAME "guest/sandbox.sh"
 
-#define MIN_RAM_SIZE_MB		(64ULL)
-#define MIN_RAM_SIZE_BYTE	(MIN_RAM_SIZE_MB << MB_SHIFT)
+#define MIN_RAM_SIZE		SZ_64M
 
 struct kvm_config {
 	struct kvm_config_arch arch;
 	struct disk_image_params disk_image[MAX_DISK_IMAGES];
 	struct vfio_device_params *vfio_devices;
-	u64 ram_size;
+	u64 ram_size;		/* Guest memory size, in bytes */
 	u8 num_net_devices;
 	u8 num_vfio_devices;
 	u64 vsock_cid;
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index ad732e56f5ed..7b14b33b50ca 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -87,7 +87,7 @@ struct kvm {
 	struct kvm_cpu		**cpus;
 
 	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
-	u64			ram_size;
+	u64			ram_size;	/* Guest memory size, in bytes */
 	void			*ram_start;
 	u64			ram_pagesize;
 	struct mutex		mem_banks_lock;
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 03/13] builtin-run: Always use RAM size in bytes
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The user can specify the virtual machine memory size in MB, which is saved
in cfg->ram_size. kvmtool validates it against the host memory size,
converted from bytes to MB. ram_size is then converted to bytes, and this
is how it is used throughout the rest of kvmtool.

To avoid any confusion about the unit of measurement, especially once the
user is allowed to specify the unit of measurement, always use ram_size in
bytes.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 builtin-run.c            | 19 ++++++++++---------
 include/kvm/kvm-config.h |  7 ++++---
 include/kvm/kvm.h        |  2 +-
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index 0126c9fbcba6..4fc7cbed1d17 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -36,6 +36,7 @@
 
 #include <linux/types.h>
 #include <linux/err.h>
+#include <linux/sizes.h>
 
 #include <sys/utsname.h>
 #include <sys/types.h>
@@ -264,7 +265,7 @@ static u64 host_ram_size(void)
 		return 0;
 	}
 
-	return (nr_pages * page_size) >> MB_SHIFT;
+	return (u64)nr_pages * page_size;
 }
 
 /*
@@ -278,11 +279,11 @@ static u64 get_ram_size(int nr_cpus)
 	u64 available;
 	u64 ram_size;
 
-	ram_size	= 64 * (nr_cpus + 3);
+	ram_size	= SZ_64M * (nr_cpus + 3);
 
 	available	= host_ram_size() * RAM_SIZE_RATIO;
 	if (!available)
-		available = MIN_RAM_SIZE_MB;
+		available = MIN_RAM_SIZE;
 
 	if (ram_size > available)
 		ram_size	= available;
@@ -595,13 +596,13 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	if (!kvm->cfg.ram_size)
 		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
+	else
+		kvm->cfg.ram_size <<= MB_SHIFT;
 
 	if (kvm->cfg.ram_size > host_ram_size())
 		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-			(unsigned long long)kvm->cfg.ram_size,
-			(unsigned long long)host_ram_size());
-
-	kvm->cfg.ram_size <<= MB_SHIFT;
+			(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
+			(unsigned long long)host_ram_size() >> MB_SHIFT);
 
 	if (!kvm->cfg.dev)
 		kvm->cfg.dev = DEFAULT_KVM_DEV;
@@ -676,12 +677,12 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 	if (kvm->cfg.kernel_filename) {
 		printf("  # %s run -k %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
 		       kvm->cfg.kernel_filename,
-		       (unsigned long long)kvm->cfg.ram_size / 1024 / 1024,
+		       (unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
 		       kvm->cfg.nrcpus, kvm->cfg.guest_name);
 	} else if (kvm->cfg.firmware_filename) {
 		printf("  # %s run --firmware %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
 		       kvm->cfg.firmware_filename,
-		       (unsigned long long)kvm->cfg.ram_size / 1024 / 1024,
+		       (unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
 		       kvm->cfg.nrcpus, kvm->cfg.guest_name);
 	}
 
diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
index 6a5720c4c7d4..31bc89520d52 100644
--- a/include/kvm/kvm-config.h
+++ b/include/kvm/kvm-config.h
@@ -5,6 +5,8 @@
 #include "kvm/vfio.h"
 #include "kvm/kvm-config-arch.h"
 
+#include <linux/sizes.h>
+
 #define DEFAULT_KVM_DEV		"/dev/kvm"
 #define DEFAULT_CONSOLE		"serial"
 #define DEFAULT_NETWORK		"user"
@@ -15,14 +17,13 @@
 #define DEFAULT_SCRIPT		"none"
 #define DEFAULT_SANDBOX_FILENAME "guest/sandbox.sh"
 
-#define MIN_RAM_SIZE_MB		(64ULL)
-#define MIN_RAM_SIZE_BYTE	(MIN_RAM_SIZE_MB << MB_SHIFT)
+#define MIN_RAM_SIZE		SZ_64M
 
 struct kvm_config {
 	struct kvm_config_arch arch;
 	struct disk_image_params disk_image[MAX_DISK_IMAGES];
 	struct vfio_device_params *vfio_devices;
-	u64 ram_size;
+	u64 ram_size;		/* Guest memory size, in bytes */
 	u8 num_net_devices;
 	u8 num_vfio_devices;
 	u64 vsock_cid;
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index ad732e56f5ed..7b14b33b50ca 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -87,7 +87,7 @@ struct kvm {
 	struct kvm_cpu		**cpus;
 
 	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
-	u64			ram_size;
+	u64			ram_size;	/* Guest memory size, in bytes */
 	void			*ram_start;
 	u64			ram_pagesize;
 	struct mutex		mem_banks_lock;
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 04/13] builtin-run: Rework RAM size validation
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

host_ram_size() uses sysconf() to calculate the available ram, and
sysconf() can fail. When that happens, host_ram_size() returns 0. kvmtool
warns the user when the configured VM ram size exceeds the size of the
host's memory, but doesn't take into account that host_ram_size() can
return 0. If the function returns zero, skip the warning.

Since this can only happen when the user sets the memory size (via the
-m/--mem command line argument), skip the check entirely if the user hasn't
set it. Move the check to kvm_run_validate_cfg(), as it checks for valid
user configuration.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 builtin-run.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index 4fc7cbed1d17..b1accbce7da3 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -509,6 +509,8 @@ static void kvm_run_set_real_cmdline(struct kvm *kvm)
 
 static void kvm_run_validate_cfg(struct kvm *kvm)
 {
+	u64 available_ram;
+
 	if (kvm->cfg.kernel_filename && kvm->cfg.firmware_filename)
 		die("Only one of --kernel or --firmware can be specified");
 
@@ -518,6 +520,17 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
 
 	if (kvm->cfg.firmware_filename && kvm->cfg.initrd_filename)
 		pr_warning("Ignoring initrd file when loading a firmware image");
+
+	if (kvm->cfg.ram_size) {
+		/* User specifies RAM size in megabytes. */
+		kvm->cfg.ram_size <<= MB_SHIFT;
+		available_ram = host_ram_size();
+		if (available_ram && kvm->cfg.ram_size > available_ram) {
+			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
+				(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
+				(unsigned long long)available_ram >> MB_SHIFT);
+		}
+	}
 }
 
 static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
@@ -596,13 +609,6 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	if (!kvm->cfg.ram_size)
 		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
-	else
-		kvm->cfg.ram_size <<= MB_SHIFT;
-
-	if (kvm->cfg.ram_size > host_ram_size())
-		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-			(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
-			(unsigned long long)host_ram_size() >> MB_SHIFT);
 
 	if (!kvm->cfg.dev)
 		kvm->cfg.dev = DEFAULT_KVM_DEV;
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 04/13] builtin-run: Rework RAM size validation
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

host_ram_size() uses sysconf() to calculate the available ram, and
sysconf() can fail. When that happens, host_ram_size() returns 0. kvmtool
warns the user when the configured VM ram size exceeds the size of the
host's memory, but doesn't take into account that host_ram_size() can
return 0. If the function returns zero, skip the warning.

Since this can only happen when the user sets the memory size (via the
-m/--mem command line argument), skip the check entirely if the user hasn't
set it. Move the check to kvm_run_validate_cfg(), as it checks for valid
user configuration.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 builtin-run.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index 4fc7cbed1d17..b1accbce7da3 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -509,6 +509,8 @@ static void kvm_run_set_real_cmdline(struct kvm *kvm)
 
 static void kvm_run_validate_cfg(struct kvm *kvm)
 {
+	u64 available_ram;
+
 	if (kvm->cfg.kernel_filename && kvm->cfg.firmware_filename)
 		die("Only one of --kernel or --firmware can be specified");
 
@@ -518,6 +520,17 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
 
 	if (kvm->cfg.firmware_filename && kvm->cfg.initrd_filename)
 		pr_warning("Ignoring initrd file when loading a firmware image");
+
+	if (kvm->cfg.ram_size) {
+		/* User specifies RAM size in megabytes. */
+		kvm->cfg.ram_size <<= MB_SHIFT;
+		available_ram = host_ram_size();
+		if (available_ram && kvm->cfg.ram_size > available_ram) {
+			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
+				(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
+				(unsigned long long)available_ram >> MB_SHIFT);
+		}
+	}
 }
 
 static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
@@ -596,13 +609,6 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	if (!kvm->cfg.ram_size)
 		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
-	else
-		kvm->cfg.ram_size <<= MB_SHIFT;
-
-	if (kvm->cfg.ram_size > host_ram_size())
-		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-			(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
-			(unsigned long long)host_ram_size() >> MB_SHIFT);
 
 	if (!kvm->cfg.dev)
 		kvm->cfg.dev = DEFAULT_KVM_DEV;
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 05/13] builtin-run: Add arch hook to validate VM configuration
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Architectures are free to set their own command line options. Add an
architecture specific hook to validate these options.

For now, the hook does nothing, but it will be used in later patches.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 Makefile          | 1 +
 arm/aarch32/kvm.c | 5 +++++
 arm/aarch64/kvm.c | 4 ++++
 builtin-run.c     | 2 ++
 include/kvm/kvm.h | 1 +
 mips/kvm.c        | 4 ++++
 powerpc/kvm.c     | 4 ++++
 riscv/kvm.c       | 4 ++++
 x86/kvm.c         | 4 ++++
 9 files changed, 29 insertions(+)
 create mode 100644 arm/aarch32/kvm.c

diff --git a/Makefile b/Makefile
index 9e67c7637b1e..25d79637b561 100644
--- a/Makefile
+++ b/Makefile
@@ -168,6 +168,7 @@ ifeq ($(ARCH), arm)
 	OBJS		+= $(OBJS_ARM_COMMON)
 	OBJS		+= arm/aarch32/arm-cpu.o
 	OBJS		+= arm/aarch32/kvm-cpu.o
+	OBJS		+= arm/aarch32/kvm.o
 	ARCH_INCLUDE	:= $(HDRS_ARM_COMMON)
 	ARCH_INCLUDE	+= -Iarm/aarch32/include
 	CFLAGS		+= -march=armv7-a
diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
new file mode 100644
index 000000000000..ae33ac92479a
--- /dev/null
+++ b/arm/aarch32/kvm.c
@@ -0,0 +1,5 @@
+#include "kvm/kvm.h"
+
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index f3fe854e0b3f..ca348f118a56 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -37,6 +37,10 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 /*
  * Return the TEXT_OFFSET value that the guest kernel expects. Note
  * that pre-3.17 kernels expose this value using the native endianness
diff --git a/builtin-run.c b/builtin-run.c
index b1accbce7da3..2ef159cdb2a3 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -531,6 +531,8 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
 				(unsigned long long)available_ram >> MB_SHIFT);
 		}
 	}
+
+	kvm__arch_validate_cfg(kvm);
 }
 
 static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 7b14b33b50ca..9f7b2fb26e95 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -187,6 +187,7 @@ int kvm__get_sock_by_instance(const char *name);
 int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
+void kvm__arch_validate_cfg(struct kvm *kvm);
 void kvm__arch_set_cmdline(char *cmdline, bool video);
 void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
 void kvm__arch_delete_ram(struct kvm *kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index 3470dbb2e433..f5b137f46dff 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -12,6 +12,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 void kvm__arch_read_term(struct kvm *kvm)
 {
 	virtio_console__inject_interrupt(kvm);
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index 702d67dca614..3215b579f5dc 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -48,6 +48,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 static uint32_t mfpvr(void)
 {
 	uint32_t r;
diff --git a/riscv/kvm.c b/riscv/kvm.c
index 84e02779a91c..7fb496282f4c 100644
--- a/riscv/kvm.c
+++ b/riscv/kvm.c
@@ -13,6 +13,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 },
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 bool kvm__arch_cpu_supports_vm(void)
 {
 	/* The KVM capability check is enough. */
diff --git a/x86/kvm.c b/x86/kvm.c
index 3e0f0b743f8c..6683a5c81d49 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -35,6 +35,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 bool kvm__arch_cpu_supports_vm(void)
 {
 	struct cpuid_regs regs;
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 05/13] builtin-run: Add arch hook to validate VM configuration
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Architectures are free to set their own command line options. Add an
architecture specific hook to validate these options.

For now, the hook does nothing, but it will be used in later patches.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 Makefile          | 1 +
 arm/aarch32/kvm.c | 5 +++++
 arm/aarch64/kvm.c | 4 ++++
 builtin-run.c     | 2 ++
 include/kvm/kvm.h | 1 +
 mips/kvm.c        | 4 ++++
 powerpc/kvm.c     | 4 ++++
 riscv/kvm.c       | 4 ++++
 x86/kvm.c         | 4 ++++
 9 files changed, 29 insertions(+)
 create mode 100644 arm/aarch32/kvm.c

diff --git a/Makefile b/Makefile
index 9e67c7637b1e..25d79637b561 100644
--- a/Makefile
+++ b/Makefile
@@ -168,6 +168,7 @@ ifeq ($(ARCH), arm)
 	OBJS		+= $(OBJS_ARM_COMMON)
 	OBJS		+= arm/aarch32/arm-cpu.o
 	OBJS		+= arm/aarch32/kvm-cpu.o
+	OBJS		+= arm/aarch32/kvm.o
 	ARCH_INCLUDE	:= $(HDRS_ARM_COMMON)
 	ARCH_INCLUDE	+= -Iarm/aarch32/include
 	CFLAGS		+= -march=armv7-a
diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
new file mode 100644
index 000000000000..ae33ac92479a
--- /dev/null
+++ b/arm/aarch32/kvm.c
@@ -0,0 +1,5 @@
+#include "kvm/kvm.h"
+
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index f3fe854e0b3f..ca348f118a56 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -37,6 +37,10 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 /*
  * Return the TEXT_OFFSET value that the guest kernel expects. Note
  * that pre-3.17 kernels expose this value using the native endianness
diff --git a/builtin-run.c b/builtin-run.c
index b1accbce7da3..2ef159cdb2a3 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -531,6 +531,8 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
 				(unsigned long long)available_ram >> MB_SHIFT);
 		}
 	}
+
+	kvm__arch_validate_cfg(kvm);
 }
 
 static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 7b14b33b50ca..9f7b2fb26e95 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -187,6 +187,7 @@ int kvm__get_sock_by_instance(const char *name);
 int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
 void kvm__remove_socket(const char *name);
 
+void kvm__arch_validate_cfg(struct kvm *kvm);
 void kvm__arch_set_cmdline(char *cmdline, bool video);
 void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
 void kvm__arch_delete_ram(struct kvm *kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index 3470dbb2e433..f5b137f46dff 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -12,6 +12,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 void kvm__arch_read_term(struct kvm *kvm)
 {
 	virtio_console__inject_interrupt(kvm);
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index 702d67dca614..3215b579f5dc 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -48,6 +48,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 static uint32_t mfpvr(void)
 {
 	uint32_t r;
diff --git a/riscv/kvm.c b/riscv/kvm.c
index 84e02779a91c..7fb496282f4c 100644
--- a/riscv/kvm.c
+++ b/riscv/kvm.c
@@ -13,6 +13,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 },
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 bool kvm__arch_cpu_supports_vm(void)
 {
 	/* The KVM capability check is enough. */
diff --git a/x86/kvm.c b/x86/kvm.c
index 3e0f0b743f8c..6683a5c81d49 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -35,6 +35,10 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+void kvm__arch_validate_cfg(struct kvm *kvm)
+{
+}
+
 bool kvm__arch_cpu_supports_vm(void)
 {
 	struct cpuid_regs regs;
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 06/13] arm/arm64: Fail if RAM size is too large for 32-bit guests
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

For 64-bit guests, kvmtool exists with an error in kvm__get_vm_type() if
the memory size is larger than what KVM supports. For 32-bit guests, the
RAM size is silently rounded down to ARM_LOMAP_MAX_MEMORY in
kvm__arch_init().

Be consistent and exit with an error when the user has configured the
wrong RAM size for 32-bit guests.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/kvm.c | 4 ++++
 arm/aarch64/kvm.c | 5 +++++
 arm/kvm.c         | 2 +-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
index ae33ac92479a..9d68d7a15ee2 100644
--- a/arm/aarch32/kvm.c
+++ b/arm/aarch32/kvm.c
@@ -2,4 +2,8 @@
 
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
+	if (kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
+		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
+		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
+	}
 }
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index ca348f118a56..2134528bf7f2 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -39,6 +39,11 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
 
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
+	if (kvm->cfg.arch.aarch32_guest &&
+	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
+		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
+		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
+	}
 }
 
 /*
diff --git a/arm/kvm.c b/arm/kvm.c
index c5913000e1ed..af0feae495d7 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -65,7 +65,7 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
 	 */
-	kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
+	kvm->ram_size = ram_size;
 	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
 	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 06/13] arm/arm64: Fail if RAM size is too large for 32-bit guests
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

For 64-bit guests, kvmtool exists with an error in kvm__get_vm_type() if
the memory size is larger than what KVM supports. For 32-bit guests, the
RAM size is silently rounded down to ARM_LOMAP_MAX_MEMORY in
kvm__arch_init().

Be consistent and exit with an error when the user has configured the
wrong RAM size for 32-bit guests.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/kvm.c | 4 ++++
 arm/aarch64/kvm.c | 5 +++++
 arm/kvm.c         | 2 +-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
index ae33ac92479a..9d68d7a15ee2 100644
--- a/arm/aarch32/kvm.c
+++ b/arm/aarch32/kvm.c
@@ -2,4 +2,8 @@
 
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
+	if (kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
+		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
+		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
+	}
 }
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index ca348f118a56..2134528bf7f2 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -39,6 +39,11 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
 
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
+	if (kvm->cfg.arch.aarch32_guest &&
+	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
+		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
+		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
+	}
 }
 
 /*
diff --git a/arm/kvm.c b/arm/kvm.c
index c5913000e1ed..af0feae495d7 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -65,7 +65,7 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
 	 */
-	kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
+	kvm->ram_size = ram_size;
 	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
 	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 07/13] arm/arm64: Kill the ARM_MAX_MEMORY() macro
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

For 32-bit guests, the maximum memory size is represented by the define
ARM_LOMAP_MAX_MEMORY, which ARM_MAX_MEMORY() returns.

For 64-bit guests, the RAM size is checked against the maximum allowed
by KVM in kvm__get_vm_type().

There are no users left for the ARM_MAX_MEMORY() macro, remove it.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/include/kvm/kvm-arch.h |  2 --
 arm/aarch64/include/kvm/kvm-arch.h | 16 ----------------
 2 files changed, 18 deletions(-)

diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index 5616b27e257e..467fb09175b8 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -8,8 +8,6 @@
 struct kvm;
 static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
 
-#define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
-
 #define MAX_PAGE_SIZE	SZ_4K
 
 #include "arm-common/kvm-arch.h"
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 9124f6919d0f..ff857ca6e7b4 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -8,22 +8,6 @@ unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
 int kvm__arch_get_ipa_limit(struct kvm *kvm);
 void kvm__arch_enable_mte(struct kvm *kvm);
 
-#define ARM_MAX_MEMORY(kvm)	({					\
-	u64 max_ram;							\
-									\
-	if ((kvm)->cfg.arch.aarch32_guest) {				\
-		max_ram = ARM_LOMAP_MAX_MEMORY;				\
-	} else {							\
-		int ipabits = kvm__arch_get_ipa_limit(kvm);		\
-		if (ipabits <= 0)					\
-			max_ram = ARM_HIMAP_MAX_MEMORY;			\
-		else							\
-			max_ram = (1ULL << ipabits) - ARM_MEMORY_AREA;	\
-	}								\
-									\
-	max_ram;							\
-})
-
 #define MAX_PAGE_SIZE	SZ_64K
 
 #include "arm-common/kvm-arch.h"
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 07/13] arm/arm64: Kill the ARM_MAX_MEMORY() macro
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

For 32-bit guests, the maximum memory size is represented by the define
ARM_LOMAP_MAX_MEMORY, which ARM_MAX_MEMORY() returns.

For 64-bit guests, the RAM size is checked against the maximum allowed
by KVM in kvm__get_vm_type().

There are no users left for the ARM_MAX_MEMORY() macro, remove it.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/include/kvm/kvm-arch.h |  2 --
 arm/aarch64/include/kvm/kvm-arch.h | 16 ----------------
 2 files changed, 18 deletions(-)

diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index 5616b27e257e..467fb09175b8 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -8,8 +8,6 @@
 struct kvm;
 static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
 
-#define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
-
 #define MAX_PAGE_SIZE	SZ_4K
 
 #include "arm-common/kvm-arch.h"
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 9124f6919d0f..ff857ca6e7b4 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -8,22 +8,6 @@ unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
 int kvm__arch_get_ipa_limit(struct kvm *kvm);
 void kvm__arch_enable_mte(struct kvm *kvm);
 
-#define ARM_MAX_MEMORY(kvm)	({					\
-	u64 max_ram;							\
-									\
-	if ((kvm)->cfg.arch.aarch32_guest) {				\
-		max_ram = ARM_LOMAP_MAX_MEMORY;				\
-	} else {							\
-		int ipabits = kvm__arch_get_ipa_limit(kvm);		\
-		if (ipabits <= 0)					\
-			max_ram = ARM_HIMAP_MAX_MEMORY;			\
-		else							\
-			max_ram = (1ULL << ipabits) - ARM_MEMORY_AREA;	\
-	}								\
-									\
-	max_ram;							\
-})
-
 #define MAX_PAGE_SIZE	SZ_64K
 
 #include "arm-common/kvm-arch.h"
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 08/13] arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The ARM_HIMAP_MAX_MEMORY() is a remnant of a time when KVM only supported
40 bits if IPA. There are no users left for this macro, remove it.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/include/arm-common/kvm-arch.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
index fc55360d4d15..6d80aac17125 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -65,7 +65,6 @@
 
 
 #define ARM_LOMAP_MAX_MEMORY	((1ULL << 32) - ARM_MEMORY_AREA)
-#define ARM_HIMAP_MAX_MEMORY	((1ULL << 40) - ARM_MEMORY_AREA)
 
 
 #define KVM_IOEVENTFD_HAS_PIO	0
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 08/13] arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

The ARM_HIMAP_MAX_MEMORY() is a remnant of a time when KVM only supported
40 bits if IPA. There are no users left for this macro, remove it.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/include/arm-common/kvm-arch.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
index fc55360d4d15..6d80aac17125 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -65,7 +65,6 @@
 
 
 #define ARM_LOMAP_MAX_MEMORY	((1ULL << 32) - ARM_MEMORY_AREA)
-#define ARM_HIMAP_MAX_MEMORY	((1ULL << 40) - ARM_MEMORY_AREA)
 
 
 #define KVM_IOEVENTFD_HAS_PIO	0
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

From: Suzuki K Poulose <suzuki.poulose@arm.com>

Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
When none are specified, the default is megabytes.

Also raise an error if the guest specifies 0 as the memory size, instead
of treating it as uninitialized, as kvmtool has done so far.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index 2ef159cdb2a3..a49698d5b2fe 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -49,9 +49,11 @@
 #include <ctype.h>
 #include <stdio.h>
 
-#define MB_SHIFT		(20)
 #define KB_SHIFT		(10)
+#define MB_SHIFT		(20)
 #define GB_SHIFT		(30)
+#define TB_SHIFT		(40)
+#define PB_SHIFT		(50)
 
 __thread struct kvm_cpu *current_kvm_cpu;
 
@@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
 	kvm_run_wrapper = KVM_RUN_SANDBOX;
 }
 
+static int parse_mem_unit(char **next)
+{
+	int shift = -1;
+
+	switch (**next) {
+	case 'B': case 'b': shift = 0; break;
+	case 'K': case 'k': shift = KB_SHIFT; break;
+	case 'M': case 'm': shift = MB_SHIFT; break;
+	case 'G': case 'g': shift = GB_SHIFT; break;
+	case 'T': case 't': shift = TB_SHIFT; break;
+	case 'P': case 'p': shift = PB_SHIFT; break;
+	}
+
+	if (shift == -1) {
+		/* The default is megabytes. */
+		shift = MB_SHIFT;
+	} else {
+		(*next)++;
+	}
+
+	return shift;
+}
+
+static u64 parse_mem_option(const char *nptr, char **next)
+{
+	u64 shift;
+	u64 val;
+
+	val = strtoull(nptr, next, 10);
+	if (errno == ERANGE)
+		die("Memory too large: %s", nptr);
+	shift = parse_mem_unit(next);
+
+	if ((val << shift) < val)
+		die("Memory too large: %s", nptr);
+
+	return val << shift;
+}
+
+static int mem_parser(const struct option *opt, const char *arg, int unset)
+{
+	struct kvm *kvm = opt->ptr;
+	char *next;
+
+	kvm->cfg.ram_size = parse_mem_option(arg, &next);
+	if (kvm->cfg.ram_size == 0)
+		die("Invalid RAM size: %s", arg);
+
+	if (*next != '\0')
+		die("Invalid memory specifier: %s", arg);
+
+	return 0;
+}
+
 #ifndef OPT_ARCH_RUN
 #define OPT_ARCH_RUN(...)
 #endif
@@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
 	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
-	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
-		" size in MB."),					\
+	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
+		     "Virtual machine memory size, by default measured"	\
+		     " in megabytes (M)", mem_parser, kvm),		\
 	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
 			" image or rootfs directory", img_name_parser,	\
 			kvm),						\
@@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
 		pr_warning("Ignoring initrd file when loading a firmware image");
 
 	if (kvm->cfg.ram_size) {
-		/* User specifies RAM size in megabytes. */
-		kvm->cfg.ram_size <<= MB_SHIFT;
 		available_ram = host_ram_size();
 		if (available_ram && kvm->cfg.ram_size > available_ram) {
 			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

From: Suzuki K Poulose <suzuki.poulose@arm.com>

Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
When none are specified, the default is megabytes.

Also raise an error if the guest specifies 0 as the memory size, instead
of treating it as uninitialized, as kvmtool has done so far.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index 2ef159cdb2a3..a49698d5b2fe 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -49,9 +49,11 @@
 #include <ctype.h>
 #include <stdio.h>
 
-#define MB_SHIFT		(20)
 #define KB_SHIFT		(10)
+#define MB_SHIFT		(20)
 #define GB_SHIFT		(30)
+#define TB_SHIFT		(40)
+#define PB_SHIFT		(50)
 
 __thread struct kvm_cpu *current_kvm_cpu;
 
@@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
 	kvm_run_wrapper = KVM_RUN_SANDBOX;
 }
 
+static int parse_mem_unit(char **next)
+{
+	int shift = -1;
+
+	switch (**next) {
+	case 'B': case 'b': shift = 0; break;
+	case 'K': case 'k': shift = KB_SHIFT; break;
+	case 'M': case 'm': shift = MB_SHIFT; break;
+	case 'G': case 'g': shift = GB_SHIFT; break;
+	case 'T': case 't': shift = TB_SHIFT; break;
+	case 'P': case 'p': shift = PB_SHIFT; break;
+	}
+
+	if (shift == -1) {
+		/* The default is megabytes. */
+		shift = MB_SHIFT;
+	} else {
+		(*next)++;
+	}
+
+	return shift;
+}
+
+static u64 parse_mem_option(const char *nptr, char **next)
+{
+	u64 shift;
+	u64 val;
+
+	val = strtoull(nptr, next, 10);
+	if (errno == ERANGE)
+		die("Memory too large: %s", nptr);
+	shift = parse_mem_unit(next);
+
+	if ((val << shift) < val)
+		die("Memory too large: %s", nptr);
+
+	return val << shift;
+}
+
+static int mem_parser(const struct option *opt, const char *arg, int unset)
+{
+	struct kvm *kvm = opt->ptr;
+	char *next;
+
+	kvm->cfg.ram_size = parse_mem_option(arg, &next);
+	if (kvm->cfg.ram_size == 0)
+		die("Invalid RAM size: %s", arg);
+
+	if (*next != '\0')
+		die("Invalid memory specifier: %s", arg);
+
+	return 0;
+}
+
 #ifndef OPT_ARCH_RUN
 #define OPT_ARCH_RUN(...)
 #endif
@@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
 	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
-	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
-		" size in MB."),					\
+	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
+		     "Virtual machine memory size, by default measured"	\
+		     " in megabytes (M)", mem_parser, kvm),		\
 	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
 			" image or rootfs directory", img_name_parser,	\
 			kvm),						\
@@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
 		pr_warning("Ignoring initrd file when loading a firmware image");
 
 	if (kvm->cfg.ram_size) {
-		/* User specifies RAM size in megabytes. */
-		kvm->cfg.ram_size <<= MB_SHIFT;
 		available_ram = host_ram_size();
 		if (available_ram && kvm->cfg.ram_size > available_ram) {
 			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 10/13] kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara
  Cc: Julien Grall

From: Julien Grall <julien.grall@arm.com>

The kvm struct already contains a pointer to the configuration, which
contains both hugetlbfs_path and ram_size, so is it not necessary to pass
them as arguments to kvm__arch_init().

Signed-off-by: Julien Grall <julien.grall@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/kvm.c         | 7 ++++---
 include/kvm/kvm.h | 2 +-
 kvm.c             | 2 +-
 mips/kvm.c        | 7 ++++---
 powerpc/kvm.c     | 5 +++--
 riscv/kvm.c       | 7 ++++---
 x86/kvm.c         | 4 +++-
 7 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index af0feae495d7..bd44aa350796 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -57,7 +57,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
@@ -65,9 +65,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
 	 */
-	kvm->ram_size = ram_size;
+	kvm->ram_size = kvm->cfg.ram_size;
 	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
+						kvm->cfg.hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
 
 	if (kvm->arch.ram_alloc_start == MAP_FAILED)
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 9f7b2fb26e95..640b76c095f9 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -189,7 +189,7 @@ void kvm__remove_socket(const char *name);
 
 void kvm__arch_validate_cfg(struct kvm *kvm);
 void kvm__arch_set_cmdline(char *cmdline, bool video);
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
+void kvm__arch_init(struct kvm *kvm);
 void kvm__arch_delete_ram(struct kvm *kvm);
 int kvm__arch_setup_firmware(struct kvm *kvm);
 int kvm__arch_free_firmware(struct kvm *kvm);
diff --git a/kvm.c b/kvm.c
index 952ef1fbb41c..42b881217df6 100644
--- a/kvm.c
+++ b/kvm.c
@@ -479,7 +479,7 @@ int kvm__init(struct kvm *kvm)
 		goto err_vm_fd;
 	}
 
-	kvm__arch_init(kvm, kvm->cfg.hugetlbfs_path, kvm->cfg.ram_size);
+	kvm__arch_init(kvm);
 
 	INIT_LIST_HEAD(&kvm->mem_banks);
 	kvm__init_ram(kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index f5b137f46dff..d8610cf81b94 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -61,12 +61,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	int ret;
 
-	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
-	kvm->ram_size = ram_size;
+	kvm->ram_size = kvm->cfg.ram_size;
+	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, kvm->cfg.hugetlbfs_path,
+						kvm->ram_size);
 
 	if (kvm->ram_start == MAP_FAILED)
 		die("out of memory");
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index 3215b579f5dc..d281b070fd0e 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -92,12 +92,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 	int cap_ppc_rma;
 	unsigned long hpt;
 
-	kvm->ram_size		= ram_size;
+	kvm->ram_size		= kvm->cfg.ram_size;
 
 	/* Map "default" hugetblfs path to the standard 16M mount point */
 	if (hugetlbfs_path && !strcmp(hugetlbfs_path, "default"))
diff --git a/riscv/kvm.c b/riscv/kvm.c
index 7fb496282f4c..c46660772aa0 100644
--- a/riscv/kvm.c
+++ b/riscv/kvm.c
@@ -56,7 +56,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
@@ -64,9 +64,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
 	 */
-	kvm->ram_size = min(ram_size, (u64)RISCV_MAX_MEMORY(kvm));
+	kvm->ram_size = min(kvm->cfg.ram_size, (u64)RISCV_MAX_MEMORY(kvm));
 	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
+						kvm->cfg.hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
 
 	if (kvm->arch.ram_alloc_start == MAP_FAILED)
diff --git a/x86/kvm.c b/x86/kvm.c
index 6683a5c81d49..24b0305a1841 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -134,9 +134,11 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 	struct kvm_pit_config pit_config = { .flags = 0, };
+	u64 ram_size = kvm->cfg.ram_size;
 	int ret;
 
 	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 10/13] kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara
  Cc: Julien Grall

From: Julien Grall <julien.grall@arm.com>

The kvm struct already contains a pointer to the configuration, which
contains both hugetlbfs_path and ram_size, so is it not necessary to pass
them as arguments to kvm__arch_init().

Signed-off-by: Julien Grall <julien.grall@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/kvm.c         | 7 ++++---
 include/kvm/kvm.h | 2 +-
 kvm.c             | 2 +-
 mips/kvm.c        | 7 ++++---
 powerpc/kvm.c     | 5 +++--
 riscv/kvm.c       | 7 ++++---
 x86/kvm.c         | 4 +++-
 7 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index af0feae495d7..bd44aa350796 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -57,7 +57,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
@@ -65,9 +65,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
 	 */
-	kvm->ram_size = ram_size;
+	kvm->ram_size = kvm->cfg.ram_size;
 	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
+						kvm->cfg.hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
 
 	if (kvm->arch.ram_alloc_start == MAP_FAILED)
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 9f7b2fb26e95..640b76c095f9 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -189,7 +189,7 @@ void kvm__remove_socket(const char *name);
 
 void kvm__arch_validate_cfg(struct kvm *kvm);
 void kvm__arch_set_cmdline(char *cmdline, bool video);
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
+void kvm__arch_init(struct kvm *kvm);
 void kvm__arch_delete_ram(struct kvm *kvm);
 int kvm__arch_setup_firmware(struct kvm *kvm);
 int kvm__arch_free_firmware(struct kvm *kvm);
diff --git a/kvm.c b/kvm.c
index 952ef1fbb41c..42b881217df6 100644
--- a/kvm.c
+++ b/kvm.c
@@ -479,7 +479,7 @@ int kvm__init(struct kvm *kvm)
 		goto err_vm_fd;
 	}
 
-	kvm__arch_init(kvm, kvm->cfg.hugetlbfs_path, kvm->cfg.ram_size);
+	kvm__arch_init(kvm);
 
 	INIT_LIST_HEAD(&kvm->mem_banks);
 	kvm__init_ram(kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index f5b137f46dff..d8610cf81b94 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -61,12 +61,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	int ret;
 
-	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
-	kvm->ram_size = ram_size;
+	kvm->ram_size = kvm->cfg.ram_size;
+	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, kvm->cfg.hugetlbfs_path,
+						kvm->ram_size);
 
 	if (kvm->ram_start == MAP_FAILED)
 		die("out of memory");
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index 3215b579f5dc..d281b070fd0e 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -92,12 +92,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 	int cap_ppc_rma;
 	unsigned long hpt;
 
-	kvm->ram_size		= ram_size;
+	kvm->ram_size		= kvm->cfg.ram_size;
 
 	/* Map "default" hugetblfs path to the standard 16M mount point */
 	if (hugetlbfs_path && !strcmp(hugetlbfs_path, "default"))
diff --git a/riscv/kvm.c b/riscv/kvm.c
index 7fb496282f4c..c46660772aa0 100644
--- a/riscv/kvm.c
+++ b/riscv/kvm.c
@@ -56,7 +56,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 {
 }
 
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
@@ -64,9 +64,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	 * If using THP, then our minimal alignment becomes 2M.
 	 * 2M trumps 64K, so let's go with that.
 	 */
-	kvm->ram_size = min(ram_size, (u64)RISCV_MAX_MEMORY(kvm));
+	kvm->ram_size = min(kvm->cfg.ram_size, (u64)RISCV_MAX_MEMORY(kvm));
 	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
+						kvm->cfg.hugetlbfs_path,
 						kvm->arch.ram_alloc_size);
 
 	if (kvm->arch.ram_alloc_start == MAP_FAILED)
diff --git a/x86/kvm.c b/x86/kvm.c
index 6683a5c81d49..24b0305a1841 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -134,9 +134,11 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 }
 
 /* Architecture-specific KVM init */
-void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+void kvm__arch_init(struct kvm *kvm)
 {
+	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
 	struct kvm_pit_config pit_config = { .flags = 0, };
+	u64 ram_size = kvm->cfg.ram_size;
 	int ret;
 
 	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 11/13] arm/arm64: Consolidate RAM initialization in kvm__init_ram()
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara
  Cc: Julien Grall

From: Julien Grall <julien.grall@arm.com>

RAM initialization is unnecessarily split between kvm__init_ram() and
kvm__arch_init(). Move all code related to RAM initialization to
kvm__init_ram(), making the code easier to follow and to modify.

One thing to note is that the initialization order is slightly altered:
kvm__arch_enable_mte() and gic__create() are now called before mmap'ing the
guest RAM. That is perfectly fine, as they don't use the host's mapping of
the guest memory.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/kvm.c | 52 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index bd44aa350796..abcccfabf59e 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -26,9 +26,34 @@ bool kvm__arch_cpu_supports_vm(void)
 
 void kvm__init_ram(struct kvm *kvm)
 {
-	int err;
 	u64 phys_start, phys_size;
 	void *host_mem;
+	int err;
+
+	/*
+	 * Allocate guest memory. We must align our buffer to 64K to
+	 * correlate with the maximum guest page size for virtio-mmio.
+	 * If using THP, then our minimal alignment becomes 2M.
+	 * 2M trumps 64K, so let's go with that.
+	 */
+	kvm->ram_size = kvm->cfg.ram_size;
+	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
+						kvm->cfg.hugetlbfs_path,
+						kvm->arch.ram_alloc_size);
+
+	if (kvm->arch.ram_alloc_start == MAP_FAILED)
+		die("Failed to map %lld bytes for guest memory (%d)",
+		    kvm->arch.ram_alloc_size, errno);
+
+	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
+					SZ_2M);
+
+	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+		MADV_MERGEABLE);
+
+	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+		MADV_HUGEPAGE);
 
 	phys_start	= ARM_MEMORY_AREA;
 	phys_size	= kvm->ram_size;
@@ -59,31 +84,6 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 
 void kvm__arch_init(struct kvm *kvm)
 {
-	/*
-	 * Allocate guest memory. We must align our buffer to 64K to
-	 * correlate with the maximum guest page size for virtio-mmio.
-	 * If using THP, then our minimal alignment becomes 2M.
-	 * 2M trumps 64K, so let's go with that.
-	 */
-	kvm->ram_size = kvm->cfg.ram_size;
-	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
-						kvm->cfg.hugetlbfs_path,
-						kvm->arch.ram_alloc_size);
-
-	if (kvm->arch.ram_alloc_start == MAP_FAILED)
-		die("Failed to map %lld bytes for guest memory (%d)",
-		    kvm->arch.ram_alloc_size, errno);
-
-	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
-					SZ_2M);
-
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_MERGEABLE);
-
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_HUGEPAGE);
-
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 11/13] arm/arm64: Consolidate RAM initialization in kvm__init_ram()
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara
  Cc: Julien Grall

From: Julien Grall <julien.grall@arm.com>

RAM initialization is unnecessarily split between kvm__init_ram() and
kvm__arch_init(). Move all code related to RAM initialization to
kvm__init_ram(), making the code easier to follow and to modify.

One thing to note is that the initialization order is slightly altered:
kvm__arch_enable_mte() and gic__create() are now called before mmap'ing the
guest RAM. That is perfectly fine, as they don't use the host's mapping of
the guest memory.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/kvm.c | 52 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/arm/kvm.c b/arm/kvm.c
index bd44aa350796..abcccfabf59e 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -26,9 +26,34 @@ bool kvm__arch_cpu_supports_vm(void)
 
 void kvm__init_ram(struct kvm *kvm)
 {
-	int err;
 	u64 phys_start, phys_size;
 	void *host_mem;
+	int err;
+
+	/*
+	 * Allocate guest memory. We must align our buffer to 64K to
+	 * correlate with the maximum guest page size for virtio-mmio.
+	 * If using THP, then our minimal alignment becomes 2M.
+	 * 2M trumps 64K, so let's go with that.
+	 */
+	kvm->ram_size = kvm->cfg.ram_size;
+	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
+	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
+						kvm->cfg.hugetlbfs_path,
+						kvm->arch.ram_alloc_size);
+
+	if (kvm->arch.ram_alloc_start == MAP_FAILED)
+		die("Failed to map %lld bytes for guest memory (%d)",
+		    kvm->arch.ram_alloc_size, errno);
+
+	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
+					SZ_2M);
+
+	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+		MADV_MERGEABLE);
+
+	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
+		MADV_HUGEPAGE);
 
 	phys_start	= ARM_MEMORY_AREA;
 	phys_size	= kvm->ram_size;
@@ -59,31 +84,6 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
 
 void kvm__arch_init(struct kvm *kvm)
 {
-	/*
-	 * Allocate guest memory. We must align our buffer to 64K to
-	 * correlate with the maximum guest page size for virtio-mmio.
-	 * If using THP, then our minimal alignment becomes 2M.
-	 * 2M trumps 64K, so let's go with that.
-	 */
-	kvm->ram_size = kvm->cfg.ram_size;
-	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
-	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
-						kvm->cfg.hugetlbfs_path,
-						kvm->arch.ram_alloc_size);
-
-	if (kvm->arch.ram_alloc_start == MAP_FAILED)
-		die("Failed to map %lld bytes for guest memory (%d)",
-		    kvm->arch.ram_alloc_size, errno);
-
-	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
-					SZ_2M);
-
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_MERGEABLE);
-
-	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
-		MADV_HUGEPAGE);
-
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 12/13] Introduce kvm__arch_default_ram_address()
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Add a new function, kvm__arch_default_ram_address(), which returns the
default address for guest RAM for each architecture.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/kvm.c | 5 +++++
 arm/aarch64/kvm.c | 5 +++++
 include/kvm/kvm.h | 1 +
 mips/kvm.c        | 5 +++++
 powerpc/kvm.c     | 5 +++++
 riscv/kvm.c       | 5 +++++
 x86/kvm.c         | 5 +++++
 7 files changed, 31 insertions(+)

diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
index 9d68d7a15ee2..768a56bbb5b4 100644
--- a/arm/aarch32/kvm.c
+++ b/arm/aarch32/kvm.c
@@ -7,3 +7,8 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
 		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
 	}
 }
+
+u64 kvm__arch_default_ram_address(void)
+{
+	return ARM_MEMORY_AREA;
+}
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 2134528bf7f2..357936844046 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -46,6 +46,11 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
 	}
 }
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return ARM_MEMORY_AREA;
+}
+
 /*
  * Return the TEXT_OFFSET value that the guest kernel expects. Note
  * that pre-3.17 kernels expose this value using the native endianness
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 640b76c095f9..360430b78b1e 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -190,6 +190,7 @@ void kvm__remove_socket(const char *name);
 void kvm__arch_validate_cfg(struct kvm *kvm);
 void kvm__arch_set_cmdline(char *cmdline, bool video);
 void kvm__arch_init(struct kvm *kvm);
+u64 kvm__arch_default_ram_address(void);
 void kvm__arch_delete_ram(struct kvm *kvm);
 int kvm__arch_setup_firmware(struct kvm *kvm);
 int kvm__arch_free_firmware(struct kvm *kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index d8610cf81b94..4cbc9907731b 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -12,6 +12,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return 0;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index d281b070fd0e..7b0d0669aff4 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -48,6 +48,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return 0;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
diff --git a/riscv/kvm.c b/riscv/kvm.c
index c46660772aa0..4d6f5cb57ac8 100644
--- a/riscv/kvm.c
+++ b/riscv/kvm.c
@@ -13,6 +13,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 },
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return RISCV_RAM;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
diff --git a/x86/kvm.c b/x86/kvm.c
index 24b0305a1841..328fa7500596 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -35,6 +35,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return 0;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 12/13] Introduce kvm__arch_default_ram_address()
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Add a new function, kvm__arch_default_ram_address(), which returns the
default address for guest RAM for each architecture.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/kvm.c | 5 +++++
 arm/aarch64/kvm.c | 5 +++++
 include/kvm/kvm.h | 1 +
 mips/kvm.c        | 5 +++++
 powerpc/kvm.c     | 5 +++++
 riscv/kvm.c       | 5 +++++
 x86/kvm.c         | 5 +++++
 7 files changed, 31 insertions(+)

diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
index 9d68d7a15ee2..768a56bbb5b4 100644
--- a/arm/aarch32/kvm.c
+++ b/arm/aarch32/kvm.c
@@ -7,3 +7,8 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
 		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
 	}
 }
+
+u64 kvm__arch_default_ram_address(void)
+{
+	return ARM_MEMORY_AREA;
+}
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 2134528bf7f2..357936844046 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -46,6 +46,11 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
 	}
 }
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return ARM_MEMORY_AREA;
+}
+
 /*
  * Return the TEXT_OFFSET value that the guest kernel expects. Note
  * that pre-3.17 kernels expose this value using the native endianness
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 640b76c095f9..360430b78b1e 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -190,6 +190,7 @@ void kvm__remove_socket(const char *name);
 void kvm__arch_validate_cfg(struct kvm *kvm);
 void kvm__arch_set_cmdline(char *cmdline, bool video);
 void kvm__arch_init(struct kvm *kvm);
+u64 kvm__arch_default_ram_address(void);
 void kvm__arch_delete_ram(struct kvm *kvm);
 int kvm__arch_setup_firmware(struct kvm *kvm);
 int kvm__arch_free_firmware(struct kvm *kvm);
diff --git a/mips/kvm.c b/mips/kvm.c
index d8610cf81b94..4cbc9907731b 100644
--- a/mips/kvm.c
+++ b/mips/kvm.c
@@ -12,6 +12,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return 0;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
diff --git a/powerpc/kvm.c b/powerpc/kvm.c
index d281b070fd0e..7b0d0669aff4 100644
--- a/powerpc/kvm.c
+++ b/powerpc/kvm.c
@@ -48,6 +48,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return 0;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
diff --git a/riscv/kvm.c b/riscv/kvm.c
index c46660772aa0..4d6f5cb57ac8 100644
--- a/riscv/kvm.c
+++ b/riscv/kvm.c
@@ -13,6 +13,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 },
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return RISCV_RAM;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
diff --git a/x86/kvm.c b/x86/kvm.c
index 24b0305a1841..328fa7500596 100644
--- a/x86/kvm.c
+++ b/x86/kvm.c
@@ -35,6 +35,11 @@ struct kvm_ext kvm_req_ext[] = {
 	{ 0, 0 }
 };
 
+u64 kvm__arch_default_ram_address(void)
+{
+	return 0;
+}
+
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
 }
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 kvmtool 13/13] arm64: Allow the user to specify the RAM base address
  2022-05-25 11:23 ` Alexandru Elisei
@ 2022-05-25 11:23   ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Allow the user to specify the RAM base address by using -m/--mem size@addr
command line argument. The base address must be above 2GB, as to not
overlap with the MMIO I/O region.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch64/include/kvm/kvm-arch.h |  2 ++
 arm/aarch64/kvm.c                  | 14 ++++++++----
 arm/kvm.c                          |  7 ++++--
 builtin-run.c                      | 36 ++++++++++++++++++++++++++----
 include/kvm/kvm-config.h           |  1 +
 include/kvm/kvm.h                  | 12 ++++++++++
 include/linux/sizes.h              |  2 ++
 7 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index ff857ca6e7b4..02d09a413831 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -10,6 +10,8 @@ void kvm__arch_enable_mte(struct kvm *kvm);
 
 #define MAX_PAGE_SIZE	SZ_64K
 
+#define ARCH_HAS_CFG_RAM_ADDRESS	1
+
 #include "arm-common/kvm-arch.h"
 
 #endif /* KVM__KVM_ARCH_H */
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 357936844046..54200c9eec9d 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -4,6 +4,7 @@
 
 #include <linux/byteorder.h>
 #include <linux/cpumask.h>
+#include <linux/sizes.h>
 
 #include <kvm/util.h>
 
@@ -39,10 +40,15 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
 
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
+
+	if (kvm->cfg.ram_addr < ARM_MEMORY_AREA) {
+		die("RAM address is below the I/O region ending at %luGB",
+		    ARM_MEMORY_AREA >> 30);
+	}
+
 	if (kvm->cfg.arch.aarch32_guest &&
-	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
-		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
-		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
+	    kvm->cfg.ram_addr + kvm->cfg.ram_size > SZ_4G) {
+		die("RAM extends above 4GB");
 	}
 }
 
@@ -117,7 +123,7 @@ int kvm__get_vm_type(struct kvm *kvm)
 		return 0;
 
 	/* Otherwise, compute the minimal required IPA size */
-	max_ipa = ARM_MEMORY_AREA + kvm->cfg.ram_size - 1;
+	max_ipa = kvm->cfg.ram_addr + kvm->cfg.ram_size - 1;
 	ipa_bits = max(32, fls_long(max_ipa));
 	pr_debug("max_ipa %lx ipa_bits %d max_ipa_bits %d",
 		 max_ipa, ipa_bits, max_ipa_bits);
diff --git a/arm/kvm.c b/arm/kvm.c
index abcccfabf59e..d51cc15d8b1c 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -55,7 +55,7 @@ void kvm__init_ram(struct kvm *kvm)
 	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
 		MADV_HUGEPAGE);
 
-	phys_start	= ARM_MEMORY_AREA;
+	phys_start	= kvm->cfg.ram_addr;
 	phys_size	= kvm->ram_size;
 	host_mem	= kvm->ram_start;
 
@@ -65,6 +65,9 @@ void kvm__init_ram(struct kvm *kvm)
 		    "address 0x%llx [err %d]", phys_size, phys_start, err);
 
 	kvm->arch.memory_guest_start = phys_start;
+
+	pr_debug("RAM created at 0x%llx - 0x%llx",
+		 phys_start, phys_start + phys_size - 1);
 }
 
 void kvm__arch_delete_ram(struct kvm *kvm)
@@ -201,7 +204,7 @@ bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
 
 	/* For default firmware address, lets load it at the begining of RAM */
 	if (fw_addr == 0)
-		fw_addr = ARM_MEMORY_AREA;
+		fw_addr = kvm->arch.memory_guest_start;
 
 	if (!validate_fw_addr(kvm, fw_addr))
 		die("Bad firmware destination: 0x%016llx", fw_addr);
diff --git a/builtin-run.c b/builtin-run.c
index a49698d5b2fe..68beaaa7c06f 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -131,12 +131,21 @@ static u64 parse_mem_option(const char *nptr, char **next)
 static int mem_parser(const struct option *opt, const char *arg, int unset)
 {
 	struct kvm *kvm = opt->ptr;
-	char *next;
+	char *next, *nptr;
 
 	kvm->cfg.ram_size = parse_mem_option(arg, &next);
 	if (kvm->cfg.ram_size == 0)
 		die("Invalid RAM size: %s", arg);
 
+	if (kvm__arch_has_cfg_ram_address() && *next == '@') {
+		next++;
+		if (*next == '\0')
+			die("Missing memory address: %s", arg);
+
+		nptr = next;
+		kvm->cfg.ram_addr = parse_mem_option(nptr, &next);
+	}
+
 	if (*next != '\0')
 		die("Invalid memory specifier: %s", arg);
 
@@ -147,15 +156,26 @@ static int mem_parser(const struct option *opt, const char *arg, int unset)
 #define OPT_ARCH_RUN(...)
 #endif
 
+#ifdef ARCH_HAS_CFG_RAM_ADDRESS
+#define MEM_OPT_HELP_SHORT	"size[BKMGTP][@addr[BKMGTP]]"
+#define MEM_OPT_HELP_LONG						\
+	"Virtual machine memory size and optional base address, both"	\
+	" measured by default in megabytes (M)"
+#else
+#define MEM_OPT_HELP_SHORT	"size[BKMGTP]"
+#define MEM_OPT_HELP_LONG						\
+	"Virtual machine memory size, by default measured in"		\
+	" in megabytes (M)"
+#endif
+
 #define BUILD_OPTIONS(name, cfg, kvm)					\
 	struct option name[] = {					\
 	OPT_GROUP("Basic options:"),					\
 	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
-	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
-		     "Virtual machine memory size, by default measured"	\
-		     " in megabytes (M)", mem_parser, kvm),		\
+	OPT_CALLBACK('m', "mem", NULL, MEM_OPT_HELP_SHORT,		\
+		     MEM_OPT_HELP_LONG, mem_parser, kvm),		\
 	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
 			" image or rootfs directory", img_name_parser,	\
 			kvm),						\
@@ -601,6 +621,14 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 	kvm->cfg.custom_rootfs_name = "default";
+	/*
+	 * An architecture might allow the user to set the RAM base address to
+	 * zero. Initialize the address before parsing the command line
+	 * arguments, because otherwise it will be impossible to distinguish
+	 * between the user setting the base address to zero or letting it
+	 * unspecified.
+	 */
+	kvm->cfg.ram_addr = kvm__arch_default_ram_address();
 
 	while (argc != 0) {
 		BUILD_OPTIONS(options, &kvm->cfg, kvm);
diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
index 31bc89520d52..45fe1caaebce 100644
--- a/include/kvm/kvm-config.h
+++ b/include/kvm/kvm-config.h
@@ -23,6 +23,7 @@ struct kvm_config {
 	struct kvm_config_arch arch;
 	struct disk_image_params disk_image[MAX_DISK_IMAGES];
 	struct vfio_device_params *vfio_devices;
+	u64 ram_addr;		/* Guest memory physical base address, in bytes */
 	u64 ram_size;		/* Guest memory size, in bytes */
 	u8 num_net_devices;
 	u8 num_vfio_devices;
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 360430b78b1e..eb23e2f77310 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -197,6 +197,18 @@ int kvm__arch_free_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
 void kvm__arch_read_term(struct kvm *kvm);
 
+#ifdef ARCH_HAS_CFG_RAM_ADDRESS
+static inline bool kvm__arch_has_cfg_ram_address(void)
+{
+	return true;
+}
+#else
+static inline bool kvm__arch_has_cfg_ram_address(void)
+{
+	return false;
+}
+#endif
+
 void *guest_flat_to_host(struct kvm *kvm, u64 offset);
 u64 host_to_guest_flat(struct kvm *kvm, void *ptr);
 
diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index b2b5c457cf1c..52afca02aa6e 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -44,4 +44,6 @@
 #define SZ_1G				0x40000000ULL
 #define SZ_2G				0x80000000ULL
 
+#define SZ_4G				0x100000000ULL
+
 #endif /* __LINUX_SIZES_H__ */
-- 
2.36.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* [PATCH v3 kvmtool 13/13] arm64: Allow the user to specify the RAM base address
@ 2022-05-25 11:23   ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-05-25 11:23 UTC (permalink / raw)
  To: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, andre.przywara

Allow the user to specify the RAM base address by using -m/--mem size@addr
command line argument. The base address must be above 2GB, as to not
overlap with the MMIO I/O region.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch64/include/kvm/kvm-arch.h |  2 ++
 arm/aarch64/kvm.c                  | 14 ++++++++----
 arm/kvm.c                          |  7 ++++--
 builtin-run.c                      | 36 ++++++++++++++++++++++++++----
 include/kvm/kvm-config.h           |  1 +
 include/kvm/kvm.h                  | 12 ++++++++++
 include/linux/sizes.h              |  2 ++
 7 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index ff857ca6e7b4..02d09a413831 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -10,6 +10,8 @@ void kvm__arch_enable_mte(struct kvm *kvm);
 
 #define MAX_PAGE_SIZE	SZ_64K
 
+#define ARCH_HAS_CFG_RAM_ADDRESS	1
+
 #include "arm-common/kvm-arch.h"
 
 #endif /* KVM__KVM_ARCH_H */
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 357936844046..54200c9eec9d 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -4,6 +4,7 @@
 
 #include <linux/byteorder.h>
 #include <linux/cpumask.h>
+#include <linux/sizes.h>
 
 #include <kvm/util.h>
 
@@ -39,10 +40,15 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
 
 void kvm__arch_validate_cfg(struct kvm *kvm)
 {
+
+	if (kvm->cfg.ram_addr < ARM_MEMORY_AREA) {
+		die("RAM address is below the I/O region ending at %luGB",
+		    ARM_MEMORY_AREA >> 30);
+	}
+
 	if (kvm->cfg.arch.aarch32_guest &&
-	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
-		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
-		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
+	    kvm->cfg.ram_addr + kvm->cfg.ram_size > SZ_4G) {
+		die("RAM extends above 4GB");
 	}
 }
 
@@ -117,7 +123,7 @@ int kvm__get_vm_type(struct kvm *kvm)
 		return 0;
 
 	/* Otherwise, compute the minimal required IPA size */
-	max_ipa = ARM_MEMORY_AREA + kvm->cfg.ram_size - 1;
+	max_ipa = kvm->cfg.ram_addr + kvm->cfg.ram_size - 1;
 	ipa_bits = max(32, fls_long(max_ipa));
 	pr_debug("max_ipa %lx ipa_bits %d max_ipa_bits %d",
 		 max_ipa, ipa_bits, max_ipa_bits);
diff --git a/arm/kvm.c b/arm/kvm.c
index abcccfabf59e..d51cc15d8b1c 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -55,7 +55,7 @@ void kvm__init_ram(struct kvm *kvm)
 	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
 		MADV_HUGEPAGE);
 
-	phys_start	= ARM_MEMORY_AREA;
+	phys_start	= kvm->cfg.ram_addr;
 	phys_size	= kvm->ram_size;
 	host_mem	= kvm->ram_start;
 
@@ -65,6 +65,9 @@ void kvm__init_ram(struct kvm *kvm)
 		    "address 0x%llx [err %d]", phys_size, phys_start, err);
 
 	kvm->arch.memory_guest_start = phys_start;
+
+	pr_debug("RAM created at 0x%llx - 0x%llx",
+		 phys_start, phys_start + phys_size - 1);
 }
 
 void kvm__arch_delete_ram(struct kvm *kvm)
@@ -201,7 +204,7 @@ bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
 
 	/* For default firmware address, lets load it at the begining of RAM */
 	if (fw_addr == 0)
-		fw_addr = ARM_MEMORY_AREA;
+		fw_addr = kvm->arch.memory_guest_start;
 
 	if (!validate_fw_addr(kvm, fw_addr))
 		die("Bad firmware destination: 0x%016llx", fw_addr);
diff --git a/builtin-run.c b/builtin-run.c
index a49698d5b2fe..68beaaa7c06f 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -131,12 +131,21 @@ static u64 parse_mem_option(const char *nptr, char **next)
 static int mem_parser(const struct option *opt, const char *arg, int unset)
 {
 	struct kvm *kvm = opt->ptr;
-	char *next;
+	char *next, *nptr;
 
 	kvm->cfg.ram_size = parse_mem_option(arg, &next);
 	if (kvm->cfg.ram_size == 0)
 		die("Invalid RAM size: %s", arg);
 
+	if (kvm__arch_has_cfg_ram_address() && *next == '@') {
+		next++;
+		if (*next == '\0')
+			die("Missing memory address: %s", arg);
+
+		nptr = next;
+		kvm->cfg.ram_addr = parse_mem_option(nptr, &next);
+	}
+
 	if (*next != '\0')
 		die("Invalid memory specifier: %s", arg);
 
@@ -147,15 +156,26 @@ static int mem_parser(const struct option *opt, const char *arg, int unset)
 #define OPT_ARCH_RUN(...)
 #endif
 
+#ifdef ARCH_HAS_CFG_RAM_ADDRESS
+#define MEM_OPT_HELP_SHORT	"size[BKMGTP][@addr[BKMGTP]]"
+#define MEM_OPT_HELP_LONG						\
+	"Virtual machine memory size and optional base address, both"	\
+	" measured by default in megabytes (M)"
+#else
+#define MEM_OPT_HELP_SHORT	"size[BKMGTP]"
+#define MEM_OPT_HELP_LONG						\
+	"Virtual machine memory size, by default measured in"		\
+	" in megabytes (M)"
+#endif
+
 #define BUILD_OPTIONS(name, cfg, kvm)					\
 	struct option name[] = {					\
 	OPT_GROUP("Basic options:"),					\
 	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
 			"A name for the guest"),			\
 	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
-	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
-		     "Virtual machine memory size, by default measured"	\
-		     " in megabytes (M)", mem_parser, kvm),		\
+	OPT_CALLBACK('m', "mem", NULL, MEM_OPT_HELP_SHORT,		\
+		     MEM_OPT_HELP_LONG, mem_parser, kvm),		\
 	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
 			" image or rootfs directory", img_name_parser,	\
 			kvm),						\
@@ -601,6 +621,14 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
 
 	nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 	kvm->cfg.custom_rootfs_name = "default";
+	/*
+	 * An architecture might allow the user to set the RAM base address to
+	 * zero. Initialize the address before parsing the command line
+	 * arguments, because otherwise it will be impossible to distinguish
+	 * between the user setting the base address to zero or letting it
+	 * unspecified.
+	 */
+	kvm->cfg.ram_addr = kvm__arch_default_ram_address();
 
 	while (argc != 0) {
 		BUILD_OPTIONS(options, &kvm->cfg, kvm);
diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
index 31bc89520d52..45fe1caaebce 100644
--- a/include/kvm/kvm-config.h
+++ b/include/kvm/kvm-config.h
@@ -23,6 +23,7 @@ struct kvm_config {
 	struct kvm_config_arch arch;
 	struct disk_image_params disk_image[MAX_DISK_IMAGES];
 	struct vfio_device_params *vfio_devices;
+	u64 ram_addr;		/* Guest memory physical base address, in bytes */
 	u64 ram_size;		/* Guest memory size, in bytes */
 	u8 num_net_devices;
 	u8 num_vfio_devices;
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 360430b78b1e..eb23e2f77310 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -197,6 +197,18 @@ int kvm__arch_free_firmware(struct kvm *kvm);
 bool kvm__arch_cpu_supports_vm(void);
 void kvm__arch_read_term(struct kvm *kvm);
 
+#ifdef ARCH_HAS_CFG_RAM_ADDRESS
+static inline bool kvm__arch_has_cfg_ram_address(void)
+{
+	return true;
+}
+#else
+static inline bool kvm__arch_has_cfg_ram_address(void)
+{
+	return false;
+}
+#endif
+
 void *guest_flat_to_host(struct kvm *kvm, u64 offset);
 u64 host_to_guest_flat(struct kvm *kvm, void *ptr);
 
diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index b2b5c457cf1c..52afca02aa6e 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -44,4 +44,6 @@
 #define SZ_1G				0x40000000ULL
 #define SZ_2G				0x80000000ULL
 
+#define SZ_4G				0x100000000ULL
+
 #endif /* __LINUX_SIZES_H__ */
-- 
2.36.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-05-30 15:05     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-05-30 15:05 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:34 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> Append ULL to all of the size definitions to make them 64bit and avoid
> overflows.

I am not fully convinced this is the best solution, as it deviates from
the kernel file, and just papers over issues at the call sites. I
acknowledge the pragmatic approach of trying to fix multiple problems at
once, but am wondering if we should use -fsanitize=undefined to identify
problematic code and fix it (I started doing this, actually).

Cheers,
Andre

> Reported-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  include/linux/sizes.h | 64 +++++++++++++++++++++----------------------
>  1 file changed, 32 insertions(+), 32 deletions(-)
> 
> diff --git a/include/linux/sizes.h b/include/linux/sizes.h
> index ce3e8150c174..b2b5c457cf1c 100644
> --- a/include/linux/sizes.h
> +++ b/include/linux/sizes.h
> @@ -8,40 +8,40 @@
>  #ifndef __LINUX_SIZES_H__
>  #define __LINUX_SIZES_H__
>  
> -#define SZ_1				0x00000001
> -#define SZ_2				0x00000002
> -#define SZ_4				0x00000004
> -#define SZ_8				0x00000008
> -#define SZ_16				0x00000010
> -#define SZ_32				0x00000020
> -#define SZ_64				0x00000040
> -#define SZ_128				0x00000080
> -#define SZ_256				0x00000100
> -#define SZ_512				0x00000200
> +#define SZ_1				0x00000001ULL
> +#define SZ_2				0x00000002ULL
> +#define SZ_4				0x00000004ULL
> +#define SZ_8				0x00000008ULL
> +#define SZ_16				0x00000010ULL
> +#define SZ_32				0x00000020ULL
> +#define SZ_64				0x00000040ULL
> +#define SZ_128				0x00000080ULL
> +#define SZ_256				0x00000100ULL
> +#define SZ_512				0x00000200ULL
>  
> -#define SZ_1K				0x00000400
> -#define SZ_2K				0x00000800
> -#define SZ_4K				0x00001000
> -#define SZ_8K				0x00002000
> -#define SZ_16K				0x00004000
> -#define SZ_32K				0x00008000
> -#define SZ_64K				0x00010000
> -#define SZ_128K				0x00020000
> -#define SZ_256K				0x00040000
> -#define SZ_512K				0x00080000
> +#define SZ_1K				0x00000400ULL
> +#define SZ_2K				0x00000800ULL
> +#define SZ_4K				0x00001000ULL
> +#define SZ_8K				0x00002000ULL
> +#define SZ_16K				0x00004000ULL
> +#define SZ_32K				0x00008000ULL
> +#define SZ_64K				0x00010000ULL
> +#define SZ_128K				0x00020000ULL
> +#define SZ_256K				0x00040000ULL
> +#define SZ_512K				0x00080000ULL
>  
> -#define SZ_1M				0x00100000
> -#define SZ_2M				0x00200000
> -#define SZ_4M				0x00400000
> -#define SZ_8M				0x00800000
> -#define SZ_16M				0x01000000
> -#define SZ_32M				0x02000000
> -#define SZ_64M				0x04000000
> -#define SZ_128M				0x08000000
> -#define SZ_256M				0x10000000
> -#define SZ_512M				0x20000000
> +#define SZ_1M				0x00100000ULL
> +#define SZ_2M				0x00200000ULL
> +#define SZ_4M				0x00400000ULL
> +#define SZ_8M				0x00800000ULL
> +#define SZ_16M				0x01000000ULL
> +#define SZ_32M				0x02000000ULL
> +#define SZ_64M				0x04000000ULL
> +#define SZ_128M				0x08000000ULL
> +#define SZ_256M				0x10000000ULL
> +#define SZ_512M				0x20000000ULL
>  
> -#define SZ_1G				0x40000000
> -#define SZ_2G				0x80000000
> +#define SZ_1G				0x40000000ULL
> +#define SZ_2G				0x80000000ULL
>  
>  #endif /* __LINUX_SIZES_H__ */

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit
@ 2022-05-30 15:05     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-05-30 15:05 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:34 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> Append ULL to all of the size definitions to make them 64bit and avoid
> overflows.

I am not fully convinced this is the best solution, as it deviates from
the kernel file, and just papers over issues at the call sites. I
acknowledge the pragmatic approach of trying to fix multiple problems at
once, but am wondering if we should use -fsanitize=undefined to identify
problematic code and fix it (I started doing this, actually).

Cheers,
Andre

> Reported-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  include/linux/sizes.h | 64 +++++++++++++++++++++----------------------
>  1 file changed, 32 insertions(+), 32 deletions(-)
> 
> diff --git a/include/linux/sizes.h b/include/linux/sizes.h
> index ce3e8150c174..b2b5c457cf1c 100644
> --- a/include/linux/sizes.h
> +++ b/include/linux/sizes.h
> @@ -8,40 +8,40 @@
>  #ifndef __LINUX_SIZES_H__
>  #define __LINUX_SIZES_H__
>  
> -#define SZ_1				0x00000001
> -#define SZ_2				0x00000002
> -#define SZ_4				0x00000004
> -#define SZ_8				0x00000008
> -#define SZ_16				0x00000010
> -#define SZ_32				0x00000020
> -#define SZ_64				0x00000040
> -#define SZ_128				0x00000080
> -#define SZ_256				0x00000100
> -#define SZ_512				0x00000200
> +#define SZ_1				0x00000001ULL
> +#define SZ_2				0x00000002ULL
> +#define SZ_4				0x00000004ULL
> +#define SZ_8				0x00000008ULL
> +#define SZ_16				0x00000010ULL
> +#define SZ_32				0x00000020ULL
> +#define SZ_64				0x00000040ULL
> +#define SZ_128				0x00000080ULL
> +#define SZ_256				0x00000100ULL
> +#define SZ_512				0x00000200ULL
>  
> -#define SZ_1K				0x00000400
> -#define SZ_2K				0x00000800
> -#define SZ_4K				0x00001000
> -#define SZ_8K				0x00002000
> -#define SZ_16K				0x00004000
> -#define SZ_32K				0x00008000
> -#define SZ_64K				0x00010000
> -#define SZ_128K				0x00020000
> -#define SZ_256K				0x00040000
> -#define SZ_512K				0x00080000
> +#define SZ_1K				0x00000400ULL
> +#define SZ_2K				0x00000800ULL
> +#define SZ_4K				0x00001000ULL
> +#define SZ_8K				0x00002000ULL
> +#define SZ_16K				0x00004000ULL
> +#define SZ_32K				0x00008000ULL
> +#define SZ_64K				0x00010000ULL
> +#define SZ_128K				0x00020000ULL
> +#define SZ_256K				0x00040000ULL
> +#define SZ_512K				0x00080000ULL
>  
> -#define SZ_1M				0x00100000
> -#define SZ_2M				0x00200000
> -#define SZ_4M				0x00400000
> -#define SZ_8M				0x00800000
> -#define SZ_16M				0x01000000
> -#define SZ_32M				0x02000000
> -#define SZ_64M				0x04000000
> -#define SZ_128M				0x08000000
> -#define SZ_256M				0x10000000
> -#define SZ_512M				0x20000000
> +#define SZ_1M				0x00100000ULL
> +#define SZ_2M				0x00200000ULL
> +#define SZ_4M				0x00400000ULL
> +#define SZ_8M				0x00800000ULL
> +#define SZ_16M				0x01000000ULL
> +#define SZ_32M				0x02000000ULL
> +#define SZ_64M				0x04000000ULL
> +#define SZ_128M				0x08000000ULL
> +#define SZ_256M				0x10000000ULL
> +#define SZ_512M				0x20000000ULL
>  
> -#define SZ_1G				0x40000000
> -#define SZ_2G				0x80000000
> +#define SZ_1G				0x40000000ULL
> +#define SZ_2G				0x80000000ULL
>  
>  #endif /* __LINUX_SIZES_H__ */


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 04/13] builtin-run: Rework RAM size validation
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-05-30 17:13     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-05-30 17:13 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:36 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> host_ram_size() uses sysconf() to calculate the available ram, and
> sysconf() can fail. When that happens, host_ram_size() returns 0. kvmtool
> warns the user when the configured VM ram size exceeds the size of the
> host's memory, but doesn't take into account that host_ram_size() can
> return 0. If the function returns zero, skip the warning.
> 
> Since this can only happen when the user sets the memory size (via the
> -m/--mem command line argument), skip the check entirely if the user hasn't
> set it. Move the check to kvm_run_validate_cfg(), as it checks for valid
> user configuration.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  builtin-run.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/builtin-run.c b/builtin-run.c
> index 4fc7cbed1d17..b1accbce7da3 100644
> --- a/builtin-run.c
> +++ b/builtin-run.c
> @@ -509,6 +509,8 @@ static void kvm_run_set_real_cmdline(struct kvm *kvm)
>  
>  static void kvm_run_validate_cfg(struct kvm *kvm)
>  {
> +	u64 available_ram;

Just a nit, you can pull this declaration inside the if statement below,
IIUC you will only need it there.

Otherwise looks fine:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

> +
>  	if (kvm->cfg.kernel_filename && kvm->cfg.firmware_filename)
>  		die("Only one of --kernel or --firmware can be specified");
>  
> @@ -518,6 +520,17 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
>  
>  	if (kvm->cfg.firmware_filename && kvm->cfg.initrd_filename)
>  		pr_warning("Ignoring initrd file when loading a firmware image");
> +
> +	if (kvm->cfg.ram_size) {
> +		/* User specifies RAM size in megabytes. */
> +		kvm->cfg.ram_size <<= MB_SHIFT;
> +		available_ram = host_ram_size();
> +		if (available_ram && kvm->cfg.ram_size > available_ram) {
> +			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
> +				(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
> +				(unsigned long long)available_ram >> MB_SHIFT);
> +		}
> +	}
>  }
>  
>  static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
> @@ -596,13 +609,6 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
>  
>  	if (!kvm->cfg.ram_size)
>  		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
> -	else
> -		kvm->cfg.ram_size <<= MB_SHIFT;
> -
> -	if (kvm->cfg.ram_size > host_ram_size())
> -		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
> -			(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
> -			(unsigned long long)host_ram_size() >> MB_SHIFT);
>  
>  	if (!kvm->cfg.dev)
>  		kvm->cfg.dev = DEFAULT_KVM_DEV;

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 04/13] builtin-run: Rework RAM size validation
@ 2022-05-30 17:13     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-05-30 17:13 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:36 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> host_ram_size() uses sysconf() to calculate the available ram, and
> sysconf() can fail. When that happens, host_ram_size() returns 0. kvmtool
> warns the user when the configured VM ram size exceeds the size of the
> host's memory, but doesn't take into account that host_ram_size() can
> return 0. If the function returns zero, skip the warning.
> 
> Since this can only happen when the user sets the memory size (via the
> -m/--mem command line argument), skip the check entirely if the user hasn't
> set it. Move the check to kvm_run_validate_cfg(), as it checks for valid
> user configuration.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  builtin-run.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/builtin-run.c b/builtin-run.c
> index 4fc7cbed1d17..b1accbce7da3 100644
> --- a/builtin-run.c
> +++ b/builtin-run.c
> @@ -509,6 +509,8 @@ static void kvm_run_set_real_cmdline(struct kvm *kvm)
>  
>  static void kvm_run_validate_cfg(struct kvm *kvm)
>  {
> +	u64 available_ram;

Just a nit, you can pull this declaration inside the if statement below,
IIUC you will only need it there.

Otherwise looks fine:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

> +
>  	if (kvm->cfg.kernel_filename && kvm->cfg.firmware_filename)
>  		die("Only one of --kernel or --firmware can be specified");
>  
> @@ -518,6 +520,17 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
>  
>  	if (kvm->cfg.firmware_filename && kvm->cfg.initrd_filename)
>  		pr_warning("Ignoring initrd file when loading a firmware image");
> +
> +	if (kvm->cfg.ram_size) {
> +		/* User specifies RAM size in megabytes. */
> +		kvm->cfg.ram_size <<= MB_SHIFT;
> +		available_ram = host_ram_size();
> +		if (available_ram && kvm->cfg.ram_size > available_ram) {
> +			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
> +				(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
> +				(unsigned long long)available_ram >> MB_SHIFT);
> +		}
> +	}
>  }
>  
>  static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
> @@ -596,13 +609,6 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
>  
>  	if (!kvm->cfg.ram_size)
>  		kvm->cfg.ram_size = get_ram_size(kvm->cfg.nrcpus);
> -	else
> -		kvm->cfg.ram_size <<= MB_SHIFT;
> -
> -	if (kvm->cfg.ram_size > host_ram_size())
> -		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
> -			(unsigned long long)kvm->cfg.ram_size >> MB_SHIFT,
> -			(unsigned long long)host_ram_size() >> MB_SHIFT);
>  
>  	if (!kvm->cfg.dev)
>  		kvm->cfg.dev = DEFAULT_KVM_DEV;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 06/13] arm/arm64: Fail if RAM size is too large for 32-bit guests
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 11:09     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 11:09 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:38 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> For 64-bit guests, kvmtool exists with an error in kvm__get_vm_type() if
> the memory size is larger than what KVM supports. For 32-bit guests, the
> RAM size is silently rounded down to ARM_LOMAP_MAX_MEMORY in
> kvm__arch_init().
> 
> Be consistent and exit with an error when the user has configured the
> wrong RAM size for 32-bit guests.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

This patch looks fine, as it improves the situation and maintains the
current support level, but it turns out that the AArch32 memory limitation
is bogus: With LPAE (which is mandatory for any system supporting KVM),
there is no reason we can't have memory beyond 4GB of guest PA.
In fact, after removing this check, I managed to boot a 32GB AArch32 guest
just fine (on a Juno), and a 2919MB guest on an ARMv7 box.
It might be useful to lift this limit, as this allows easy testing of the
arm(32) kernel's highmem support, but this would be a separate patch, I
guess.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre
 

> ---
>  arm/aarch32/kvm.c | 4 ++++
>  arm/aarch64/kvm.c | 5 +++++
>  arm/kvm.c         | 2 +-
>  3 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
> index ae33ac92479a..9d68d7a15ee2 100644
> --- a/arm/aarch32/kvm.c
> +++ b/arm/aarch32/kvm.c
> @@ -2,4 +2,8 @@
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
> +	if (kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
> +		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
> +		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
> +	}
>  }
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index ca348f118a56..2134528bf7f2 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -39,6 +39,11 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
> +	if (kvm->cfg.arch.aarch32_guest &&
> +	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
> +		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
> +		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
> +	}
>  }
>  
>  /*
> diff --git a/arm/kvm.c b/arm/kvm.c
> index c5913000e1ed..af0feae495d7 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -65,7 +65,7 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	 * If using THP, then our minimal alignment becomes 2M.
>  	 * 2M trumps 64K, so let's go with that.
>  	 */
> -	kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
> +	kvm->ram_size = ram_size;
>  	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
>  	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
>  						kvm->arch.ram_alloc_size);

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 06/13] arm/arm64: Fail if RAM size is too large for 32-bit guests
@ 2022-06-01 11:09     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 11:09 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:38 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> For 64-bit guests, kvmtool exists with an error in kvm__get_vm_type() if
> the memory size is larger than what KVM supports. For 32-bit guests, the
> RAM size is silently rounded down to ARM_LOMAP_MAX_MEMORY in
> kvm__arch_init().
> 
> Be consistent and exit with an error when the user has configured the
> wrong RAM size for 32-bit guests.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

This patch looks fine, as it improves the situation and maintains the
current support level, but it turns out that the AArch32 memory limitation
is bogus: With LPAE (which is mandatory for any system supporting KVM),
there is no reason we can't have memory beyond 4GB of guest PA.
In fact, after removing this check, I managed to boot a 32GB AArch32 guest
just fine (on a Juno), and a 2919MB guest on an ARMv7 box.
It might be useful to lift this limit, as this allows easy testing of the
arm(32) kernel's highmem support, but this would be a separate patch, I
guess.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre
 

> ---
>  arm/aarch32/kvm.c | 4 ++++
>  arm/aarch64/kvm.c | 5 +++++
>  arm/kvm.c         | 2 +-
>  3 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
> index ae33ac92479a..9d68d7a15ee2 100644
> --- a/arm/aarch32/kvm.c
> +++ b/arm/aarch32/kvm.c
> @@ -2,4 +2,8 @@
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
> +	if (kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
> +		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
> +		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
> +	}
>  }
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index ca348f118a56..2134528bf7f2 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -39,6 +39,11 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
> +	if (kvm->cfg.arch.aarch32_guest &&
> +	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
> +		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
> +		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
> +	}
>  }
>  
>  /*
> diff --git a/arm/kvm.c b/arm/kvm.c
> index c5913000e1ed..af0feae495d7 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -65,7 +65,7 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	 * If using THP, then our minimal alignment becomes 2M.
>  	 * 2M trumps 64K, so let's go with that.
>  	 */
> -	kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm));
> +	kvm->ram_size = ram_size;
>  	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
>  	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
>  						kvm->arch.ram_alloc_size);


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 07/13] arm/arm64: Kill the ARM_MAX_MEMORY() macro
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 11:14     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 11:14 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:39 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> For 32-bit guests, the maximum memory size is represented by the define
> ARM_LOMAP_MAX_MEMORY, which ARM_MAX_MEMORY() returns.
> 
> For 64-bit guests, the RAM size is checked against the maximum allowed
> by KVM in kvm__get_vm_type().
> 
> There are no users left for the ARM_MAX_MEMORY() macro, remove it.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks,
Andre

> ---
>  arm/aarch32/include/kvm/kvm-arch.h |  2 --
>  arm/aarch64/include/kvm/kvm-arch.h | 16 ----------------
>  2 files changed, 18 deletions(-)
> 
> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> index 5616b27e257e..467fb09175b8 100644
> --- a/arm/aarch32/include/kvm/kvm-arch.h
> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> @@ -8,8 +8,6 @@
>  struct kvm;
>  static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>  
> -#define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
> -
>  #define MAX_PAGE_SIZE	SZ_4K
>  
>  #include "arm-common/kvm-arch.h"
> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> index 9124f6919d0f..ff857ca6e7b4 100644
> --- a/arm/aarch64/include/kvm/kvm-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> @@ -8,22 +8,6 @@ unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>  int kvm__arch_get_ipa_limit(struct kvm *kvm);
>  void kvm__arch_enable_mte(struct kvm *kvm);
>  
> -#define ARM_MAX_MEMORY(kvm)	({					\
> -	u64 max_ram;							\
> -									\
> -	if ((kvm)->cfg.arch.aarch32_guest) {				\
> -		max_ram = ARM_LOMAP_MAX_MEMORY;				\
> -	} else {							\
> -		int ipabits = kvm__arch_get_ipa_limit(kvm);		\
> -		if (ipabits <= 0)					\
> -			max_ram = ARM_HIMAP_MAX_MEMORY;			\
> -		else							\
> -			max_ram = (1ULL << ipabits) - ARM_MEMORY_AREA;	\
> -	}								\
> -									\
> -	max_ram;							\
> -})
> -
>  #define MAX_PAGE_SIZE	SZ_64K
>  
>  #include "arm-common/kvm-arch.h"

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 07/13] arm/arm64: Kill the ARM_MAX_MEMORY() macro
@ 2022-06-01 11:14     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 11:14 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:39 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> For 32-bit guests, the maximum memory size is represented by the define
> ARM_LOMAP_MAX_MEMORY, which ARM_MAX_MEMORY() returns.
> 
> For 64-bit guests, the RAM size is checked against the maximum allowed
> by KVM in kvm__get_vm_type().
> 
> There are no users left for the ARM_MAX_MEMORY() macro, remove it.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Thanks,
Andre

> ---
>  arm/aarch32/include/kvm/kvm-arch.h |  2 --
>  arm/aarch64/include/kvm/kvm-arch.h | 16 ----------------
>  2 files changed, 18 deletions(-)
> 
> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> index 5616b27e257e..467fb09175b8 100644
> --- a/arm/aarch32/include/kvm/kvm-arch.h
> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> @@ -8,8 +8,6 @@
>  struct kvm;
>  static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>  
> -#define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
> -
>  #define MAX_PAGE_SIZE	SZ_4K
>  
>  #include "arm-common/kvm-arch.h"
> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> index 9124f6919d0f..ff857ca6e7b4 100644
> --- a/arm/aarch64/include/kvm/kvm-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> @@ -8,22 +8,6 @@ unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>  int kvm__arch_get_ipa_limit(struct kvm *kvm);
>  void kvm__arch_enable_mte(struct kvm *kvm);
>  
> -#define ARM_MAX_MEMORY(kvm)	({					\
> -	u64 max_ram;							\
> -									\
> -	if ((kvm)->cfg.arch.aarch32_guest) {				\
> -		max_ram = ARM_LOMAP_MAX_MEMORY;				\
> -	} else {							\
> -		int ipabits = kvm__arch_get_ipa_limit(kvm);		\
> -		if (ipabits <= 0)					\
> -			max_ram = ARM_HIMAP_MAX_MEMORY;			\
> -		else							\
> -			max_ram = (1ULL << ipabits) - ARM_MEMORY_AREA;	\
> -	}								\
> -									\
> -	max_ram;							\
> -})
> -
>  #define MAX_PAGE_SIZE	SZ_64K
>  
>  #include "arm-common/kvm-arch.h"


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 08/13] arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 11:16     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 11:16 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:40 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> The ARM_HIMAP_MAX_MEMORY() is a remnant of a time when KVM only supported
> 40 bits if IPA. There are no users left for this macro, remove it.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Could be stashed together with the previous patch, I guess, but anyway:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/include/arm-common/kvm-arch.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
> index fc55360d4d15..6d80aac17125 100644
> --- a/arm/include/arm-common/kvm-arch.h
> +++ b/arm/include/arm-common/kvm-arch.h
> @@ -65,7 +65,6 @@
>  
>  
>  #define ARM_LOMAP_MAX_MEMORY	((1ULL << 32) - ARM_MEMORY_AREA)
> -#define ARM_HIMAP_MAX_MEMORY	((1ULL << 40) - ARM_MEMORY_AREA)
>  
>  
>  #define KVM_IOEVENTFD_HAS_PIO	0

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 08/13] arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro
@ 2022-06-01 11:16     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 11:16 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:40 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> The ARM_HIMAP_MAX_MEMORY() is a remnant of a time when KVM only supported
> 40 bits if IPA. There are no users left for this macro, remove it.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Could be stashed together with the previous patch, I guess, but anyway:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/include/arm-common/kvm-arch.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
> index fc55360d4d15..6d80aac17125 100644
> --- a/arm/include/arm-common/kvm-arch.h
> +++ b/arm/include/arm-common/kvm-arch.h
> @@ -65,7 +65,6 @@
>  
>  
>  #define ARM_LOMAP_MAX_MEMORY	((1ULL << 32) - ARM_MEMORY_AREA)
> -#define ARM_HIMAP_MAX_MEMORY	((1ULL << 40) - ARM_MEMORY_AREA)
>  
>  
>  #define KVM_IOEVENTFD_HAS_PIO	0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 10/13] kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 13:13     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:13 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: julien, maz, Julien Grall, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:42 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> From: Julien Grall <julien.grall@arm.com>
> 
> The kvm struct already contains a pointer to the configuration, which
> contains both hugetlbfs_path and ram_size, so is it not necessary to pass
> them as arguments to kvm__arch_init().
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Like that cleanup.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/kvm.c         | 7 ++++---
>  include/kvm/kvm.h | 2 +-
>  kvm.c             | 2 +-
>  mips/kvm.c        | 7 ++++---
>  powerpc/kvm.c     | 5 +++--
>  riscv/kvm.c       | 7 ++++---
>  x86/kvm.c         | 4 +++-
>  7 files changed, 20 insertions(+), 14 deletions(-)
> 
> diff --git a/arm/kvm.c b/arm/kvm.c
> index af0feae495d7..bd44aa350796 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -57,7 +57,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  {
>  }
>  
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
>  	/*
>  	 * Allocate guest memory. We must align our buffer to 64K to
> @@ -65,9 +65,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	 * If using THP, then our minimal alignment becomes 2M.
>  	 * 2M trumps 64K, so let's go with that.
>  	 */
> -	kvm->ram_size = ram_size;
> +	kvm->ram_size = kvm->cfg.ram_size;
>  	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> -	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
> +	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> +						kvm->cfg.hugetlbfs_path,
>  						kvm->arch.ram_alloc_size);
>  
>  	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
> index 9f7b2fb26e95..640b76c095f9 100644
> --- a/include/kvm/kvm.h
> +++ b/include/kvm/kvm.h
> @@ -189,7 +189,7 @@ void kvm__remove_socket(const char *name);
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm);
>  void kvm__arch_set_cmdline(char *cmdline, bool video);
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
> +void kvm__arch_init(struct kvm *kvm);
>  void kvm__arch_delete_ram(struct kvm *kvm);
>  int kvm__arch_setup_firmware(struct kvm *kvm);
>  int kvm__arch_free_firmware(struct kvm *kvm);
> diff --git a/kvm.c b/kvm.c
> index 952ef1fbb41c..42b881217df6 100644
> --- a/kvm.c
> +++ b/kvm.c
> @@ -479,7 +479,7 @@ int kvm__init(struct kvm *kvm)
>  		goto err_vm_fd;
>  	}
>  
> -	kvm__arch_init(kvm, kvm->cfg.hugetlbfs_path, kvm->cfg.ram_size);
> +	kvm__arch_init(kvm);
>  
>  	INIT_LIST_HEAD(&kvm->mem_banks);
>  	kvm__init_ram(kvm);
> diff --git a/mips/kvm.c b/mips/kvm.c
> index f5b137f46dff..d8610cf81b94 100644
> --- a/mips/kvm.c
> +++ b/mips/kvm.c
> @@ -61,12 +61,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  }
>  
>  /* Architecture-specific KVM init */
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
>  	int ret;
>  
> -	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
> -	kvm->ram_size = ram_size;
> +	kvm->ram_size = kvm->cfg.ram_size;
> +	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, kvm->cfg.hugetlbfs_path,
> +						kvm->ram_size);
>  
>  	if (kvm->ram_start == MAP_FAILED)
>  		die("out of memory");
> diff --git a/powerpc/kvm.c b/powerpc/kvm.c
> index 3215b579f5dc..d281b070fd0e 100644
> --- a/powerpc/kvm.c
> +++ b/powerpc/kvm.c
> @@ -92,12 +92,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  }
>  
>  /* Architecture-specific KVM init */
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
> +	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
>  	int cap_ppc_rma;
>  	unsigned long hpt;
>  
> -	kvm->ram_size		= ram_size;
> +	kvm->ram_size		= kvm->cfg.ram_size;
>  
>  	/* Map "default" hugetblfs path to the standard 16M mount point */
>  	if (hugetlbfs_path && !strcmp(hugetlbfs_path, "default"))
> diff --git a/riscv/kvm.c b/riscv/kvm.c
> index 7fb496282f4c..c46660772aa0 100644
> --- a/riscv/kvm.c
> +++ b/riscv/kvm.c
> @@ -56,7 +56,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  {
>  }
>  
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
>  	/*
>  	 * Allocate guest memory. We must align our buffer to 64K to
> @@ -64,9 +64,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	 * If using THP, then our minimal alignment becomes 2M.
>  	 * 2M trumps 64K, so let's go with that.
>  	 */
> -	kvm->ram_size = min(ram_size, (u64)RISCV_MAX_MEMORY(kvm));
> +	kvm->ram_size = min(kvm->cfg.ram_size, (u64)RISCV_MAX_MEMORY(kvm));
>  	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> -	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
> +	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> +						kvm->cfg.hugetlbfs_path,
>  						kvm->arch.ram_alloc_size);
>  
>  	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> diff --git a/x86/kvm.c b/x86/kvm.c
> index 6683a5c81d49..24b0305a1841 100644
> --- a/x86/kvm.c
> +++ b/x86/kvm.c
> @@ -134,9 +134,11 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  }
>  
>  /* Architecture-specific KVM init */
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
> +	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
>  	struct kvm_pit_config pit_config = { .flags = 0, };
> +	u64 ram_size = kvm->cfg.ram_size;
>  	int ret;
>  
>  	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 10/13] kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters
@ 2022-06-01 13:13     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:13 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, Julien Grall

On Wed, 25 May 2022 12:23:42 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> From: Julien Grall <julien.grall@arm.com>
> 
> The kvm struct already contains a pointer to the configuration, which
> contains both hugetlbfs_path and ram_size, so is it not necessary to pass
> them as arguments to kvm__arch_init().
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Like that cleanup.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/kvm.c         | 7 ++++---
>  include/kvm/kvm.h | 2 +-
>  kvm.c             | 2 +-
>  mips/kvm.c        | 7 ++++---
>  powerpc/kvm.c     | 5 +++--
>  riscv/kvm.c       | 7 ++++---
>  x86/kvm.c         | 4 +++-
>  7 files changed, 20 insertions(+), 14 deletions(-)
> 
> diff --git a/arm/kvm.c b/arm/kvm.c
> index af0feae495d7..bd44aa350796 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -57,7 +57,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  {
>  }
>  
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
>  	/*
>  	 * Allocate guest memory. We must align our buffer to 64K to
> @@ -65,9 +65,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	 * If using THP, then our minimal alignment becomes 2M.
>  	 * 2M trumps 64K, so let's go with that.
>  	 */
> -	kvm->ram_size = ram_size;
> +	kvm->ram_size = kvm->cfg.ram_size;
>  	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> -	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
> +	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> +						kvm->cfg.hugetlbfs_path,
>  						kvm->arch.ram_alloc_size);
>  
>  	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
> index 9f7b2fb26e95..640b76c095f9 100644
> --- a/include/kvm/kvm.h
> +++ b/include/kvm/kvm.h
> @@ -189,7 +189,7 @@ void kvm__remove_socket(const char *name);
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm);
>  void kvm__arch_set_cmdline(char *cmdline, bool video);
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
> +void kvm__arch_init(struct kvm *kvm);
>  void kvm__arch_delete_ram(struct kvm *kvm);
>  int kvm__arch_setup_firmware(struct kvm *kvm);
>  int kvm__arch_free_firmware(struct kvm *kvm);
> diff --git a/kvm.c b/kvm.c
> index 952ef1fbb41c..42b881217df6 100644
> --- a/kvm.c
> +++ b/kvm.c
> @@ -479,7 +479,7 @@ int kvm__init(struct kvm *kvm)
>  		goto err_vm_fd;
>  	}
>  
> -	kvm__arch_init(kvm, kvm->cfg.hugetlbfs_path, kvm->cfg.ram_size);
> +	kvm__arch_init(kvm);
>  
>  	INIT_LIST_HEAD(&kvm->mem_banks);
>  	kvm__init_ram(kvm);
> diff --git a/mips/kvm.c b/mips/kvm.c
> index f5b137f46dff..d8610cf81b94 100644
> --- a/mips/kvm.c
> +++ b/mips/kvm.c
> @@ -61,12 +61,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  }
>  
>  /* Architecture-specific KVM init */
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
>  	int ret;
>  
> -	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
> -	kvm->ram_size = ram_size;
> +	kvm->ram_size = kvm->cfg.ram_size;
> +	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, kvm->cfg.hugetlbfs_path,
> +						kvm->ram_size);
>  
>  	if (kvm->ram_start == MAP_FAILED)
>  		die("out of memory");
> diff --git a/powerpc/kvm.c b/powerpc/kvm.c
> index 3215b579f5dc..d281b070fd0e 100644
> --- a/powerpc/kvm.c
> +++ b/powerpc/kvm.c
> @@ -92,12 +92,13 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  }
>  
>  /* Architecture-specific KVM init */
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
> +	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
>  	int cap_ppc_rma;
>  	unsigned long hpt;
>  
> -	kvm->ram_size		= ram_size;
> +	kvm->ram_size		= kvm->cfg.ram_size;
>  
>  	/* Map "default" hugetblfs path to the standard 16M mount point */
>  	if (hugetlbfs_path && !strcmp(hugetlbfs_path, "default"))
> diff --git a/riscv/kvm.c b/riscv/kvm.c
> index 7fb496282f4c..c46660772aa0 100644
> --- a/riscv/kvm.c
> +++ b/riscv/kvm.c
> @@ -56,7 +56,7 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  {
>  }
>  
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
>  	/*
>  	 * Allocate guest memory. We must align our buffer to 64K to
> @@ -64,9 +64,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	 * If using THP, then our minimal alignment becomes 2M.
>  	 * 2M trumps 64K, so let's go with that.
>  	 */
> -	kvm->ram_size = min(ram_size, (u64)RISCV_MAX_MEMORY(kvm));
> +	kvm->ram_size = min(kvm->cfg.ram_size, (u64)RISCV_MAX_MEMORY(kvm));
>  	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> -	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path,
> +	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> +						kvm->cfg.hugetlbfs_path,
>  						kvm->arch.ram_alloc_size);
>  
>  	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> diff --git a/x86/kvm.c b/x86/kvm.c
> index 6683a5c81d49..24b0305a1841 100644
> --- a/x86/kvm.c
> +++ b/x86/kvm.c
> @@ -134,9 +134,11 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  }
>  
>  /* Architecture-specific KVM init */
> -void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> +void kvm__arch_init(struct kvm *kvm)
>  {
> +	const char *hugetlbfs_path = kvm->cfg.hugetlbfs_path;
>  	struct kvm_pit_config pit_config = { .flags = 0, };
> +	u64 ram_size = kvm->cfg.ram_size;
>  	int ret;
>  
>  	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 11/13] arm/arm64: Consolidate RAM initialization in kvm__init_ram()
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 13:20     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:20 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: julien, maz, Julien Grall, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:43 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> From: Julien Grall <julien.grall@arm.com>
> 
> RAM initialization is unnecessarily split between kvm__init_ram() and
> kvm__arch_init(). Move all code related to RAM initialization to
> kvm__init_ram(), making the code easier to follow and to modify.
> 
> One thing to note is that the initialization order is slightly altered:
> kvm__arch_enable_mte() and gic__create() are now called before mmap'ing the
> guest RAM. That is perfectly fine, as they don't use the host's mapping of
> the guest memory.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

I can confirm that this is just a code move, also MTE and GIC init do not
seem to rely on RAM in any way.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/kvm.c | 52 ++++++++++++++++++++++++++--------------------------
>  1 file changed, 26 insertions(+), 26 deletions(-)
> 
> diff --git a/arm/kvm.c b/arm/kvm.c
> index bd44aa350796..abcccfabf59e 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -26,9 +26,34 @@ bool kvm__arch_cpu_supports_vm(void)
>  
>  void kvm__init_ram(struct kvm *kvm)
>  {
> -	int err;
>  	u64 phys_start, phys_size;
>  	void *host_mem;
> +	int err;
> +
> +	/*
> +	 * Allocate guest memory. We must align our buffer to 64K to
> +	 * correlate with the maximum guest page size for virtio-mmio.
> +	 * If using THP, then our minimal alignment becomes 2M.
> +	 * 2M trumps 64K, so let's go with that.
> +	 */
> +	kvm->ram_size = kvm->cfg.ram_size;
> +	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> +	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> +						kvm->cfg.hugetlbfs_path,
> +						kvm->arch.ram_alloc_size);
> +
> +	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> +		die("Failed to map %lld bytes for guest memory (%d)",
> +		    kvm->arch.ram_alloc_size, errno);
> +
> +	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
> +					SZ_2M);
> +
> +	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> +		MADV_MERGEABLE);
> +
> +	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> +		MADV_HUGEPAGE);
>  
>  	phys_start	= ARM_MEMORY_AREA;
>  	phys_size	= kvm->ram_size;
> @@ -59,31 +84,6 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  
>  void kvm__arch_init(struct kvm *kvm)
>  {
> -	/*
> -	 * Allocate guest memory. We must align our buffer to 64K to
> -	 * correlate with the maximum guest page size for virtio-mmio.
> -	 * If using THP, then our minimal alignment becomes 2M.
> -	 * 2M trumps 64K, so let's go with that.
> -	 */
> -	kvm->ram_size = kvm->cfg.ram_size;
> -	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> -	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> -						kvm->cfg.hugetlbfs_path,
> -						kvm->arch.ram_alloc_size);
> -
> -	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> -		die("Failed to map %lld bytes for guest memory (%d)",
> -		    kvm->arch.ram_alloc_size, errno);
> -
> -	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
> -					SZ_2M);
> -
> -	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> -		MADV_MERGEABLE);
> -
> -	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> -		MADV_HUGEPAGE);
> -
>  	/* Create the virtual GIC. */
>  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>  		die("Failed to create virtual GIC");

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 11/13] arm/arm64: Consolidate RAM initialization in kvm__init_ram()
@ 2022-06-01 13:20     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:20 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse, Julien Grall

On Wed, 25 May 2022 12:23:43 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> From: Julien Grall <julien.grall@arm.com>
> 
> RAM initialization is unnecessarily split between kvm__init_ram() and
> kvm__arch_init(). Move all code related to RAM initialization to
> kvm__init_ram(), making the code easier to follow and to modify.
> 
> One thing to note is that the initialization order is slightly altered:
> kvm__arch_enable_mte() and gic__create() are now called before mmap'ing the
> guest RAM. That is perfectly fine, as they don't use the host's mapping of
> the guest memory.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

I can confirm that this is just a code move, also MTE and GIC init do not
seem to rely on RAM in any way.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/kvm.c | 52 ++++++++++++++++++++++++++--------------------------
>  1 file changed, 26 insertions(+), 26 deletions(-)
> 
> diff --git a/arm/kvm.c b/arm/kvm.c
> index bd44aa350796..abcccfabf59e 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -26,9 +26,34 @@ bool kvm__arch_cpu_supports_vm(void)
>  
>  void kvm__init_ram(struct kvm *kvm)
>  {
> -	int err;
>  	u64 phys_start, phys_size;
>  	void *host_mem;
> +	int err;
> +
> +	/*
> +	 * Allocate guest memory. We must align our buffer to 64K to
> +	 * correlate with the maximum guest page size for virtio-mmio.
> +	 * If using THP, then our minimal alignment becomes 2M.
> +	 * 2M trumps 64K, so let's go with that.
> +	 */
> +	kvm->ram_size = kvm->cfg.ram_size;
> +	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> +	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> +						kvm->cfg.hugetlbfs_path,
> +						kvm->arch.ram_alloc_size);
> +
> +	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> +		die("Failed to map %lld bytes for guest memory (%d)",
> +		    kvm->arch.ram_alloc_size, errno);
> +
> +	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
> +					SZ_2M);
> +
> +	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> +		MADV_MERGEABLE);
> +
> +	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> +		MADV_HUGEPAGE);
>  
>  	phys_start	= ARM_MEMORY_AREA;
>  	phys_size	= kvm->ram_size;
> @@ -59,31 +84,6 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
>  
>  void kvm__arch_init(struct kvm *kvm)
>  {
> -	/*
> -	 * Allocate guest memory. We must align our buffer to 64K to
> -	 * correlate with the maximum guest page size for virtio-mmio.
> -	 * If using THP, then our minimal alignment becomes 2M.
> -	 * 2M trumps 64K, so let's go with that.
> -	 */
> -	kvm->ram_size = kvm->cfg.ram_size;
> -	kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M;
> -	kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
> -						kvm->cfg.hugetlbfs_path,
> -						kvm->arch.ram_alloc_size);
> -
> -	if (kvm->arch.ram_alloc_start == MAP_FAILED)
> -		die("Failed to map %lld bytes for guest memory (%d)",
> -		    kvm->arch.ram_alloc_size, errno);
> -
> -	kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
> -					SZ_2M);
> -
> -	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> -		MADV_MERGEABLE);
> -
> -	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
> -		MADV_HUGEPAGE);
> -
>  	/* Create the virtual GIC. */
>  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>  		die("Failed to create virtual GIC");


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 12/13] Introduce kvm__arch_default_ram_address()
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 13:21     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:21 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:44 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> Add a new function, kvm__arch_default_ram_address(), which returns the
> default address for guest RAM for each architecture.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/aarch32/kvm.c | 5 +++++
>  arm/aarch64/kvm.c | 5 +++++
>  include/kvm/kvm.h | 1 +
>  mips/kvm.c        | 5 +++++
>  powerpc/kvm.c     | 5 +++++
>  riscv/kvm.c       | 5 +++++
>  x86/kvm.c         | 5 +++++
>  7 files changed, 31 insertions(+)
> 
> diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
> index 9d68d7a15ee2..768a56bbb5b4 100644
> --- a/arm/aarch32/kvm.c
> +++ b/arm/aarch32/kvm.c
> @@ -7,3 +7,8 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
>  		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
>  	}
>  }
> +
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return ARM_MEMORY_AREA;
> +}
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index 2134528bf7f2..357936844046 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -46,6 +46,11 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
>  	}
>  }
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return ARM_MEMORY_AREA;
> +}
> +
>  /*
>   * Return the TEXT_OFFSET value that the guest kernel expects. Note
>   * that pre-3.17 kernels expose this value using the native endianness
> diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
> index 640b76c095f9..360430b78b1e 100644
> --- a/include/kvm/kvm.h
> +++ b/include/kvm/kvm.h
> @@ -190,6 +190,7 @@ void kvm__remove_socket(const char *name);
>  void kvm__arch_validate_cfg(struct kvm *kvm);
>  void kvm__arch_set_cmdline(char *cmdline, bool video);
>  void kvm__arch_init(struct kvm *kvm);
> +u64 kvm__arch_default_ram_address(void);
>  void kvm__arch_delete_ram(struct kvm *kvm);
>  int kvm__arch_setup_firmware(struct kvm *kvm);
>  int kvm__arch_free_firmware(struct kvm *kvm);
> diff --git a/mips/kvm.c b/mips/kvm.c
> index d8610cf81b94..4cbc9907731b 100644
> --- a/mips/kvm.c
> +++ b/mips/kvm.c
> @@ -12,6 +12,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 }
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return 0;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }
> diff --git a/powerpc/kvm.c b/powerpc/kvm.c
> index d281b070fd0e..7b0d0669aff4 100644
> --- a/powerpc/kvm.c
> +++ b/powerpc/kvm.c
> @@ -48,6 +48,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 }
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return 0;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }
> diff --git a/riscv/kvm.c b/riscv/kvm.c
> index c46660772aa0..4d6f5cb57ac8 100644
> --- a/riscv/kvm.c
> +++ b/riscv/kvm.c
> @@ -13,6 +13,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 },
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return RISCV_RAM;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }
> diff --git a/x86/kvm.c b/x86/kvm.c
> index 24b0305a1841..328fa7500596 100644
> --- a/x86/kvm.c
> +++ b/x86/kvm.c
> @@ -35,6 +35,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 }
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return 0;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 12/13] Introduce kvm__arch_default_ram_address()
@ 2022-06-01 13:21     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:21 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:44 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

> Add a new function, kvm__arch_default_ram_address(), which returns the
> default address for guest RAM for each architecture.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> ---
>  arm/aarch32/kvm.c | 5 +++++
>  arm/aarch64/kvm.c | 5 +++++
>  include/kvm/kvm.h | 1 +
>  mips/kvm.c        | 5 +++++
>  powerpc/kvm.c     | 5 +++++
>  riscv/kvm.c       | 5 +++++
>  x86/kvm.c         | 5 +++++
>  7 files changed, 31 insertions(+)
> 
> diff --git a/arm/aarch32/kvm.c b/arm/aarch32/kvm.c
> index 9d68d7a15ee2..768a56bbb5b4 100644
> --- a/arm/aarch32/kvm.c
> +++ b/arm/aarch32/kvm.c
> @@ -7,3 +7,8 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
>  		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
>  	}
>  }
> +
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return ARM_MEMORY_AREA;
> +}
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index 2134528bf7f2..357936844046 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -46,6 +46,11 @@ void kvm__arch_validate_cfg(struct kvm *kvm)
>  	}
>  }
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return ARM_MEMORY_AREA;
> +}
> +
>  /*
>   * Return the TEXT_OFFSET value that the guest kernel expects. Note
>   * that pre-3.17 kernels expose this value using the native endianness
> diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
> index 640b76c095f9..360430b78b1e 100644
> --- a/include/kvm/kvm.h
> +++ b/include/kvm/kvm.h
> @@ -190,6 +190,7 @@ void kvm__remove_socket(const char *name);
>  void kvm__arch_validate_cfg(struct kvm *kvm);
>  void kvm__arch_set_cmdline(char *cmdline, bool video);
>  void kvm__arch_init(struct kvm *kvm);
> +u64 kvm__arch_default_ram_address(void);
>  void kvm__arch_delete_ram(struct kvm *kvm);
>  int kvm__arch_setup_firmware(struct kvm *kvm);
>  int kvm__arch_free_firmware(struct kvm *kvm);
> diff --git a/mips/kvm.c b/mips/kvm.c
> index d8610cf81b94..4cbc9907731b 100644
> --- a/mips/kvm.c
> +++ b/mips/kvm.c
> @@ -12,6 +12,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 }
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return 0;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }
> diff --git a/powerpc/kvm.c b/powerpc/kvm.c
> index d281b070fd0e..7b0d0669aff4 100644
> --- a/powerpc/kvm.c
> +++ b/powerpc/kvm.c
> @@ -48,6 +48,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 }
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return 0;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }
> diff --git a/riscv/kvm.c b/riscv/kvm.c
> index c46660772aa0..4d6f5cb57ac8 100644
> --- a/riscv/kvm.c
> +++ b/riscv/kvm.c
> @@ -13,6 +13,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 },
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return RISCV_RAM;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }
> diff --git a/x86/kvm.c b/x86/kvm.c
> index 24b0305a1841..328fa7500596 100644
> --- a/x86/kvm.c
> +++ b/x86/kvm.c
> @@ -35,6 +35,11 @@ struct kvm_ext kvm_req_ext[] = {
>  	{ 0, 0 }
>  };
>  
> +u64 kvm__arch_default_ram_address(void)
> +{
> +	return 0;
> +}
> +
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
>  }


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 13/13] arm64: Allow the user to specify the RAM base address
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 13:39     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:39 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:45 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> Allow the user to specify the RAM base address by using -m/--mem size@addr
> command line argument. The base address must be above 2GB, as to not
> overlap with the MMIO I/O region.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  arm/aarch64/include/kvm/kvm-arch.h |  2 ++
>  arm/aarch64/kvm.c                  | 14 ++++++++----
>  arm/kvm.c                          |  7 ++++--
>  builtin-run.c                      | 36 ++++++++++++++++++++++++++----
>  include/kvm/kvm-config.h           |  1 +
>  include/kvm/kvm.h                  | 12 ++++++++++
>  include/linux/sizes.h              |  2 ++
>  7 files changed, 64 insertions(+), 10 deletions(-)
> 
> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> index ff857ca6e7b4..02d09a413831 100644
> --- a/arm/aarch64/include/kvm/kvm-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> @@ -10,6 +10,8 @@ void kvm__arch_enable_mte(struct kvm *kvm);
>  
>  #define MAX_PAGE_SIZE	SZ_64K
>  
> +#define ARCH_HAS_CFG_RAM_ADDRESS	1
> +
>  #include "arm-common/kvm-arch.h"
>  
>  #endif /* KVM__KVM_ARCH_H */
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index 357936844046..54200c9eec9d 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -4,6 +4,7 @@
>  
>  #include <linux/byteorder.h>
>  #include <linux/cpumask.h>
> +#include <linux/sizes.h>
>  
>  #include <kvm/util.h>
>  
> @@ -39,10 +40,15 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
> +
> +	if (kvm->cfg.ram_addr < ARM_MEMORY_AREA) {
> +		die("RAM address is below the I/O region ending at %luGB",
> +		    ARM_MEMORY_AREA >> 30);
> +	}
> +
>  	if (kvm->cfg.arch.aarch32_guest &&
> -	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
> -		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
> -		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
> +	    kvm->cfg.ram_addr + kvm->cfg.ram_size > SZ_4G) {
> +		die("RAM extends above 4GB");

As mentioned in the other patch, this is actually no problem at all, but
as this patch just retains the current check, that's fine, for now.

The rest looks good, and it seems to work now.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

>  	}
>  }
>  
> @@ -117,7 +123,7 @@ int kvm__get_vm_type(struct kvm *kvm)
>  		return 0;
>  
>  	/* Otherwise, compute the minimal required IPA size */
> -	max_ipa = ARM_MEMORY_AREA + kvm->cfg.ram_size - 1;
> +	max_ipa = kvm->cfg.ram_addr + kvm->cfg.ram_size - 1;
>  	ipa_bits = max(32, fls_long(max_ipa));
>  	pr_debug("max_ipa %lx ipa_bits %d max_ipa_bits %d",
>  		 max_ipa, ipa_bits, max_ipa_bits);
> diff --git a/arm/kvm.c b/arm/kvm.c
> index abcccfabf59e..d51cc15d8b1c 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -55,7 +55,7 @@ void kvm__init_ram(struct kvm *kvm)
>  	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
>  		MADV_HUGEPAGE);
>  
> -	phys_start	= ARM_MEMORY_AREA;
> +	phys_start	= kvm->cfg.ram_addr;
>  	phys_size	= kvm->ram_size;
>  	host_mem	= kvm->ram_start;
>  
> @@ -65,6 +65,9 @@ void kvm__init_ram(struct kvm *kvm)
>  		    "address 0x%llx [err %d]", phys_size, phys_start, err);
>  
>  	kvm->arch.memory_guest_start = phys_start;
> +
> +	pr_debug("RAM created at 0x%llx - 0x%llx",
> +		 phys_start, phys_start + phys_size - 1);
>  }
>  
>  void kvm__arch_delete_ram(struct kvm *kvm)
> @@ -201,7 +204,7 @@ bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
>  
>  	/* For default firmware address, lets load it at the begining of RAM */
>  	if (fw_addr == 0)
> -		fw_addr = ARM_MEMORY_AREA;
> +		fw_addr = kvm->arch.memory_guest_start;
>  
>  	if (!validate_fw_addr(kvm, fw_addr))
>  		die("Bad firmware destination: 0x%016llx", fw_addr);
> diff --git a/builtin-run.c b/builtin-run.c
> index a49698d5b2fe..68beaaa7c06f 100644
> --- a/builtin-run.c
> +++ b/builtin-run.c
> @@ -131,12 +131,21 @@ static u64 parse_mem_option(const char *nptr, char **next)
>  static int mem_parser(const struct option *opt, const char *arg, int unset)
>  {
>  	struct kvm *kvm = opt->ptr;
> -	char *next;
> +	char *next, *nptr;
>  
>  	kvm->cfg.ram_size = parse_mem_option(arg, &next);
>  	if (kvm->cfg.ram_size == 0)
>  		die("Invalid RAM size: %s", arg);
>  
> +	if (kvm__arch_has_cfg_ram_address() && *next == '@') {
> +		next++;
> +		if (*next == '\0')
> +			die("Missing memory address: %s", arg);
> +
> +		nptr = next;
> +		kvm->cfg.ram_addr = parse_mem_option(nptr, &next);
> +	}
> +
>  	if (*next != '\0')
>  		die("Invalid memory specifier: %s", arg);
>  
> @@ -147,15 +156,26 @@ static int mem_parser(const struct option *opt, const char *arg, int unset)
>  #define OPT_ARCH_RUN(...)
>  #endif
>  
> +#ifdef ARCH_HAS_CFG_RAM_ADDRESS
> +#define MEM_OPT_HELP_SHORT	"size[BKMGTP][@addr[BKMGTP]]"
> +#define MEM_OPT_HELP_LONG						\
> +	"Virtual machine memory size and optional base address, both"	\
> +	" measured by default in megabytes (M)"
> +#else
> +#define MEM_OPT_HELP_SHORT	"size[BKMGTP]"
> +#define MEM_OPT_HELP_LONG						\
> +	"Virtual machine memory size, by default measured in"		\
> +	" in megabytes (M)"
> +#endif
> +
>  #define BUILD_OPTIONS(name, cfg, kvm)					\
>  	struct option name[] = {					\
>  	OPT_GROUP("Basic options:"),					\
>  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
>  			"A name for the guest"),			\
>  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> -	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> -		     "Virtual machine memory size, by default measured"	\
> -		     " in megabytes (M)", mem_parser, kvm),		\
> +	OPT_CALLBACK('m', "mem", NULL, MEM_OPT_HELP_SHORT,		\
> +		     MEM_OPT_HELP_LONG, mem_parser, kvm),		\
>  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
>  			" image or rootfs directory", img_name_parser,	\
>  			kvm),						\
> @@ -601,6 +621,14 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
>  
>  	nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
>  	kvm->cfg.custom_rootfs_name = "default";
> +	/*
> +	 * An architecture might allow the user to set the RAM base address to
> +	 * zero. Initialize the address before parsing the command line
> +	 * arguments, because otherwise it will be impossible to distinguish
> +	 * between the user setting the base address to zero or letting it
> +	 * unspecified.
> +	 */
> +	kvm->cfg.ram_addr = kvm__arch_default_ram_address();
>  
>  	while (argc != 0) {
>  		BUILD_OPTIONS(options, &kvm->cfg, kvm);
> diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
> index 31bc89520d52..45fe1caaebce 100644
> --- a/include/kvm/kvm-config.h
> +++ b/include/kvm/kvm-config.h
> @@ -23,6 +23,7 @@ struct kvm_config {
>  	struct kvm_config_arch arch;
>  	struct disk_image_params disk_image[MAX_DISK_IMAGES];
>  	struct vfio_device_params *vfio_devices;
> +	u64 ram_addr;		/* Guest memory physical base address, in bytes */
>  	u64 ram_size;		/* Guest memory size, in bytes */
>  	u8 num_net_devices;
>  	u8 num_vfio_devices;
> diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
> index 360430b78b1e..eb23e2f77310 100644
> --- a/include/kvm/kvm.h
> +++ b/include/kvm/kvm.h
> @@ -197,6 +197,18 @@ int kvm__arch_free_firmware(struct kvm *kvm);
>  bool kvm__arch_cpu_supports_vm(void);
>  void kvm__arch_read_term(struct kvm *kvm);
>  
> +#ifdef ARCH_HAS_CFG_RAM_ADDRESS
> +static inline bool kvm__arch_has_cfg_ram_address(void)
> +{
> +	return true;
> +}
> +#else
> +static inline bool kvm__arch_has_cfg_ram_address(void)
> +{
> +	return false;
> +}
> +#endif
> +
>  void *guest_flat_to_host(struct kvm *kvm, u64 offset);
>  u64 host_to_guest_flat(struct kvm *kvm, void *ptr);
>  
> diff --git a/include/linux/sizes.h b/include/linux/sizes.h
> index b2b5c457cf1c..52afca02aa6e 100644
> --- a/include/linux/sizes.h
> +++ b/include/linux/sizes.h
> @@ -44,4 +44,6 @@
>  #define SZ_1G				0x40000000ULL
>  #define SZ_2G				0x80000000ULL
>  
> +#define SZ_4G				0x100000000ULL
> +
>  #endif /* __LINUX_SIZES_H__ */

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 13/13] arm64: Allow the user to specify the RAM base address
@ 2022-06-01 13:39     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:39 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:45 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> Allow the user to specify the RAM base address by using -m/--mem size@addr
> command line argument. The base address must be above 2GB, as to not
> overlap with the MMIO I/O region.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  arm/aarch64/include/kvm/kvm-arch.h |  2 ++
>  arm/aarch64/kvm.c                  | 14 ++++++++----
>  arm/kvm.c                          |  7 ++++--
>  builtin-run.c                      | 36 ++++++++++++++++++++++++++----
>  include/kvm/kvm-config.h           |  1 +
>  include/kvm/kvm.h                  | 12 ++++++++++
>  include/linux/sizes.h              |  2 ++
>  7 files changed, 64 insertions(+), 10 deletions(-)
> 
> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> index ff857ca6e7b4..02d09a413831 100644
> --- a/arm/aarch64/include/kvm/kvm-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> @@ -10,6 +10,8 @@ void kvm__arch_enable_mte(struct kvm *kvm);
>  
>  #define MAX_PAGE_SIZE	SZ_64K
>  
> +#define ARCH_HAS_CFG_RAM_ADDRESS	1
> +
>  #include "arm-common/kvm-arch.h"
>  
>  #endif /* KVM__KVM_ARCH_H */
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index 357936844046..54200c9eec9d 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -4,6 +4,7 @@
>  
>  #include <linux/byteorder.h>
>  #include <linux/cpumask.h>
> +#include <linux/sizes.h>
>  
>  #include <kvm/util.h>
>  
> @@ -39,10 +40,15 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
>  
>  void kvm__arch_validate_cfg(struct kvm *kvm)
>  {
> +
> +	if (kvm->cfg.ram_addr < ARM_MEMORY_AREA) {
> +		die("RAM address is below the I/O region ending at %luGB",
> +		    ARM_MEMORY_AREA >> 30);
> +	}
> +
>  	if (kvm->cfg.arch.aarch32_guest &&
> -	    kvm->cfg.ram_size > ARM_LOMAP_MAX_MEMORY) {
> -		die("RAM size 0x%llx exceeds maximum allowed 0x%llx",
> -		    kvm->cfg.ram_size, ARM_LOMAP_MAX_MEMORY);
> +	    kvm->cfg.ram_addr + kvm->cfg.ram_size > SZ_4G) {
> +		die("RAM extends above 4GB");

As mentioned in the other patch, this is actually no problem at all, but
as this patch just retains the current check, that's fine, for now.

The rest looks good, and it seems to work now.

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

>  	}
>  }
>  
> @@ -117,7 +123,7 @@ int kvm__get_vm_type(struct kvm *kvm)
>  		return 0;
>  
>  	/* Otherwise, compute the minimal required IPA size */
> -	max_ipa = ARM_MEMORY_AREA + kvm->cfg.ram_size - 1;
> +	max_ipa = kvm->cfg.ram_addr + kvm->cfg.ram_size - 1;
>  	ipa_bits = max(32, fls_long(max_ipa));
>  	pr_debug("max_ipa %lx ipa_bits %d max_ipa_bits %d",
>  		 max_ipa, ipa_bits, max_ipa_bits);
> diff --git a/arm/kvm.c b/arm/kvm.c
> index abcccfabf59e..d51cc15d8b1c 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -55,7 +55,7 @@ void kvm__init_ram(struct kvm *kvm)
>  	madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
>  		MADV_HUGEPAGE);
>  
> -	phys_start	= ARM_MEMORY_AREA;
> +	phys_start	= kvm->cfg.ram_addr;
>  	phys_size	= kvm->ram_size;
>  	host_mem	= kvm->ram_start;
>  
> @@ -65,6 +65,9 @@ void kvm__init_ram(struct kvm *kvm)
>  		    "address 0x%llx [err %d]", phys_size, phys_start, err);
>  
>  	kvm->arch.memory_guest_start = phys_start;
> +
> +	pr_debug("RAM created at 0x%llx - 0x%llx",
> +		 phys_start, phys_start + phys_size - 1);
>  }
>  
>  void kvm__arch_delete_ram(struct kvm *kvm)
> @@ -201,7 +204,7 @@ bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
>  
>  	/* For default firmware address, lets load it at the begining of RAM */
>  	if (fw_addr == 0)
> -		fw_addr = ARM_MEMORY_AREA;
> +		fw_addr = kvm->arch.memory_guest_start;
>  
>  	if (!validate_fw_addr(kvm, fw_addr))
>  		die("Bad firmware destination: 0x%016llx", fw_addr);
> diff --git a/builtin-run.c b/builtin-run.c
> index a49698d5b2fe..68beaaa7c06f 100644
> --- a/builtin-run.c
> +++ b/builtin-run.c
> @@ -131,12 +131,21 @@ static u64 parse_mem_option(const char *nptr, char **next)
>  static int mem_parser(const struct option *opt, const char *arg, int unset)
>  {
>  	struct kvm *kvm = opt->ptr;
> -	char *next;
> +	char *next, *nptr;
>  
>  	kvm->cfg.ram_size = parse_mem_option(arg, &next);
>  	if (kvm->cfg.ram_size == 0)
>  		die("Invalid RAM size: %s", arg);
>  
> +	if (kvm__arch_has_cfg_ram_address() && *next == '@') {
> +		next++;
> +		if (*next == '\0')
> +			die("Missing memory address: %s", arg);
> +
> +		nptr = next;
> +		kvm->cfg.ram_addr = parse_mem_option(nptr, &next);
> +	}
> +
>  	if (*next != '\0')
>  		die("Invalid memory specifier: %s", arg);
>  
> @@ -147,15 +156,26 @@ static int mem_parser(const struct option *opt, const char *arg, int unset)
>  #define OPT_ARCH_RUN(...)
>  #endif
>  
> +#ifdef ARCH_HAS_CFG_RAM_ADDRESS
> +#define MEM_OPT_HELP_SHORT	"size[BKMGTP][@addr[BKMGTP]]"
> +#define MEM_OPT_HELP_LONG						\
> +	"Virtual machine memory size and optional base address, both"	\
> +	" measured by default in megabytes (M)"
> +#else
> +#define MEM_OPT_HELP_SHORT	"size[BKMGTP]"
> +#define MEM_OPT_HELP_LONG						\
> +	"Virtual machine memory size, by default measured in"		\
> +	" in megabytes (M)"
> +#endif
> +
>  #define BUILD_OPTIONS(name, cfg, kvm)					\
>  	struct option name[] = {					\
>  	OPT_GROUP("Basic options:"),					\
>  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
>  			"A name for the guest"),			\
>  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> -	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> -		     "Virtual machine memory size, by default measured"	\
> -		     " in megabytes (M)", mem_parser, kvm),		\
> +	OPT_CALLBACK('m', "mem", NULL, MEM_OPT_HELP_SHORT,		\
> +		     MEM_OPT_HELP_LONG, mem_parser, kvm),		\
>  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
>  			" image or rootfs directory", img_name_parser,	\
>  			kvm),						\
> @@ -601,6 +621,14 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
>  
>  	nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
>  	kvm->cfg.custom_rootfs_name = "default";
> +	/*
> +	 * An architecture might allow the user to set the RAM base address to
> +	 * zero. Initialize the address before parsing the command line
> +	 * arguments, because otherwise it will be impossible to distinguish
> +	 * between the user setting the base address to zero or letting it
> +	 * unspecified.
> +	 */
> +	kvm->cfg.ram_addr = kvm__arch_default_ram_address();
>  
>  	while (argc != 0) {
>  		BUILD_OPTIONS(options, &kvm->cfg, kvm);
> diff --git a/include/kvm/kvm-config.h b/include/kvm/kvm-config.h
> index 31bc89520d52..45fe1caaebce 100644
> --- a/include/kvm/kvm-config.h
> +++ b/include/kvm/kvm-config.h
> @@ -23,6 +23,7 @@ struct kvm_config {
>  	struct kvm_config_arch arch;
>  	struct disk_image_params disk_image[MAX_DISK_IMAGES];
>  	struct vfio_device_params *vfio_devices;
> +	u64 ram_addr;		/* Guest memory physical base address, in bytes */
>  	u64 ram_size;		/* Guest memory size, in bytes */
>  	u8 num_net_devices;
>  	u8 num_vfio_devices;
> diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
> index 360430b78b1e..eb23e2f77310 100644
> --- a/include/kvm/kvm.h
> +++ b/include/kvm/kvm.h
> @@ -197,6 +197,18 @@ int kvm__arch_free_firmware(struct kvm *kvm);
>  bool kvm__arch_cpu_supports_vm(void);
>  void kvm__arch_read_term(struct kvm *kvm);
>  
> +#ifdef ARCH_HAS_CFG_RAM_ADDRESS
> +static inline bool kvm__arch_has_cfg_ram_address(void)
> +{
> +	return true;
> +}
> +#else
> +static inline bool kvm__arch_has_cfg_ram_address(void)
> +{
> +	return false;
> +}
> +#endif
> +
>  void *guest_flat_to_host(struct kvm *kvm, u64 offset);
>  u64 host_to_guest_flat(struct kvm *kvm, void *ptr);
>  
> diff --git a/include/linux/sizes.h b/include/linux/sizes.h
> index b2b5c457cf1c..52afca02aa6e 100644
> --- a/include/linux/sizes.h
> +++ b/include/linux/sizes.h
> @@ -44,4 +44,6 @@
>  #define SZ_1G				0x40000000ULL
>  #define SZ_2G				0x80000000ULL
>  
> +#define SZ_4G				0x100000000ULL
> +
>  #endif /* __LINUX_SIZES_H__ */


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-05-25 11:23   ` Alexandru Elisei
@ 2022-06-01 13:39     ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:39 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 25 May 2022 12:23:41 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> From: Suzuki K Poulose <suzuki.poulose@arm.com>
> 
> Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> When none are specified, the default is megabytes.
> 
> Also raise an error if the guest specifies 0 as the memory size, instead
> of treating it as uninitialized, as kvmtool has done so far.
> 
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 60 insertions(+), 5 deletions(-)
> 
> diff --git a/builtin-run.c b/builtin-run.c
> index 2ef159cdb2a3..a49698d5b2fe 100644
> --- a/builtin-run.c
> +++ b/builtin-run.c
> @@ -49,9 +49,11 @@
>  #include <ctype.h>
>  #include <stdio.h>
>  
> -#define MB_SHIFT		(20)
>  #define KB_SHIFT		(10)
> +#define MB_SHIFT		(20)
>  #define GB_SHIFT		(30)
> +#define TB_SHIFT		(40)
> +#define PB_SHIFT		(50)

Can we lose the parentheses?

>  
>  __thread struct kvm_cpu *current_kvm_cpu;
>  
> @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
>  	kvm_run_wrapper = KVM_RUN_SANDBOX;
>  }
>  
> +static int parse_mem_unit(char **next)
> +{
> +	int shift = -1;
> +
> +	switch (**next) {
> +	case 'B': case 'b': shift = 0; break;
> +	case 'K': case 'k': shift = KB_SHIFT; break;
> +	case 'M': case 'm': shift = MB_SHIFT; break;
> +	case 'G': case 'g': shift = GB_SHIFT; break;
> +	case 'T': case 't': shift = TB_SHIFT; break;
> +	case 'P': case 'p': shift = PB_SHIFT; break;
> +	}
> +
> +	if (shift == -1) {
> +		/* The default is megabytes. */
> +		shift = MB_SHIFT;

Doesn't that look better inside the switch/case?
	default: return MB_SHIFT;

> +	} else {
> +		(*next)++;
> +	}
> +
> +	return shift;
> +}
> +
> +static u64 parse_mem_option(const char *nptr, char **next)
> +{
> +	u64 shift;
> +	u64 val;
> +
> +	val = strtoull(nptr, next, 10);
> +	if (errno == ERANGE)
> +		die("Memory too large: %s", nptr);

strtoull does not clear errno if it succeeds, so it retains the
previous error value. So we would need to set errno to 0 just before
calling strtoull.

> +	shift = parse_mem_unit(next);
> +
> +	if ((val << shift) < val)
> +		die("Memory too large: %s", nptr);
> +
> +	return val << shift;
> +}
> +
> +static int mem_parser(const struct option *opt, const char *arg, int unset)
> +{
> +	struct kvm *kvm = opt->ptr;
> +	char *next;
> +
> +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> +	if (kvm->cfg.ram_size == 0)
> +		die("Invalid RAM size: %s", arg);

Does 0 hold any significant value (anymore)? I think we die() if we
encounter invalid values in parse_mem_option()?

Cheers,
Andre

> +
> +	if (*next != '\0')
> +		die("Invalid memory specifier: %s", arg);
> +
> +	return 0;
> +}
> +
>  #ifndef OPT_ARCH_RUN
>  #define OPT_ARCH_RUN(...)
>  #endif
> @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
>  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
>  			"A name for the guest"),			\
>  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> -		" size in MB."),					\
> +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> +		     "Virtual machine memory size, by default measured"	\
> +		     " in megabytes (M)", mem_parser, kvm),		\
>  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
>  			" image or rootfs directory", img_name_parser,	\
>  			kvm),						\
> @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
>  		pr_warning("Ignoring initrd file when loading a firmware image");
>  
>  	if (kvm->cfg.ram_size) {
> -		/* User specifies RAM size in megabytes. */
> -		kvm->cfg.ram_size <<= MB_SHIFT;
>  		available_ram = host_ram_size();
>  		if (available_ram && kvm->cfg.ram_size > available_ram) {
>  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-01 13:39     ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 13:39 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 25 May 2022 12:23:41 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> From: Suzuki K Poulose <suzuki.poulose@arm.com>
> 
> Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> When none are specified, the default is megabytes.
> 
> Also raise an error if the guest specifies 0 as the memory size, instead
> of treating it as uninitialized, as kvmtool has done so far.
> 
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 60 insertions(+), 5 deletions(-)
> 
> diff --git a/builtin-run.c b/builtin-run.c
> index 2ef159cdb2a3..a49698d5b2fe 100644
> --- a/builtin-run.c
> +++ b/builtin-run.c
> @@ -49,9 +49,11 @@
>  #include <ctype.h>
>  #include <stdio.h>
>  
> -#define MB_SHIFT		(20)
>  #define KB_SHIFT		(10)
> +#define MB_SHIFT		(20)
>  #define GB_SHIFT		(30)
> +#define TB_SHIFT		(40)
> +#define PB_SHIFT		(50)

Can we lose the parentheses?

>  
>  __thread struct kvm_cpu *current_kvm_cpu;
>  
> @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
>  	kvm_run_wrapper = KVM_RUN_SANDBOX;
>  }
>  
> +static int parse_mem_unit(char **next)
> +{
> +	int shift = -1;
> +
> +	switch (**next) {
> +	case 'B': case 'b': shift = 0; break;
> +	case 'K': case 'k': shift = KB_SHIFT; break;
> +	case 'M': case 'm': shift = MB_SHIFT; break;
> +	case 'G': case 'g': shift = GB_SHIFT; break;
> +	case 'T': case 't': shift = TB_SHIFT; break;
> +	case 'P': case 'p': shift = PB_SHIFT; break;
> +	}
> +
> +	if (shift == -1) {
> +		/* The default is megabytes. */
> +		shift = MB_SHIFT;

Doesn't that look better inside the switch/case?
	default: return MB_SHIFT;

> +	} else {
> +		(*next)++;
> +	}
> +
> +	return shift;
> +}
> +
> +static u64 parse_mem_option(const char *nptr, char **next)
> +{
> +	u64 shift;
> +	u64 val;
> +
> +	val = strtoull(nptr, next, 10);
> +	if (errno == ERANGE)
> +		die("Memory too large: %s", nptr);

strtoull does not clear errno if it succeeds, so it retains the
previous error value. So we would need to set errno to 0 just before
calling strtoull.

> +	shift = parse_mem_unit(next);
> +
> +	if ((val << shift) < val)
> +		die("Memory too large: %s", nptr);
> +
> +	return val << shift;
> +}
> +
> +static int mem_parser(const struct option *opt, const char *arg, int unset)
> +{
> +	struct kvm *kvm = opt->ptr;
> +	char *next;
> +
> +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> +	if (kvm->cfg.ram_size == 0)
> +		die("Invalid RAM size: %s", arg);

Does 0 hold any significant value (anymore)? I think we die() if we
encounter invalid values in parse_mem_option()?

Cheers,
Andre

> +
> +	if (*next != '\0')
> +		die("Invalid memory specifier: %s", arg);
> +
> +	return 0;
> +}
> +
>  #ifndef OPT_ARCH_RUN
>  #define OPT_ARCH_RUN(...)
>  #endif
> @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
>  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
>  			"A name for the guest"),			\
>  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> -		" size in MB."),					\
> +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> +		     "Virtual machine memory size, by default measured"	\
> +		     " in megabytes (M)", mem_parser, kvm),		\
>  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
>  			" image or rootfs directory", img_name_parser,	\
>  			kvm),						\
> @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
>  		pr_warning("Ignoring initrd file when loading a firmware image");
>  
>  	if (kvm->cfg.ram_size) {
> -		/* User specifies RAM size in megabytes. */
> -		kvm->cfg.ram_size <<= MB_SHIFT;
>  		available_ram = host_ram_size();
>  		if (available_ram && kvm->cfg.ram_size > available_ram) {
>  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-06-01 13:39     ` Andre Przywara
@ 2022-06-01 14:17       ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 14:17 UTC (permalink / raw)
  To: Andre Przywara; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

Hi,

Thank you for having a look! Replies below.

On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> On Wed, 25 May 2022 12:23:41 +0100
> Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi,
> 
> > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > 
> > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > When none are specified, the default is megabytes.
> > 
> > Also raise an error if the guest specifies 0 as the memory size, instead
> > of treating it as uninitialized, as kvmtool has done so far.
> > 
> > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > ---
> >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> >  1 file changed, 60 insertions(+), 5 deletions(-)
> > 
> > diff --git a/builtin-run.c b/builtin-run.c
> > index 2ef159cdb2a3..a49698d5b2fe 100644
> > --- a/builtin-run.c
> > +++ b/builtin-run.c
> > @@ -49,9 +49,11 @@
> >  #include <ctype.h>
> >  #include <stdio.h>
> >  
> > -#define MB_SHIFT		(20)
> >  #define KB_SHIFT		(10)
> > +#define MB_SHIFT		(20)
> >  #define GB_SHIFT		(30)
> > +#define TB_SHIFT		(40)
> > +#define PB_SHIFT		(50)
> 
> Can we lose the parentheses?

Yes.

> 
> >  
> >  __thread struct kvm_cpu *current_kvm_cpu;
> >  
> > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> >  }
> >  
> > +static int parse_mem_unit(char **next)
> > +{
> > +	int shift = -1;
> > +
> > +	switch (**next) {
> > +	case 'B': case 'b': shift = 0; break;
> > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > +	case 'T': case 't': shift = TB_SHIFT; break;
> > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > +	}
> > +
> > +	if (shift == -1) {
> > +		/* The default is megabytes. */
> > +		shift = MB_SHIFT;
> 
> Doesn't that look better inside the switch/case?
> 	default: return MB_SHIFT;

I think that change alone breaks the logic.

The code needs to advance next if and only if it matches on one of the
characters. I'll have a go at advancing next in each of the switch arms
above (with the exception of the default one, which I'll add) to see how it
ends up looking.

> 
> > +	} else {
> > +		(*next)++;
> > +	}
> > +
> > +	return shift;
> > +}
> > +
> > +static u64 parse_mem_option(const char *nptr, char **next)
> > +{
> > +	u64 shift;
> > +	u64 val;
> > +
> > +	val = strtoull(nptr, next, 10);
> > +	if (errno == ERANGE)
> > +		die("Memory too large: %s", nptr);
> 
> strtoull does not clear errno if it succeeds, so it retains the
> previous error value. So we would need to set errno to 0 just before
> calling strtoull.

This was intentional on my part, because I was under the impression that
kvmtool treats all instances where errno != 0 as a fatal error. I think I
was wrong about that, I see at least one instance when that isn't the case,
in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
errno is a fatal error.

I'll change the code to zero errno before calling strtoull.

> 
> > +	shift = parse_mem_unit(next);
> > +
> > +	if ((val << shift) < val)
> > +		die("Memory too large: %s", nptr);
> > +
> > +	return val << shift;
> > +}
> > +
> > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > +{
> > +	struct kvm *kvm = opt->ptr;
> > +	char *next;
> > +
> > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > +	if (kvm->cfg.ram_size == 0)
> > +		die("Invalid RAM size: %s", arg);
> 
> Does 0 hold any significant value (anymore)? I think we die() if we
> encounter invalid values in parse_mem_option()?

strtoull does not consider an error to convert the string "0" to an
unsigned long long.

Thanks,
Alex

> 
> Cheers,
> Andre
> 
> > +
> > +	if (*next != '\0')
> > +		die("Invalid memory specifier: %s", arg);
> > +
> > +	return 0;
> > +}
> > +
> >  #ifndef OPT_ARCH_RUN
> >  #define OPT_ARCH_RUN(...)
> >  #endif
> > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> >  			"A name for the guest"),			\
> >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > -		" size in MB."),					\
> > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > +		     "Virtual machine memory size, by default measured"	\
> > +		     " in megabytes (M)", mem_parser, kvm),		\
> >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> >  			" image or rootfs directory", img_name_parser,	\
> >  			kvm),						\
> > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> >  		pr_warning("Ignoring initrd file when loading a firmware image");
> >  
> >  	if (kvm->cfg.ram_size) {
> > -		/* User specifies RAM size in megabytes. */
> > -		kvm->cfg.ram_size <<= MB_SHIFT;
> >  		available_ram = host_ram_size();
> >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
> 
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-01 14:17       ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 14:17 UTC (permalink / raw)
  To: Andre Przywara
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

Hi,

Thank you for having a look! Replies below.

On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> On Wed, 25 May 2022 12:23:41 +0100
> Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi,
> 
> > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > 
> > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > When none are specified, the default is megabytes.
> > 
> > Also raise an error if the guest specifies 0 as the memory size, instead
> > of treating it as uninitialized, as kvmtool has done so far.
> > 
> > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > ---
> >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> >  1 file changed, 60 insertions(+), 5 deletions(-)
> > 
> > diff --git a/builtin-run.c b/builtin-run.c
> > index 2ef159cdb2a3..a49698d5b2fe 100644
> > --- a/builtin-run.c
> > +++ b/builtin-run.c
> > @@ -49,9 +49,11 @@
> >  #include <ctype.h>
> >  #include <stdio.h>
> >  
> > -#define MB_SHIFT		(20)
> >  #define KB_SHIFT		(10)
> > +#define MB_SHIFT		(20)
> >  #define GB_SHIFT		(30)
> > +#define TB_SHIFT		(40)
> > +#define PB_SHIFT		(50)
> 
> Can we lose the parentheses?

Yes.

> 
> >  
> >  __thread struct kvm_cpu *current_kvm_cpu;
> >  
> > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> >  }
> >  
> > +static int parse_mem_unit(char **next)
> > +{
> > +	int shift = -1;
> > +
> > +	switch (**next) {
> > +	case 'B': case 'b': shift = 0; break;
> > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > +	case 'T': case 't': shift = TB_SHIFT; break;
> > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > +	}
> > +
> > +	if (shift == -1) {
> > +		/* The default is megabytes. */
> > +		shift = MB_SHIFT;
> 
> Doesn't that look better inside the switch/case?
> 	default: return MB_SHIFT;

I think that change alone breaks the logic.

The code needs to advance next if and only if it matches on one of the
characters. I'll have a go at advancing next in each of the switch arms
above (with the exception of the default one, which I'll add) to see how it
ends up looking.

> 
> > +	} else {
> > +		(*next)++;
> > +	}
> > +
> > +	return shift;
> > +}
> > +
> > +static u64 parse_mem_option(const char *nptr, char **next)
> > +{
> > +	u64 shift;
> > +	u64 val;
> > +
> > +	val = strtoull(nptr, next, 10);
> > +	if (errno == ERANGE)
> > +		die("Memory too large: %s", nptr);
> 
> strtoull does not clear errno if it succeeds, so it retains the
> previous error value. So we would need to set errno to 0 just before
> calling strtoull.

This was intentional on my part, because I was under the impression that
kvmtool treats all instances where errno != 0 as a fatal error. I think I
was wrong about that, I see at least one instance when that isn't the case,
in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
errno is a fatal error.

I'll change the code to zero errno before calling strtoull.

> 
> > +	shift = parse_mem_unit(next);
> > +
> > +	if ((val << shift) < val)
> > +		die("Memory too large: %s", nptr);
> > +
> > +	return val << shift;
> > +}
> > +
> > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > +{
> > +	struct kvm *kvm = opt->ptr;
> > +	char *next;
> > +
> > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > +	if (kvm->cfg.ram_size == 0)
> > +		die("Invalid RAM size: %s", arg);
> 
> Does 0 hold any significant value (anymore)? I think we die() if we
> encounter invalid values in parse_mem_option()?

strtoull does not consider an error to convert the string "0" to an
unsigned long long.

Thanks,
Alex

> 
> Cheers,
> Andre
> 
> > +
> > +	if (*next != '\0')
> > +		die("Invalid memory specifier: %s", arg);
> > +
> > +	return 0;
> > +}
> > +
> >  #ifndef OPT_ARCH_RUN
> >  #define OPT_ARCH_RUN(...)
> >  #endif
> > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> >  			"A name for the guest"),			\
> >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > -		" size in MB."),					\
> > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > +		     "Virtual machine memory size, by default measured"	\
> > +		     " in megabytes (M)", mem_parser, kvm),		\
> >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> >  			" image or rootfs directory", img_name_parser,	\
> >  			kvm),						\
> > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> >  		pr_warning("Ignoring initrd file when loading a firmware image");
> >  
> >  	if (kvm->cfg.ram_size) {
> > -		/* User specifies RAM size in megabytes. */
> > -		kvm->cfg.ram_size <<= MB_SHIFT;
> >  		available_ram = host_ram_size();
> >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-06-01 14:17       ` Alexandru Elisei
@ 2022-06-01 16:14         ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 16:14 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 1 Jun 2022 15:17:50 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi Alex,

> Hi,
> 
> Thank you for having a look! Replies below.
> 
> On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> > On Wed, 25 May 2022 12:23:41 +0100
> > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > 
> > Hi,
> >   
> > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > 
> > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > When none are specified, the default is megabytes.
> > > 
> > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > of treating it as uninitialized, as kvmtool has done so far.
> > > 
> > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > ---
> > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/builtin-run.c b/builtin-run.c
> > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > --- a/builtin-run.c
> > > +++ b/builtin-run.c
> > > @@ -49,9 +49,11 @@
> > >  #include <ctype.h>
> > >  #include <stdio.h>
> > >  
> > > -#define MB_SHIFT		(20)
> > >  #define KB_SHIFT		(10)
> > > +#define MB_SHIFT		(20)
> > >  #define GB_SHIFT		(30)
> > > +#define TB_SHIFT		(40)
> > > +#define PB_SHIFT		(50)  
> > 
> > Can we lose the parentheses?  
> 
> Yes.
> 
> >   
> > >  
> > >  __thread struct kvm_cpu *current_kvm_cpu;
> > >  
> > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > >  }
> > >  
> > > +static int parse_mem_unit(char **next)
> > > +{
> > > +	int shift = -1;
> > > +
> > > +	switch (**next) {
> > > +	case 'B': case 'b': shift = 0; break;
> > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > +	}
> > > +
> > > +	if (shift == -1) {
> > > +		/* The default is megabytes. */
> > > +		shift = MB_SHIFT;  
> > 
> > Doesn't that look better inside the switch/case?
> > 	default: return MB_SHIFT;  
> 
> I think that change alone breaks the logic.
> 
> The code needs to advance next if and only if it matches on one of the
> characters. I'll have a go at advancing next in each of the switch arms
> above (with the exception of the default one, which I'll add) to see how it
> ends up looking.

Mmh, but I meant:
{
	switch (**next) {
	case 'B': case 'b': shift = 0; break;
	case 'K': case 'k': shift = KB_SHIFT; break;
	case 'M': case 'm': shift = MB_SHIFT; break;
	case 'G': case 'g': shift = GB_SHIFT; break;
	case 'T': case 't': shift = TB_SHIFT; break;
	case 'P': case 'p': shift = PB_SHIFT; break;
	default: return MB_SHIFT;  
	}

	(*next)++;

	return shift;
}

that should solve it, shouldn't it?

> 
> >   
> > > +	} else {
> > > +		(*next)++;
> > > +	}
> > > +
> > > +	return shift;
> > > +}
> > > +
> > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > +{
> > > +	u64 shift;
> > > +	u64 val;
> > > +
> > > +	val = strtoull(nptr, next, 10);
> > > +	if (errno == ERANGE)
> > > +		die("Memory too large: %s", nptr);  
> > 
> > strtoull does not clear errno if it succeeds, so it retains the
> > previous error value. So we would need to set errno to 0 just before
> > calling strtoull.  
> 
> This was intentional on my part, because I was under the impression that
> kvmtool treats all instances where errno != 0 as a fatal error. I think I
> was wrong about that, I see at least one instance when that isn't the case,
> in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> errno is a fatal error.
> 
> I'll change the code to zero errno before calling strtoull.

Thanks!

> 
> >   
> > > +	shift = parse_mem_unit(next);
> > > +
> > > +	if ((val << shift) < val)
> > > +		die("Memory too large: %s", nptr);
> > > +
> > > +	return val << shift;
> > > +}
> > > +
> > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > +{
> > > +	struct kvm *kvm = opt->ptr;
> > > +	char *next;
> > > +
> > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > +	if (kvm->cfg.ram_size == 0)
> > > +		die("Invalid RAM size: %s", arg);  
> > 
> > Does 0 hold any significant value (anymore)? I think we die() if we
> > encounter invalid values in parse_mem_option()?  
> 
> strtoull does not consider an error to convert the string "0" to an
> unsigned long long.

I was wondering if we treat 0 as an indicator of a conversion error, or as
a too-low memory size value here. I don't think we should special case the
latter, as even 1MB or 2MB are typically too low values for a "normal"
kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
On the other hand, with --firmware I think we can run a (admittedly very
limited) guest with 0MB of RAM.

So if we care about garbage as an argument, we should do it by the book
(strtoul manpage), and compare the next pointer to the input string
address, plus checking for the returned value being 0, so that
"-m gimme-all" is explicitly denied. But that would need to happen in
parse_mem_option(), I think, not here.

If we cannot be asked, that's probably fine, but I just wanted to
check this.

Cheers,
Andre

> > > +
> > > +	if (*next != '\0')
> > > +		die("Invalid memory specifier: %s", arg);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  #ifndef OPT_ARCH_RUN
> > >  #define OPT_ARCH_RUN(...)
> > >  #endif
> > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > >  			"A name for the guest"),			\
> > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > -		" size in MB."),					\
> > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > +		     "Virtual machine memory size, by default measured"	\
> > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > >  			" image or rootfs directory", img_name_parser,	\
> > >  			kvm),						\
> > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > >  
> > >  	if (kvm->cfg.ram_size) {
> > > -		/* User specifies RAM size in megabytes. */
> > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > >  		available_ram = host_ram_size();
> > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",  
> >   

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-01 16:14         ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-01 16:14 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

On Wed, 1 Jun 2022 15:17:50 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi Alex,

> Hi,
> 
> Thank you for having a look! Replies below.
> 
> On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> > On Wed, 25 May 2022 12:23:41 +0100
> > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > 
> > Hi,
> >   
> > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > 
> > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > When none are specified, the default is megabytes.
> > > 
> > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > of treating it as uninitialized, as kvmtool has done so far.
> > > 
> > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > ---
> > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/builtin-run.c b/builtin-run.c
> > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > --- a/builtin-run.c
> > > +++ b/builtin-run.c
> > > @@ -49,9 +49,11 @@
> > >  #include <ctype.h>
> > >  #include <stdio.h>
> > >  
> > > -#define MB_SHIFT		(20)
> > >  #define KB_SHIFT		(10)
> > > +#define MB_SHIFT		(20)
> > >  #define GB_SHIFT		(30)
> > > +#define TB_SHIFT		(40)
> > > +#define PB_SHIFT		(50)  
> > 
> > Can we lose the parentheses?  
> 
> Yes.
> 
> >   
> > >  
> > >  __thread struct kvm_cpu *current_kvm_cpu;
> > >  
> > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > >  }
> > >  
> > > +static int parse_mem_unit(char **next)
> > > +{
> > > +	int shift = -1;
> > > +
> > > +	switch (**next) {
> > > +	case 'B': case 'b': shift = 0; break;
> > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > +	}
> > > +
> > > +	if (shift == -1) {
> > > +		/* The default is megabytes. */
> > > +		shift = MB_SHIFT;  
> > 
> > Doesn't that look better inside the switch/case?
> > 	default: return MB_SHIFT;  
> 
> I think that change alone breaks the logic.
> 
> The code needs to advance next if and only if it matches on one of the
> characters. I'll have a go at advancing next in each of the switch arms
> above (with the exception of the default one, which I'll add) to see how it
> ends up looking.

Mmh, but I meant:
{
	switch (**next) {
	case 'B': case 'b': shift = 0; break;
	case 'K': case 'k': shift = KB_SHIFT; break;
	case 'M': case 'm': shift = MB_SHIFT; break;
	case 'G': case 'g': shift = GB_SHIFT; break;
	case 'T': case 't': shift = TB_SHIFT; break;
	case 'P': case 'p': shift = PB_SHIFT; break;
	default: return MB_SHIFT;  
	}

	(*next)++;

	return shift;
}

that should solve it, shouldn't it?

> 
> >   
> > > +	} else {
> > > +		(*next)++;
> > > +	}
> > > +
> > > +	return shift;
> > > +}
> > > +
> > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > +{
> > > +	u64 shift;
> > > +	u64 val;
> > > +
> > > +	val = strtoull(nptr, next, 10);
> > > +	if (errno == ERANGE)
> > > +		die("Memory too large: %s", nptr);  
> > 
> > strtoull does not clear errno if it succeeds, so it retains the
> > previous error value. So we would need to set errno to 0 just before
> > calling strtoull.  
> 
> This was intentional on my part, because I was under the impression that
> kvmtool treats all instances where errno != 0 as a fatal error. I think I
> was wrong about that, I see at least one instance when that isn't the case,
> in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> errno is a fatal error.
> 
> I'll change the code to zero errno before calling strtoull.

Thanks!

> 
> >   
> > > +	shift = parse_mem_unit(next);
> > > +
> > > +	if ((val << shift) < val)
> > > +		die("Memory too large: %s", nptr);
> > > +
> > > +	return val << shift;
> > > +}
> > > +
> > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > +{
> > > +	struct kvm *kvm = opt->ptr;
> > > +	char *next;
> > > +
> > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > +	if (kvm->cfg.ram_size == 0)
> > > +		die("Invalid RAM size: %s", arg);  
> > 
> > Does 0 hold any significant value (anymore)? I think we die() if we
> > encounter invalid values in parse_mem_option()?  
> 
> strtoull does not consider an error to convert the string "0" to an
> unsigned long long.

I was wondering if we treat 0 as an indicator of a conversion error, or as
a too-low memory size value here. I don't think we should special case the
latter, as even 1MB or 2MB are typically too low values for a "normal"
kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
On the other hand, with --firmware I think we can run a (admittedly very
limited) guest with 0MB of RAM.

So if we care about garbage as an argument, we should do it by the book
(strtoul manpage), and compare the next pointer to the input string
address, plus checking for the returned value being 0, so that
"-m gimme-all" is explicitly denied. But that would need to happen in
parse_mem_option(), I think, not here.

If we cannot be asked, that's probably fine, but I just wanted to
check this.

Cheers,
Andre

> > > +
> > > +	if (*next != '\0')
> > > +		die("Invalid memory specifier: %s", arg);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  #ifndef OPT_ARCH_RUN
> > >  #define OPT_ARCH_RUN(...)
> > >  #endif
> > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > >  			"A name for the guest"),			\
> > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > -		" size in MB."),					\
> > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > +		     "Virtual machine memory size, by default measured"	\
> > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > >  			" image or rootfs directory", img_name_parser,	\
> > >  			kvm),						\
> > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > >  
> > >  	if (kvm->cfg.ram_size) {
> > > -		/* User specifies RAM size in megabytes. */
> > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > >  		available_ram = host_ram_size();
> > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",  
> >   


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-06-01 16:14         ` Andre Przywara
@ 2022-06-01 19:39           ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 19:39 UTC (permalink / raw)
  To: Andre Przywara; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

Hi,

On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:
> On Wed, 1 Jun 2022 15:17:50 +0100
> Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi Alex,
> 
> > Hi,
> > 
> > Thank you for having a look! Replies below.
> > 
> > On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> > > On Wed, 25 May 2022 12:23:41 +0100
> > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > 
> > > Hi,
> > >   
> > > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > 
> > > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > > When none are specified, the default is megabytes.
> > > > 
> > > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > > of treating it as uninitialized, as kvmtool has done so far.
> > > > 
> > > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > ---
> > > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/builtin-run.c b/builtin-run.c
> > > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > > --- a/builtin-run.c
> > > > +++ b/builtin-run.c
> > > > @@ -49,9 +49,11 @@
> > > >  #include <ctype.h>
> > > >  #include <stdio.h>
> > > >  
> > > > -#define MB_SHIFT		(20)
> > > >  #define KB_SHIFT		(10)
> > > > +#define MB_SHIFT		(20)
> > > >  #define GB_SHIFT		(30)
> > > > +#define TB_SHIFT		(40)
> > > > +#define PB_SHIFT		(50)  
> > > 
> > > Can we lose the parentheses?  
> > 
> > Yes.
> > 
> > >   
> > > >  
> > > >  __thread struct kvm_cpu *current_kvm_cpu;
> > > >  
> > > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > > >  }
> > > >  
> > > > +static int parse_mem_unit(char **next)
> > > > +{
> > > > +	int shift = -1;
> > > > +
> > > > +	switch (**next) {
> > > > +	case 'B': case 'b': shift = 0; break;
> > > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > > +	}
> > > > +
> > > > +	if (shift == -1) {
> > > > +		/* The default is megabytes. */
> > > > +		shift = MB_SHIFT;  
> > > 
> > > Doesn't that look better inside the switch/case?
> > > 	default: return MB_SHIFT;  
> > 
> > I think that change alone breaks the logic.
> > 
> > The code needs to advance next if and only if it matches on one of the
> > characters. I'll have a go at advancing next in each of the switch arms
> > above (with the exception of the default one, which I'll add) to see how it
> > ends up looking.
> 
> Mmh, but I meant:
> {
> 	switch (**next) {
> 	case 'B': case 'b': shift = 0; break;
> 	case 'K': case 'k': shift = KB_SHIFT; break;
> 	case 'M': case 'm': shift = MB_SHIFT; break;
> 	case 'G': case 'g': shift = GB_SHIFT; break;
> 	case 'T': case 't': shift = TB_SHIFT; break;
> 	case 'P': case 'p': shift = PB_SHIFT; break;
> 	default: return MB_SHIFT;  
> 	}
> 
> 	(*next)++;
> 
> 	return shift;
> }
> 
> that should solve it, shouldn't it?
> 
> > 
> > >   
> > > > +	} else {
> > > > +		(*next)++;
> > > > +	}
> > > > +
> > > > +	return shift;
> > > > +}
> > > > +
> > > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > > +{
> > > > +	u64 shift;
> > > > +	u64 val;
> > > > +
> > > > +	val = strtoull(nptr, next, 10);
> > > > +	if (errno == ERANGE)
> > > > +		die("Memory too large: %s", nptr);  
> > > 
> > > strtoull does not clear errno if it succeeds, so it retains the
> > > previous error value. So we would need to set errno to 0 just before
> > > calling strtoull.  
> > 
> > This was intentional on my part, because I was under the impression that
> > kvmtool treats all instances where errno != 0 as a fatal error. I think I
> > was wrong about that, I see at least one instance when that isn't the case,
> > in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> > errno is a fatal error.
> > 
> > I'll change the code to zero errno before calling strtoull.
> 
> Thanks!
> 
> > 
> > >   
> > > > +	shift = parse_mem_unit(next);
> > > > +
> > > > +	if ((val << shift) < val)
> > > > +		die("Memory too large: %s", nptr);
> > > > +
> > > > +	return val << shift;
> > > > +}
> > > > +
> > > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > > +{
> > > > +	struct kvm *kvm = opt->ptr;
> > > > +	char *next;
> > > > +
> > > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > > +	if (kvm->cfg.ram_size == 0)
> > > > +		die("Invalid RAM size: %s", arg);  
> > > 
> > > Does 0 hold any significant value (anymore)? I think we die() if we
> > > encounter invalid values in parse_mem_option()?  
> > 
> > strtoull does not consider an error to convert the string "0" to an
> > unsigned long long.
> 
> I was wondering if we treat 0 as an indicator of a conversion error, or as
> a too-low memory size value here. I don't think we should special case the

It's both. It's an error because (man 2 strotoull, cherry-pick to prove my
point):

"If there were no digits at all, strtoul() stores the original value of
nptr in *endptr (and returns 0)"

As for the second part, I'm not sure how setting the size of the VM memory
to 0 can be considered anything else but an error. I am willing to be
convinced otherwise though.

> latter, as even 1MB or 2MB are typically too low values for a "normal"
> kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
> On the other hand, with --firmware I think we can run a (admittedly very
> limited) guest with 0MB of RAM.

That leaves us with the rather interesting question of how the firmware
image can fit in RAM if the size of the RAM is 0. It looks to me like
kvm__load_firmware should fail in this situation.

> 
> So if we care about garbage as an argument, we should do it by the book
> (strtoul manpage), and compare the next pointer to the input string

I believe my approach is by the man page, where strotoull returns ERANGE on
overflow, and 0 if no valid numbers are found. Care to point out what I am
missing?

Thanks,
Alex

> address, plus checking for the returned value being 0, so that
> "-m gimme-all" is explicitly denied. But that would need to happen in
> parse_mem_option(), I think, not here.
> 
> If we cannot be asked, that's probably fine, but I just wanted to
> check this.
> 
> Cheers,
> Andre
> 
> > > > +
> > > > +	if (*next != '\0')
> > > > +		die("Invalid memory specifier: %s", arg);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >  #ifndef OPT_ARCH_RUN
> > > >  #define OPT_ARCH_RUN(...)
> > > >  #endif
> > > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > > >  			"A name for the guest"),			\
> > > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > > -		" size in MB."),					\
> > > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > > +		     "Virtual machine memory size, by default measured"	\
> > > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > > >  			" image or rootfs directory", img_name_parser,	\
> > > >  			kvm),						\
> > > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > > >  
> > > >  	if (kvm->cfg.ram_size) {
> > > > -		/* User specifies RAM size in megabytes. */
> > > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > > >  		available_ram = host_ram_size();
> > > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",  
> > >   
> 
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-01 19:39           ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 19:39 UTC (permalink / raw)
  To: Andre Przywara
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

Hi,

On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:
> On Wed, 1 Jun 2022 15:17:50 +0100
> Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi Alex,
> 
> > Hi,
> > 
> > Thank you for having a look! Replies below.
> > 
> > On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> > > On Wed, 25 May 2022 12:23:41 +0100
> > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > 
> > > Hi,
> > >   
> > > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > 
> > > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > > When none are specified, the default is megabytes.
> > > > 
> > > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > > of treating it as uninitialized, as kvmtool has done so far.
> > > > 
> > > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > ---
> > > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/builtin-run.c b/builtin-run.c
> > > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > > --- a/builtin-run.c
> > > > +++ b/builtin-run.c
> > > > @@ -49,9 +49,11 @@
> > > >  #include <ctype.h>
> > > >  #include <stdio.h>
> > > >  
> > > > -#define MB_SHIFT		(20)
> > > >  #define KB_SHIFT		(10)
> > > > +#define MB_SHIFT		(20)
> > > >  #define GB_SHIFT		(30)
> > > > +#define TB_SHIFT		(40)
> > > > +#define PB_SHIFT		(50)  
> > > 
> > > Can we lose the parentheses?  
> > 
> > Yes.
> > 
> > >   
> > > >  
> > > >  __thread struct kvm_cpu *current_kvm_cpu;
> > > >  
> > > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > > >  }
> > > >  
> > > > +static int parse_mem_unit(char **next)
> > > > +{
> > > > +	int shift = -1;
> > > > +
> > > > +	switch (**next) {
> > > > +	case 'B': case 'b': shift = 0; break;
> > > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > > +	}
> > > > +
> > > > +	if (shift == -1) {
> > > > +		/* The default is megabytes. */
> > > > +		shift = MB_SHIFT;  
> > > 
> > > Doesn't that look better inside the switch/case?
> > > 	default: return MB_SHIFT;  
> > 
> > I think that change alone breaks the logic.
> > 
> > The code needs to advance next if and only if it matches on one of the
> > characters. I'll have a go at advancing next in each of the switch arms
> > above (with the exception of the default one, which I'll add) to see how it
> > ends up looking.
> 
> Mmh, but I meant:
> {
> 	switch (**next) {
> 	case 'B': case 'b': shift = 0; break;
> 	case 'K': case 'k': shift = KB_SHIFT; break;
> 	case 'M': case 'm': shift = MB_SHIFT; break;
> 	case 'G': case 'g': shift = GB_SHIFT; break;
> 	case 'T': case 't': shift = TB_SHIFT; break;
> 	case 'P': case 'p': shift = PB_SHIFT; break;
> 	default: return MB_SHIFT;  
> 	}
> 
> 	(*next)++;
> 
> 	return shift;
> }
> 
> that should solve it, shouldn't it?
> 
> > 
> > >   
> > > > +	} else {
> > > > +		(*next)++;
> > > > +	}
> > > > +
> > > > +	return shift;
> > > > +}
> > > > +
> > > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > > +{
> > > > +	u64 shift;
> > > > +	u64 val;
> > > > +
> > > > +	val = strtoull(nptr, next, 10);
> > > > +	if (errno == ERANGE)
> > > > +		die("Memory too large: %s", nptr);  
> > > 
> > > strtoull does not clear errno if it succeeds, so it retains the
> > > previous error value. So we would need to set errno to 0 just before
> > > calling strtoull.  
> > 
> > This was intentional on my part, because I was under the impression that
> > kvmtool treats all instances where errno != 0 as a fatal error. I think I
> > was wrong about that, I see at least one instance when that isn't the case,
> > in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> > errno is a fatal error.
> > 
> > I'll change the code to zero errno before calling strtoull.
> 
> Thanks!
> 
> > 
> > >   
> > > > +	shift = parse_mem_unit(next);
> > > > +
> > > > +	if ((val << shift) < val)
> > > > +		die("Memory too large: %s", nptr);
> > > > +
> > > > +	return val << shift;
> > > > +}
> > > > +
> > > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > > +{
> > > > +	struct kvm *kvm = opt->ptr;
> > > > +	char *next;
> > > > +
> > > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > > +	if (kvm->cfg.ram_size == 0)
> > > > +		die("Invalid RAM size: %s", arg);  
> > > 
> > > Does 0 hold any significant value (anymore)? I think we die() if we
> > > encounter invalid values in parse_mem_option()?  
> > 
> > strtoull does not consider an error to convert the string "0" to an
> > unsigned long long.
> 
> I was wondering if we treat 0 as an indicator of a conversion error, or as
> a too-low memory size value here. I don't think we should special case the

It's both. It's an error because (man 2 strotoull, cherry-pick to prove my
point):

"If there were no digits at all, strtoul() stores the original value of
nptr in *endptr (and returns 0)"

As for the second part, I'm not sure how setting the size of the VM memory
to 0 can be considered anything else but an error. I am willing to be
convinced otherwise though.

> latter, as even 1MB or 2MB are typically too low values for a "normal"
> kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
> On the other hand, with --firmware I think we can run a (admittedly very
> limited) guest with 0MB of RAM.

That leaves us with the rather interesting question of how the firmware
image can fit in RAM if the size of the RAM is 0. It looks to me like
kvm__load_firmware should fail in this situation.

> 
> So if we care about garbage as an argument, we should do it by the book
> (strtoul manpage), and compare the next pointer to the input string

I believe my approach is by the man page, where strotoull returns ERANGE on
overflow, and 0 if no valid numbers are found. Care to point out what I am
missing?

Thanks,
Alex

> address, plus checking for the returned value being 0, so that
> "-m gimme-all" is explicitly denied. But that would need to happen in
> parse_mem_option(), I think, not here.
> 
> If we cannot be asked, that's probably fine, but I just wanted to
> check this.
> 
> Cheers,
> Andre
> 
> > > > +
> > > > +	if (*next != '\0')
> > > > +		die("Invalid memory specifier: %s", arg);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >  #ifndef OPT_ARCH_RUN
> > > >  #define OPT_ARCH_RUN(...)
> > > >  #endif
> > > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > > >  			"A name for the guest"),			\
> > > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > > -		" size in MB."),					\
> > > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > > +		     "Virtual machine memory size, by default measured"	\
> > > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > > >  			" image or rootfs directory", img_name_parser,	\
> > > >  			kvm),						\
> > > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > > >  
> > > >  	if (kvm->cfg.ram_size) {
> > > > -		/* User specifies RAM size in megabytes. */
> > > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > > >  		available_ram = host_ram_size();
> > > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",  
> > >   
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-06-01 19:39           ` Alexandru Elisei
@ 2022-06-01 19:42             ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 19:42 UTC (permalink / raw)
  To: Andre Przywara; +Cc: linux-arm-kernel, maz, julien, kvmarm, will

Hi,

On Wed, Jun 01, 2022 at 08:39:08PM +0100, Alexandru Elisei wrote:
> Hi,
> 
> On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:
> > On Wed, 1 Jun 2022 15:17:50 +0100
> > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > 
> > Hi Alex,
> > 
[..]
> > So if we care about garbage as an argument, we should do it by the book
> > (strtoul manpage), and compare the next pointer to the input string
> 
> I believe my approach is by the man page, where strotoull returns ERANGE on

Err... by return ERANGE I mean that is sets errno to ERANGE (it return
ULLONG_MAX on overflow).

Thanks,
Alex
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-01 19:42             ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 19:42 UTC (permalink / raw)
  To: Andre Przywara; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

Hi,

On Wed, Jun 01, 2022 at 08:39:08PM +0100, Alexandru Elisei wrote:
> Hi,
> 
> On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:
> > On Wed, 1 Jun 2022 15:17:50 +0100
> > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > 
> > Hi Alex,
> > 
[..]
> > So if we care about garbage as an argument, we should do it by the book
> > (strtoul manpage), and compare the next pointer to the input string
> 
> I believe my approach is by the man page, where strotoull returns ERANGE on

Err... by return ERANGE I mean that is sets errno to ERANGE (it return
ULLONG_MAX on overflow).

Thanks,
Alex

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-06-01 19:39           ` Alexandru Elisei
@ 2022-06-01 20:13             ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 20:13 UTC (permalink / raw)
  To: Andre Przywara; +Cc: linux-arm-kernel, maz, julien, kvmarm, will

Hi,

On Wed, Jun 01, 2022 at 08:39:08PM +0100, Alexandru Elisei wrote:
> Hi,
> 
> On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:
> > On Wed, 1 Jun 2022 15:17:50 +0100
> > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > 
> > Hi Alex,
> > 
> > > Hi,
> > > 
> > > Thank you for having a look! Replies below.
> > > 
> > > On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> > > > On Wed, 25 May 2022 12:23:41 +0100
> > > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > > 
> > > > Hi,
> > > >   
> > > > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > 
> > > > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > > > When none are specified, the default is megabytes.
> > > > > 
> > > > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > > > of treating it as uninitialized, as kvmtool has done so far.
> > > > > 
> > > > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > > ---
> > > > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > > > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > > > 
> > > > > diff --git a/builtin-run.c b/builtin-run.c
> > > > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > > > --- a/builtin-run.c
> > > > > +++ b/builtin-run.c
> > > > > @@ -49,9 +49,11 @@
> > > > >  #include <ctype.h>
> > > > >  #include <stdio.h>
> > > > >  
> > > > > -#define MB_SHIFT		(20)
> > > > >  #define KB_SHIFT		(10)
> > > > > +#define MB_SHIFT		(20)
> > > > >  #define GB_SHIFT		(30)
> > > > > +#define TB_SHIFT		(40)
> > > > > +#define PB_SHIFT		(50)  
> > > > 
> > > > Can we lose the parentheses?  
> > > 
> > > Yes.
> > > 
> > > >   
> > > > >  
> > > > >  __thread struct kvm_cpu *current_kvm_cpu;
> > > > >  
> > > > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > > > >  }
> > > > >  
> > > > > +static int parse_mem_unit(char **next)
> > > > > +{
> > > > > +	int shift = -1;
> > > > > +
> > > > > +	switch (**next) {
> > > > > +	case 'B': case 'b': shift = 0; break;
> > > > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > > > +	}
> > > > > +
> > > > > +	if (shift == -1) {
> > > > > +		/* The default is megabytes. */
> > > > > +		shift = MB_SHIFT;  
> > > > 
> > > > Doesn't that look better inside the switch/case?
> > > > 	default: return MB_SHIFT;  
> > > 
> > > I think that change alone breaks the logic.
> > > 
> > > The code needs to advance next if and only if it matches on one of the
> > > characters. I'll have a go at advancing next in each of the switch arms
> > > above (with the exception of the default one, which I'll add) to see how it
> > > ends up looking.
> > 
> > Mmh, but I meant:
> > {
> > 	switch (**next) {
> > 	case 'B': case 'b': shift = 0; break;
> > 	case 'K': case 'k': shift = KB_SHIFT; break;
> > 	case 'M': case 'm': shift = MB_SHIFT; break;
> > 	case 'G': case 'g': shift = GB_SHIFT; break;
> > 	case 'T': case 't': shift = TB_SHIFT; break;
> > 	case 'P': case 'p': shift = PB_SHIFT; break;
> > 	default: return MB_SHIFT;  
> > 	}
> > 
> > 	(*next)++;
> > 
> > 	return shift;
> > }
> > 
> > that should solve it, shouldn't it?
> > 
> > > 
> > > >   
> > > > > +	} else {
> > > > > +		(*next)++;
> > > > > +	}
> > > > > +
> > > > > +	return shift;
> > > > > +}
> > > > > +
> > > > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > > > +{
> > > > > +	u64 shift;
> > > > > +	u64 val;
> > > > > +
> > > > > +	val = strtoull(nptr, next, 10);
> > > > > +	if (errno == ERANGE)
> > > > > +		die("Memory too large: %s", nptr);  
> > > > 
> > > > strtoull does not clear errno if it succeeds, so it retains the
> > > > previous error value. So we would need to set errno to 0 just before
> > > > calling strtoull.  
> > > 
> > > This was intentional on my part, because I was under the impression that
> > > kvmtool treats all instances where errno != 0 as a fatal error. I think I
> > > was wrong about that, I see at least one instance when that isn't the case,
> > > in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> > > errno is a fatal error.
> > > 
> > > I'll change the code to zero errno before calling strtoull.
> > 
> > Thanks!
> > 
> > > 
> > > >   
> > > > > +	shift = parse_mem_unit(next);
> > > > > +
> > > > > +	if ((val << shift) < val)
> > > > > +		die("Memory too large: %s", nptr);
> > > > > +
> > > > > +	return val << shift;
> > > > > +}
> > > > > +
> > > > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > > > +{
> > > > > +	struct kvm *kvm = opt->ptr;
> > > > > +	char *next;
> > > > > +
> > > > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > > > +	if (kvm->cfg.ram_size == 0)
> > > > > +		die("Invalid RAM size: %s", arg);  
> > > > 
> > > > Does 0 hold any significant value (anymore)? I think we die() if we
> > > > encounter invalid values in parse_mem_option()?  
> > > 
> > > strtoull does not consider an error to convert the string "0" to an
> > > unsigned long long.
> > 
> > I was wondering if we treat 0 as an indicator of a conversion error, or as
> > a too-low memory size value here. I don't think we should special case the
> 
> It's both. It's an error because (man 2 strotoull, cherry-pick to prove my
> point):
> 
> "If there were no digits at all, strtoul() stores the original value of
> nptr in *endptr (and returns 0)"
> 
> As for the second part, I'm not sure how setting the size of the VM memory
> to 0 can be considered anything else but an error. I am willing to be
> convinced otherwise though.
> 
> > latter, as even 1MB or 2MB are typically too low values for a "normal"
> > kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
> > On the other hand, with --firmware I think we can run a (admittedly very
> > limited) guest with 0MB of RAM.
> 
> That leaves us with the rather interesting question of how the firmware
> image can fit in RAM if the size of the RAM is 0. It looks to me like
> kvm__load_firmware should fail in this situation.
> 
> > 
> > So if we care about garbage as an argument, we should do it by the book
> > (strtoul manpage), and compare the next pointer to the input string
> 
> I believe my approach is by the man page, where strotoull returns ERANGE on
> overflow, and 0 if no valid numbers are found. Care to point out what I am
> missing?

Did some thinking, and I think I understand where you're coming from: the
comparison against 0 serves both to check for invalid user input and as a
logical condition for the correct flow of the program.

That's not ideal, as in the future kvmtool might allow 0 as a valid
address. I'll split the two checks, and move the check for valid input to
parse_mem_option, and do it like you suggested (and as is described in the
man page).

Thanks,
Alex

> 
> Thanks,
> Alex
> 
> > address, plus checking for the returned value being 0, so that
> > "-m gimme-all" is explicitly denied. But that would need to happen in
> > parse_mem_option(), I think, not here.
> > 
> > If we cannot be asked, that's probably fine, but I just wanted to
> > check this.
> > 
> > Cheers,
> > Andre
> > 
> > > > > +
> > > > > +	if (*next != '\0')
> > > > > +		die("Invalid memory specifier: %s", arg);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >  #ifndef OPT_ARCH_RUN
> > > > >  #define OPT_ARCH_RUN(...)
> > > > >  #endif
> > > > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > > > >  			"A name for the guest"),			\
> > > > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > > > -		" size in MB."),					\
> > > > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > > > +		     "Virtual machine memory size, by default measured"	\
> > > > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > > > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > > > >  			" image or rootfs directory", img_name_parser,	\
> > > > >  			kvm),						\
> > > > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > > > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > > > >  
> > > > >  	if (kvm->cfg.ram_size) {
> > > > > -		/* User specifies RAM size in megabytes. */
> > > > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > > > >  		available_ram = host_ram_size();
> > > > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > > > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",  
> > > >   
> > 
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-01 20:13             ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-01 20:13 UTC (permalink / raw)
  To: Andre Przywara; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

Hi,

On Wed, Jun 01, 2022 at 08:39:08PM +0100, Alexandru Elisei wrote:
> Hi,
> 
> On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:
> > On Wed, 1 Jun 2022 15:17:50 +0100
> > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > 
> > Hi Alex,
> > 
> > > Hi,
> > > 
> > > Thank you for having a look! Replies below.
> > > 
> > > On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:
> > > > On Wed, 25 May 2022 12:23:41 +0100
> > > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > > 
> > > > Hi,
> > > >   
> > > > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > 
> > > > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > > > When none are specified, the default is megabytes.
> > > > > 
> > > > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > > > of treating it as uninitialized, as kvmtool has done so far.
> > > > > 
> > > > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > > ---
> > > > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > > > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > > > 
> > > > > diff --git a/builtin-run.c b/builtin-run.c
> > > > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > > > --- a/builtin-run.c
> > > > > +++ b/builtin-run.c
> > > > > @@ -49,9 +49,11 @@
> > > > >  #include <ctype.h>
> > > > >  #include <stdio.h>
> > > > >  
> > > > > -#define MB_SHIFT		(20)
> > > > >  #define KB_SHIFT		(10)
> > > > > +#define MB_SHIFT		(20)
> > > > >  #define GB_SHIFT		(30)
> > > > > +#define TB_SHIFT		(40)
> > > > > +#define PB_SHIFT		(50)  
> > > > 
> > > > Can we lose the parentheses?  
> > > 
> > > Yes.
> > > 
> > > >   
> > > > >  
> > > > >  __thread struct kvm_cpu *current_kvm_cpu;
> > > > >  
> > > > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > > > >  }
> > > > >  
> > > > > +static int parse_mem_unit(char **next)
> > > > > +{
> > > > > +	int shift = -1;
> > > > > +
> > > > > +	switch (**next) {
> > > > > +	case 'B': case 'b': shift = 0; break;
> > > > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > > > +	}
> > > > > +
> > > > > +	if (shift == -1) {
> > > > > +		/* The default is megabytes. */
> > > > > +		shift = MB_SHIFT;  
> > > > 
> > > > Doesn't that look better inside the switch/case?
> > > > 	default: return MB_SHIFT;  
> > > 
> > > I think that change alone breaks the logic.
> > > 
> > > The code needs to advance next if and only if it matches on one of the
> > > characters. I'll have a go at advancing next in each of the switch arms
> > > above (with the exception of the default one, which I'll add) to see how it
> > > ends up looking.
> > 
> > Mmh, but I meant:
> > {
> > 	switch (**next) {
> > 	case 'B': case 'b': shift = 0; break;
> > 	case 'K': case 'k': shift = KB_SHIFT; break;
> > 	case 'M': case 'm': shift = MB_SHIFT; break;
> > 	case 'G': case 'g': shift = GB_SHIFT; break;
> > 	case 'T': case 't': shift = TB_SHIFT; break;
> > 	case 'P': case 'p': shift = PB_SHIFT; break;
> > 	default: return MB_SHIFT;  
> > 	}
> > 
> > 	(*next)++;
> > 
> > 	return shift;
> > }
> > 
> > that should solve it, shouldn't it?
> > 
> > > 
> > > >   
> > > > > +	} else {
> > > > > +		(*next)++;
> > > > > +	}
> > > > > +
> > > > > +	return shift;
> > > > > +}
> > > > > +
> > > > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > > > +{
> > > > > +	u64 shift;
> > > > > +	u64 val;
> > > > > +
> > > > > +	val = strtoull(nptr, next, 10);
> > > > > +	if (errno == ERANGE)
> > > > > +		die("Memory too large: %s", nptr);  
> > > > 
> > > > strtoull does not clear errno if it succeeds, so it retains the
> > > > previous error value. So we would need to set errno to 0 just before
> > > > calling strtoull.  
> > > 
> > > This was intentional on my part, because I was under the impression that
> > > kvmtool treats all instances where errno != 0 as a fatal error. I think I
> > > was wrong about that, I see at least one instance when that isn't the case,
> > > in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> > > errno is a fatal error.
> > > 
> > > I'll change the code to zero errno before calling strtoull.
> > 
> > Thanks!
> > 
> > > 
> > > >   
> > > > > +	shift = parse_mem_unit(next);
> > > > > +
> > > > > +	if ((val << shift) < val)
> > > > > +		die("Memory too large: %s", nptr);
> > > > > +
> > > > > +	return val << shift;
> > > > > +}
> > > > > +
> > > > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > > > +{
> > > > > +	struct kvm *kvm = opt->ptr;
> > > > > +	char *next;
> > > > > +
> > > > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > > > +	if (kvm->cfg.ram_size == 0)
> > > > > +		die("Invalid RAM size: %s", arg);  
> > > > 
> > > > Does 0 hold any significant value (anymore)? I think we die() if we
> > > > encounter invalid values in parse_mem_option()?  
> > > 
> > > strtoull does not consider an error to convert the string "0" to an
> > > unsigned long long.
> > 
> > I was wondering if we treat 0 as an indicator of a conversion error, or as
> > a too-low memory size value here. I don't think we should special case the
> 
> It's both. It's an error because (man 2 strotoull, cherry-pick to prove my
> point):
> 
> "If there were no digits at all, strtoul() stores the original value of
> nptr in *endptr (and returns 0)"
> 
> As for the second part, I'm not sure how setting the size of the VM memory
> to 0 can be considered anything else but an error. I am willing to be
> convinced otherwise though.
> 
> > latter, as even 1MB or 2MB are typically too low values for a "normal"
> > kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
> > On the other hand, with --firmware I think we can run a (admittedly very
> > limited) guest with 0MB of RAM.
> 
> That leaves us with the rather interesting question of how the firmware
> image can fit in RAM if the size of the RAM is 0. It looks to me like
> kvm__load_firmware should fail in this situation.
> 
> > 
> > So if we care about garbage as an argument, we should do it by the book
> > (strtoul manpage), and compare the next pointer to the input string
> 
> I believe my approach is by the man page, where strotoull returns ERANGE on
> overflow, and 0 if no valid numbers are found. Care to point out what I am
> missing?

Did some thinking, and I think I understand where you're coming from: the
comparison against 0 serves both to check for invalid user input and as a
logical condition for the correct flow of the program.

That's not ideal, as in the future kvmtool might allow 0 as a valid
address. I'll split the two checks, and move the check for valid input to
parse_mem_option, and do it like you suggested (and as is described in the
man page).

Thanks,
Alex

> 
> Thanks,
> Alex
> 
> > address, plus checking for the returned value being 0, so that
> > "-m gimme-all" is explicitly denied. But that would need to happen in
> > parse_mem_option(), I think, not here.
> > 
> > If we cannot be asked, that's probably fine, but I just wanted to
> > check this.
> > 
> > Cheers,
> > Andre
> > 
> > > > > +
> > > > > +	if (*next != '\0')
> > > > > +		die("Invalid memory specifier: %s", arg);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >  #ifndef OPT_ARCH_RUN
> > > > >  #define OPT_ARCH_RUN(...)
> > > > >  #endif
> > > > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > > > >  			"A name for the guest"),			\
> > > > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > > > -		" size in MB."),					\
> > > > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > > > +		     "Virtual machine memory size, by default measured"	\
> > > > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > > > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > > > >  			" image or rootfs directory", img_name_parser,	\
> > > > >  			kvm),						\
> > > > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > > > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > > > >  
> > > > >  	if (kvm->cfg.ram_size) {
> > > > > -		/* User specifies RAM size in megabytes. */
> > > > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > > > >  		available_ram = host_ram_size();
> > > > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > > > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",  
> > > >   
> > 
> _______________________________________________
> kvmarm mailing list
> kvmarm@lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
  2022-06-01 20:13             ` Alexandru Elisei
@ 2022-06-06 10:53               ` Andre Przywara
  -1 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-06 10:53 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: linux-arm-kernel, maz, julien, kvmarm, will

On Wed, 1 Jun 2022 21:13:27 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> On Wed, Jun 01, 2022 at 08:39:08PM +0100, Alexandru Elisei wrote:
> > Hi,
> > 
> > On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:  
> > > On Wed, 1 Jun 2022 15:17:50 +0100
> > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > 
> > > Hi Alex,
> > >   
> > > > Hi,
> > > > 
> > > > Thank you for having a look! Replies below.
> > > > 
> > > > On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:  
> > > > > On Wed, 25 May 2022 12:23:41 +0100
> > > > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > > > 
> > > > > Hi,
> > > > >     
> > > > > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > > 
> > > > > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > > > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > > > > When none are specified, the default is megabytes.
> > > > > > 
> > > > > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > > > > of treating it as uninitialized, as kvmtool has done so far.
> > > > > > 
> > > > > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > > > ---
> > > > > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > > > > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > > > > 
> > > > > > diff --git a/builtin-run.c b/builtin-run.c
> > > > > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > > > > --- a/builtin-run.c
> > > > > > +++ b/builtin-run.c
> > > > > > @@ -49,9 +49,11 @@
> > > > > >  #include <ctype.h>
> > > > > >  #include <stdio.h>
> > > > > >  
> > > > > > -#define MB_SHIFT		(20)
> > > > > >  #define KB_SHIFT		(10)
> > > > > > +#define MB_SHIFT		(20)
> > > > > >  #define GB_SHIFT		(30)
> > > > > > +#define TB_SHIFT		(40)
> > > > > > +#define PB_SHIFT		(50)    
> > > > > 
> > > > > Can we lose the parentheses?    
> > > > 
> > > > Yes.
> > > >   
> > > > >     
> > > > > >  
> > > > > >  __thread struct kvm_cpu *current_kvm_cpu;
> > > > > >  
> > > > > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > > > > >  }
> > > > > >  
> > > > > > +static int parse_mem_unit(char **next)
> > > > > > +{
> > > > > > +	int shift = -1;
> > > > > > +
> > > > > > +	switch (**next) {
> > > > > > +	case 'B': case 'b': shift = 0; break;
> > > > > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > > > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > > > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > > > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > > > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > > > > +	}
> > > > > > +
> > > > > > +	if (shift == -1) {
> > > > > > +		/* The default is megabytes. */
> > > > > > +		shift = MB_SHIFT;    
> > > > > 
> > > > > Doesn't that look better inside the switch/case?
> > > > > 	default: return MB_SHIFT;    
> > > > 
> > > > I think that change alone breaks the logic.
> > > > 
> > > > The code needs to advance next if and only if it matches on one of the
> > > > characters. I'll have a go at advancing next in each of the switch arms
> > > > above (with the exception of the default one, which I'll add) to see how it
> > > > ends up looking.  
> > > 
> > > Mmh, but I meant:
> > > {
> > > 	switch (**next) {
> > > 	case 'B': case 'b': shift = 0; break;
> > > 	case 'K': case 'k': shift = KB_SHIFT; break;
> > > 	case 'M': case 'm': shift = MB_SHIFT; break;
> > > 	case 'G': case 'g': shift = GB_SHIFT; break;
> > > 	case 'T': case 't': shift = TB_SHIFT; break;
> > > 	case 'P': case 'p': shift = PB_SHIFT; break;
> > > 	default: return MB_SHIFT;  
> > > 	}
> > > 
> > > 	(*next)++;
> > > 
> > > 	return shift;
> > > }
> > > 
> > > that should solve it, shouldn't it?
> > >   
> > > >   
> > > > >     
> > > > > > +	} else {
> > > > > > +		(*next)++;
> > > > > > +	}
> > > > > > +
> > > > > > +	return shift;
> > > > > > +}
> > > > > > +
> > > > > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > > > > +{
> > > > > > +	u64 shift;
> > > > > > +	u64 val;
> > > > > > +
> > > > > > +	val = strtoull(nptr, next, 10);
> > > > > > +	if (errno == ERANGE)
> > > > > > +		die("Memory too large: %s", nptr);    
> > > > > 
> > > > > strtoull does not clear errno if it succeeds, so it retains the
> > > > > previous error value. So we would need to set errno to 0 just before
> > > > > calling strtoull.    
> > > > 
> > > > This was intentional on my part, because I was under the impression that
> > > > kvmtool treats all instances where errno != 0 as a fatal error. I think I
> > > > was wrong about that, I see at least one instance when that isn't the case,
> > > > in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> > > > errno is a fatal error.
> > > > 
> > > > I'll change the code to zero errno before calling strtoull.  
> > > 
> > > Thanks!
> > >   
> > > >   
> > > > >     
> > > > > > +	shift = parse_mem_unit(next);
> > > > > > +
> > > > > > +	if ((val << shift) < val)
> > > > > > +		die("Memory too large: %s", nptr);
> > > > > > +
> > > > > > +	return val << shift;
> > > > > > +}
> > > > > > +
> > > > > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > > > > +{
> > > > > > +	struct kvm *kvm = opt->ptr;
> > > > > > +	char *next;
> > > > > > +
> > > > > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > > > > +	if (kvm->cfg.ram_size == 0)
> > > > > > +		die("Invalid RAM size: %s", arg);    
> > > > > 
> > > > > Does 0 hold any significant value (anymore)? I think we die() if we
> > > > > encounter invalid values in parse_mem_option()?    
> > > > 
> > > > strtoull does not consider an error to convert the string "0" to an
> > > > unsigned long long.  
> > > 
> > > I was wondering if we treat 0 as an indicator of a conversion error, or as
> > > a too-low memory size value here. I don't think we should special case the  
> > 
> > It's both. It's an error because (man 2 strotoull, cherry-pick to prove my
> > point):
> > 
> > "If there were no digits at all, strtoul() stores the original value of
> > nptr in *endptr (and returns 0)"
> > 
> > As for the second part, I'm not sure how setting the size of the VM memory
> > to 0 can be considered anything else but an error. I am willing to be
> > convinced otherwise though.
> >   
> > > latter, as even 1MB or 2MB are typically too low values for a "normal"
> > > kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
> > > On the other hand, with --firmware I think we can run a (admittedly very
> > > limited) guest with 0MB of RAM.  
> > 
> > That leaves us with the rather interesting question of how the firmware
> > image can fit in RAM if the size of the RAM is 0. It looks to me like
> > kvm__load_firmware should fail in this situation.

Yeah, sorry, I was under the impression we could run firmware directly
from the CFI flash, as QEMU does. But we explicitly check that the firmware
address is in RAM. Also we always allocate one memslot: when its size is
zero, the kernel thinks we want to delete an existing memslot, and returns
an error. So running with 0 MB of DRAM is not supported in kvmtool.

> > > So if we care about garbage as an argument, we should do it by the book
> > > (strtoul manpage), and compare the next pointer to the input string  
> > 
> > I believe my approach is by the man page, where strotoull returns ERANGE on
> > overflow, and 0 if no valid numbers are found. Care to point out what I am
> > missing?  
> 
> Did some thinking, and I think I understand where you're coming from: the
> comparison against 0 serves both to check for invalid user input and as a
> logical condition for the correct flow of the program.
> 
> That's not ideal, as in the future kvmtool might allow 0 as a valid
> address. I'll split the two checks, and move the check for valid input to
> parse_mem_option, and do it like you suggested (and as is described in the
> man page).

Yeah, I was coming from a more academic point here ;-)
Thanks for considering the change, happy to review that.

Cheers,
Andre

> > > address, plus checking for the returned value being 0, so that
> > > "-m gimme-all" is explicitly denied. But that would need to happen in
> > > parse_mem_option(), I think, not here.
> > > 
> > > If we cannot be asked, that's probably fine, but I just wanted to
> > > check this.
> > > 
> > > Cheers,
> > > Andre
> > >   
> > > > > > +
> > > > > > +	if (*next != '\0')
> > > > > > +		die("Invalid memory specifier: %s", arg);
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > >  #ifndef OPT_ARCH_RUN
> > > > > >  #define OPT_ARCH_RUN(...)
> > > > > >  #endif
> > > > > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > > > > >  			"A name for the guest"),			\
> > > > > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > > > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > > > > -		" size in MB."),					\
> > > > > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > > > > +		     "Virtual machine memory size, by default measured"	\
> > > > > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > > > > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > > > > >  			" image or rootfs directory", img_name_parser,	\
> > > > > >  			kvm),						\
> > > > > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > > > > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > > > > >  
> > > > > >  	if (kvm->cfg.ram_size) {
> > > > > > -		/* User specifies RAM size in megabytes. */
> > > > > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > > > > >  		available_ram = host_ram_size();
> > > > > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > > > > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",    
> > > > >     
> > >   
> > _______________________________________________
> > kvmarm mailing list
> > kvmarm@lists.cs.columbia.edu
> > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm  

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory
@ 2022-06-06 10:53               ` Andre Przywara
  0 siblings, 0 replies; 62+ messages in thread
From: Andre Przywara @ 2022-06-06 10:53 UTC (permalink / raw)
  To: Alexandru Elisei; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

On Wed, 1 Jun 2022 21:13:27 +0100
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> On Wed, Jun 01, 2022 at 08:39:08PM +0100, Alexandru Elisei wrote:
> > Hi,
> > 
> > On Wed, Jun 01, 2022 at 05:14:00PM +0100, Andre Przywara wrote:  
> > > On Wed, 1 Jun 2022 15:17:50 +0100
> > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > 
> > > Hi Alex,
> > >   
> > > > Hi,
> > > > 
> > > > Thank you for having a look! Replies below.
> > > > 
> > > > On Wed, Jun 01, 2022 at 02:39:55PM +0100, Andre Przywara wrote:  
> > > > > On Wed, 25 May 2022 12:23:41 +0100
> > > > > Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> > > > > 
> > > > > Hi,
> > > > >     
> > > > > > From: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > > 
> > > > > > Allow the user to use the standard B (bytes), K (kilobytes), M (megabytes),
> > > > > > G (gigabytes), T (terabytes) and P (petabytes) suffixes for memory size.
> > > > > > When none are specified, the default is megabytes.
> > > > > > 
> > > > > > Also raise an error if the guest specifies 0 as the memory size, instead
> > > > > > of treating it as uninitialized, as kvmtool has done so far.
> > > > > > 
> > > > > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > > > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > > > ---
> > > > > >  builtin-run.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++----
> > > > > >  1 file changed, 60 insertions(+), 5 deletions(-)
> > > > > > 
> > > > > > diff --git a/builtin-run.c b/builtin-run.c
> > > > > > index 2ef159cdb2a3..a49698d5b2fe 100644
> > > > > > --- a/builtin-run.c
> > > > > > +++ b/builtin-run.c
> > > > > > @@ -49,9 +49,11 @@
> > > > > >  #include <ctype.h>
> > > > > >  #include <stdio.h>
> > > > > >  
> > > > > > -#define MB_SHIFT		(20)
> > > > > >  #define KB_SHIFT		(10)
> > > > > > +#define MB_SHIFT		(20)
> > > > > >  #define GB_SHIFT		(30)
> > > > > > +#define TB_SHIFT		(40)
> > > > > > +#define PB_SHIFT		(50)    
> > > > > 
> > > > > Can we lose the parentheses?    
> > > > 
> > > > Yes.
> > > >   
> > > > >     
> > > > > >  
> > > > > >  __thread struct kvm_cpu *current_kvm_cpu;
> > > > > >  
> > > > > > @@ -87,6 +89,60 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > > >  	kvm_run_wrapper = KVM_RUN_SANDBOX;
> > > > > >  }
> > > > > >  
> > > > > > +static int parse_mem_unit(char **next)
> > > > > > +{
> > > > > > +	int shift = -1;
> > > > > > +
> > > > > > +	switch (**next) {
> > > > > > +	case 'B': case 'b': shift = 0; break;
> > > > > > +	case 'K': case 'k': shift = KB_SHIFT; break;
> > > > > > +	case 'M': case 'm': shift = MB_SHIFT; break;
> > > > > > +	case 'G': case 'g': shift = GB_SHIFT; break;
> > > > > > +	case 'T': case 't': shift = TB_SHIFT; break;
> > > > > > +	case 'P': case 'p': shift = PB_SHIFT; break;
> > > > > > +	}
> > > > > > +
> > > > > > +	if (shift == -1) {
> > > > > > +		/* The default is megabytes. */
> > > > > > +		shift = MB_SHIFT;    
> > > > > 
> > > > > Doesn't that look better inside the switch/case?
> > > > > 	default: return MB_SHIFT;    
> > > > 
> > > > I think that change alone breaks the logic.
> > > > 
> > > > The code needs to advance next if and only if it matches on one of the
> > > > characters. I'll have a go at advancing next in each of the switch arms
> > > > above (with the exception of the default one, which I'll add) to see how it
> > > > ends up looking.  
> > > 
> > > Mmh, but I meant:
> > > {
> > > 	switch (**next) {
> > > 	case 'B': case 'b': shift = 0; break;
> > > 	case 'K': case 'k': shift = KB_SHIFT; break;
> > > 	case 'M': case 'm': shift = MB_SHIFT; break;
> > > 	case 'G': case 'g': shift = GB_SHIFT; break;
> > > 	case 'T': case 't': shift = TB_SHIFT; break;
> > > 	case 'P': case 'p': shift = PB_SHIFT; break;
> > > 	default: return MB_SHIFT;  
> > > 	}
> > > 
> > > 	(*next)++;
> > > 
> > > 	return shift;
> > > }
> > > 
> > > that should solve it, shouldn't it?
> > >   
> > > >   
> > > > >     
> > > > > > +	} else {
> > > > > > +		(*next)++;
> > > > > > +	}
> > > > > > +
> > > > > > +	return shift;
> > > > > > +}
> > > > > > +
> > > > > > +static u64 parse_mem_option(const char *nptr, char **next)
> > > > > > +{
> > > > > > +	u64 shift;
> > > > > > +	u64 val;
> > > > > > +
> > > > > > +	val = strtoull(nptr, next, 10);
> > > > > > +	if (errno == ERANGE)
> > > > > > +		die("Memory too large: %s", nptr);    
> > > > > 
> > > > > strtoull does not clear errno if it succeeds, so it retains the
> > > > > previous error value. So we would need to set errno to 0 just before
> > > > > calling strtoull.    
> > > > 
> > > > This was intentional on my part, because I was under the impression that
> > > > kvmtool treats all instances where errno != 0 as a fatal error. I think I
> > > > was wrong about that, I see at least one instance when that isn't the case,
> > > > in kvm_setup_guest_init -> extract_file. So it isn't a rule that a non-zero
> > > > errno is a fatal error.
> > > > 
> > > > I'll change the code to zero errno before calling strtoull.  
> > > 
> > > Thanks!
> > >   
> > > >   
> > > > >     
> > > > > > +	shift = parse_mem_unit(next);
> > > > > > +
> > > > > > +	if ((val << shift) < val)
> > > > > > +		die("Memory too large: %s", nptr);
> > > > > > +
> > > > > > +	return val << shift;
> > > > > > +}
> > > > > > +
> > > > > > +static int mem_parser(const struct option *opt, const char *arg, int unset)
> > > > > > +{
> > > > > > +	struct kvm *kvm = opt->ptr;
> > > > > > +	char *next;
> > > > > > +
> > > > > > +	kvm->cfg.ram_size = parse_mem_option(arg, &next);
> > > > > > +	if (kvm->cfg.ram_size == 0)
> > > > > > +		die("Invalid RAM size: %s", arg);    
> > > > > 
> > > > > Does 0 hold any significant value (anymore)? I think we die() if we
> > > > > encounter invalid values in parse_mem_option()?    
> > > > 
> > > > strtoull does not consider an error to convert the string "0" to an
> > > > unsigned long long.  
> > > 
> > > I was wondering if we treat 0 as an indicator of a conversion error, or as
> > > a too-low memory size value here. I don't think we should special case the  
> > 
> > It's both. It's an error because (man 2 strotoull, cherry-pick to prove my
> > point):
> > 
> > "If there were no digits at all, strtoul() stores the original value of
> > nptr in *endptr (and returns 0)"
> > 
> > As for the second part, I'm not sure how setting the size of the VM memory
> > to 0 can be considered anything else but an error. I am willing to be
> > convinced otherwise though.
> >   
> > > latter, as even 1MB or 2MB are typically too low values for a "normal"
> > > kvmtool run ("Fatal: kernel image too big to contain in guest memory.").
> > > On the other hand, with --firmware I think we can run a (admittedly very
> > > limited) guest with 0MB of RAM.  
> > 
> > That leaves us with the rather interesting question of how the firmware
> > image can fit in RAM if the size of the RAM is 0. It looks to me like
> > kvm__load_firmware should fail in this situation.

Yeah, sorry, I was under the impression we could run firmware directly
from the CFI flash, as QEMU does. But we explicitly check that the firmware
address is in RAM. Also we always allocate one memslot: when its size is
zero, the kernel thinks we want to delete an existing memslot, and returns
an error. So running with 0 MB of DRAM is not supported in kvmtool.

> > > So if we care about garbage as an argument, we should do it by the book
> > > (strtoul manpage), and compare the next pointer to the input string  
> > 
> > I believe my approach is by the man page, where strotoull returns ERANGE on
> > overflow, and 0 if no valid numbers are found. Care to point out what I am
> > missing?  
> 
> Did some thinking, and I think I understand where you're coming from: the
> comparison against 0 serves both to check for invalid user input and as a
> logical condition for the correct flow of the program.
> 
> That's not ideal, as in the future kvmtool might allow 0 as a valid
> address. I'll split the two checks, and move the check for valid input to
> parse_mem_option, and do it like you suggested (and as is described in the
> man page).

Yeah, I was coming from a more academic point here ;-)
Thanks for considering the change, happy to review that.

Cheers,
Andre

> > > address, plus checking for the returned value being 0, so that
> > > "-m gimme-all" is explicitly denied. But that would need to happen in
> > > parse_mem_option(), I think, not here.
> > > 
> > > If we cannot be asked, that's probably fine, but I just wanted to
> > > check this.
> > > 
> > > Cheers,
> > > Andre
> > >   
> > > > > > +
> > > > > > +	if (*next != '\0')
> > > > > > +		die("Invalid memory specifier: %s", arg);
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > >  #ifndef OPT_ARCH_RUN
> > > > > >  #define OPT_ARCH_RUN(...)
> > > > > >  #endif
> > > > > > @@ -97,8 +153,9 @@ void kvm_run_set_wrapper_sandbox(void)
> > > > > >  	OPT_STRING('\0', "name", &(cfg)->guest_name, "guest name",	\
> > > > > >  			"A name for the guest"),			\
> > > > > >  	OPT_INTEGER('c', "cpus", &(cfg)->nrcpus, "Number of CPUs"),	\
> > > > > > -	OPT_U64('m', "mem", &(cfg)->ram_size, "Virtual machine memory"	\
> > > > > > -		" size in MB."),					\
> > > > > > +	OPT_CALLBACK('m', "mem", NULL, "size[BKMGTP]",			\
> > > > > > +		     "Virtual machine memory size, by default measured"	\
> > > > > > +		     " in megabytes (M)", mem_parser, kvm),		\
> > > > > >  	OPT_CALLBACK('d', "disk", kvm, "image or rootfs_dir", "Disk "	\
> > > > > >  			" image or rootfs directory", img_name_parser,	\
> > > > > >  			kvm),						\
> > > > > > @@ -522,8 +579,6 @@ static void kvm_run_validate_cfg(struct kvm *kvm)
> > > > > >  		pr_warning("Ignoring initrd file when loading a firmware image");
> > > > > >  
> > > > > >  	if (kvm->cfg.ram_size) {
> > > > > > -		/* User specifies RAM size in megabytes. */
> > > > > > -		kvm->cfg.ram_size <<= MB_SHIFT;
> > > > > >  		available_ram = host_ram_size();
> > > > > >  		if (available_ram && kvm->cfg.ram_size > available_ram) {
> > > > > >  			pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB",    
> > > > >     
> > >   
> > _______________________________________________
> > kvmarm mailing list
> > kvmarm@lists.cs.columbia.edu
> > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit
  2022-05-30 15:05     ` Andre Przywara
@ 2022-06-15 16:01       ` Alexandru Elisei
  -1 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-15 16:01 UTC (permalink / raw)
  To: Andre Przywara; +Cc: julien, maz, will, kvmarm, linux-arm-kernel

Hi,

On Mon, May 30, 2022 at 04:05:17PM +0100, Andre Przywara wrote:
> On Wed, 25 May 2022 12:23:34 +0100
> Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi,
> 
> > Append ULL to all of the size definitions to make them 64bit and avoid
> > overflows.
> 
> I am not fully convinced this is the best solution, as it deviates from
> the kernel file, and just papers over issues at the call sites. I
> acknowledge the pragmatic approach of trying to fix multiple problems at
> once, but am wondering if we should use -fsanitize=undefined to identify
> problematic code and fix it (I started doing this, actually).

I have to admit I'm slightly on the fence too about modifying a header file
taken from Linux, especially considering that I'm not really sure why they are
using ints instead of casting everything (it does seem that sizes.h was intended
to be used by assembly code on 32-bit systems before it was moved from
include/asm-generic/sizes.h to include/linux/sizes.h, but I can't be really sure
that's the only reason).

So yes, I'll add the needed cast(s) and avoid changing the size definitions.

Thanks,
Alex

> 
> Cheers,
> Andre
> 
> > Reported-by: Andre Przywara <andre.przywara@arm.com>
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > ---
> >  include/linux/sizes.h | 64 +++++++++++++++++++++----------------------
> >  1 file changed, 32 insertions(+), 32 deletions(-)
> > 
> > diff --git a/include/linux/sizes.h b/include/linux/sizes.h
> > index ce3e8150c174..b2b5c457cf1c 100644
> > --- a/include/linux/sizes.h
> > +++ b/include/linux/sizes.h
> > @@ -8,40 +8,40 @@
> >  #ifndef __LINUX_SIZES_H__
> >  #define __LINUX_SIZES_H__
> >  
> > -#define SZ_1				0x00000001
> > -#define SZ_2				0x00000002
> > -#define SZ_4				0x00000004
> > -#define SZ_8				0x00000008
> > -#define SZ_16				0x00000010
> > -#define SZ_32				0x00000020
> > -#define SZ_64				0x00000040
> > -#define SZ_128				0x00000080
> > -#define SZ_256				0x00000100
> > -#define SZ_512				0x00000200
> > +#define SZ_1				0x00000001ULL
> > +#define SZ_2				0x00000002ULL
> > +#define SZ_4				0x00000004ULL
> > +#define SZ_8				0x00000008ULL
> > +#define SZ_16				0x00000010ULL
> > +#define SZ_32				0x00000020ULL
> > +#define SZ_64				0x00000040ULL
> > +#define SZ_128				0x00000080ULL
> > +#define SZ_256				0x00000100ULL
> > +#define SZ_512				0x00000200ULL
> >  
> > -#define SZ_1K				0x00000400
> > -#define SZ_2K				0x00000800
> > -#define SZ_4K				0x00001000
> > -#define SZ_8K				0x00002000
> > -#define SZ_16K				0x00004000
> > -#define SZ_32K				0x00008000
> > -#define SZ_64K				0x00010000
> > -#define SZ_128K				0x00020000
> > -#define SZ_256K				0x00040000
> > -#define SZ_512K				0x00080000
> > +#define SZ_1K				0x00000400ULL
> > +#define SZ_2K				0x00000800ULL
> > +#define SZ_4K				0x00001000ULL
> > +#define SZ_8K				0x00002000ULL
> > +#define SZ_16K				0x00004000ULL
> > +#define SZ_32K				0x00008000ULL
> > +#define SZ_64K				0x00010000ULL
> > +#define SZ_128K				0x00020000ULL
> > +#define SZ_256K				0x00040000ULL
> > +#define SZ_512K				0x00080000ULL
> >  
> > -#define SZ_1M				0x00100000
> > -#define SZ_2M				0x00200000
> > -#define SZ_4M				0x00400000
> > -#define SZ_8M				0x00800000
> > -#define SZ_16M				0x01000000
> > -#define SZ_32M				0x02000000
> > -#define SZ_64M				0x04000000
> > -#define SZ_128M				0x08000000
> > -#define SZ_256M				0x10000000
> > -#define SZ_512M				0x20000000
> > +#define SZ_1M				0x00100000ULL
> > +#define SZ_2M				0x00200000ULL
> > +#define SZ_4M				0x00400000ULL
> > +#define SZ_8M				0x00800000ULL
> > +#define SZ_16M				0x01000000ULL
> > +#define SZ_32M				0x02000000ULL
> > +#define SZ_64M				0x04000000ULL
> > +#define SZ_128M				0x08000000ULL
> > +#define SZ_256M				0x10000000ULL
> > +#define SZ_512M				0x20000000ULL
> >  
> > -#define SZ_1G				0x40000000
> > -#define SZ_2G				0x80000000
> > +#define SZ_1G				0x40000000ULL
> > +#define SZ_2G				0x80000000ULL
> >  
> >  #endif /* __LINUX_SIZES_H__ */
> 
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

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

* Re: [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit
@ 2022-06-15 16:01       ` Alexandru Elisei
  0 siblings, 0 replies; 62+ messages in thread
From: Alexandru Elisei @ 2022-06-15 16:01 UTC (permalink / raw)
  To: Andre Przywara
  Cc: will, julien.thierry.kdev, maz, suzuki.poulose, julien,
	linux-arm-kernel, kvmarm, james.morse

Hi,

On Mon, May 30, 2022 at 04:05:17PM +0100, Andre Przywara wrote:
> On Wed, 25 May 2022 12:23:34 +0100
> Alexandru Elisei <alexandru.elisei@arm.com> wrote:
> 
> Hi,
> 
> > Append ULL to all of the size definitions to make them 64bit and avoid
> > overflows.
> 
> I am not fully convinced this is the best solution, as it deviates from
> the kernel file, and just papers over issues at the call sites. I
> acknowledge the pragmatic approach of trying to fix multiple problems at
> once, but am wondering if we should use -fsanitize=undefined to identify
> problematic code and fix it (I started doing this, actually).

I have to admit I'm slightly on the fence too about modifying a header file
taken from Linux, especially considering that I'm not really sure why they are
using ints instead of casting everything (it does seem that sizes.h was intended
to be used by assembly code on 32-bit systems before it was moved from
include/asm-generic/sizes.h to include/linux/sizes.h, but I can't be really sure
that's the only reason).

So yes, I'll add the needed cast(s) and avoid changing the size definitions.

Thanks,
Alex

> 
> Cheers,
> Andre
> 
> > Reported-by: Andre Przywara <andre.przywara@arm.com>
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > ---
> >  include/linux/sizes.h | 64 +++++++++++++++++++++----------------------
> >  1 file changed, 32 insertions(+), 32 deletions(-)
> > 
> > diff --git a/include/linux/sizes.h b/include/linux/sizes.h
> > index ce3e8150c174..b2b5c457cf1c 100644
> > --- a/include/linux/sizes.h
> > +++ b/include/linux/sizes.h
> > @@ -8,40 +8,40 @@
> >  #ifndef __LINUX_SIZES_H__
> >  #define __LINUX_SIZES_H__
> >  
> > -#define SZ_1				0x00000001
> > -#define SZ_2				0x00000002
> > -#define SZ_4				0x00000004
> > -#define SZ_8				0x00000008
> > -#define SZ_16				0x00000010
> > -#define SZ_32				0x00000020
> > -#define SZ_64				0x00000040
> > -#define SZ_128				0x00000080
> > -#define SZ_256				0x00000100
> > -#define SZ_512				0x00000200
> > +#define SZ_1				0x00000001ULL
> > +#define SZ_2				0x00000002ULL
> > +#define SZ_4				0x00000004ULL
> > +#define SZ_8				0x00000008ULL
> > +#define SZ_16				0x00000010ULL
> > +#define SZ_32				0x00000020ULL
> > +#define SZ_64				0x00000040ULL
> > +#define SZ_128				0x00000080ULL
> > +#define SZ_256				0x00000100ULL
> > +#define SZ_512				0x00000200ULL
> >  
> > -#define SZ_1K				0x00000400
> > -#define SZ_2K				0x00000800
> > -#define SZ_4K				0x00001000
> > -#define SZ_8K				0x00002000
> > -#define SZ_16K				0x00004000
> > -#define SZ_32K				0x00008000
> > -#define SZ_64K				0x00010000
> > -#define SZ_128K				0x00020000
> > -#define SZ_256K				0x00040000
> > -#define SZ_512K				0x00080000
> > +#define SZ_1K				0x00000400ULL
> > +#define SZ_2K				0x00000800ULL
> > +#define SZ_4K				0x00001000ULL
> > +#define SZ_8K				0x00002000ULL
> > +#define SZ_16K				0x00004000ULL
> > +#define SZ_32K				0x00008000ULL
> > +#define SZ_64K				0x00010000ULL
> > +#define SZ_128K				0x00020000ULL
> > +#define SZ_256K				0x00040000ULL
> > +#define SZ_512K				0x00080000ULL
> >  
> > -#define SZ_1M				0x00100000
> > -#define SZ_2M				0x00200000
> > -#define SZ_4M				0x00400000
> > -#define SZ_8M				0x00800000
> > -#define SZ_16M				0x01000000
> > -#define SZ_32M				0x02000000
> > -#define SZ_64M				0x04000000
> > -#define SZ_128M				0x08000000
> > -#define SZ_256M				0x10000000
> > -#define SZ_512M				0x20000000
> > +#define SZ_1M				0x00100000ULL
> > +#define SZ_2M				0x00200000ULL
> > +#define SZ_4M				0x00400000ULL
> > +#define SZ_8M				0x00800000ULL
> > +#define SZ_16M				0x01000000ULL
> > +#define SZ_32M				0x02000000ULL
> > +#define SZ_64M				0x04000000ULL
> > +#define SZ_128M				0x08000000ULL
> > +#define SZ_256M				0x10000000ULL
> > +#define SZ_512M				0x20000000ULL
> >  
> > -#define SZ_1G				0x40000000
> > -#define SZ_2G				0x80000000
> > +#define SZ_1G				0x40000000ULL
> > +#define SZ_2G				0x80000000ULL
> >  
> >  #endif /* __LINUX_SIZES_H__ */
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2022-06-15 16:02 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-25 11:23 [PATCH v3 kvmtool 00/13] arm64: Allow the user to set RAM base address Alexandru Elisei
2022-05-25 11:23 ` Alexandru Elisei
2022-05-25 11:23 ` [PATCH v3 kvmtool 01/13] Use MB for megabytes consistently Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-05-25 11:23 ` [PATCH v3 kvmtool 02/13] sizes.h: Make all sizes 64bit Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-05-30 15:05   ` Andre Przywara
2022-05-30 15:05     ` Andre Przywara
2022-06-15 16:01     ` Alexandru Elisei
2022-06-15 16:01       ` Alexandru Elisei
2022-05-25 11:23 ` [PATCH v3 kvmtool 03/13] builtin-run: Always use RAM size in bytes Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-05-25 11:23 ` [PATCH v3 kvmtool 04/13] builtin-run: Rework RAM size validation Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-05-30 17:13   ` Andre Przywara
2022-05-30 17:13     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 05/13] builtin-run: Add arch hook to validate VM configuration Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-05-25 11:23 ` [PATCH v3 kvmtool 06/13] arm/arm64: Fail if RAM size is too large for 32-bit guests Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 11:09   ` Andre Przywara
2022-06-01 11:09     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 07/13] arm/arm64: Kill the ARM_MAX_MEMORY() macro Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 11:14   ` Andre Przywara
2022-06-01 11:14     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 08/13] arm/arm64: Kill the ARM_HIMAP_MAX_MEMORY() macro Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 11:16   ` Andre Przywara
2022-06-01 11:16     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 09/13] builtin_run: Allow standard size specifiers for memory Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 13:39   ` Andre Przywara
2022-06-01 13:39     ` Andre Przywara
2022-06-01 14:17     ` Alexandru Elisei
2022-06-01 14:17       ` Alexandru Elisei
2022-06-01 16:14       ` Andre Przywara
2022-06-01 16:14         ` Andre Przywara
2022-06-01 19:39         ` Alexandru Elisei
2022-06-01 19:39           ` Alexandru Elisei
2022-06-01 19:42           ` Alexandru Elisei
2022-06-01 19:42             ` Alexandru Elisei
2022-06-01 20:13           ` Alexandru Elisei
2022-06-01 20:13             ` Alexandru Elisei
2022-06-06 10:53             ` Andre Przywara
2022-06-06 10:53               ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 10/13] kvm__arch_init: Remove hugetlbfs_path and ram_size as parameters Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 13:13   ` Andre Przywara
2022-06-01 13:13     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 11/13] arm/arm64: Consolidate RAM initialization in kvm__init_ram() Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 13:20   ` Andre Przywara
2022-06-01 13:20     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 12/13] Introduce kvm__arch_default_ram_address() Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 13:21   ` Andre Przywara
2022-06-01 13:21     ` Andre Przywara
2022-05-25 11:23 ` [PATCH v3 kvmtool 13/13] arm64: Allow the user to specify the RAM base address Alexandru Elisei
2022-05-25 11:23   ` Alexandru Elisei
2022-06-01 13:39   ` Andre Przywara
2022-06-01 13:39     ` Andre Przywara

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.