[PATCH v2] MAINTAINERS: Update my email address

2024-05-05 Thread Bin Meng
From: Bin Meng 

The old Wind River email address (bin.m...@windriver.com) is no longer
available due to an internal infrastructure change within the company.
While a new email address (bin.meng...@windriver.com) has been assigned
to me, I am unable to find a way to send this patch directly from the
new address. Presumably, the basic authentication with client submission
(SMTP AUTH) [1] has been disabled by the company's IT.

Switch to use my personal email address instead.

Signed-off-by: Bin Meng 
Signed-off-by: Bin Meng 

[1] 
https://learn.microsoft.com/en-us/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365

---

Changes in v2:
- Provide more background info for the email address change

 MAINTAINERS | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f08cc528e..d3282ee29f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -319,7 +319,7 @@ F: tests/tcg/ppc*/*
 RISC-V TCG CPUs
 M: Palmer Dabbelt 
 M: Alistair Francis 
-M: Bin Meng 
+M: Bin Meng 
 R: Weiwei Li 
 R: Daniel Henrique Barboza 
 R: Liu Zhiwei 
@@ -1602,7 +1602,7 @@ F: include/hw/riscv/opentitan.h
 F: include/hw/*/ibex_*.h
 
 Microchip PolarFire SoC Icicle Kit
-M: Bin Meng 
+M: Bin Meng 
 L: qemu-ri...@nongnu.org
 S: Supported
 F: docs/system/riscv/microchip-icicle-kit.rst
@@ -1629,7 +1629,7 @@ F: include/hw/char/shakti_uart.h
 
 SiFive Machines
 M: Alistair Francis 
-M: Bin Meng 
+M: Bin Meng 
 M: Palmer Dabbelt 
 L: qemu-ri...@nongnu.org
 S: Supported
@@ -2125,7 +2125,7 @@ F: hw/ssi/xilinx_*
 
 SD (Secure Card)
 M: Philippe Mathieu-Daudé 
-M: Bin Meng 
+M: Bin Meng 
 L: qemu-bl...@nongnu.org
 S: Odd Fixes
 F: include/hw/sd/sd*
-- 
2.34.1




[PATCH] MAINTAINERS: Update my email address

2024-04-12 Thread Bin Meng
The Wind River email address might change in the future. Use my
personal email address instead.

Signed-off-by: Bin Meng 

---

 MAINTAINERS | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index f1f6922025..50729a0985 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -332,7 +332,7 @@ F: tests/tcg/ppc*/*
 RISC-V TCG CPUs
 M: Palmer Dabbelt 
 M: Alistair Francis 
-M: Bin Meng 
+M: Bin Meng 
 R: Weiwei Li 
 R: Daniel Henrique Barboza 
 R: Liu Zhiwei 
@@ -1614,7 +1614,7 @@ F: include/hw/riscv/opentitan.h
 F: include/hw/*/ibex_*.h
 
 Microchip PolarFire SoC Icicle Kit
-M: Bin Meng 
+M: Bin Meng 
 L: qemu-ri...@nongnu.org
 S: Supported
 F: docs/system/riscv/microchip-icicle-kit.rst
@@ -1641,7 +1641,7 @@ F: include/hw/char/shakti_uart.h
 
 SiFive Machines
 M: Alistair Francis 
-M: Bin Meng 
+M: Bin Meng 
 M: Palmer Dabbelt 
 L: qemu-ri...@nongnu.org
 S: Supported
@@ -2137,7 +2137,7 @@ F: hw/ssi/xilinx_*
 
 SD (Secure Card)
 M: Philippe Mathieu-Daudé 
-M: Bin Meng 
+M: Bin Meng 
 L: qemu-bl...@nongnu.org
 S: Odd Fixes
 F: include/hw/sd/sd*
-- 
2.34.1




Re: [PATCH 3/7] scripts/nsis.py: Automatically package required DLLs of QEMU executables

2024-02-25 Thread Bin Meng
On Mon, Feb 26, 2024 at 1:37 AM Stefan Weil  wrote:
>
> Am 10.09.22 um 02:37 schrieb Bin Meng:
> > On Sat, Sep 10, 2022 at 12:49 AM Mark Cave-Ayland
> >  wrote:
> >>
> >> On 08/09/2022 14:28, Bin Meng wrote:
> >>
> >>> From: Bin Meng 
> >>>
> >>> At present packaging the required DLLs of QEMU executables is a
> >>> manual process, and error prone.
> >>>
> >>> Actually build/config-host.mak contains a GLIB_BINDIR variable
> >>> which is the directory where glib and other DLLs reside. This
> >>> works for both Windows native build and cross-build on Linux.
> >>> We can use it as the search directory for DLLs and automate
> >>> the whole DLL packaging process.
> >>>
> >>> Signed-off-by: Bin Meng 
> >>> ---
> >>>
> >>>meson.build |  1 +
> >>>scripts/nsis.py | 46 ++
> >>>2 files changed, 43 insertions(+), 4 deletions(-)
> >>>
> [...]>>> diff --git a/scripts/nsis.py b/scripts/nsis.py
> >>> index baa6ef9594..03ed7608a2 100644
> >>> --- a/scripts/nsis.py
> >>> +++ b/scripts/nsis.py
> >>> @@ -18,12 +18,36 @@ def signcode(path):
> >>>return
> >>>subprocess.run([cmd, path])
> >>>
> >>> +def find_deps(exe_or_dll, search_path, analyzed_deps):
> >>> +deps = [exe_or_dll]
> >>> +output = subprocess.check_output(["objdump", "-p", exe_or_dll], 
> >>> text=True)
>
> This fails on non x86 hosts where objdump does not know how to handle a
> Windows x86_64 exe file.

Does this command work in the MSYS2 environment on Windows Arm?

>
> >>> +output = output.split("\n")
> >>> +for line in output:
> >>> +if not line.startswith("\tDLL Name: "):
> >>> +continue
> >>> +
> >>> +dep = line.split("DLL Name: ")[1].strip()
> >>> +if dep in analyzed_deps:
> >>> +continue
> >>> +
> >>> +dll = os.path.join(search_path, dep)
> >>> +if not os.path.exists(dll):
> >>> +# assume it's a Windows provided dll, skip it
> >>> +continue
> >>> +
> >>> +analyzed_deps.add(dep)
> >>> +# locate the dll dependencies recursively
> >>> +rdeps = find_deps(dll, search_path, analyzed_deps)
> >>> +deps.extend(rdeps)
> >>> +
> >>> +return deps
> [...]
> >>
> >> FWIW I wrote a similar script a while back to help package a custom 
> >> Windows build for
> >> a client, however I used ldd instead of objdump since it provided the full 
> >> paths for
> >> DLLs installed in the msys2/mingw-w64 environment via pacman which were 
> >> outside the
> >> QEMU build tree.
> >>
> >
> > Yep, ldd also works, but only on Windows native build. objdump can
> > work on both Windows native and Linux cross builds.
>
>
> objdump fails on Linux cross builds on any non x86 host, because objdump
> typically only supports the native host architecture.
>
> Therefore I get an error on an ARM64 host (podman on Mac M1):
>
>  objdump: /tmp/tmpvae5u0qm/qemu/qemu-system-aarch64.exe: file
> format not recognized
>
> I could use x86_64-w64-mingw32-objdump to fix the cross builds, but then
> native builds might fail because they don't have x86_64-w64-mingw32-objdump.
>
> Is there a simple way how we can get the information here whether
> objdump requires a cross build prefix?

For QEMU Windows, I believe the only supported architecture is x86_64,
correct? Do we want to support (cross) building QEMU for Windows Arm?

Based on your observation, objdump on Linux cross builds on any x86
host works, but not on non x86 host.
Maybe it's a hint to ask for binutils guys to include the PE format
support for objdump Arm by default.

Regards,
Bin



[PATCH] util/cutil: Allow relocatable install with prefix /

2024-01-23 Thread Bin Meng
When configuring QEMU with --prefix=/, the generated QEMU executables
can't be relocated to other directories. Add an additional test logic
in starts_with_prefix() to handle this.

Signed-off-by: Bin Meng 

---

 util/cutils.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/util/cutils.c b/util/cutils.c
index 42364039a5..676bd757ba 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -1021,7 +1021,8 @@ static inline bool starts_with_prefix(const char *dir)
 #pragma GCC diagnostic ignored "-Warray-bounds="
 #endif
 return !memcmp(dir, CONFIG_PREFIX, prefix_len) &&
-(!dir[prefix_len] || G_IS_DIR_SEPARATOR(dir[prefix_len]));
+(!dir[prefix_len] || G_IS_DIR_SEPARATOR(dir[prefix_len]) ||
+ !strcmp(CONFIG_PREFIX, "/"));
 #pragma GCC diagnostic pop
 }
 
-- 
2.34.1




[PATCH] hw/elf_ops: Ignore loadable segments with zero size

2024-01-16 Thread Bin Meng
Some ELF files really do have segments of zero size, e.g.:

Program Headers:
  Type   Offset VirtAddr   PhysAddr
 FileSizMemSiz  Flags  Align
  RISCV_ATTRIBUT 0x25b8 0x 0x
 0x003e 0x  R  0x1
  LOAD   0x1000 0x8020 0x8020
 0x01d1 0x01d1  R E0x1000
  LOAD   0x11d1 0x802001d1 0x802001d1
 0x0e37 0x0e37  RW 0x1000
  LOAD   0x0120 0x 0x
 0x 0x 0x1000

The current logic does not check for this condition, resulting in
the incorrect assignment of 'lowaddr' as zero.

There is already a piece of codes inside the segment traversal loop
that checks for zero-sized loadable segments for not creating empty
ROM blobs. Let's move this check to the beginning of the loop to
cover both scenarios.

Signed-off-by: Bin Meng 
---

 include/hw/elf_ops.h | 75 +++-
 1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index 0a5c258fe6..f014399b50 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -427,6 +427,16 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd,
 file_size = ph->p_filesz; /* Size of the allocated data */
 data_offset = ph->p_offset; /* Offset where the data is located */
 
+/*
+ * Some ELF files really do have segments of zero size;
+ * just ignore them rather than trying to set the wrong addr,
+ * or create empty ROM blobs, because the zero-length blob can
+ * falsely trigger the overlapping-ROM-blobs check.
+ */
+if (mem_size == 0) {
+continue;
+}
+
 if (file_size > 0) {
 if (g_mapped_file_get_length(mapped_file) <
 file_size + data_offset) {
@@ -530,45 +540,38 @@ static ssize_t glue(load_elf, SZ)(const char *name, int 
fd,
 *pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
 }
 
-/* Some ELF files really do have segments of zero size;
- * just ignore them rather than trying to create empty
- * ROM blobs, because the zero-length blob can falsely
- * trigger the overlapping-ROM-blobs check.
- */
-if (mem_size != 0) {
-if (load_rom) {
-g_autofree char *label =
-g_strdup_printf("%s ELF program header segment %d",
-name, i);
-
-/*
- * rom_add_elf_program() takes its own reference to
- * 'mapped_file'.
- */
-rom_add_elf_program(label, mapped_file, data, file_size,
-mem_size, addr, as);
-} else {
-MemTxResult res;
-
-res = address_space_write(as ? as : &address_space_memory,
-  addr, MEMTXATTRS_UNSPECIFIED,
-  data, file_size);
+if (load_rom) {
+g_autofree char *label =
+g_strdup_printf("%s ELF program header segment %d",
+name, i);
+
+/*
+ * rom_add_elf_program() takes its own reference to
+ * 'mapped_file'.
+ */
+rom_add_elf_program(label, mapped_file, data, file_size,
+mem_size, addr, as);
+} else {
+MemTxResult res;
+
+res = address_space_write(as ? as : &address_space_memory,
+  addr, MEMTXATTRS_UNSPECIFIED,
+  data, file_size);
+if (res != MEMTX_OK) {
+goto fail;
+}
+/*
+ * We need to zero'ify the space that is not copied
+ * from file
+ */
+if (file_size < mem_size) {
+res = address_space_set(as ? as : &address_space_memory,
+addr + file_size, 0,
+mem_size - file_size,
+MEMTXATTRS_UNSPECIFIED);
 if (res != MEMTX_OK) {
 goto fail;
 }
-  

Re: [PATCH 3/3] tests/acpi: Update virt/SSDT.memhp

2024-01-15 Thread Bin Meng
On Mon, Jan 15, 2024 at 7:40 PM Alex Bennée  wrote:
>
> Bin Meng  writes:
>
> > The Arm dtb changes caused an address change:
> >
> >  DefinitionBlock ("", "SSDT", 1, "BOCHS ", "NVDIMM", 0x0001)
> >  {
> >  [ ... ]
> > -Name (MEMA, 0x43C8)
> > +Name (MEMA, 0x43D8)
> >  }
>
> I'm confused by why this changes. Isn't this declaring the size of a
> NVDIMM region of the memory map? Why does a DTB change affect an ACPI
> based boot?
>

I have no idea too. I suspect that's because the AllocateAlignedPages
call to allocate a 1 MiB aligned address in the BiosTableTest.c is
affected by the shrinked DTB now.

+ Laszlo who might know the root cause.

Regards,
Bin



[PATCH 1/3] hw/arm: Refactor struct arm_boot_info::get_dtb()

2024-01-14 Thread Bin Meng
At present we expect struct arm_boot_info::get_dtb() to return the
device tree pointer as well as the device tree size. However, this
is not necessary as we can get the device tree size via the device
tree header directly. Change get_dtb() signature to drop the *size
argument, and get the size by ourselves.

Signed-off-by: Bin Meng 
---

 include/hw/arm/boot.h | 8 
 hw/arm/boot.c | 3 ++-
 hw/arm/sbsa-ref.c | 3 +--
 hw/arm/virt.c | 4 +---
 hw/arm/xlnx-versal-virt.c | 4 +---
 5 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index 80c492d742..37fd1b520e 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -82,11 +82,11 @@ struct arm_boot_info {
  const struct arm_boot_info *info);
 /* if a board is able to create a dtb without a dtb file then it
  * sets get_dtb. This will only be used if no dtb file is provided
- * by the user. On success, sets *size to the length of the created
- * dtb, and returns a pointer to it. (The caller must free this memory
- * with g_free() when it has finished with it.) On failure, returns NULL.
+ * by the user. On success, returns a pointer to it. (The caller must
+ * free this memory with g_free() when it has finished with it.)
+ * On failure, returns NULL.
  */
-void *(*get_dtb)(const struct arm_boot_info *info, int *size);
+void *(*get_dtb)(const struct arm_boot_info *info);
 /* if a board needs to be able to modify a device tree provided by
  * the user it should implement this hook.
  */
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 84ea6a807a..ff1173299f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -538,11 +538,12 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 }
 g_free(filename);
 } else {
-fdt = binfo->get_dtb(binfo, &size);
+fdt = binfo->get_dtb(binfo);
 if (!fdt) {
 fprintf(stderr, "Board was unable to create a dtb blob\n");
 goto fail;
 }
+size = fdt_totalsize(fdt);
 }
 
 if (addr_limit > addr && size > (addr_limit - addr)) {
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 477dca0637..c5023871a7 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -681,12 +681,11 @@ static void create_pcie(SBSAMachineState *sms)
 create_smmu(sms, pci->bus);
 }
 
-static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+static void *sbsa_ref_dtb(const struct arm_boot_info *binfo)
 {
 const SBSAMachineState *board = container_of(binfo, SBSAMachineState,
  bootinfo);
 
-*fdt_size = board->fdt_size;
 return board->fdt;
 }
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 2793121cb4..1996fffa99 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1577,14 +1577,12 @@ static void create_secure_ram(VirtMachineState *vms,
 g_free(nodename);
 }
 
-static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+static void *machvirt_dtb(const struct arm_boot_info *binfo)
 {
 const VirtMachineState *board = container_of(binfo, VirtMachineState,
  bootinfo);
 MachineState *ms = MACHINE(board);
 
-
-*fdt_size = board->fdt_size;
 return ms->fdt;
 }
 
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 537118224f..1e043c813e 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -551,12 +551,10 @@ static void versal_virt_modify_dtb(const struct 
arm_boot_info *binfo,
 fdt_add_memory_nodes(s, fdt, binfo->ram_size);
 }
 
-static void *versal_virt_get_dtb(const struct arm_boot_info *binfo,
-  int *fdt_size)
+static void *versal_virt_get_dtb(const struct arm_boot_info *binfo)
 {
 const VersalVirt *board = container_of(binfo, VersalVirt, binfo);
 
-*fdt_size = board->fdt_size;
 return board->fdt;
 }
 
-- 
2.34.1




[PATCH 3/3] tests/acpi: Update virt/SSDT.memhp

2024-01-14 Thread Bin Meng
The Arm dtb changes caused an address change:

 DefinitionBlock ("", "SSDT", 1, "BOCHS ", "NVDIMM", 0x0001)
 {
 [ ... ]
-Name (MEMA, 0x43C8)
+Name (MEMA, 0x43D8)
 }

Signed-off-by: Bin Meng 

---

 tests/data/acpi/virt/SSDT.memhp | Bin 1817 -> 1817 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/tests/data/acpi/virt/SSDT.memhp b/tests/data/acpi/virt/SSDT.memhp
index 
fb3dcde5a10936667ad75a759b8bd444a7b19fc2..4d3ef733276bf5992da5b0bb967f6d60e243417d
 100644
GIT binary patch
delta 22
dcmbQqH

[PATCH 0/3] hw/arm: Pack the QEMU generated device tree

2024-01-14 Thread Bin Meng


By default, QEMU generates a 1 MiB sized device tree. This appears
to be unnecessary, as the actual size is much smaller than what the
DTB header claims. Let's pack it to save some room.


Bin Meng (3):
  hw/arm: Refactor struct arm_boot_info::get_dtb()
  hw/arm: Pack the QEMU generated device tree
  tests/acpi: Update virt/SSDT.memhp

 include/hw/arm/boot.h   |   8 
 hw/arm/boot.c   |  14 +-
 hw/arm/sbsa-ref.c   |   3 +--
 hw/arm/virt.c   |   4 +---
 hw/arm/xlnx-versal-virt.c   |   4 +---
 tests/data/acpi/virt/SSDT.memhp | Bin 1817 -> 1817 bytes
 6 files changed, 20 insertions(+), 13 deletions(-)

-- 
2.34.1




[PATCH 2/3] hw/arm: Pack the QEMU generated device tree

2024-01-14 Thread Bin Meng
By default QEMU generates a 1 MiB sized device tree. Let's pack it
to save some room.

Signed-off-by: Bin Meng 
---

 hw/arm/boot.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index ff1173299f..511ec10ed0 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -662,6 +662,17 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 binfo->modify_dtb(binfo, fdt);
 }
 
+/*
+ * By default QEMU generates a 1 MiB sized device tree.
+ * Let's pack it to save some room.
+ */
+if (binfo->get_dtb) {
+rc = fdt_pack(fdt);
+/* Should only fail if we've built a corrupted tree */
+g_assert(rc == 0);
+size = fdt_totalsize(fdt);
+}
+
 qemu_fdt_dumpdtb(fdt, size);
 
 /* Put the DTB into the memory map as a ROM image: this will ensure
-- 
2.34.1




Re: [PATCH] net/vmnet: Pad short Ethernet frames

2024-01-07 Thread Bin Meng
On Sun, Jan 7, 2024 at 7:19 AM William Hooper  wrote:
>
> At least on macOS 12.7.2, vmnet doesn't pad Ethernet frames, such as the
> host's ARP replies, to the minimum size (60 bytes before the frame check
> sequence) defined in IEEE Std 802.3-2022, so guests' Ethernet device
> drivers may drop them with "frame too short" errors.
>
> This patch calls eth_pad_short_frame() to add padding, as in net/tap.c
> and net/slirp.c.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2058
> Signed-off-by: William Hooper 
> ---
>  net/vmnet-common.m | 20 +---
>  1 file changed, 17 insertions(+), 3 deletions(-)
>

Reviewed-by: Bin Meng 



[PATCH] docs/system/riscv: sifive_u: Update S-mode U-Boot image build instructions

2024-01-03 Thread Bin Meng
Currently, the documentation outlines the process for building the
S-mode U-Boot image using `make menuconfig` and manual actions within
the menuconfig UI. However, this approach is fragile due to Kconfig
options potentially changing across different releases. For example,
CONFIG_OF_PRIOR_STAGE has been replaced by CONFIG_BOARD since v2022.01
release, and CONFIG_TEXT_BASE has been moved to the 'General setup'
menu from the 'Boot options' menu in v2024.01 release.

This update aims to make the S-mode U-Boot image build instructions
future-proof. It leverages the 'config' script provided in the U-Boot
source tree to edit the .config file, followed by a `make olddefconfig`.

Validated with U-Boot v2024.01 release.

Signed-off-by: Bin Meng 

---

 docs/system/riscv/sifive_u.rst | 33 -
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
index 7b166567f9..8f55ae8e31 100644
--- a/docs/system/riscv/sifive_u.rst
+++ b/docs/system/riscv/sifive_u.rst
@@ -210,7 +210,7 @@ command line options with ``qemu-system-riscv32``.
 Running U-Boot
 --
 
-U-Boot mainline v2021.07 release is tested at the time of writing. To build a
+U-Boot mainline v2024.01 release is tested at the time of writing. To build a
 U-Boot mainline bootloader that can be booted by the ``sifive_u`` machine, use
 the sifive_unleashed_defconfig with similar commands as described above for
 Linux:
@@ -325,15 +325,10 @@ configuration of U-Boot:
 
   $ export CROSS_COMPILE=riscv64-linux-
   $ make sifive_unleashed_defconfig
-  $ make menuconfig
-
-then manually select the following configuration:
-
-  * Device Tree Control ---> Provider of DTB for DT Control ---> Prior Stage 
bootloader DTB
-
-and unselect the following configuration:
-
-  * Library routines ---> Allow access to binman information in the device tree
+  $ ./scripts/config --enable OF_BOARD
+  $ ./scripts/config --disable BINMAN_FDT
+  $ ./scripts/config --disable SPL
+  $ make olddefconfig
 
 This changes U-Boot to use the QEMU generated device tree blob, and bypass
 running the U-Boot SPL stage.
@@ -352,17 +347,13 @@ It's possible to create a 32-bit U-Boot S-mode image as 
well.
 
   $ export CROSS_COMPILE=riscv64-linux-
   $ make sifive_unleashed_defconfig
-  $ make menuconfig
-
-then manually update the following configuration in U-Boot:
-
-  * Device Tree Control ---> Provider of DTB for DT Control ---> Prior Stage 
bootloader DTB
-  * RISC-V architecture ---> Base ISA ---> RV32I
-  * Boot options ---> Boot images ---> Text Base ---> 0x8040
-
-and unselect the following configuration:
-
-  * Library routines ---> Allow access to binman information in the device tree
+  $ ./scripts/config --disable ARCH_RV64I
+  $ ./scripts/config --enable ARCH_RV32I
+  $ ./scripts/config --set-val TEXT_BASE 0x8040
+  $ ./scripts/config --enable OF_BOARD
+  $ ./scripts/config --disable BINMAN_FDT
+  $ ./scripts/config --disable SPL
+  $ make olddefconfig
 
 Use the same command line options to boot the 32-bit U-Boot S-mode image:
 
-- 
2.34.1




Re: [PATCH 1/1] Leaving Migration

2024-01-02 Thread Bin Meng
On Wed, Jan 3, 2024 at 4:20 AM Juan Quintela  wrote:
>
> I am leaving Red Hat, and as part of that I am leaving Migration
> maintenarship.

maintainership?

>
> You are left in good hands with Peter and Fabiano.
>
> Thanks for all the fish.

Best wishes!

>
> Signed-off-by: Juan Quintela 
> ---
>  MAINTAINERS | 3 ---
>  .mailmap| 1 +
>  2 files changed, 1 insertion(+), 3 deletions(-)
>

Reviewed-by: Bin Meng 



[PATCH] roms/opensbi: Upgrade from v1.3.1 to v1.4

2024-01-02 Thread Bin Meng
latform: update platform_requirements.md
3632f2b lib: sbi: Add support for mconfigptr
ec0559e lib: sbi_misaligned_ldst: Fix handling of C.SWSP and C.SDSP
cbdd869 include: sbi: Change spec version to 2.0
5d0ed1b lib: sbi: simplify sanitize_domain()
c1a6987 platform: generic: thead: move to thead c9xx header to vendor specific 
postion
8e941e7 platform: generic: thead: separate implement of T-HEAD c9xx pmu
492d9b1 platform: generic: thead: separate implement of T-HEAD c9xx errata
3e21b96 platform: generic: thead: initialize PMU by default in thead generic 
platform
a140a4e lib: sbi: Correctly limit flushes to a single ASID/VMID
88ae718 platform: generic: thead: improve tlb flush errata
52fd64b platform: Uses hart count as the default size of tlb info
07f2ccd lib: utils/serial: Optimize semihosting_putc implementation
fccdf41 firmware: fw_base.S: Fix boot hart status synchronization
d1e0f7f utils/reset: Remove fdt_reset_thead
896d2c9 lib: utils/timer: Allow ACLINT MTIMER driver to setup quirks
accafb1 lib: utils/timer: mtimer: add separate T-Head C9xx CLINT mtimer 
compatible
98bc25f lib: utils/ipi: mswi: add separate T-Head C9xx CLINT mswi compatible
5b2f55d lib: sbi: separate the swap operation of domain region
3b03cdd lib: sbi: Add regions merging when sanitizing domain region
2bfdb9e platform: generic: Add Sophgo sg2042 platform support
280f7ae include: sbi: macros for mseccfg.sseed and .useed
efcac33 lib: sbi: Add Zkr in hart extensions
6e5b0cf lib: sbi: enable seed access in S-mode
6602e11 lib: sbi: change sbi_hart_features.extensions as an array
3aaed4f lib: sbi: Make console_puts/console_putc interchangeable
dc0bb19 lib: utils/serial: remove semihosting_putc
16bb930 lib: sbi: Fix PMP granularity handling in sbi_hart_map_saddr()
574b9c8 lib: sbi_pmu: avoid buffer overflow
791704c lib: utils/irqchip: Avoid redundant writes to APLIC CLRIE register
f520256 lib: sbi: Allow relaxed MMIO writes in device ipi_send() callback
b70d628 lib: sbi: Allow relaxed MMIO writes in device ipi_clear() callback
bd74931 lib: ipi: Adjust Andes PLICSW to single-bit-per-hart scheme
291403f sbi: sbi_pmu: Improve sbi_pmu_init() error handling
090fa99 lib: sbi: Add XAndesPMU in hart extensions
a48f2cf sbi: sbi_pmu: Add hw_counter_filter_mode() to pmu device
51ec60c platform: include: andes45: Add PMU related CSR defines
effd89a platform: generic: Introduce pmu_init() platform override
1b9e743 platform: andes: Add Andes custom PMU support
2e50c24 platform: andes: Enable Andes PMU for AE350
535c661 platform: rzfive: Enable Andes PMU for RZ/Five
0b3262e lib: utils: fdt_fixup: Allow preserving PMU properties
009ae4e platform: andes: Factor out is_andes() helper
0308f93 lib: utils: fdt_pmu: Make the fdt_pmu_evt_select table global variable
e19d419 lib: utils: fdt_pmu: Do not iterate over the fdt_pmu_evt_select table
d162009 docs: pmu: Add Andes PMU node example
6b9a849 lib: sbi: Remove xchg/cmpxchg implemented via lr/sc
11bf49b lib: sbi: Fix __atomic_op_bit_ord and comments
8839869 lib: sbi: Replace __atomic_op_bit_ord with __atomic intrinsics
07419ec lib: sbi: Prevent redundant sbi_ipi_process
93da66b lib: sbi_hart: Store PMP granularity as log base 2
ee72517 lib: sbi_pmu: Add PMU snapshot definitions
11a0ba5 lib: sbi_pmu: Fix the counter info function
0696810 firmware: fix section types
a25fc74 lib: sbi_hsm: Put the resume_pending hart in the interruptible hart mask
87aa306 platform: recalculate heap size to support new tlb entry number
a2e254e lib: sbi: skip wait_for_coldboot when coolboot done
6112d58 lib: utils/fdt: Allow to use reg-names when parsing ACLINT
35cba92 lib: sbi_tlb: Check tlb_range_flush_limit only once per request
a894187 lib: sbi_ipi: Do not ignore errors from sbi_ipi_send()
446fa65 lib: sbi_ipi: Process self-IPIs in sbi_ipi_send()
2707250 lib: sbi_ipi: Drop unnecessary ipi_process check
925ce14 lib: sbi: Simplify the initialization of root_hmask in sbi_domain_init
2c8be56 lib: sbi: Improve the code of privilege mode and extensions detection
056fe6f lib: sbi: Refactor the code for enable extensions in menvfg CSR
776770d lib: sbi: Using one array to define the name of extensions
3daac8f lib: sbi: Detect extensions from the ISA string in DT
416ceb3 lib: sbi_tlb: Reduce size of struct sbi_tlb_info
80169b2 platform: generic: Fine tune fw_platform_calculate_heap_size()
cdebae2 lib: utils/irqchip: Add shared MMIO region for PLIC in root domain
3284bea lib: sbi: Allow ecall handlers to directly update register state
5a57e8c lib: sbi: Remove the SBI_ETRAP error code
2b80b92 lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1
63e09ad lib: sbi: Fix shift bug in sbi_system_reset
ba29293 lib: utils/timer: mtimer: only use regname for aclint
bbd065d lib: sbi: Detect Zicntr extension only based on traps
a2b255b include: Bump-up version to 1.4

Signed-off-by: Bin Meng 

---
Please pull the complete patch from https://github.com/lbmeng/qemu
opensbi branch.

 .../opensbi-riscv32-generic-fw_dynamic.bin| Bin 135376 ->

[PATCH for 8.2.1] hw/net: cadence_gem: Fix MDIO_OP_xxx values

2024-01-02 Thread Bin Meng
Testing upstream U-Boot with 'sifive_u' machine we see:

  => dhcp
  ethernet@1009: PHY present at 0
  Could not get PHY for ethernet@1009: addr 0
  phy_connect failed

This has been working till QEMU 8.1 but broken since QEMU 8.2.

Fixes: 1b09eeb122aa ("hw/net/cadence_gem: use FIELD to describe PHYMNTNC 
register fields")
Reported-by: Heinrich Schuchardt 
Signed-off-by: Bin Meng 

---

 hw/net/cadence_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 296bba238e..472ce9c8cf 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -199,8 +199,8 @@ REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
 FIELD(PHYMNTNC, PHY_ADDR, 23, 5)
 FIELD(PHYMNTNC, OP, 28, 2)
 FIELD(PHYMNTNC, ST, 30, 2)
-#define MDIO_OP_READ0x3
-#define MDIO_OP_WRITE   0x2
+#define MDIO_OP_READ0x2
+#define MDIO_OP_WRITE   0x1
 
 REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
 REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
-- 
2.34.1




Re: [PATCH 1/1] MAINTAINERS: update mail address for Weiwei Li

2023-10-30 Thread Bin Meng
On Mon, Oct 30, 2023 at 4:17 PM Weiwei Li  wrote:
>
> My Iscas mail account will be disabled soon, change to my personal
> gmail account.
>
> Signed-off-by: Weiwei Li 
> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>

Wish you best of luck on your new journey!

Reviewed-by: Bin Meng 



Re: [PATCH] hw/ufs: Fix incorrect register fields

2023-10-10 Thread Bin Meng
On Tue, Oct 10, 2023 at 1:11 PM Jeuk Kim  wrote:
>
> From: Jeuk Kim 
>
> This patch fixes invalid ufs register fields.
> This fixes an issue reported by Bin Meng that
> caused ufs to fail over riscv.
>

Fixes: bc4e68d362ec ("hw/ufs: Initial commit for emulated
Universal-Flash-Storage")
Reported-by: Bin Meng 

> Signed-off-by: Jeuk Kim 
> ---
>  include/block/ufs.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>

Reviewed-by: Bin Meng 
Tested-by: Bin Meng 



Re: [PATCH 2/2] hw/char/riscv_htif: Fix the console syscall on big endian hosts

2023-07-21 Thread Bin Meng
On Fri, Jul 21, 2023 at 5:48 PM Thomas Huth  wrote:
>
> Values that have been read via cpu_physical_memory_read() from the
> guest's memory have to be swapped in case the host endianess differs

typo: endianness

> from the guest.
>
> Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
> Signed-off-by: Thomas Huth 
> ---
>  hw/char/riscv_htif.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
>

Reviewed-by: Bin Meng 



Re: [PATCH 1/2] hw/char/riscv_htif: Fix printing of console characters on big endian hosts

2023-07-21 Thread Bin Meng
On Fri, Jul 21, 2023 at 5:48 PM Thomas Huth  wrote:
>
> The character that should be printed is stored in the 64 bit "payload"
> variable. The code currently tries to print it by taking the address
> of the variable and passing this pointer to qemu_chr_fe_write(). However,
> this only works on little endian hosts where the least significant bits
> are stored on the lowest address. To do this in a portable way, we have
> to store the value in an uint8_t variable instead.
>
> Fixes: 5033606780 ("RISC-V HTIF Console")
> Signed-off-by: Thomas Huth 
> ---
>  hw/char/riscv_htif.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>

Reviewed-by: Bin Meng 



[PATCH] roms/opensbi: Upgrade from v1.3 to v1.3.1

2023-07-19 Thread Bin Meng
Upgrade OpenSBI from v1.3 to v1.3.1 and the pre-built bios images
which fixes the boot failure seen when using QEMU to do a direct
kernel boot with Microchip Icicle Kit board machine.

The v1.3.1 release includes the following commits:

0907de3 lib: sbi: fix comment indent
eb736a5 lib: sbi_pmu: Avoid out of bounds access
7828eeb gpio/desginware: add Synopsys DesignWare APB GPIO support
c6a3573 lib: utils: Fix sbi_hartid_to_scratch() usage in ACLINT drivers
057eb10 lib: utils/gpio: Fix RV32 compile error for designware GPIO driver

Signed-off-by: Bin Meng 

---
Please pull the complete patch from https://github.com/lbmeng/qemu
opensbi branch.

 .../opensbi-riscv32-generic-fw_dynamic.bin| Bin 135344 -> 135376 bytes
 .../opensbi-riscv64-generic-fw_dynamic.bin| Bin 138304 -> 138368 bytes
 roms/opensbi  |   2 +-
 3 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin 
b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
index 7b6c67e0ae..9a2ba3f2a4 100644
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and 
b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin 
b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
index 1b831b412c..5d4e812819 100644
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and 
b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ
diff --git a/roms/opensbi b/roms/opensbi
index 2552799a1d..057eb10b6d 16
--- a/roms/opensbi
+++ b/roms/opensbi
@@ -1 +1 @@
-Subproject commit 2552799a1df30a3dcd2321a8b75d61d06f5fb9fc
+Subproject commit 057eb10b6d523540012e6947d5c9f63e95244e94
-- 
2.34.1




Re: Boot failure after QEMU's upgrade to OpenSBI v1.3 (was Re: [PATCH for-8.2 6/7] target/riscv: add 'max' CPU type)

2023-07-19 Thread Bin Meng
Hi Anup,

On Thu, Jul 20, 2023 at 12:10 AM Anup Patel  wrote:
>
> Hi Bin,
>
> On Wed, Jul 19, 2023 at 9:15 PM Bin Meng  wrote:
> >
> > On Wed, Jul 19, 2023 at 11:22 PM Anup Patel  wrote:
> > >
> > > On Wed, Jul 19, 2023 at 3:23 PM Alistair Francis  
> > > wrote:
> > > >
> > > > On Wed, Jul 19, 2023 at 3:39 PM Anup Patel  wrote:
> > > > >
> > > > > On Wed, Jul 19, 2023 at 7:03 AM Alistair Francis 
> > > > >  wrote:
> > > > > >
> > > > > > On Sat, Jul 15, 2023 at 7:14 PM Atish Patra  
> > > > > > wrote:
> > > > > > >
> > > > > > > On Fri, Jul 14, 2023 at 5:29 AM Conor Dooley  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On Fri, Jul 14, 2023 at 11:19:34AM +0100, Conor Dooley wrote:
> > > > > > > > > On Fri, Jul 14, 2023 at 10:00:19AM +0530, Anup Patel wrote:
> > > > > > > > >
> > > > > > > > > > > > OpenSBI v1.3
> > > > > > > > > > > >_  _
> > > > > > > > > > > >   / __ \  / |  _ \_   _|
> > > > > > > > > > > >  | |  | |_ __   ___ _ __ | (___ | |_) || |
> > > > > > > > > > > >  | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
> > > > > > > > > > > >  | |__| | |_) |  __/ | | |) | |_) || |_
> > > > > > > > > > > >   \/| .__/ \___|_| |_|_/|___/_|
> > > > > > > > > > > > | |
> > > > > > > > > > > > |_|
> > > > > > > > > > > >
> > > > > > > > > > > > init_coldboot: ipi init failed (error -1009)
> > > > > > > > > > > >
> > > > > > > > > > > > Just to note, because we use our own firmware that 
> > > > > > > > > > > > vendors in OpenSBI
> > > > > > > > > > > > and compiles only a significantly cut down number of 
> > > > > > > > > > > > files from it, we
> > > > > > > > > > > > do not use the fw_dynamic etc flow on our hardware. As 
> > > > > > > > > > > > a result, we have
> > > > > > > > > > > > not tested v1.3, nor do we have any immediate plans to 
> > > > > > > > > > > > change our
> > > > > > > > > > > > platform firmware to vendor v1.3 either.
> > > > > > > > > > > >
> > > > > > > > > > > > I unless there's something obvious to you, it sounds 
> > > > > > > > > > > > like I will need to
> > > > > > > > > > > > go and bisect OpenSBI. That's a job for another day 
> > > > > > > > > > > > though, given the
> > > > > > > > > > > > time.
> > > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > The real issue is some CPU/HART DT nodes marked as disabled 
> > > > > > > > > > in the
> > > > > > > > > > DT passed to OpenSBI 1.3.
> > > > > > > > > >
> > > > > > > > > > This issue does not exist in any of the DTs generated by 
> > > > > > > > > > QEMU but some
> > > > > > > > > > of the DTs in the kernel (such as microchip and SiFive 
> > > > > > > > > > board DTs) have
> > > > > > > > > > the E-core disabled.
> > > > > > > > > >
> > > > > > > > > > I had discovered this issue in a totally different context 
> > > > > > > > > > after the OpenSBI 1.3
> > > > > > > > > > release happened. This issue is already fixed in the latest 
> > > > > > > > > > OpenSBI by the
> > > > > > > > > > following commit c6a35733b74aeff612398f274ed19a74f81d1f37 
> > > > > > > > > > ("lib: util

Re: Boot failure after QEMU's upgrade to OpenSBI v1.3 (was Re: [PATCH for-8.2 6/7] target/riscv: add 'max' CPU type)

2023-07-19 Thread Bin Meng
On Wed, Jul 19, 2023 at 11:22 PM Anup Patel  wrote:
>
> On Wed, Jul 19, 2023 at 3:23 PM Alistair Francis  wrote:
> >
> > On Wed, Jul 19, 2023 at 3:39 PM Anup Patel  wrote:
> > >
> > > On Wed, Jul 19, 2023 at 7:03 AM Alistair Francis  
> > > wrote:
> > > >
> > > > On Sat, Jul 15, 2023 at 7:14 PM Atish Patra  
> > > > wrote:
> > > > >
> > > > > On Fri, Jul 14, 2023 at 5:29 AM Conor Dooley  wrote:
> > > > > >
> > > > > > On Fri, Jul 14, 2023 at 11:19:34AM +0100, Conor Dooley wrote:
> > > > > > > On Fri, Jul 14, 2023 at 10:00:19AM +0530, Anup Patel wrote:
> > > > > > >
> > > > > > > > > > OpenSBI v1.3
> > > > > > > > > >_  _
> > > > > > > > > >   / __ \  / |  _ \_   _|
> > > > > > > > > >  | |  | |_ __   ___ _ __ | (___ | |_) || |
> > > > > > > > > >  | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
> > > > > > > > > >  | |__| | |_) |  __/ | | |) | |_) || |_
> > > > > > > > > >   \/| .__/ \___|_| |_|_/|___/_|
> > > > > > > > > > | |
> > > > > > > > > > |_|
> > > > > > > > > >
> > > > > > > > > > init_coldboot: ipi init failed (error -1009)
> > > > > > > > > >
> > > > > > > > > > Just to note, because we use our own firmware that vendors 
> > > > > > > > > > in OpenSBI
> > > > > > > > > > and compiles only a significantly cut down number of files 
> > > > > > > > > > from it, we
> > > > > > > > > > do not use the fw_dynamic etc flow on our hardware. As a 
> > > > > > > > > > result, we have
> > > > > > > > > > not tested v1.3, nor do we have any immediate plans to 
> > > > > > > > > > change our
> > > > > > > > > > platform firmware to vendor v1.3 either.
> > > > > > > > > >
> > > > > > > > > > I unless there's something obvious to you, it sounds like I 
> > > > > > > > > > will need to
> > > > > > > > > > go and bisect OpenSBI. That's a job for another day though, 
> > > > > > > > > > given the
> > > > > > > > > > time.
> > > > > > > > > >
> > > > > > > >
> > > > > > > > The real issue is some CPU/HART DT nodes marked as disabled in 
> > > > > > > > the
> > > > > > > > DT passed to OpenSBI 1.3.
> > > > > > > >
> > > > > > > > This issue does not exist in any of the DTs generated by QEMU 
> > > > > > > > but some
> > > > > > > > of the DTs in the kernel (such as microchip and SiFive board 
> > > > > > > > DTs) have
> > > > > > > > the E-core disabled.
> > > > > > > >
> > > > > > > > I had discovered this issue in a totally different context 
> > > > > > > > after the OpenSBI 1.3
> > > > > > > > release happened. This issue is already fixed in the latest 
> > > > > > > > OpenSBI by the
> > > > > > > > following commit c6a35733b74aeff612398f274ed19a74f81d1f37 
> > > > > > > > ("lib: utils:
> > > > > > > > Fix sbi_hartid_to_scratch() usage in ACLINT drivers").
> > > > > > >
> > > > > > > Great, thanks Anup! I thought I had tested tip-of-tree too, but
> > > > > > > obviously not.
> > > > > > >
> > > > > > > > I always assumed that Microchip hss.bin is the preferred BIOS 
> > > > > > > > for the
> > > > > > > > QEMU microchip-icicle-kit machine but I guess that's not true.
> > > > > > >
> > > > > > > Unfortunately the HSS has not worked in QEMU for a long time, and 
> > > > > > > while
> > > > > > > I would love to fix it, but am pretty stretched for spare time to 
> > > > > > > begin
> > > > > > > with.
> > > > > > > I usually just do direct kernel boots, which use the OpenSBI that 
> > > > > > > comes
> > > > > > > with QEMU, as I am sure you already know :)
> > > > > > >
> > > > > > > > At this point, you can either:
> > > > > > > > 1) Use latest OpenSBI on QEMU microchip-icicle-kit machine
> > > > > >
> > > > > > I forgot to reply to this point, wondering what should be done with
> > > > > > QEMU. Bumping to v1.3 in QEMU introduces a regression here, 
> > > > > > regardless
> > > > > > of whether I can go and build a fixed version of OpenSBI.
> > > > > >
> > > > > FYI: The no-map fix went in OpenSBI v1.3. Without the upgrade, any
> > > > > user using the latest kernel (> v6.4)
> > > > > may hit those random linear map related issues (in hibernation or EFI
> > > > > booting path).
> > > > >
> > > > > There are three possible scenarios:
> > > > >
> > > > > 1. Upgrade to OpenSBI v1.3: Any user of microchip-icicle-kit machine
> > > > > or sifive fu540 machine users
> > > > > may hit this issue if the device tree has the disabled hart (e core).
> > > > > 2. No upgrade to OpenSBI v1.2. Any user using hibernation or UEFI may
> > > > > have issues [1]
> > > > > 3. Include a non-release version OpenSBI in Qemu with the fix as an 
> > > > > exception.
> > > > >
> > > > > #3 probably deviates from policy and sets a bad precedent. So I am not
> > > > > advocating for it though ;)
> > > > > For both #1 & #2, the solution would be to use the latest OpenSBI in
> > > > > -bios argument instead of the stock one.
> > > > > I could be wrong but my guess is the number of users facing #2 would
> > > > > be higher than #1.
> > > >
> > > > Thanks for 

Re: [PATCH v4 0/6] net/tap: Fix QEMU frozen issue when the maximum number of file descriptors is very large

2023-07-09 Thread Bin Meng
On Wed, Jun 28, 2023 at 11:29 PM Bin Meng  wrote:
>
>
> Current codes using a brute-force traversal of all file descriptors
> do not scale on a system where the maximum number of file descriptors
> is set to a very large value (e.g.: in a Docker container of Manjaro
> distribution it is set to 1073741816). QEMU just looks frozen during
> start-up.
>
> The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
> 2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
> doesn't need to manually close the fds for child process as the proper
> O_CLOEXEC flag should have been set properly on files with its own
> codes, QEMU uses a huge number of 3rd party libraries and we don't
> trust them to reliably be using O_CLOEXEC on everything they open.
>
> Modern Linux and BSDs have the close_range() call we can use to do the
> job, and on Linux we have one more way to walk through /proc/self/fd
> to complete the task efficiently, which is what qemu_close_range()
> does, a new API we add in util/osdep.c.
>
> V1 link: 
> https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/
>
> Changes in v4:
> - add 'first > last' check logic
> - reorder the ifdefs logic
> - change i to unsigned int type
> - use qemu_strtoi() instead of atoi()
> - limit last upper value to sysconf(_SC_OPEN_MAX) - 1
> - call sysconf directly instead of using a variable
> - put fd on its own line
>
> Changes in v3:
> - fix win32 build failure
> - limit the last_fd of qemu_close_range() to sysconf(_SC_OPEN_MAX)
>
> Changes in v2:
> - new patch: "tests/tcg/cris: Fix the coding style"
> - new patch: "tests/tcg/cris: Correct the off-by-one error"
> - new patch: "util/async-teardown: Fall back to close fds one by one"
> - new patch: "util/osdep: Introduce qemu_close_range()"
> - new patch: "util/async-teardown: Use qemu_close_range() to close fds"
> - Change to use qemu_close_range() to close fds for child process efficiently
> - v1 link: 
> https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/
>
> Bin Meng (4):
>   tests/tcg/cris: Fix the coding style
>   tests/tcg/cris: Correct the off-by-one error
>   util/async-teardown: Fall back to close fds one by one
>   util/osdep: Introduce qemu_close_range()
>
> Zhangjin Wu (2):
>   util/async-teardown: Use qemu_close_range() to close fds
>   net: tap: Use qemu_close_range() to close fds
>

Ping for 8.1?



Re: [PATCH v7 0/9] net: Pad short frames for network backends

2023-07-01 Thread Bin Meng
On Sun, Jun 25, 2023 at 9:59 AM Bin Meng  wrote:
>
> The minimum Ethernet frame length is 60 bytes. For short frames with
> smaller length like ARP packets (only 42 bytes), on a real world NIC
> it can choose either padding its length to the minimum required 60
> bytes, or sending it out directly to the wire. Such behavior can be
> hardcoded or controled by a register bit. Similarly on the receive
> path, NICs can choose either dropping such short frames directly or
> handing them over to software to handle.
>
> On the other hand, for the network backends like SLiRP/TAP, they
> don't expose a way to control the short frame behavior. As of today
> they just send/receive data from/to the other end connected to them,
> which means any sized packet is acceptable. So they can send and
> receive short frames without any problem. It is observed that ARP
> packets sent from SLiRP/TAP are 42 bytes, and SLiRP/TAP just send
> these ARP packets to the other end which might be a NIC model that
> does not allow short frames to pass through.
>
> To provide better compatibility, for packets sent from QEMU network
> backends like SLiRP/TAP, we change to pad short frames before sending
> it out to the other end, if the other end does not forbid it via the
> nc->do_not_pad flag. This ensures a backend as an Ethernet sender
> does not violate the spec. But with this change, the behavior of
> dropping short frames from SLiRP/TAP interfaces in the NIC model
> cannot be emulated because it always receives a packet that is spec
> complaint. The capability of sending short frames from NIC models is
> still supported and short frames can still pass through SLiRP/TAP.
>
> This series should be able to fix the issue as reported with some
> NIC models before, that ARP requests get dropped, preventing the
> guest from becoming visible on the network. It was workarounded in
> these NIC models on the receive path, that when a short frame is
> received, it is padded up to 60 bytes.
>
> Only the first 4 patches of the v5 series [1] were applied in QEMU 6.0,
> and the reset was said to be queued for 6.1 but for some reason they
> never landed in QEMU mainline.
>
> Hopefully this series will make it for QEMU 8.1.
>
> [1] 
> https://lore.kernel.org/qemu-devel/859cd26a-feb2-ed62-98d5-764841a46...@redhat.com/
>
> Changes in v7:
> - new patch: "hw/net: ftgmac100: Drop the small packet check in the receive 
> path"
>

Ping?



[PATCH 1/2] roms/opensbi: Upgrade from v1.2 to v1.3

2023-06-30 Thread Bin Meng
e: add gpio driver and support gpio reset
4b28afc make: Add a command line option for debugging OpenSBI
e9d08bd lib: utils/i2c: Add minimal StarFive jh7110 I2C driver
568ea49 platform: starfive: add PMIC power ops in JH7110 visionfive2 board
506144f lib: serial: Cadence: Enable compatibility for cdns,uart-r1p8
1fe8dc9 lib: sbi_pmu: add callback for counter width
51951d9 lib: sbi_pmu: Implement sbi_pmu_counter_fw_read_hi
60c358e lib: sbi_pmu: Reserve space for implementation specific firmware events
548e4b4 lib: sbi_pmu: Rename fw_counter_value
b51ddff lib: sbi_pmu: Update sbi_pmu dev ops
641d2e9 lib: sbi_pmu: Use dedicated event code for platform firmware events
57d3aa3 lib: sbi_pmu: Introduce fw_counter_write_value API
c631a7d lib: sbi_pmu: Add hartid parameter PMU device ops
d56049e lib: sbi: Refactor the calls to sbi_hart_switch_mode()
e8e9ed3 lib: sbi: Set the state of a hart to START_PENDING after the hart is 
ready
c6a092c lib: sbi: Clear IPIs before init_warm_startup in non-boot harts
ed88a63 lib: sbi_scratch: Optimize the alignment code for alloc size
73ab11d lib: sbi: Fix how to check whether the domain contains fw_region
f64dfcd lib: sbi: Introduce sbi_entry_count() function
30b9e7e lib: sbi_hsm: Fix sbi_hsm_hart_start() for platform with hart hotplug
8e90259 lib: sbi_hart: clear mip csr during hart init
45ba2b2 include: Add defines for SBI CPPC extension
33caae8 lib: sbi: Implement SBI CPPC extension
91767d0 lib: sbi: Print the CPPC device name
edc9914 lib: sbi_pmu: Align the event type offset as per SBI specification
ee016a7 docs: Correct FW_JUMP_FDT_ADDR calculation example
2868f26 lib: utils: fdt_fixup: avoid buffer overrun
66fa925 lib: sbi: Optimize sbi_tlb
24dde46 lib: sbi: Optimize sbi_ipi
80078ab sbi: tlb: Simplify to tlb_process_count/tlb_process function
bf40e07 lib: sbi: Optimize sbi_tlb queue waiting
eeab500 platform: generic: andes/renesas: Add SBI EXT to check for enabling 
IOCP errata
f692289 firmware: Optimize loading relocation type
e41dbb5 firmware: Change to use positive offset to access relocation entries
bdb3c42 lib: sbi: Do not clear active_events for cycle/instret when stopping
674e019 lib: sbi: Fix counter index calculation for SBI_PMU_CFG_FLAG_SKIP_MATCH
f5dfd99 lib: sbi: Don't check SBI error range for legacy console getchar
7919530 lib: sbi: Add debug print when sbi_pmu_init fails
4e33530 lib: sbi: Remove unnecessary semicolon
6bc02de lib: sbi: Simplify sbi_ipi_process remove goto
dc1c7db lib: sbi: Simplify BITS_PER_LONG definition
f58c140 lib: sbi: Introduce register_extensions extension callback
e307ba7 lib: sbi: Narrow vendor extension range
042f0c3 lib: sbi: pmu: Remove unnecessary probe function
8b952d4 lib: sbi: Only register available extensions
767b5fc lib: sbi: Optimize probe of srst/susp
c3e31cb lib: sbi: Remove 0/1 probe implementations
33f1722 lib: sbi: Document sbi_ecall_extension members
d4c46e0 Makefile: Dereference symlinks on install
8b99a7f lib: sbi: Fix return of sbi_console_init
264d0be lib: utils: Improve fdt_serial_init
9a0bdd0 lib: utils: Improve fdt_ipi
122f226 lib: utils: Improve fdt_timer
df75e09 lib: utils/ipi: buffer overrun aclint_mswi_cold_init
bdde2ec lib: sbi: Align system suspend errors with spec
aad7a37 include: sbi_scratch: Add helper macros to access data type
5cf9a54 platform: Allow platforms to specify heap size
40d36a6 lib: sbi: Introduce simple heap allocator
2a04f70 lib: sbi: Print scratch size and usage at boot time
bbff53f lib: sbi_pmu: Use heap for per-HART PMU state
ef4542d lib: sbi: Use heap for root domain creation
66daafe lib: sbi: Use scratch space to save per-HART domain pointer
fa5ad2e lib: utils/gpio: Use heap in SiFive and StartFive GPIO drivers
903e88c lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
5a8cfcd lib: utils/ipi: Use heap in ACLINT MSWI driver
3013716 lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
7e5636a lib: utils/timer: Use heap in ACLINT MTIMER driver
3c1c972 lib: utils/fdt: Use heap in FDT domain parsing
acbd8fc lib: utils/ipi: Use scratch space to save per-HART MSWI pointer
f0516be lib: utils/timer: Use scratch space to save per-HART MTIMER pointer
b3594ac lib: utils/irqchip: Use scratch space to save per-HART PLIC pointer
1df52fa lib: utils/irqchip: Don't check hartid in imsic_update_hartid_table()
355796c lib: utils/irqchip: Use scratch space to save per-HART IMSIC pointer
524feec docs: Add OpenSBI logo and use it in the top-level README.md
932be2c README.md: Improve project copyright information
8153b26 platform/lib: Set no-map attribute on all PMP regions
d64942f firmware: Fix find hart index
27c957a lib: reset: Move fdt_reset_init into generic_early_init
8bd666a lib: sbi: check A2 register in ecall_dbcn_handler.
2552799 include: Bump-up version to 1.3

Signed-off-by: Bin Meng 
---
Please pull the complete patch from https://github.com/lbmeng/qemu
opensbi branch.

 .../opensbi-riscv32-generic-fw_dynamic.bin| Bin 123072 -> 135344 bytes
 .../opensbi-ris

[PATCH 2/2] tests/avocado: riscv: Enable 32-bit Spike OpenSBI boot testing

2023-06-30 Thread Bin Meng
The 32-bit Spike boot issue has been fixed in the OpenSBI v1.3.
Let's enable the 32-bit Spike OpenSBI boot testing.

Signed-off-by: Bin Meng 
---

 tests/avocado/riscv_opensbi.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py
index e02f0d404a..bfff9cc3c3 100644
--- a/tests/avocado/riscv_opensbi.py
+++ b/tests/avocado/riscv_opensbi.py
@@ -6,7 +6,6 @@
 # later.  See the COPYING file in the top-level directory.
 
 from avocado_qemu import QemuSystemTest
-from avocado import skip
 from avocado_qemu import wait_for_console_pattern
 
 class RiscvOpenSBI(QemuSystemTest):
@@ -21,7 +20,6 @@ def boot_opensbi(self):
 wait_for_console_pattern(self, 'Platform Name')
 wait_for_console_pattern(self, 'Boot HART MEDELEG')
 
-@skip("requires OpenSBI fix to work")
 def test_riscv32_spike(self):
 """
 :avocado: tags=arch:riscv32
-- 
2.34.1




Re: [PATCH v3 4/6] util/osdep: Introduce qemu_close_range()

2023-06-28 Thread Bin Meng

On 2023/6/19 17:22:53, "Markus Armbruster"  wrote:


Bin Meng  writes:


 This introduces a new QEMU API qemu_close_range() that closes all
 open file descriptors from first to last (included).

 This API will try a more efficient call to close_range(), or walk
 through of /proc/self/fd whenever these are possible, otherwise it
 falls back to a plain close loop.

 Co-developed-by: Zhangjin Wu 
 Signed-off-by: Bin Meng 

 ---

 Changes in v3:
 - fix win32 build failure

 Changes in v2:
 - new patch: "util/osdep: Introduce qemu_close_range()"

  include/qemu/osdep.h |  1 +
  util/osdep.c | 48 
  2 files changed, 49 insertions(+)

 diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
 index cc61b00ba9..e22434ce10 100644
 --- a/include/qemu/osdep.h
 +++ b/include/qemu/osdep.h
 @@ -560,6 +560,7 @@ int qemu_open_old(const char *name, int flags, ...);
  int qemu_open(const char *name, int flags, Error **errp);
  int qemu_create(const char *name, int flags, mode_t mode, Error **errp);
  int qemu_close(int fd);
 +int qemu_close_range(unsigned int first, unsigned int last);
  int qemu_unlink(const char *name);
  #ifndef _WIN32
  int qemu_dup_flags(int fd, int flags);
 diff --git a/util/osdep.c b/util/osdep.c
 index e996c4744a..91275e70f8 100644
 --- a/util/osdep.c
 +++ b/util/osdep.c
 @@ -30,6 +30,7 @@
  #include "qemu/mprotect.h"
  #include "qemu/hw-version.h"
  #include "monitor/monitor.h"
 +#include 

  static const char *hw_version = QEMU_HW_VERSION;

 @@ -411,6 +412,53 @@ int qemu_close(int fd)
  return close(fd);
  }

 +int qemu_close_range(unsigned int first, unsigned int last)
 +{
 +DIR *dir = NULL;
 +
 +#ifdef CONFIG_CLOSE_RANGE
 +int r = close_range(first, last, 0);


close_range(2) explains flag

   CLOSE_RANGE_UNSHARE
  Unshare  the specified file descriptors from any other processes
  before closing them, avoiding races with other  threads  sharing
  the file descriptor table.

Can anybody explain the races this avoids?


The kernel commit [1] which adds the close_range syscall says:

unshare(CLONE_FILES) should only be needed if the calling
task is multi-threaded and shares the file descriptor table with another
thread in which case two threads could race with one thread allocating 
file

descriptors and the other one closing them via close_range().





 +if (!r) {
 +/* Success, no need to try other ways. */
 +return 0;
 +}


What are the failure modes of close_range() where the other ways are
worth trying?


Added first < last check in v4 so that the technically close_range() 
should not fail.






 +#endif
 +
 +#ifdef __linux__
 +dir = opendir("/proc/self/fd");
 +#endif
 +if (!dir) {
 +/*
 + * If /proc is not mounted or /proc/self/fd is not supported,
 + * try close() from first to last.
 + */
 +for (int i = first; i <= last; i++) {
 +close(i);
 +}
 +
 +return 0;
 +}
 +
 +#ifndef _WIN32
 +/* Avoid closing the directory */
 +int dfd = dirfd(dir);


This directory contains "." "..", "0", "1", ...


 +
 +for (struct dirent *de = readdir(dir); de; de = readdir(dir)) {
 +int fd = atoi(de->d_name);


Maps "." and ".." to 0.  Unclean.

Please use qemu_strtoi(de->d_name, NULL, 10, &fd), and skip entries
where it fails.


Fixed in v4.





 +if (fd < first || fd > last) {
 +/* Exclude the fds outside the target range */
 +continue;
 +}
 +if (fd != dfd) {
 +close(fd);
 +}
 +}
 +closedir(dir);
 +#endif /* _WIN32 */
 +
 +return 0;
 +}


I'd prefer to order this from most to least preferred:

close_range()
iterate over /proc/self/fd
iterate from first to last

Unlike close_range(), qemu_close_range() returns 0 when last < first.
If we want to deviate from close_range(), we better document the
differences.

This is a generalized version of async-teardown.c's close_all_open_fd().
I'd mention this in the commit message.  Suggestion, not demand.


[1] 
https://github.com/torvalds/linux/commit/278a5fbaed89dacd04e9d052f4594ffd0e0585de


Regards,
Bin



[PATCH v4 5/6] util/async-teardown: Use qemu_close_range() to close fds

2023-06-28 Thread Bin Meng
From: Zhangjin Wu 

Based on the old close_all_open_fd() of util/async-teardown.c, a new
generic qemu_close_range() has been added in osdep.c.

Now, let's switch over to use the generic qemu_close_range().

Signed-off-by: Zhangjin Wu 
Signed-off-by: Bin Meng 

---

Changes in v4:
- call sysconf directly instead of using a variable

Changes in v3:
- limit the last_fd of qemu_close_range() to sysconf(_SC_OPEN_MAX)

Changes in v2:
- new patch: "util/async-teardown: Use qemu_close_range() to close fds"

 util/async-teardown.c | 41 +
 1 file changed, 1 insertion(+), 40 deletions(-)

diff --git a/util/async-teardown.c b/util/async-teardown.c
index 7e0177a8da..a038a255ff 100644
--- a/util/async-teardown.c
+++ b/util/async-teardown.c
@@ -29,44 +29,6 @@
 
 static pid_t the_ppid;
 
-/*
- * Close all open file descriptors.
- */
-static void close_all_open_fd(void)
-{
-struct dirent *de;
-int fd, dfd;
-DIR *dir;
-
-#ifdef CONFIG_CLOSE_RANGE
-int r = close_range(0, ~0U, 0);
-if (!r) {
-/* Success, no need to try other ways. */
-return;
-}
-#endif
-
-dir = opendir("/proc/self/fd");
-if (!dir) {
-/* If /proc is not mounted, close fds one by one. */
-int open_max = sysconf(_SC_OPEN_MAX), i;
-for (i = 0; i < open_max; i++) {
-close(i);
-}
-return;
-}
-/* Avoid closing the directory. */
-dfd = dirfd(dir);
-
-for (de = readdir(dir); de; de = readdir(dir)) {
-fd = atoi(de->d_name);
-if (fd != dfd) {
-close(fd);
-}
-}
-closedir(dir);
-}
-
 static void hup_handler(int signal)
 {
 /* Check every second if this process has been reparented. */
@@ -92,9 +54,8 @@ static int async_teardown_fn(void *arg)
 /*
  * Close all file descriptors that might have been inherited from the
  * main qemu process when doing clone, needed to make libvirt happy.
- * Not using close_range for increased compatibility with older kernels.
  */
-close_all_open_fd();
+qemu_close_range(0, sysconf(_SC_OPEN_MAX) - 1);
 
 /* Set up a handler for SIGHUP and unblock SIGHUP. */
 sigaction(SIGHUP, &sa, NULL);
-- 
2.34.1




[PATCH v4 3/6] util/async-teardown: Fall back to close fds one by one

2023-06-28 Thread Bin Meng
When opening /proc/self/fd fails, current codes just return directly,
but we can fall back to close fds one by one.

Signed-off-by: Bin Meng 

---
- feel free to drop this patch if it does not make too much sense

(no changes since v2)

Changes in v2:
- new patch: "util/async-teardown: Fall back to close fds one by one"

 util/async-teardown.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/util/async-teardown.c b/util/async-teardown.c
index 3ab19c8740..7e0177a8da 100644
--- a/util/async-teardown.c
+++ b/util/async-teardown.c
@@ -48,7 +48,11 @@ static void close_all_open_fd(void)
 
 dir = opendir("/proc/self/fd");
 if (!dir) {
-/* If /proc is not mounted, there is nothing that can be done. */
+/* If /proc is not mounted, close fds one by one. */
+int open_max = sysconf(_SC_OPEN_MAX), i;
+for (i = 0; i < open_max; i++) {
+close(i);
+}
 return;
 }
 /* Avoid closing the directory. */
-- 
2.34.1




[PATCH v4 4/6] util/osdep: Introduce qemu_close_range()

2023-06-28 Thread Bin Meng
This introduces a new QEMU API qemu_close_range() that closes all
open file descriptors from first to last (included).

This API will try a more efficient call to close_range(), or walk
through of /proc/self/fd whenever these are possible, otherwise it
falls back to a plain close loop.

Co-developed-by: Zhangjin Wu 
Signed-off-by: Bin Meng 

---

Changes in v4:
- add 'first > last' check logic
- reorder the ifdefs logic
- change i to unsigned int type
- use qemu_strtoi() instead of atoi()
- limit last upper value to sysconf(_SC_OPEN_MAX) - 1

Changes in v3:
- fix win32 build failure

Changes in v2:
- new patch: "util/osdep: Introduce qemu_close_range()"

 include/qemu/osdep.h |  1 +
 util/osdep.c | 60 
 2 files changed, 61 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index cc61b00ba9..e22434ce10 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -560,6 +560,7 @@ int qemu_open_old(const char *name, int flags, ...);
 int qemu_open(const char *name, int flags, Error **errp);
 int qemu_create(const char *name, int flags, mode_t mode, Error **errp);
 int qemu_close(int fd);
+int qemu_close_range(unsigned int first, unsigned int last);
 int qemu_unlink(const char *name);
 #ifndef _WIN32
 int qemu_dup_flags(int fd, int flags);
diff --git a/util/osdep.c b/util/osdep.c
index e996c4744a..1d8c719b3f 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -411,6 +411,66 @@ int qemu_close(int fd)
 return close(fd);
 }
 
+int qemu_close_range(unsigned int first, unsigned int last)
+{
+if (first > last) {
+errno = EINVAL;
+return -1;
+}
+
+#ifndef _WIN32
+if (last >= sysconf(_SC_OPEN_MAX)) {
+last = sysconf(_SC_OPEN_MAX) - 1;
+}
+#endif
+
+#ifdef CONFIG_CLOSE_RANGE
+int r = close_range(first, last, 0);
+if (!r) {
+/* Success, no need to try other ways */
+return 0;
+}
+#endif
+
+#ifdef __linux__
+DIR *dir = opendir("/proc/self/fd");
+if (dir) {
+/* Avoid closing the directory */
+int dfd = dirfd(dir);
+
+for (struct dirent *de = readdir(dir); de; de = readdir(dir)) {
+int fd, ret;
+
+ret = qemu_strtoi(de->d_name, NULL, 10, &fd);
+if (ret) {
+/* skip "." and ".." */
+continue;
+}
+if (fd < first || fd > last) {
+/* Exclude the fds outside the target range */
+continue;
+}
+if (fd != dfd) {
+close(fd);
+}
+}
+closedir(dir);
+
+return 0;
+}
+#endif
+
+/*
+ * If /proc is not mounted or /proc/self/fd is not supported,
+ * try close() from first to last.
+ */
+for (unsigned int i = first; i <= last; i++) {
+close(i);
+}
+
+return 0;
+}
+
 /*
  * Delete a file from the filesystem, unless the filename is /dev/fdset/...
  *
-- 
2.34.1




[PATCH v4 6/6] net: tap: Use qemu_close_range() to close fds

2023-06-28 Thread Bin Meng
From: Zhangjin Wu 

Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
is set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks frozen during
start-up.

The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
doesn't need to manually close the fds for child process as the proper
O_CLOEXEC flag should have been set properly on files with its own
codes, QEMU uses a huge number of 3rd party libraries and we don't
trust them to reliably be using O_CLOEXEC on everything they open.

Modern Linux and BSDs have the close_range() call we can use to do the
job, and on Linux we have one more way to walk through /proc/self/fd
to complete the task efficiently, which is what qemu_close_range() does.

Reported-by: Zhangjin Wu 
Co-developed-by: Bin Meng 
Signed-off-by: Zhangjin Wu 
Signed-off-by: Bin Meng 
Reviewed-by: Richard Henderson 

---

Changes in v4:
- put fd on its own line

Changes in v2:
- Change to use qemu_close_range() to close fds for child process efficiently
- v1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

 net/tap.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index 1bf085d422..9f080215f0 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -446,13 +446,13 @@ static void launch_script(const char *setup_script, const 
char *ifname,
 return;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
+unsigned int last_fd = sysconf(_SC_OPEN_MAX) - 1;
+
+/* skip stdin, stdout and stderr */
+qemu_close_range(3, fd - 1);
+/* skip the currently used fd */
+qemu_close_range(fd + 1, last_fd);
 
-for (i = 3; i < open_max; i++) {
-if (i != fd) {
-close(i);
-}
-}
 parg = args;
 *parg++ = (char *)setup_script;
 *parg++ = (char *)ifname;
@@ -536,16 +536,16 @@ static int net_bridge_run_helper(const char *helper, 
const char *bridge,
 return -1;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
+unsigned int last_fd = sysconf(_SC_OPEN_MAX) - 1;
+unsigned int fd = sv[1];
 char *fd_buf = NULL;
 char *br_buf = NULL;
 char *helper_cmd = NULL;
 
-for (i = 3; i < open_max; i++) {
-if (i != sv[1]) {
-close(i);
-}
-}
+/* skip stdin, stdout and stderr */
+qemu_close_range(3, fd - 1);
+/* skip the currently used fd */
+qemu_close_range(fd + 1, last_fd);
 
 fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
 
-- 
2.34.1




[PATCH v4 0/6] net/tap: Fix QEMU frozen issue when the maximum number of file descriptors is very large

2023-06-28 Thread Bin Meng


Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
is set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks frozen during
start-up.

The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
doesn't need to manually close the fds for child process as the proper
O_CLOEXEC flag should have been set properly on files with its own
codes, QEMU uses a huge number of 3rd party libraries and we don't
trust them to reliably be using O_CLOEXEC on everything they open.

Modern Linux and BSDs have the close_range() call we can use to do the
job, and on Linux we have one more way to walk through /proc/self/fd
to complete the task efficiently, which is what qemu_close_range()
does, a new API we add in util/osdep.c.

V1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

Changes in v4:
- add 'first > last' check logic
- reorder the ifdefs logic
- change i to unsigned int type
- use qemu_strtoi() instead of atoi()
- limit last upper value to sysconf(_SC_OPEN_MAX) - 1
- call sysconf directly instead of using a variable
- put fd on its own line

Changes in v3:
- fix win32 build failure
- limit the last_fd of qemu_close_range() to sysconf(_SC_OPEN_MAX)

Changes in v2:
- new patch: "tests/tcg/cris: Fix the coding style"
- new patch: "tests/tcg/cris: Correct the off-by-one error"
- new patch: "util/async-teardown: Fall back to close fds one by one"
- new patch: "util/osdep: Introduce qemu_close_range()"
- new patch: "util/async-teardown: Use qemu_close_range() to close fds"
- Change to use qemu_close_range() to close fds for child process efficiently
- v1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

Bin Meng (4):
  tests/tcg/cris: Fix the coding style
  tests/tcg/cris: Correct the off-by-one error
  util/async-teardown: Fall back to close fds one by one
  util/osdep: Introduce qemu_close_range()

Zhangjin Wu (2):
  util/async-teardown: Use qemu_close_range() to close fds
  net: tap: Use qemu_close_range() to close fds

 include/qemu/osdep.h|  1 +
 net/tap.c   | 24 ++--
 tests/tcg/cris/libc/check_openpf5.c | 57 +--
 util/async-teardown.c   | 37 +-
 util/osdep.c| 60 +
 5 files changed, 101 insertions(+), 78 deletions(-)

-- 
2.34.1




[PATCH v4 1/6] tests/tcg/cris: Fix the coding style

2023-06-28 Thread Bin Meng
The code style does not conform with QEMU's. Correct it so that the
upcoming commit does not trigger checkpatch warnings.

Signed-off-by: Bin Meng 
Acked-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 

---

(no changes since v2)

Changes in v2:
- new patch: "tests/tcg/cris: Fix the coding style"

 tests/tcg/cris/libc/check_openpf5.c | 57 ++---
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/tests/tcg/cris/libc/check_openpf5.c 
b/tests/tcg/cris/libc/check_openpf5.c
index 1f86ea283d..0037fbca4c 100644
--- a/tests/tcg/cris/libc/check_openpf5.c
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -13,44 +13,41 @@
 #include 
 #include 
 
-int main (int argc, char *argv[])
+int main(int argc, char *argv[])
 {
-  int i;
-  int filemax;
+int i;
+int filemax;
 
 #ifdef OPEN_MAX
-  filemax = OPEN_MAX;
+filemax = OPEN_MAX;
 #else
-  filemax = sysconf (_SC_OPEN_MAX);
+filemax = sysconf(_SC_OPEN_MAX);
 #endif
 
-  char *fn = malloc (strlen (argv[0]) + 2);
-  if (fn == NULL)
-abort ();
-  strcpy (fn, "/");
-  strcat (fn, argv[0]);
+char *fn = malloc(strlen(argv[0]) + 2);
+if (fn == NULL) {
+abort();
+}
+strcpy(fn, "/");
+strcat(fn, argv[0]);
 
-  for (i = 0; i < filemax + 1; i++)
-{
-  if (open (fn, O_RDONLY) < 0)
-   {
- /* Shouldn't happen too early.  */
- if (i < filemax - 3 - 1)
-   {
- fprintf (stderr, "i: %d\n", i);
- abort ();
-   }
- if (errno != EMFILE)
-   {
- perror ("open");
- abort ();
-   }
- goto ok;
-   }
+for (i = 0; i < filemax + 1; i++) {
+if (open(fn, O_RDONLY) < 0) {
+/* Shouldn't happen too early.  */
+if (i < filemax - 3 - 1) {
+fprintf(stderr, "i: %d\n", i);
+abort();
+}
+if (errno != EMFILE) {
+perror("open");
+abort();
+}
+goto ok;
+}
 }
-  abort ();
+abort();
 
 ok:
-  printf ("pass\n");
-  exit (0);
+printf("pass\n");
+exit(0);
 }
-- 
2.34.1




[PATCH v4 2/6] tests/tcg/cris: Correct the off-by-one error

2023-06-28 Thread Bin Meng
sysconf(_SC_OPEN_MAX) returns the maximum number of files that
a process can have open at any time, which means the fd should
not be larger than or equal to the return value.

Signed-off-by: Bin Meng 
Acked-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 

---

(no changes since v2)

Changes in v2:
- new patch: "tests/tcg/cris: Correct the off-by-one error"

 tests/tcg/cris/libc/check_openpf5.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/tcg/cris/libc/check_openpf5.c 
b/tests/tcg/cris/libc/check_openpf5.c
index 0037fbca4c..7f585c6d37 100644
--- a/tests/tcg/cris/libc/check_openpf5.c
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -31,10 +31,10 @@ int main(int argc, char *argv[])
 strcpy(fn, "/");
 strcat(fn, argv[0]);
 
-for (i = 0; i < filemax + 1; i++) {
+for (i = 0; i < filemax; i++) {
 if (open(fn, O_RDONLY) < 0) {
 /* Shouldn't happen too early.  */
-if (i < filemax - 3 - 1) {
+if (i < filemax - 3) {
 fprintf(stderr, "i: %d\n", i);
 abort();
 }
-- 
2.34.1




Re: [PATCH v3 4/6] util/osdep: Introduce qemu_close_range()

2023-06-28 Thread Bin Meng
On 2023/6/19 17:18:53, "Claudio Imbrenda"  
wrote:



On Sat, 17 Jun 2023 13:36:19 +0800
Bin Meng  wrote:


 This introduces a new QEMU API qemu_close_range() that closes all
 open file descriptors from first to last (included).

 This API will try a more efficient call to close_range(), or walk
 through of /proc/self/fd whenever these are possible, otherwise it
 falls back to a plain close loop.

 Co-developed-by: Zhangjin Wu 
 Signed-off-by: Bin Meng 

 ---

 Changes in v3:
 - fix win32 build failure

 Changes in v2:
 - new patch: "util/osdep: Introduce qemu_close_range()"

  include/qemu/osdep.h |  1 +
  util/osdep.c | 48 
  2 files changed, 49 insertions(+)

 diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
 index cc61b00ba9..e22434ce10 100644
 --- a/include/qemu/osdep.h
 +++ b/include/qemu/osdep.h
 @@ -560,6 +560,7 @@ int qemu_open_old(const char *name, int flags, ...);
  int qemu_open(const char *name, int flags, Error **errp);
  int qemu_create(const char *name, int flags, mode_t mode, Error **errp);
  int qemu_close(int fd);
 +int qemu_close_range(unsigned int first, unsigned int last);
  int qemu_unlink(const char *name);
  #ifndef _WIN32
  int qemu_dup_flags(int fd, int flags);
 diff --git a/util/osdep.c b/util/osdep.c
 index e996c4744a..91275e70f8 100644
 --- a/util/osdep.c
 +++ b/util/osdep.c
 @@ -30,6 +30,7 @@
  #include "qemu/mprotect.h"
  #include "qemu/hw-version.h"
  #include "monitor/monitor.h"
 +#include 

  static const char *hw_version = QEMU_HW_VERSION;

 @@ -411,6 +412,53 @@ int qemu_close(int fd)
  return close(fd);
  }

 +int qemu_close_range(unsigned int first, unsigned int last)
 +{
 +DIR *dir = NULL;
 +
 +#ifdef CONFIG_CLOSE_RANGE
 +int r = close_range(first, last, 0);
 +if (!r) {
 +/* Success, no need to try other ways. */
 +return 0;
 +}
 +#endif
 +
 +#ifdef __linux__
 +dir = opendir("/proc/self/fd");
 +#endif
 +if (!dir) {
 +/*
 + * If /proc is not mounted or /proc/self/fd is not supported,
 + * try close() from first to last.
 + */
 +for (int i = first; i <= last; i++) {
 +close(i);


will this compile on windows?


Yes, it will.

Regards,
Bin



Re: [PATCH v3 3/6] util/async-teardown: Fall back to close fds one by one

2023-06-25 Thread Bin Meng

On 2023/6/19 17:18:23, "Claudio Imbrenda"  wrote:


On Sat, 17 Jun 2023 13:36:18 +0800
Bin Meng  wrote:


 When opening /proc/self/fd fails, current codes just return directly,
 but we can fall back to close fds one by one.

 Signed-off-by: Bin Meng 

 ---

 (no changes since v2)

 Changes in v2:
 - new patch: "util/async-teardown: Fall back to close fds one by one"

  util/async-teardown.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

 diff --git a/util/async-teardown.c b/util/async-teardown.c
 index 3ab19c8740..7e0177a8da 100644
 --- a/util/async-teardown.c
 +++ b/util/async-teardown.c
 @@ -48,7 +48,11 @@ static void close_all_open_fd(void)

  dir = opendir("/proc/self/fd");
  if (!dir) {
 -/* If /proc is not mounted, there is nothing that can be done. */
 +/* If /proc is not mounted, close fds one by one. */
 +int open_max = sysconf(_SC_OPEN_MAX), i;
 +for (i = 0; i < open_max; i++) {
 +close(i);
 +}
  return;
  }
  /* Avoid closing the directory. */


a few patches later, you replace the whole close_all_open_fd() with a
generic version, I don't see a point in changing the code here.


I meant to do a 100% replacement, and this patch added the missing loop.




this patch is useless, just drop it


Regards,
Bin



[PATCH v7 1/9] hw/net: e1000: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

This actually reverts commit 78aeb23eded2d0b765bf9145c71f80025b568acd.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/e1000.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index aae5f0bdc0..093c2d4531 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -888,7 +888,6 @@ e1000_receive_iov(NetClientState *nc, const struct iovec 
*iov, int iovcnt)
 uint16_t vlan_special = 0;
 uint8_t vlan_status = 0;
 uint8_t min_buf[ETH_ZLEN];
-struct iovec min_iov;
 uint8_t *filter_buf = iov->iov_base;
 size_t size = iov_size(iov, iovcnt);
 size_t iov_ofs = 0;
@@ -905,15 +904,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec 
*iov, int iovcnt)
 return 0;
 }
 
-/* Pad to minimum Ethernet frame length */
-if (size < sizeof(min_buf)) {
-iov_to_buf(iov, iovcnt, 0, min_buf, size);
-memset(&min_buf[size], 0, sizeof(min_buf) - size);
-min_iov.iov_base = filter_buf = min_buf;
-min_iov.iov_len = size = sizeof(min_buf);
-iovcnt = 1;
-iov = &min_iov;
-} else if (iov->iov_len < MAXIMUM_ETHERNET_HDR_LEN) {
+if (iov->iov_len < MAXIMUM_ETHERNET_HDR_LEN) {
 /* This is very unlikely, but may happen. */
 iov_to_buf(iov, iovcnt, 0, min_buf, MAXIMUM_ETHERNET_HDR_LEN);
 filter_buf = min_buf;
-- 
2.34.1




[PATCH v7 2/9] hw/net: vmxnet3: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

This actually reverts commit 40a87c6c9b11ef9c14e0301f76abf0eb2582f08e.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/vmxnet3.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 18b9edfdb2..5dfacb1098 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -40,7 +40,6 @@
 
 #define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1
 #define VMXNET3_MSIX_BAR_SIZE 0x2000
-#define MIN_BUF_SIZE 60
 
 /* Compatibility flags for migration */
 #define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0
@@ -1977,7 +1976,6 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
 {
 VMXNET3State *s = qemu_get_nic_opaque(nc);
 size_t bytes_indicated;
-uint8_t min_buf[MIN_BUF_SIZE];
 
 if (!vmxnet3_can_receive(nc)) {
 VMW_PKPRN("Cannot receive now");
@@ -1990,14 +1988,6 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
 size -= sizeof(struct virtio_net_hdr);
 }
 
-/* Pad to minimum Ethernet frame length */
-if (size < sizeof(min_buf)) {
-memcpy(min_buf, buf, size);
-memset(&min_buf[size], 0, sizeof(min_buf) - size);
-buf = min_buf;
-size = sizeof(min_buf);
-}
-
 net_rx_pkt_set_packet_type(s->rx_pkt,
 get_eth_packet_type(PKT_GET_ETH_HDR(buf)));
 
-- 
2.34.1




[PATCH v7 8/9] hw/net: sunhme: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/sunhme.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index 1f3d8011ae..391d26fb82 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -714,8 +714,6 @@ static inline void sunhme_set_rx_ring_nr(SunHMEState *s, 
int i)
 s->erxregs[HME_ERXI_RING >> 2] = ring;
 }
 
-#define MIN_BUF_SIZE 60
-
 static ssize_t sunhme_receive(NetClientState *nc, const uint8_t *buf,
   size_t size)
 {
@@ -724,7 +722,6 @@ static ssize_t sunhme_receive(NetClientState *nc, const 
uint8_t *buf,
 dma_addr_t rb, addr;
 uint32_t intstatus, status, buffer, buffersize, sum;
 uint16_t csum;
-uint8_t buf1[60];
 int nr, cr, len, rxoffset, csum_offset;
 
 trace_sunhme_rx_incoming(size);
@@ -775,14 +772,6 @@ static ssize_t sunhme_receive(NetClientState *nc, const 
uint8_t *buf,
 
 trace_sunhme_rx_filter_accept();
 
-/* If too small buffer, then expand it */
-if (size < MIN_BUF_SIZE) {
-memcpy(buf1, buf, size);
-memset(buf1 + size, 0, MIN_BUF_SIZE - size);
-buf = buf1;
-size = MIN_BUF_SIZE;
-}
-
 rb = s->erxregs[HME_ERXI_RING >> 2] & HME_ERXI_RING_ADDR;
 nr = sunhme_get_rx_ring_count(s);
 cr = sunhme_get_rx_ring_nr(s);
-- 
2.34.1




[PATCH v7 6/9] hw/net: rtl8139: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/rtl8139.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 5f1a4d359b..b4df75b2c9 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -826,7 +826,6 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, const 
uint8_t *buf, size_t
 
 uint32_t packet_header = 0;
 
-uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];
 static const uint8_t broadcast_macaddr[6] =
 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
@@ -938,17 +937,6 @@ static ssize_t rtl8139_do_receive(NetClientState *nc, 
const uint8_t *buf, size_t
 }
 }
 
-/* if too small buffer, then expand it
- * Include some tailroom in case a vlan tag is later removed. */
-if (size < MIN_BUF_SIZE + VLAN_HLEN) {
-memcpy(buf1, buf, size);
-memset(buf1 + size, 0, MIN_BUF_SIZE + VLAN_HLEN - size);
-buf = buf1;
-if (size < MIN_BUF_SIZE) {
-size = MIN_BUF_SIZE;
-}
-}
-
 if (rtl8139_cp_receiver_enabled(s))
 {
 if (!rtl8139_cp_rx_valid(s)) {
-- 
2.34.1




[PATCH v7 9/9] hw/net: ftgmac100: Drop the small packet check in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, the small packet check logic in the receive
path is no longer needed.

Suggested-by: Cédric Le Goater 
Signed-off-by: Bin Meng 

---

Changes in v7:
- new patch: "hw/net: ftgmac100: Drop the small packet check in the receive 
path"

 hw/net/ftgmac100.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index d3bf14be53..702b001be2 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -968,14 +968,6 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const 
uint8_t *buf,
 return -1;
 }
 
-/* TODO : Pad to minimum Ethernet frame length */
-/* handle small packets.  */
-if (size < 10) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: dropped frame of %zd bytes\n",
-  __func__, size);
-return size;
-}
-
 if (!ftgmac100_filter(s, buf, size)) {
 return size;
 }
-- 
2.34.1




[PATCH v7 4/9] hw/net: ne2000: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/ne2000.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 3f31d04efb..d79c884d50 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -167,15 +167,12 @@ static int ne2000_buffer_full(NE2000State *s)
 return 0;
 }
 
-#define MIN_BUF_SIZE 60
-
 ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
 {
 NE2000State *s = qemu_get_nic_opaque(nc);
 size_t size = size_;
 uint8_t *p;
 unsigned int total_len, next, avail, len, index, mcast_idx;
-uint8_t buf1[60];
 static const uint8_t broadcast_macaddr[6] =
 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
@@ -213,15 +210,6 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t 
*buf, size_t size_)
 }
 }
 
-
-/* if too small buffer, then expand it */
-if (size < MIN_BUF_SIZE) {
-memcpy(buf1, buf, size);
-memset(buf1 + size, 0, MIN_BUF_SIZE - size);
-buf = buf1;
-size = MIN_BUF_SIZE;
-}
-
 index = s->curpag << 8;
 if (index >= NE2000_PMEM_END) {
 index = s->start;
-- 
2.34.1




[PATCH v7 5/9] hw/net: pcnet: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/pcnet.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index d456094575..02828ae716 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -987,7 +987,6 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t 
*buf, size_t size_)
 {
 PCNetState *s = qemu_get_nic_opaque(nc);
 int is_padr = 0, is_bcast = 0, is_ladr = 0;
-uint8_t buf1[60];
 int remaining;
 int crc_err = 0;
 size_t size = size_;
@@ -1000,14 +999,6 @@ ssize_t pcnet_receive(NetClientState *nc, const uint8_t 
*buf, size_t size_)
 printf("pcnet_receive size=%zu\n", size);
 #endif
 
-/* if too small buffer, then expand it */
-if (size < MIN_BUF_SIZE) {
-memcpy(buf1, buf, size);
-memset(buf1 + size, 0, MIN_BUF_SIZE - size);
-buf = buf1;
-size = MIN_BUF_SIZE;
-}
-
 if (CSR_PROM(s)
 || (is_padr=padr_match(s, buf, size))
 || (is_bcast=padr_bcast(s, buf, size))
-- 
2.34.1




[PATCH v7 0/9] net: Pad short frames for network backends

2023-06-24 Thread Bin Meng
The minimum Ethernet frame length is 60 bytes. For short frames with
smaller length like ARP packets (only 42 bytes), on a real world NIC
it can choose either padding its length to the minimum required 60
bytes, or sending it out directly to the wire. Such behavior can be
hardcoded or controled by a register bit. Similarly on the receive
path, NICs can choose either dropping such short frames directly or
handing them over to software to handle.

On the other hand, for the network backends like SLiRP/TAP, they
don't expose a way to control the short frame behavior. As of today
they just send/receive data from/to the other end connected to them,
which means any sized packet is acceptable. So they can send and
receive short frames without any problem. It is observed that ARP
packets sent from SLiRP/TAP are 42 bytes, and SLiRP/TAP just send
these ARP packets to the other end which might be a NIC model that
does not allow short frames to pass through.

To provide better compatibility, for packets sent from QEMU network
backends like SLiRP/TAP, we change to pad short frames before sending
it out to the other end, if the other end does not forbid it via the
nc->do_not_pad flag. This ensures a backend as an Ethernet sender
does not violate the spec. But with this change, the behavior of
dropping short frames from SLiRP/TAP interfaces in the NIC model
cannot be emulated because it always receives a packet that is spec
complaint. The capability of sending short frames from NIC models is
still supported and short frames can still pass through SLiRP/TAP.

This series should be able to fix the issue as reported with some
NIC models before, that ARP requests get dropped, preventing the
guest from becoming visible on the network. It was workarounded in
these NIC models on the receive path, that when a short frame is
received, it is padded up to 60 bytes.

Only the first 4 patches of the v5 series [1] were applied in QEMU 6.0,
and the reset was said to be queued for 6.1 but for some reason they
never landed in QEMU mainline.

Hopefully this series will make it for QEMU 8.1.

[1] 
https://lore.kernel.org/qemu-devel/859cd26a-feb2-ed62-98d5-764841a46...@redhat.com/

Changes in v7:
- new patch: "hw/net: ftgmac100: Drop the small packet check in the receive 
path"

Bin Meng (9):
  hw/net: e1000: Remove the logic of padding short frames in the receive
path
  hw/net: vmxnet3: Remove the logic of padding short frames in the
receive path
  hw/net: i82596: Remove the logic of padding short frames in the
receive path
  hw/net: ne2000: Remove the logic of padding short frames in the
receive path
  hw/net: pcnet: Remove the logic of padding short frames in the receive
path
  hw/net: rtl8139: Remove the logic of padding short frames in the
receive path
  hw/net: sungem: Remove the logic of padding short frames in the
receive path
  hw/net: sunhme: Remove the logic of padding short frames in the
receive path
  hw/net: ftgmac100: Drop the small packet check in the receive path

 hw/net/e1000.c | 11 +--
 hw/net/ftgmac100.c |  8 
 hw/net/i82596.c| 18 --
 hw/net/ne2000.c| 12 
 hw/net/pcnet.c |  9 -
 hw/net/rtl8139.c   | 12 
 hw/net/sungem.c| 14 --
 hw/net/sunhme.c| 11 ---
 hw/net/vmxnet3.c   | 10 --
 9 files changed, 1 insertion(+), 104 deletions(-)

-- 
2.34.1




[PATCH v7 3/9] hw/net: i82596: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/i82596.c | 18 --
 1 file changed, 18 deletions(-)

diff --git a/hw/net/i82596.c b/hw/net/i82596.c
index ec21e2699a..ab26f8bea1 100644
--- a/hw/net/i82596.c
+++ b/hw/net/i82596.c
@@ -72,10 +72,6 @@ enum commands {
 #define I596_EOF0x8000
 #define SIZE_MASK   0x3fff
 
-#define ETHER_TYPE_LEN 2
-#define VLAN_TCI_LEN 2
-#define VLAN_HLEN (ETHER_TYPE_LEN + VLAN_TCI_LEN)
-
 /* various flags in the chip config registers */
 #define I596_PREFETCH   (s->config[0] & 0x80)
 #define I596_PROMISC(s->config[8] & 0x01)
@@ -488,8 +484,6 @@ bool i82596_can_receive(NetClientState *nc)
 return true;
 }
 
-#define MIN_BUF_SIZE 60
-
 ssize_t i82596_receive(NetClientState *nc, const uint8_t *buf, size_t sz)
 {
 I82596State *s = qemu_get_nic_opaque(nc);
@@ -500,7 +494,6 @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t 
*buf, size_t sz)
 size_t bufsz = sz; /* length of data in buf */
 uint32_t crc;
 uint8_t *crc_ptr;
-uint8_t buf1[MIN_BUF_SIZE + VLAN_HLEN];
 static const uint8_t broadcast_macaddr[6] = {
 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
@@ -583,17 +576,6 @@ ssize_t i82596_receive(NetClientState *nc, const uint8_t 
*buf, size_t sz)
 }
 }
 
-/* if too small buffer, then expand it */
-if (len < MIN_BUF_SIZE + VLAN_HLEN) {
-memcpy(buf1, buf, len);
-memset(buf1 + len, 0, MIN_BUF_SIZE + VLAN_HLEN - len);
-buf = buf1;
-if (len < MIN_BUF_SIZE) {
-len = MIN_BUF_SIZE;
-}
-bufsz = len;
-}
-
 /* Calculate the ethernet checksum (4 bytes) */
 len += 4;
 crc = cpu_to_be32(crc32(~0, buf, sz));
-- 
2.34.1




[PATCH v7 7/9] hw/net: sungem: Remove the logic of padding short frames in the receive path

2023-06-24 Thread Bin Meng
Now that we have implemented unified short frames padding in the
QEMU networking codes, remove the same logic in the NIC codes.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 hw/net/sungem.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/hw/net/sungem.c b/hw/net/sungem.c
index eb01520790..103376c133 100644
--- a/hw/net/sungem.c
+++ b/hw/net/sungem.c
@@ -550,7 +550,6 @@ static ssize_t sungem_receive(NetClientState *nc, const 
uint8_t *buf,
 PCIDevice *d = PCI_DEVICE(s);
 uint32_t mac_crc, done, kick, max_fsize;
 uint32_t fcs_size, ints, rxdma_cfg, rxmac_cfg, csum, coff;
-uint8_t smallbuf[60];
 struct gem_rxd desc;
 uint64_t dbase, baddr;
 unsigned int rx_cond;
@@ -584,19 +583,6 @@ static ssize_t sungem_receive(NetClientState *nc, const 
uint8_t *buf,
 return size;
 }
 
-/* We don't drop too small frames since we get them in qemu, we pad
- * them instead. We should probably use the min frame size register
- * but I don't want to use a variable size staging buffer and I
- * know both MacOS and Linux use the default 64 anyway. We use 60
- * here to account for the non-existent FCS.
- */
-if (size < 60) {
-memcpy(smallbuf, buf, size);
-memset(&smallbuf[size], 0, 60 - size);
-buf = smallbuf;
-size = 60;
-}
-
 /* Get MAC crc */
 mac_crc = net_crc32_le(buf, ETH_ALEN);
 
-- 
2.34.1




[PATCH v3 5/6] util/async-teardown: Use qemu_close_range() to close fds

2023-06-16 Thread Bin Meng
From: Zhangjin Wu 

Based on the old close_all_open_fd() of util/async-teardown.c, a new
generic qemu_close_range() has been added in osdep.c.

Now, let's switch over to use the generic qemu_close_range().

Signed-off-by: Zhangjin Wu 
Signed-off-by: Bin Meng 

---

Changes in v3:
- limit the last_fd of qemu_close_range() to sysconf(_SC_OPEN_MAX)

Changes in v2:
- new patch: "util/async-teardown: Use qemu_close_range() to close fds"

 util/async-teardown.c | 42 ++
 1 file changed, 2 insertions(+), 40 deletions(-)

diff --git a/util/async-teardown.c b/util/async-teardown.c
index 7e0177a8da..e102912f3f 100644
--- a/util/async-teardown.c
+++ b/util/async-teardown.c
@@ -29,44 +29,6 @@
 
 static pid_t the_ppid;
 
-/*
- * Close all open file descriptors.
- */
-static void close_all_open_fd(void)
-{
-struct dirent *de;
-int fd, dfd;
-DIR *dir;
-
-#ifdef CONFIG_CLOSE_RANGE
-int r = close_range(0, ~0U, 0);
-if (!r) {
-/* Success, no need to try other ways. */
-return;
-}
-#endif
-
-dir = opendir("/proc/self/fd");
-if (!dir) {
-/* If /proc is not mounted, close fds one by one. */
-int open_max = sysconf(_SC_OPEN_MAX), i;
-for (i = 0; i < open_max; i++) {
-close(i);
-}
-return;
-}
-/* Avoid closing the directory. */
-dfd = dirfd(dir);
-
-for (de = readdir(dir); de; de = readdir(dir)) {
-fd = atoi(de->d_name);
-if (fd != dfd) {
-close(fd);
-}
-}
-closedir(dir);
-}
-
 static void hup_handler(int signal)
 {
 /* Check every second if this process has been reparented. */
@@ -84,6 +46,7 @@ static int async_teardown_fn(void *arg)
 struct sigaction sa = { .sa_handler = hup_handler };
 sigset_t hup_signal;
 char name[16];
+int open_max = sysconf(_SC_OPEN_MAX);
 
 /* Set a meaningful name for this process. */
 snprintf(name, 16, "cleanup/%d", the_ppid);
@@ -92,9 +55,8 @@ static int async_teardown_fn(void *arg)
 /*
  * Close all file descriptors that might have been inherited from the
  * main qemu process when doing clone, needed to make libvirt happy.
- * Not using close_range for increased compatibility with older kernels.
  */
-close_all_open_fd();
+qemu_close_range(0, open_max - 1);
 
 /* Set up a handler for SIGHUP and unblock SIGHUP. */
 sigaction(SIGHUP, &sa, NULL);
-- 
2.34.1




[PATCH v3 0/6] net/tap: Fix QEMU frozen issue when the maximum number of file descriptors is very large

2023-06-16 Thread Bin Meng


Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
is set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks frozen during
start-up.

The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
doesn't need to manually close the fds for child process as the proper
O_CLOEXEC flag should have been set properly on files with its own
codes, QEMU uses a huge number of 3rd party libraries and we don't
trust them to reliably be using O_CLOEXEC on everything they open.

Modern Linux and BSDs have the close_range() call we can use to do the
job, and on Linux we have one more way to walk through /proc/self/fd
to complete the task efficiently, which is what qemu_close_range()
does, a new API we add in util/osdep.c.

V1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

Changes in v3:
- fix win32 build failure
- limit the last_fd of qemu_close_range() to sysconf(_SC_OPEN_MAX)

Changes in v2:
- new patch: "tests/tcg/cris: Fix the coding style"
- new patch: "tests/tcg/cris: Correct the off-by-one error"
- new patch: "util/async-teardown: Fall back to close fds one by one"
- new patch: "util/osdep: Introduce qemu_close_range()"
- new patch: "util/async-teardown: Use qemu_close_range() to close fds"
- Change to use qemu_close_range() to close fds for child process efficiently
- v1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

Bin Meng (4):
  tests/tcg/cris: Fix the coding style
  tests/tcg/cris: Correct the off-by-one error
  util/async-teardown: Fall back to close fds one by one
  util/osdep: Introduce qemu_close_range()

Zhangjin Wu (2):
  util/async-teardown: Use qemu_close_range() to close fds
  net: tap: Use qemu_close_range() to close fds

 include/qemu/osdep.h|  1 +
 net/tap.c   | 23 ++--
 tests/tcg/cris/libc/check_openpf5.c | 57 ++---
 util/async-teardown.c   | 38 +--
 util/osdep.c| 48 
 5 files changed, 89 insertions(+), 78 deletions(-)

-- 
2.34.1




[PATCH v3 4/6] util/osdep: Introduce qemu_close_range()

2023-06-16 Thread Bin Meng
This introduces a new QEMU API qemu_close_range() that closes all
open file descriptors from first to last (included).

This API will try a more efficient call to close_range(), or walk
through of /proc/self/fd whenever these are possible, otherwise it
falls back to a plain close loop.

Co-developed-by: Zhangjin Wu 
Signed-off-by: Bin Meng 

---

Changes in v3:
- fix win32 build failure

Changes in v2:
- new patch: "util/osdep: Introduce qemu_close_range()"

 include/qemu/osdep.h |  1 +
 util/osdep.c | 48 
 2 files changed, 49 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index cc61b00ba9..e22434ce10 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -560,6 +560,7 @@ int qemu_open_old(const char *name, int flags, ...);
 int qemu_open(const char *name, int flags, Error **errp);
 int qemu_create(const char *name, int flags, mode_t mode, Error **errp);
 int qemu_close(int fd);
+int qemu_close_range(unsigned int first, unsigned int last);
 int qemu_unlink(const char *name);
 #ifndef _WIN32
 int qemu_dup_flags(int fd, int flags);
diff --git a/util/osdep.c b/util/osdep.c
index e996c4744a..91275e70f8 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -30,6 +30,7 @@
 #include "qemu/mprotect.h"
 #include "qemu/hw-version.h"
 #include "monitor/monitor.h"
+#include 
 
 static const char *hw_version = QEMU_HW_VERSION;
 
@@ -411,6 +412,53 @@ int qemu_close(int fd)
 return close(fd);
 }
 
+int qemu_close_range(unsigned int first, unsigned int last)
+{
+DIR *dir = NULL;
+
+#ifdef CONFIG_CLOSE_RANGE
+int r = close_range(first, last, 0);
+if (!r) {
+/* Success, no need to try other ways. */
+return 0;
+}
+#endif
+
+#ifdef __linux__
+dir = opendir("/proc/self/fd");
+#endif
+if (!dir) {
+/*
+ * If /proc is not mounted or /proc/self/fd is not supported,
+ * try close() from first to last.
+ */
+for (int i = first; i <= last; i++) {
+close(i);
+}
+
+return 0;
+}
+
+#ifndef _WIN32
+/* Avoid closing the directory */
+int dfd = dirfd(dir);
+
+for (struct dirent *de = readdir(dir); de; de = readdir(dir)) {
+int fd = atoi(de->d_name);
+if (fd < first || fd > last) {
+/* Exclude the fds outside the target range */
+continue;
+}
+if (fd != dfd) {
+close(fd);
+}
+}
+closedir(dir);
+#endif /* _WIN32 */
+
+return 0;
+}
+
 /*
  * Delete a file from the filesystem, unless the filename is /dev/fdset/...
  *
-- 
2.34.1




[PATCH v3 6/6] net: tap: Use qemu_close_range() to close fds

2023-06-16 Thread Bin Meng
From: Zhangjin Wu 

Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
is set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks frozen during
start-up.

The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
doesn't need to manually close the fds for child process as the proper
O_CLOEXEC flag should have been set properly on files with its own
codes, QEMU uses a huge number of 3rd party libraries and we don't
trust them to reliably be using O_CLOEXEC on everything they open.

Modern Linux and BSDs have the close_range() call we can use to do the
job, and on Linux we have one more way to walk through /proc/self/fd
to complete the task efficiently, which is what qemu_close_range() does.

Reported-by: Zhangjin Wu 
Co-developed-by: Bin Meng 
Signed-off-by: Zhangjin Wu 
Signed-off-by: Bin Meng 

---

(no changes since v2)

Changes in v2:
- Change to use qemu_close_range() to close fds for child process efficiently
- v1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

 net/tap.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index 1bf085d422..d482fabdff 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -446,13 +446,13 @@ static void launch_script(const char *setup_script, const 
char *ifname,
 return;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
+unsigned int last_fd = sysconf(_SC_OPEN_MAX) - 1;
+
+/* skip stdin, stdout and stderr */
+qemu_close_range(3, fd - 1);
+/* skip the currently used fd */
+qemu_close_range(fd + 1, last_fd);
 
-for (i = 3; i < open_max; i++) {
-if (i != fd) {
-close(i);
-}
-}
 parg = args;
 *parg++ = (char *)setup_script;
 *parg++ = (char *)ifname;
@@ -536,16 +536,15 @@ static int net_bridge_run_helper(const char *helper, 
const char *bridge,
 return -1;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
+unsigned int last_fd = sysconf(_SC_OPEN_MAX) - 1, fd = sv[1];
 char *fd_buf = NULL;
 char *br_buf = NULL;
 char *helper_cmd = NULL;
 
-for (i = 3; i < open_max; i++) {
-if (i != sv[1]) {
-close(i);
-}
-}
+/* skip stdin, stdout and stderr */
+qemu_close_range(3, fd - 1);
+/* skip the currently used fd */
+qemu_close_range(fd + 1, last_fd);
 
 fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
 
-- 
2.34.1




[PATCH v3 3/6] util/async-teardown: Fall back to close fds one by one

2023-06-16 Thread Bin Meng
When opening /proc/self/fd fails, current codes just return directly,
but we can fall back to close fds one by one.

Signed-off-by: Bin Meng 

---

(no changes since v2)

Changes in v2:
- new patch: "util/async-teardown: Fall back to close fds one by one"

 util/async-teardown.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/util/async-teardown.c b/util/async-teardown.c
index 3ab19c8740..7e0177a8da 100644
--- a/util/async-teardown.c
+++ b/util/async-teardown.c
@@ -48,7 +48,11 @@ static void close_all_open_fd(void)
 
 dir = opendir("/proc/self/fd");
 if (!dir) {
-/* If /proc is not mounted, there is nothing that can be done. */
+/* If /proc is not mounted, close fds one by one. */
+int open_max = sysconf(_SC_OPEN_MAX), i;
+for (i = 0; i < open_max; i++) {
+close(i);
+}
 return;
 }
 /* Avoid closing the directory. */
-- 
2.34.1




[PATCH v3 2/6] tests/tcg/cris: Correct the off-by-one error

2023-06-16 Thread Bin Meng
sysconf(_SC_OPEN_MAX) returns the maximum number of files that
a process can have open at any time, which means the fd should
not be larger than or equal to the return value.

Signed-off-by: Bin Meng 

---

(no changes since v2)

Changes in v2:
- new patch: "tests/tcg/cris: Correct the off-by-one error"

 tests/tcg/cris/libc/check_openpf5.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/tcg/cris/libc/check_openpf5.c 
b/tests/tcg/cris/libc/check_openpf5.c
index 0037fbca4c..7f585c6d37 100644
--- a/tests/tcg/cris/libc/check_openpf5.c
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -31,10 +31,10 @@ int main(int argc, char *argv[])
 strcpy(fn, "/");
 strcat(fn, argv[0]);
 
-for (i = 0; i < filemax + 1; i++) {
+for (i = 0; i < filemax; i++) {
 if (open(fn, O_RDONLY) < 0) {
 /* Shouldn't happen too early.  */
-if (i < filemax - 3 - 1) {
+if (i < filemax - 3) {
 fprintf(stderr, "i: %d\n", i);
 abort();
 }
-- 
2.34.1




[PATCH v3 1/6] tests/tcg/cris: Fix the coding style

2023-06-16 Thread Bin Meng
The code style does not conform with QEMU's. Correct it so that the
upcoming commit does not trigger checkpatch warnings.

Signed-off-by: Bin Meng 

---

(no changes since v2)

Changes in v2:
- new patch: "tests/tcg/cris: Fix the coding style"

 tests/tcg/cris/libc/check_openpf5.c | 57 ++---
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/tests/tcg/cris/libc/check_openpf5.c 
b/tests/tcg/cris/libc/check_openpf5.c
index 1f86ea283d..0037fbca4c 100644
--- a/tests/tcg/cris/libc/check_openpf5.c
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -13,44 +13,41 @@
 #include 
 #include 
 
-int main (int argc, char *argv[])
+int main(int argc, char *argv[])
 {
-  int i;
-  int filemax;
+int i;
+int filemax;
 
 #ifdef OPEN_MAX
-  filemax = OPEN_MAX;
+filemax = OPEN_MAX;
 #else
-  filemax = sysconf (_SC_OPEN_MAX);
+filemax = sysconf(_SC_OPEN_MAX);
 #endif
 
-  char *fn = malloc (strlen (argv[0]) + 2);
-  if (fn == NULL)
-abort ();
-  strcpy (fn, "/");
-  strcat (fn, argv[0]);
+char *fn = malloc(strlen(argv[0]) + 2);
+if (fn == NULL) {
+abort();
+}
+strcpy(fn, "/");
+strcat(fn, argv[0]);
 
-  for (i = 0; i < filemax + 1; i++)
-{
-  if (open (fn, O_RDONLY) < 0)
-   {
- /* Shouldn't happen too early.  */
- if (i < filemax - 3 - 1)
-   {
- fprintf (stderr, "i: %d\n", i);
- abort ();
-   }
- if (errno != EMFILE)
-   {
- perror ("open");
- abort ();
-   }
- goto ok;
-   }
+for (i = 0; i < filemax + 1; i++) {
+if (open(fn, O_RDONLY) < 0) {
+/* Shouldn't happen too early.  */
+if (i < filemax - 3 - 1) {
+fprintf(stderr, "i: %d\n", i);
+abort();
+}
+if (errno != EMFILE) {
+perror("open");
+abort();
+}
+goto ok;
+}
 }
-  abort ();
+abort();
 
 ok:
-  printf ("pass\n");
-  exit (0);
+printf("pass\n");
+exit(0);
 }
-- 
2.34.1





[PATCH v2 5/6] util/async-teardown: Use qemu_close_range() to close fds

2023-06-16 Thread Bin Meng
From: Zhangjin Wu 

Based on the old close_all_open_fd() of util/async-teardown.c, a new
generic qemu_close_range() has been added in osdep.c.

Now, let's switch over to use the generic qemu_close_range().

Signed-off-by: Zhangjin Wu 
Signed-off-by: Bin Meng 
---

(no changes since v1)

 util/async-teardown.c | 41 +
 1 file changed, 1 insertion(+), 40 deletions(-)

diff --git a/util/async-teardown.c b/util/async-teardown.c
index 7e0177a8da..200ec05101 100644
--- a/util/async-teardown.c
+++ b/util/async-teardown.c
@@ -29,44 +29,6 @@
 
 static pid_t the_ppid;
 
-/*
- * Close all open file descriptors.
- */
-static void close_all_open_fd(void)
-{
-struct dirent *de;
-int fd, dfd;
-DIR *dir;
-
-#ifdef CONFIG_CLOSE_RANGE
-int r = close_range(0, ~0U, 0);
-if (!r) {
-/* Success, no need to try other ways. */
-return;
-}
-#endif
-
-dir = opendir("/proc/self/fd");
-if (!dir) {
-/* If /proc is not mounted, close fds one by one. */
-int open_max = sysconf(_SC_OPEN_MAX), i;
-for (i = 0; i < open_max; i++) {
-close(i);
-}
-return;
-}
-/* Avoid closing the directory. */
-dfd = dirfd(dir);
-
-for (de = readdir(dir); de; de = readdir(dir)) {
-fd = atoi(de->d_name);
-if (fd != dfd) {
-close(fd);
-}
-}
-closedir(dir);
-}
-
 static void hup_handler(int signal)
 {
 /* Check every second if this process has been reparented. */
@@ -92,9 +54,8 @@ static int async_teardown_fn(void *arg)
 /*
  * Close all file descriptors that might have been inherited from the
  * main qemu process when doing clone, needed to make libvirt happy.
- * Not using close_range for increased compatibility with older kernels.
  */
-close_all_open_fd();
+qemu_close_range(0, ~0U);
 
 /* Set up a handler for SIGHUP and unblock SIGHUP. */
 sigaction(SIGHUP, &sa, NULL);
-- 
2.34.1




[PATCH v2 6/6] net: tap: Use qemu_close_range() to close fds

2023-06-16 Thread Bin Meng
From: Zhangjin Wu 

Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
is set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks frozen during
start-up.

The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
doesn't need to manually close the fds for child process as the proper
O_CLOEXEC flag should have been set properly on files with its own
codes, QEMU uses a huge number of 3rd party libraries and we don't
trust them to reliably be using O_CLOEXEC on everything they open.

Modern Linux and BSDs have the close_range() call we can use to do the
job, and on Linux we have one more way to walk through /proc/self/fd
to complete the task efficiently, which is what qemu_close_range() does.

Reported-by: Zhangjin Wu 
Signed-off-by: Zhangjin Wu 
Signed-off-by: Bin Meng 

---

Changes in v2:
- Change to use qemu_close_range() to close fds for child process efficiently
- v1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

 net/tap.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index 1bf085d422..d482fabdff 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -446,13 +446,13 @@ static void launch_script(const char *setup_script, const 
char *ifname,
 return;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
+unsigned int last_fd = sysconf(_SC_OPEN_MAX) - 1;
+
+/* skip stdin, stdout and stderr */
+qemu_close_range(3, fd - 1);
+/* skip the currently used fd */
+qemu_close_range(fd + 1, last_fd);
 
-for (i = 3; i < open_max; i++) {
-if (i != fd) {
-close(i);
-}
-}
 parg = args;
 *parg++ = (char *)setup_script;
 *parg++ = (char *)ifname;
@@ -536,16 +536,15 @@ static int net_bridge_run_helper(const char *helper, 
const char *bridge,
 return -1;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
+unsigned int last_fd = sysconf(_SC_OPEN_MAX) - 1, fd = sv[1];
 char *fd_buf = NULL;
 char *br_buf = NULL;
 char *helper_cmd = NULL;
 
-for (i = 3; i < open_max; i++) {
-if (i != sv[1]) {
-close(i);
-}
-}
+/* skip stdin, stdout and stderr */
+qemu_close_range(3, fd - 1);
+/* skip the currently used fd */
+qemu_close_range(fd + 1, last_fd);
 
 fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
 
-- 
2.34.1




[PATCH v2 0/6] net/tap: Fix QEMU frozen issue when the maximum number of file descriptors is very large

2023-06-16 Thread Bin Meng


Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
is set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks frozen during
start-up.

The close-on-exec flag (O_CLOEXEC) was introduced since Linux kernel
2.6.23, FreeBSD 8.3, OpenBSD 5.0, Solaris 11. While it's true QEMU
doesn't need to manually close the fds for child process as the proper
O_CLOEXEC flag should have been set properly on files with its own
codes, QEMU uses a huge number of 3rd party libraries and we don't
trust them to reliably be using O_CLOEXEC on everything they open.

Modern Linux and BSDs have the close_range() call we can use to do the
job, and on Linux we have one more way to walk through /proc/self/fd
to complete the task efficiently, which is what qemu_close_range()
does, a new API we add in utils/osdep.c.

Changes in v2:
- Change to use qemu_close_range() to close fds for child process efficiently
- v1 link: 
https://lore.kernel.org/qemu-devel/20230406112041.798585-1-bm...@tinylab.org/

Bin Meng (4):
  tests/tcg/cris: Fix the coding style
  tests/tcg/cris: Correct the off-by-one error
  util/async-teardown: Fall back to close fds one by one
  utils/osdep: Introduce qemu_close_range()

Zhangjin Wu (2):
  util/async-teardown: Use qemu_close_range() to close fds
  net: tap: Use qemu_close_range() to close fds

 include/qemu/osdep.h|  1 +
 net/tap.c   | 23 ++--
 tests/tcg/cris/libc/check_openpf5.c | 57 ++---
 util/async-teardown.c   | 37 +--
 util/osdep.c| 47 
 5 files changed, 87 insertions(+), 78 deletions(-)

-- 
2.34.1





[PATCH v2 1/6] tests/tcg/cris: Fix the coding style

2023-06-16 Thread Bin Meng
The code style does not conform with QEMU's. Correct it so that the
upcoming commit does not trigger checkpatch warnings.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 tests/tcg/cris/libc/check_openpf5.c | 57 ++---
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/tests/tcg/cris/libc/check_openpf5.c 
b/tests/tcg/cris/libc/check_openpf5.c
index 1f86ea283d..0037fbca4c 100644
--- a/tests/tcg/cris/libc/check_openpf5.c
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -13,44 +13,41 @@
 #include 
 #include 
 
-int main (int argc, char *argv[])
+int main(int argc, char *argv[])
 {
-  int i;
-  int filemax;
+int i;
+int filemax;
 
 #ifdef OPEN_MAX
-  filemax = OPEN_MAX;
+filemax = OPEN_MAX;
 #else
-  filemax = sysconf (_SC_OPEN_MAX);
+filemax = sysconf(_SC_OPEN_MAX);
 #endif
 
-  char *fn = malloc (strlen (argv[0]) + 2);
-  if (fn == NULL)
-abort ();
-  strcpy (fn, "/");
-  strcat (fn, argv[0]);
+char *fn = malloc(strlen(argv[0]) + 2);
+if (fn == NULL) {
+abort();
+}
+strcpy(fn, "/");
+strcat(fn, argv[0]);
 
-  for (i = 0; i < filemax + 1; i++)
-{
-  if (open (fn, O_RDONLY) < 0)
-   {
- /* Shouldn't happen too early.  */
- if (i < filemax - 3 - 1)
-   {
- fprintf (stderr, "i: %d\n", i);
- abort ();
-   }
- if (errno != EMFILE)
-   {
- perror ("open");
- abort ();
-   }
- goto ok;
-   }
+for (i = 0; i < filemax + 1; i++) {
+if (open(fn, O_RDONLY) < 0) {
+/* Shouldn't happen too early.  */
+if (i < filemax - 3 - 1) {
+fprintf(stderr, "i: %d\n", i);
+abort();
+}
+if (errno != EMFILE) {
+perror("open");
+abort();
+}
+goto ok;
+}
 }
-  abort ();
+abort();
 
 ok:
-  printf ("pass\n");
-  exit (0);
+printf("pass\n");
+exit(0);
 }
-- 
2.34.1




[PATCH v2 3/6] util/async-teardown: Fall back to close fds one by one

2023-06-16 Thread Bin Meng
When opening /proc/self/fd fails, current codes just return directly,
but we can fall back to close fds one by one.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 util/async-teardown.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/util/async-teardown.c b/util/async-teardown.c
index 3ab19c8740..7e0177a8da 100644
--- a/util/async-teardown.c
+++ b/util/async-teardown.c
@@ -48,7 +48,11 @@ static void close_all_open_fd(void)
 
 dir = opendir("/proc/self/fd");
 if (!dir) {
-/* If /proc is not mounted, there is nothing that can be done. */
+/* If /proc is not mounted, close fds one by one. */
+int open_max = sysconf(_SC_OPEN_MAX), i;
+for (i = 0; i < open_max; i++) {
+close(i);
+}
 return;
 }
 /* Avoid closing the directory. */
-- 
2.34.1




[PATCH v2 2/6] tests/tcg/cris: Correct the off-by-one error

2023-06-16 Thread Bin Meng
sysconf(_SC_OPEN_MAX) returns the maximum number of files that
a process can have open at any time, which means the fd should
not be larger than or equal to the return value.

Signed-off-by: Bin Meng 
---

(no changes since v1)

 tests/tcg/cris/libc/check_openpf5.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/tcg/cris/libc/check_openpf5.c 
b/tests/tcg/cris/libc/check_openpf5.c
index 0037fbca4c..7f585c6d37 100644
--- a/tests/tcg/cris/libc/check_openpf5.c
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -31,10 +31,10 @@ int main(int argc, char *argv[])
 strcpy(fn, "/");
 strcat(fn, argv[0]);
 
-for (i = 0; i < filemax + 1; i++) {
+for (i = 0; i < filemax; i++) {
 if (open(fn, O_RDONLY) < 0) {
 /* Shouldn't happen too early.  */
-if (i < filemax - 3 - 1) {
+if (i < filemax - 3) {
 fprintf(stderr, "i: %d\n", i);
 abort();
 }
-- 
2.34.1




[PATCH v2 4/6] utils/osdep: Introduce qemu_close_range()

2023-06-16 Thread Bin Meng
This introduces a new QEMU API qemu_close_range() that closes all
open file descriptors from first to last (included).

This API will try a more efficient call to close_range(), or walk
through of /proc/self/fd whenever these are possible, otherwise it
falls back to a plain close loop.

Co-developed-by: Zhangjin Wu 
Signed-off-by: Bin Meng 
---

(no changes since v1)

 include/qemu/osdep.h |  1 +
 util/osdep.c | 47 
 2 files changed, 48 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index cc61b00ba9..e22434ce10 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -560,6 +560,7 @@ int qemu_open_old(const char *name, int flags, ...);
 int qemu_open(const char *name, int flags, Error **errp);
 int qemu_create(const char *name, int flags, mode_t mode, Error **errp);
 int qemu_close(int fd);
+int qemu_close_range(unsigned int first, unsigned int last);
 int qemu_unlink(const char *name);
 #ifndef _WIN32
 int qemu_dup_flags(int fd, int flags);
diff --git a/util/osdep.c b/util/osdep.c
index e996c4744a..fd7dd2dbdf 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -411,6 +411,53 @@ int qemu_close(int fd)
 return close(fd);
 }
 
+int qemu_close_range(unsigned int first, unsigned int last)
+{
+DIR *dir = NULL;
+
+#ifdef CONFIG_CLOSE_RANGE
+int r = close_range(first, last, 0);
+if (!r) {
+/* Success, no need to try other ways. */
+return 0;
+}
+#endif
+
+#ifdef __linux__
+dir = opendir("/proc/self/fd");
+#endif
+if (!dir) {
+/*
+ * If /proc is not mounted or /proc/self/fd is not supported,
+ * try close() from first to last.
+ */
+for (int i = first; i <= last; i++) {
+close(i);
+}
+
+return 0;
+}
+
+#ifndef _WIN32
+/* Avoid closing the directory */
+int dfd = dirfd(dir);
+
+for (struct dirent *de = readdir(dir); de; de = readdir(dir)) {
+int fd = atoi(de->d_name);
+if (fd < first || fd > last) {
+/* Exclude the fds outside the target range */
+continue;
+}
+if (fd != dfd) {
+close(fd);
+}
+}
+closedir(dir);
+#endif /* _WIN32 */
+
+return 0;
+}
+
 /*
  * Delete a file from the filesystem, unless the filename is /dev/fdset/...
  *
-- 
2.34.1




Re: [PATCH] ui/sdl2: fix surface_gl_update_texture: Assertion 'gls' failed

2023-05-23 Thread Bin Meng
On Thu, May 11, 2023 at 3:43 PM  wrote:
>
> From: Marc-André Lureau 
>
> Before sdl2_gl_update() is called, sdl2_gl_switch() may decide to
> destroy the console window and its associated shaders.
>
> Fixes:
> https://gitlab.com/qemu-project/qemu/-/issues/1644

This should be:

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1644

>
> Fixes: commit c84ab0a5 ("ui/console: optionally update after gfx switch")

This should be:

Fixes: c84ab0a500a8 ("ui/console: optionally update after gfx switch")

>
> Signed-off-by: Marc-André Lureau 
> ---
>  ui/sdl2-gl.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
> index b36ba6415a..cc83c98349 100644
> --- a/ui/sdl2-gl.c
> +++ b/ui/sdl2-gl.c
> @@ -67,6 +67,10 @@ void sdl2_gl_update(DisplayChangeListener *dcl,
>
>  assert(scon->opengl);
>
> +if (!scon->real_window) {
> +return;
> +}
> +
>  SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
>  surface_gl_update_texture(scon->gls, scon->surface, x, y, w, h);
>  scon->updates++;
> --

Testing this patch with the "-device virtio-gpu-pci -display
sdl,gl=on" command line, the assertion mentioned in
https://gitlab.com/qemu-project/qemu/-/issues/1644 is fixed.

Tested-by: Bin Meng 

Regards,
Bin



Re: [PATCH] hw/riscv: virt: Enable booting M-mode or S-mode FW from pflash0

2023-04-20 Thread Bin Meng
On Fri, Apr 21, 2023 at 12:44 PM Sunil V L  wrote:
>
> On Fri, Apr 21, 2023 at 12:39:46PM +0800, Bin Meng wrote:
> > On Fri, Apr 21, 2023 at 12:34 PM Sunil V L  wrote:
> > >
> > > Currently, virt machine supports two pflash instances each with
> > > 32MB size. However, the first pflash is always assumed to
> > > contain M-mode firmware and reset vector is set to this if
> > > enabled. Hence, for S-mode payloads like EDK2, only one pflash
> > > instance is available for use. This means both code and NV variables
> > > of EDK2 will need to use the same pflash.
> > >
> > > The OS distros keep the EDK2 FW code as readonly. When non-volatile
> > > variables also need to share the same pflash, it is not possible
> > > to keep it as readonly since variables need write access.
> > >
> > > To resolve this issue, the code and NV variables need to be separated.
> > > But in that case we need an extra flash. Hence, modify the convention
> > > such that pflash0 will contain the M-mode FW only when "-bios none"
> > > option is used. Otherwise, pflash0 will contain the S-mode payload FW.
> > > This enables both pflash instances available for EDK2 use.
> > >
> > > Example usage:
> > > 1) pflash0 containing M-mode FW
> > > qemu-system-riscv64 -bios none -pflash  -machine virt
> > > or
> > > qemu-system-riscv64 -bios none \
> > > -drive file=,if=pflash,format=raw,unit=0 -machine virt
> > >
> > > 2) pflash0 containing S-mode payload like EDK2
> > > qemu-system-riscv64 -pflash  -pflash  -machine 
> > >  virt
> > > or
> > > qemu-system-riscv64 -bios  \
> > > -pflash  \
> > > -pflash  \
> > > -machine  virt
> > > or
> > > qemu-system-riscv64 -bios  \
> > > -drive file=,if=pflash,format=raw,unit=0,readonly=on \
> > > -drive file=,if=pflash,format=raw,unit=1 \
> > > -machine virt
> >
> > Please update the docs in docs/system/riscv/virt.rst to include how to
> > run EDK2 bios with these settings.
> >
> Thanks Bin. Shall I do it as a separate patch after this gets approved?
> The reason is, I need to make changes in EDK2 to work with this. Once
> EDK2 changes are also in place, will send a patch to update this
> documentation. Does it make sense?
>

Yeah, in the doc we should provide the EDK2 URL and commit that was
verified to work, so it makes sense we can add such info when EDK2 is
available.

Regards,
Bin



Re: [PATCH] hw/riscv: virt: Enable booting M-mode or S-mode FW from pflash0

2023-04-20 Thread Bin Meng
On Fri, Apr 21, 2023 at 12:34 PM Sunil V L  wrote:
>
> Currently, virt machine supports two pflash instances each with
> 32MB size. However, the first pflash is always assumed to
> contain M-mode firmware and reset vector is set to this if
> enabled. Hence, for S-mode payloads like EDK2, only one pflash
> instance is available for use. This means both code and NV variables
> of EDK2 will need to use the same pflash.
>
> The OS distros keep the EDK2 FW code as readonly. When non-volatile
> variables also need to share the same pflash, it is not possible
> to keep it as readonly since variables need write access.
>
> To resolve this issue, the code and NV variables need to be separated.
> But in that case we need an extra flash. Hence, modify the convention
> such that pflash0 will contain the M-mode FW only when "-bios none"
> option is used. Otherwise, pflash0 will contain the S-mode payload FW.
> This enables both pflash instances available for EDK2 use.
>
> Example usage:
> 1) pflash0 containing M-mode FW
> qemu-system-riscv64 -bios none -pflash  -machine virt
> or
> qemu-system-riscv64 -bios none \
> -drive file=,if=pflash,format=raw,unit=0 -machine virt
>
> 2) pflash0 containing S-mode payload like EDK2
> qemu-system-riscv64 -pflash  -pflash  -machine  
> virt
> or
> qemu-system-riscv64 -bios  \
> -pflash  \
> -pflash  \
> -machine  virt
> or
> qemu-system-riscv64 -bios  \
> -drive file=,if=pflash,format=raw,unit=0,readonly=on \
> -drive file=,if=pflash,format=raw,unit=1 \
> -machine virt

Please update the docs in docs/system/riscv/virt.rst to include how to
run EDK2 bios with these settings.

>
> Signed-off-by: Sunil V L 
> Reported-by: Heinrich Schuchardt 
> ---
>  hw/riscv/virt.c | 51 ++---
>  1 file changed, 19 insertions(+), 32 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 4e3efbee16..1187a60d6e 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1245,7 +1245,7 @@ static void virt_machine_done(Notifier *notifier, void 
> *data)
>  target_ulong firmware_end_addr, kernel_start_addr;
>  const char *firmware_name = riscv_default_firmware_name(&s->soc[0]);
>  uint32_t fdt_load_addr;
> -uint64_t kernel_entry;
> +uint64_t kernel_entry = 0;
>
>  /*
>   * Only direct boot kernel is currently supported for KVM VM,
> @@ -1266,42 +1266,29 @@ static void virt_machine_done(Notifier *notifier, 
> void *data)
>  firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
>   start_addr, NULL);
>
> -if (drive_get(IF_PFLASH, 0, 1)) {
> -/*
> - * S-mode FW like EDK2 will be kept in second plash (unit 1).
> - * When both kernel, initrd and pflash options are provided in the
> - * command line, the kernel and initrd will be copied to the fw_cfg
> - * table and opensbi will jump to the flash address which is the
> - * entry point of S-mode FW. It is the job of the S-mode FW to load
> - * the kernel and initrd using fw_cfg table.
> - *
> - * If only pflash is given but not -kernel, then it is the job of
> - * of the S-mode firmware to locate and load the kernel.
> - * In either case, the next_addr for opensbi will be the flash 
> address.
> - */
> -riscv_setup_firmware_boot(machine);
> -kernel_entry = virt_memmap[VIRT_FLASH].base +
> -   virt_memmap[VIRT_FLASH].size / 2;
> -} else if (machine->kernel_filename) {
> +if (drive_get(IF_PFLASH, 0, 0)) {
> +if (machine->firmware && !strcmp(machine->firmware, "none")) {
> +/*
> + * Pflash was supplied but bios is none, let's overwrite the
> + * address we jump to after reset to the base of the flash.
> + */
> +start_addr = virt_memmap[VIRT_FLASH].base;
> +} else {
> +/*
> + * Pflash was supplied but bios is not none. In this case,
> + * base of the flash would contain S-mode payload.
> + */
> +riscv_setup_firmware_boot(machine);
> +kernel_entry = virt_memmap[VIRT_FLASH].base;
> +}
> +}
> +
> +if (machine->kernel_filename && !kernel_entry) {
>  kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
>   firmware_end_addr);
>
>  kernel_entry = riscv_load_kernel(machine, &s->soc[0],
>   kernel_start_addr, true, NULL);
> -} else {
> -   /*
> -* If dynamic firmware is used, it doesn't know where is the next mode
> -* if kernel argument is not set.
> -*/
> -kernel_entry = 0;
> -}
> -
> -if (drive_get(IF_PFLASH, 0, 0)) {
> -/*
> - * Pflash was supplied, let's overwrite the address we jump to after
> - * reset to the base o

[PATCH v2] target/riscv: Restore the predicate() NULL check behavior

2023-04-16 Thread Bin Meng
When reading a non-existent CSR QEMU should raise illegal instruction
exception, but currently it just exits due to the g_assert() check.

This actually reverts commit 0ee342256af9205e7388efdf193a6d8f1ba1a617.
Some comments are also added to indicate that predicate() must be
provided for an implemented CSR.

Reported-by: Fei Wu 
Signed-off-by: Bin Meng 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 

---

Changes in v2:
- rebase on top of Alistair's riscv-to-apply.next tree

 target/riscv/csr.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f4d2dcfdc8..7000eb3350 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3817,6 +3817,11 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+/* ensure CSR is implemented by checking predicate */
+if (!csr_ops[csrno].predicate) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 /* privileged spec version check */
 if (env->priv_ver < csr_min_priv) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -3834,7 +3839,6 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
  * illegal instruction exception should be triggered instead of virtual
  * instruction exception. Hence this comes after the read / write check.
  */
-g_assert(csr_ops[csrno].predicate != NULL);
 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
 if (ret != RISCV_EXCP_NONE) {
 return ret;
@@ -4023,7 +4027,10 @@ static RISCVException write_jvt(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
-/* Control and Status Register function table */
+/*
+ * Control and Status Register function table
+ * riscv_csr_operations::predicate() must be provided for an implemented CSR
+ */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
 [CSR_FFLAGS]   = { "fflags",   fs, read_fflags,  write_fflags },
-- 
2.25.1




[PATCH] target/riscv: Restore the predicate() NULL check behavior

2023-04-11 Thread Bin Meng
When reading a non-existent CSR QEMU should raise illegal instruction
exception, but currently it just exits due to the g_assert() check.

This actually reverts commit 0ee342256af9205e7388efdf193a6d8f1ba1a617,
Some comments are also added to indicate that predicate() must be
provided for an implemented CSR.

Reported-by: Fei Wu 
Signed-off-by: Bin Meng 
---

 target/riscv/csr.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d522efc0b6..736ab64275 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3797,6 +3797,11 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+/* ensure CSR is implemented by checking predicate */
+if (!csr_ops[csrno].predicate) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 /* privileged spec version check */
 if (env->priv_ver < csr_min_priv) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -3814,7 +3819,6 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
  * illegal instruction exception should be triggered instead of virtual
  * instruction exception. Hence this comes after the read / write check.
  */
-g_assert(csr_ops[csrno].predicate != NULL);
 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
 if (ret != RISCV_EXCP_NONE) {
 return ret;
@@ -3991,7 +3995,10 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int 
csrno,
 return ret;
 }
 
-/* Control and Status Register function table */
+/*
+ * Control and Status Register function table
+ * riscv_csr_operations::predicate() must be provided for an implemented CSR
+ */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
 [CSR_FFLAGS]   = { "fflags",   fs, read_fflags,  write_fflags },
-- 
2.25.1




Re: riscv: g_assert for NULL predicate?

2023-04-10 Thread Bin Meng
On Wed, Apr 5, 2023 at 2:07 PM Alistair Francis  wrote:
>
> On Mon, Apr 3, 2023 at 11:43 PM Wu, Fei  wrote:
> >
> > Recent commit 0ee342256af92 switches to g_assert() for the predicate()
> > NULL check from returning RISCV_EXCP_ILLEGAL_INST. Qemu doesn't have
> > predicate() for un-allocated CSRs, then a buggy userspace application
> > reads CSR such as 0x4 causes qemu to exit, I don't think it's expected.
>
> Hm That's not good. Userspace shouldn't be able to crash QEMU. I
> think we want to revert that patch then.
>
> @Bin Meng any thoughts?
>

Agree, I will send a patch for this.

Regards,
Bin



Re: [PATCH] net: tap: Drop the close of fds for child process

2023-04-06 Thread Bin Meng
On Thu, Apr 6, 2023 at 8:34 PM Philippe Mathieu-Daudé  wrote:
>
> On 6/4/23 13:20, Bin Meng wrote:
> > Current codes using a brute-force traversal of all file descriptors
> > do not scale on a system where the maximum number of file descriptors
> > are set to a very large value (e.g.: in a Docker container of Manjaro
> > distribution it is set to 1073741816). QEMU just looks freezed during
> > start-up.
> >
> > The close-on-exec flag was introduced since a faily old Linux kernel
> > (2.6.23). With recent newer kernels that QEMU supports, we don't need
> > to manually close the fds for child process as the proper O_CLOEXEC
> > flag should have been set properly on files that we don't want child
> > process to see.
>
> But this file is common to all POSIX implementations, not only Linux.

Yes, this file is used for Linux, BSD and Solaris.
I checked that O_CLOEXEC is available on Linux (2.6.23), FreeBSD
(8.3), OpenBSD 5.0, Solaris 11. This flag is part of POSIX.1-2008.

Question is do we still need to support OSes that are older and do not
have this support?

>
> > Reported-by: Zhangjin Wu 
> > Signed-off-by: Bin Meng 
> > ---
> >
> >   net/tap.c | 14 --
> >   1 file changed, 14 deletions(-)
> >
> > diff --git a/net/tap.c b/net/tap.c
> > index 1bf085d422..49e1915484 100644
> > --- a/net/tap.c
> > +++ b/net/tap.c
> > @@ -446,13 +446,6 @@ static void launch_script(const char *setup_script, 
> > const char *ifname,
> >   return;
> >   }
> >   if (pid == 0) {
>
> Maybe guard with #ifndef O_CLOEXEC
>
> > -int open_max = sysconf(_SC_OPEN_MAX), i;
> > -
> > -for (i = 3; i < open_max; i++) {
> > -if (i != fd) {
> > -close(i);
> > -}
> > -}
>
> or add qemu_close_cloexec() in util/osdep.c similar to qemu_open_cloexec()?
>
> >   parg = args;
> >   *parg++ = (char *)setup_script;
> >   *parg++ = (char *)ifname;
> > @@ -536,17 +529,10 @@ static int net_bridge_run_helper(const char *helper, 
> > const char *bridge,
> >   return -1;
> >   }
> >   if (pid == 0) {
> > -int open_max = sysconf(_SC_OPEN_MAX), i;
> >   char *fd_buf = NULL;
> >   char *br_buf = NULL;
> >   char *helper_cmd = NULL;
> >
> > -for (i = 3; i < open_max; i++) {
> > -if (i != sv[1]) {
> > -close(i);
> > -}
> > -}
> > -
> >   fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
> >
> >   if (strrchr(helper, ' ') || strrchr(helper, '\t')) {

Regards,
Bin



[PATCH] net: tap: Drop the close of fds for child process

2023-04-06 Thread Bin Meng
Current codes using a brute-force traversal of all file descriptors
do not scale on a system where the maximum number of file descriptors
are set to a very large value (e.g.: in a Docker container of Manjaro
distribution it is set to 1073741816). QEMU just looks freezed during
start-up.

The close-on-exec flag was introduced since a faily old Linux kernel
(2.6.23). With recent newer kernels that QEMU supports, we don't need
to manually close the fds for child process as the proper O_CLOEXEC
flag should have been set properly on files that we don't want child
process to see.

Reported-by: Zhangjin Wu 
Signed-off-by: Bin Meng 
---

 net/tap.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index 1bf085d422..49e1915484 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -446,13 +446,6 @@ static void launch_script(const char *setup_script, const 
char *ifname,
 return;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
-
-for (i = 3; i < open_max; i++) {
-if (i != fd) {
-close(i);
-}
-}
 parg = args;
 *parg++ = (char *)setup_script;
 *parg++ = (char *)ifname;
@@ -536,17 +529,10 @@ static int net_bridge_run_helper(const char *helper, 
const char *bridge,
 return -1;
 }
 if (pid == 0) {
-int open_max = sysconf(_SC_OPEN_MAX), i;
 char *fd_buf = NULL;
 char *br_buf = NULL;
 char *helper_cmd = NULL;
 
-for (i = 3; i < open_max; i++) {
-if (i != sv[1]) {
-close(i);
-}
-}
-
 fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
 
 if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
-- 
2.34.1




Re: [PATCH v2 09/10] contrib/gitdm: add more individual contributors

2023-03-15 Thread Bin Meng



On 2023/3/11 2:03:31, "Alex Bennée"  wrote:


I'll only add names explicitly acked here. Let me know if you want
contributions mapped to a company instead.

Signed-off-by: Alex Bennée 
Cc: Bernhard Beschow 
Cc: Amarjargal Gundjalam 
Cc: Bin Meng 
Cc: Jason A. Donenfeld 
Cc: Strahinja Jankovic 
---
 contrib/gitdm/group-map-individuals | 5 +
 1 file changed, 5 insertions(+)

diff --git a/contrib/gitdm/group-map-individuals 
b/contrib/gitdm/group-map-individuals
index e2263a5ee3..0e4618f1ce 100644
--- a/contrib/gitdm/group-map-individuals
+++ b/contrib/gitdm/group-map-individuals
@@ -38,3 +38,8 @@ p...@nowt.org
g...@xen0n.name
si...@simonsafar.com
research_tra...@irq.a4lg.com
+shen...@gmail.com
+bm...@tinylab.org
+amarjarga...@gmail.com
+strahinjapjanko...@gmail.com
+ja...@zx2c4.com
--




Acked-by: Bin Meng 



Re: [PATCH qemu v2] linux-user: Emulate /proc/cpuinfo output for riscv

2023-03-13 Thread Bin Meng
On Tue, Mar 14, 2023 at 4:29 AM ~abordado  wrote:
>
> From: Afonso Bordado 
>
> RISC-V does not expose all extensions via hwcaps, thus some userspace
> applications may want to query these via /proc/cpuinfo.
>
> Currently when querying this file the host's file is shown instead
> which is slightly confusing. Emulate a basic /proc/cpuinfo file
> with mmu info and an ISA string.
>
> Changes from V1:

The changelog should go below ---

>
> - Call `g_free` on ISA string.
> - Use `riscv_cpu_cfg` API.
> - Query `cpu_env->xl` to check for RV32.
>
> Signed-off-by: Afonso Bordado 
> Reviewed-by: Palmer Dabbelt 
> Acked-by: Palmer Dabbelt 
> Reviewed-by: Laurent Vivier 
> ---
>  linux-user/syscall.c  | 34 +--
>  tests/tcg/riscv64/Makefile.target |  1 +
>  tests/tcg/riscv64/cpuinfo.c   | 30 +++
>  3 files changed, 63 insertions(+), 2 deletions(-)
>  create mode 100644 tests/tcg/riscv64/cpuinfo.c
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 24cea6fb6a..0388f8b0b0 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8230,7 +8230,8 @@ void target_exception_dump(CPUArchState *env, const 
> char *fmt, int code)
>  }
>
>  #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \
> -defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
> +defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) || 
> \
> +defined(TARGET_RISCV)
>  static int is_proc(const char *filename, const char *entry)
>  {
>  return strcmp(filename, entry) == 0;
> @@ -8308,6 +8309,35 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
>  }
>  #endif
>
> +#if defined(TARGET_RISCV)
> +static int open_cpuinfo(CPUArchState *cpu_env, int fd)
> +{
> +int i;
> +int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
> +RISCVCPU *cpu = env_archcpu(cpu_env);
> +const RISCVCPUConfig *cfg = riscv_cpu_cfg((CPURISCVState *) cpu_env);
> +char *isa_string = riscv_isa_string(cpu);
> +const char *mmu;
> +
> +if (cfg->mmu) {
> +mmu = (cpu_env->xl == MXL_RV32) ? "sv32"  : "sv48";
> +} else {
> +mmu = "none";
> +}
> +
> +for (i = 0; i < num_cpus; i++) {
> +dprintf(fd, "processor\t: %d\n", i);
> +dprintf(fd, "hart\t\t: %d\n", i);
> +dprintf(fd, "isa\t\t: %s\n", isa_string);
> +dprintf(fd, "mmu\t\t: %s\n", mmu);
> +dprintf(fd, "uarch\t\t: qemu\n\n");
> +}
> +
> +g_free(isa_string);
> +return 0;
> +}
> +#endif
> +
>  #if defined(TARGET_M68K)
>  static int open_hardware(CPUArchState *cpu_env, int fd)
>  {
> @@ -8332,7 +8362,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, 
> const char *pathname, int
>  #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
>  { "/proc/net/route", open_net_route, is_proc },
>  #endif
> -#if defined(TARGET_SPARC) || defined(TARGET_HPPA)
> +#if defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined(TARGET_RISCV)
>  { "/proc/cpuinfo", open_cpuinfo, is_proc },
>  #endif
>  #if defined(TARGET_M68K)
> diff --git a/tests/tcg/riscv64/Makefile.target 
> b/tests/tcg/riscv64/Makefile.target
> index cc3ed65ffd..df93a2ce1f 100644
> --- a/tests/tcg/riscv64/Makefile.target
> +++ b/tests/tcg/riscv64/Makefile.target
> @@ -4,6 +4,7 @@
>  VPATH += $(SRC_PATH)/tests/tcg/riscv64
>  TESTS += test-div
>  TESTS += noexec
> +TESTS += cpuinfo
>
>  # Disable compressed instructions for test-noc
>  TESTS += test-noc
> diff --git a/tests/tcg/riscv64/cpuinfo.c b/tests/tcg/riscv64/cpuinfo.c
> new file mode 100644
> index 00..296abd0a8c
> --- /dev/null
> +++ b/tests/tcg/riscv64/cpuinfo.c
> @@ -0,0 +1,30 @@
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define BUFFER_SIZE 1024
> +
> +int main(void)
> +{
> +char buffer[BUFFER_SIZE];
> +FILE *fp = fopen("/proc/cpuinfo", "r");
> +assert(fp != NULL);
> +
> +while (fgets(buffer, BUFFER_SIZE, fp) != NULL) {
> +if (strstr(buffer, "processor") != NULL) {
> +assert(strstr(buffer, "processor\t: ") == buffer);
> +} else if (strstr(buffer, "hart") != NULL) {
> +assert(strstr(buffer, "hart\t\t: ") == buffer);
> +} else if (strstr(buffer, "isa") != NULL) {
> +assert(strcmp(buffer, "isa\t\t: rv64imafdc_zicsr_zifencei\n") == 
> 0);
> +} else if (strstr(buffer, "mmu") != NULL) {
> +assert(strcmp(buffer, "mmu\t\t: sv48\n") == 0);
> +} else if (strstr(buffer, "uarch") != NULL) {
> +assert(strcmp(buffer, "uarch\t\t: qemu\n") == 0);
> +}
> +}
> +
> +fclose(fp);
> +return 0;
> +}

Regards,
Bin



Re: [PATCH-for-8.0] gitlab-ci: Remove job building EDK2 firmware binaries

2023-03-13 Thread Bin Meng
On Mon, Mar 13, 2023 at 6:01 PM Philippe Mathieu-Daudé
 wrote:
>
> On 13/3/23 10:35, Bin Meng wrote:
> > Hi Philippe,
> >
> > On Mon, Mar 13, 2023 at 4:51 PM Philippe Mathieu-Daudé
> >  wrote:
> >>
> >> On 13/3/23 03:09, Bin Meng wrote:
> >>> On Fri, Mar 10, 2023 at 9:50 PM Philippe Mathieu-Daudé
> >>>  wrote:
> >>>>
> >>>> On 10/3/23 14:38, Peter Maydell wrote:
> >>>>> On Fri, 10 Mar 2023 at 13:33, Philippe Mathieu-Daudé 
> >>>>>  wrote:
> >>>>>>
> >>>>>> When we introduced this Gitlab-CI job in commit 71920809ce
> >>>>>> ("gitlab-ci.yml: Add jobs to build EDK2 firmware binaries"),
> >>>>>> the naive plan was to have reproducible binaries by downloading
> >>>>>> what this job would build, testing it and eventually committing
> >>>>>> it. With retrospective, nothing happened 3 years later and this
> >>>>>> job is just bitrotting:
> >>>>>>
> >>>>>>  Step 1/3 : FROM ubuntu:18.04
> >>>>>>  18.04: Pulling from library/ubuntu
> >>>>>>  mediaType in manifest should be
> >>>>>>  'application/vnd.docker.distribution.manifest.v2+json' not
> >>>>>>  'application/vnd.oci.image.manifest.v1+json'
> >>>>>>
> >>>>>> Remove this job to avoid wasting maintenance and CI ressources.
> >>>>>
> >>>>> Does the same thing hold for the opensbi job ?
> >>>>
> >>>> Cc'ing Bin, I have no idea.
> >>>>
> >>>
> >>> The OpenSBI job now builds fine. I have no preference on keeping vs.
> >>> removing it.
> >>>
> >>> I remember our previous goal was to create CI jobs for every pc-bios
> >>> image but apparently that never happened.
> >>
> >> Yes, and I don't see interest in the community (neither worry that
> >> pc-bios/ images committed are built on each maintainer workstations).
> >>
> >> If it isn't consumed by QEMU, then better remove that job and save
> >> precious CI minutes. I presume OpenSBI itself is already tested
> >> by its mainstream project.
> >
> > Not sure what does "consumed" here mean?
> >
> > QEMU uses OpenSBI images on RISC-V machines by default.
>
> QEMU repository allows building QEMU system binaries which 'consume'
> the following (committed) files:
> - pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
> - pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
>
> We don't need to run the build-opensbi job to run QEMU: we use the
> prebuilt images.

Okay, thanks for the clarification. I believe that's the case for
every pc-bios image? If yes, we don't need to build these pc-bios
images in QEMU CI.

Regards,
Bin



Re: [PATCH-for-8.0] gitlab-ci: Remove job building EDK2 firmware binaries

2023-03-13 Thread Bin Meng
Hi Philippe,

On Mon, Mar 13, 2023 at 4:51 PM Philippe Mathieu-Daudé
 wrote:
>
> On 13/3/23 03:09, Bin Meng wrote:
> > On Fri, Mar 10, 2023 at 9:50 PM Philippe Mathieu-Daudé
> >  wrote:
> >>
> >> On 10/3/23 14:38, Peter Maydell wrote:
> >>> On Fri, 10 Mar 2023 at 13:33, Philippe Mathieu-Daudé  
> >>> wrote:
> >>>>
> >>>> When we introduced this Gitlab-CI job in commit 71920809ce
> >>>> ("gitlab-ci.yml: Add jobs to build EDK2 firmware binaries"),
> >>>> the naive plan was to have reproducible binaries by downloading
> >>>> what this job would build, testing it and eventually committing
> >>>> it. With retrospective, nothing happened 3 years later and this
> >>>> job is just bitrotting:
> >>>>
> >>>> Step 1/3 : FROM ubuntu:18.04
> >>>> 18.04: Pulling from library/ubuntu
> >>>> mediaType in manifest should be
> >>>> 'application/vnd.docker.distribution.manifest.v2+json' not
> >>>> 'application/vnd.oci.image.manifest.v1+json'
> >>>>
> >>>> Remove this job to avoid wasting maintenance and CI ressources.
> >>>
> >>> Does the same thing hold for the opensbi job ?
> >>
> >> Cc'ing Bin, I have no idea.
> >>
> >
> > The OpenSBI job now builds fine. I have no preference on keeping vs.
> > removing it.
> >
> > I remember our previous goal was to create CI jobs for every pc-bios
> > image but apparently that never happened.
>
> Yes, and I don't see interest in the community (neither worry that
> pc-bios/ images committed are built on each maintainer workstations).
>
> If it isn't consumed by QEMU, then better remove that job and save
> precious CI minutes. I presume OpenSBI itself is already tested
> by its mainstream project.

Not sure what does "consumed" here mean?

QEMU uses OpenSBI images on RISC-V machines by default.

Regards,
Bin



Re: [PATCH-for-8.0] gitlab-ci: Remove job building EDK2 firmware binaries

2023-03-12 Thread Bin Meng
On Fri, Mar 10, 2023 at 9:50 PM Philippe Mathieu-Daudé
 wrote:
>
> On 10/3/23 14:38, Peter Maydell wrote:
> > On Fri, 10 Mar 2023 at 13:33, Philippe Mathieu-Daudé  
> > wrote:
> >>
> >> When we introduced this Gitlab-CI job in commit 71920809ce
> >> ("gitlab-ci.yml: Add jobs to build EDK2 firmware binaries"),
> >> the naive plan was to have reproducible binaries by downloading
> >> what this job would build, testing it and eventually committing
> >> it. With retrospective, nothing happened 3 years later and this
> >> job is just bitrotting:
> >>
> >>Step 1/3 : FROM ubuntu:18.04
> >>18.04: Pulling from library/ubuntu
> >>mediaType in manifest should be
> >>'application/vnd.docker.distribution.manifest.v2+json' not
> >>'application/vnd.oci.image.manifest.v1+json'
> >>
> >> Remove this job to avoid wasting maintenance and CI ressources.
> >
> > Does the same thing hold for the opensbi job ?
>
> Cc'ing Bin, I have no idea.
>

The OpenSBI job now builds fine. I have no preference on keeping vs.
removing it.

I remember our previous goal was to create CI jobs for every pc-bios
image but apparently that never happened.

Regards,
Bin



Re: [PATCH v5 00/16] hw/9pfs: Add 9pfs support for Windows

2023-03-06 Thread Bin Meng
On Mon, Mar 6, 2023 at 10:15 PM Christian Schoenebeck
 wrote:
>
> On Monday, February 20, 2023 11:07:59 AM CET Bin Meng wrote:
> > At present there is no Windows support for 9p file system.
> > This series adds initial Windows support for 9p file system.
> >
> > 'local' file system backend driver is supported on Windows,
> > including open, read, write, close, rename, remove, etc.
> > All security models are supported. The mapped (mapped-xattr)
> > security model is implemented using NTFS Alternate Data Stream
> > (ADS) so the 9p export path shall be on an NTFS partition.
> >
> > 'synth' driver is adapted for Windows too so that we can now
> > run qtests on Windows for 9p related regression testing.
> >
> > Example command line to test:
> >   "-fsdev local,path=c:\msys64,security_model=mapped,id=p9 -device
> virtio-9p-pci,fsdev=p9,mount_tag=p9fs"
> >
> > Changes in v5:
> > - rework Windows specific xxxdir() APIs implementation
>
> I didn't have the chance to look at this v5 yet.
>
> In general it would help for review to point out in the cover letter which
> patch(es) have changed, what decisions you have made and why.
>
> In this case I guess that's patch 4.
>

Yes, it's patch 4, and v5 is reworked following your comments
regarding patch 4 of v4.

Regards,
Bin



Re: [PATCH v5 03/16] hw/9pfs: Replace the direct call to xxxdir() APIs with a wrapper

2023-03-06 Thread Bin Meng
On Mon, Mar 6, 2023 at 5:32 PM Philippe Mathieu-Daudé  wrote:
>
> On 20/2/23 11:08, Bin Meng wrote:
> > From: Guohuai Shi 
> >
> > xxxdir() APIs are not safe on Windows host. For future extension to
> > Windows, let's replace the direct call to xxxdir() APIs with a wrapper.
> >
> > Signed-off-by: Guohuai Shi 
> > Signed-off-by: Bin Meng 
> > ---
> >
> >   hw/9pfs/9p-util.h  | 14 ++
> >   hw/9pfs/9p-local.c | 12 ++--
> >   2 files changed, 20 insertions(+), 6 deletions(-)
>
>
> > +#define qemu_opendiropendir_win32
> > +#define qemu_closedir   closedir_win32
> > +#define qemu_readdirreaddir_win32
> > +#define qeme_rewinddir  rewinddir_win32
>
> Typo :)
>

Ouch! Thanks Philippe :)

Regards,
Bin



Re: [PATCH v5 00/16] hw/9pfs: Add 9pfs support for Windows

2023-03-05 Thread Bin Meng
On Mon, Feb 20, 2023 at 6:10 PM Bin Meng  wrote:
>
> At present there is no Windows support for 9p file system.
> This series adds initial Windows support for 9p file system.
>
> 'local' file system backend driver is supported on Windows,
> including open, read, write, close, rename, remove, etc.
> All security models are supported. The mapped (mapped-xattr)
> security model is implemented using NTFS Alternate Data Stream
> (ADS) so the 9p export path shall be on an NTFS partition.
>
> 'synth' driver is adapted for Windows too so that we can now
> run qtests on Windows for 9p related regression testing.
>
> Example command line to test:
>   "-fsdev local,path=c:\msys64,security_model=mapped,id=p9 -device 
> virtio-9p-pci,fsdev=p9,mount_tag=p9fs"
>
> Changes in v5:
> - rework Windows specific xxxdir() APIs implementation
>
> Bin Meng (2):
>   hw/9pfs: Update helper qemu_stat_rdev()
>   hw/9pfs: Add a helper qemu_stat_blksize()
>
> Guohuai Shi (14):
>   hw/9pfs: Add missing definitions for Windows
>   hw/9pfs: Implement Windows specific utilities functions for 9pfs
>   hw/9pfs: Replace the direct call to xxxdir() APIs with a wrapper
>   hw/9pfs: Implement Windows specific xxxdir() APIs
>   hw/9pfs: Update the local fs driver to support Windows
>   hw/9pfs: Support getting current directory offset for Windows
>   hw/9pfs: Disable unsupported flags and features for Windows
>   hw/9pfs: Update v9fs_set_fd_limit() for Windows
>   hw/9pfs: Add Linux error number definition
>   hw/9pfs: Translate Windows errno to Linux value
>   fsdev: Disable proxy fs driver on Windows
>   hw/9pfs: Update synth fs driver for Windows
>   tests/qtest: virtio-9p-test: Adapt the case for win32
>   meson.build: Turn on virtfs for Windows

Ping?



Re: [PATCH v2 1/2] gitlab/opensbi: Move to docker:stable

2023-03-03 Thread Bin Meng
On Sat, Mar 4, 2023 at 4:25 AM Palmer Dabbelt  wrote:
>
> The OpenSBI build has been using docker:19.03.1, which appears to be old
> enough that v2 of the manifest is no longer supported.  Something has
> started serving us those manifests, resulting in errors along the lines
> of
>
> $ docker build --cache-from $IMAGE_TAG --tag 
> $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $IMAGE_TAG .gitlab-ci.d/opensbi
> Step 1/7 : FROM ubuntu:18.04
> 18.04: Pulling from library/ubuntu
> mediaType in manifest should be 
> 'application/vnd.docker.distribution.manifest.v2+json' not 
> 'application/vnd.oci.image.manifest.v1+json'
>
> This moves to docker:stable, as was suggested by the template.  It also
> adds the python3 package via apt, as OpenSBI requires that to build.
>
> Signed-off-by: Palmer Dabbelt 
> ---
>  .gitlab-ci.d/opensbi.yml| 4 ++--
>  .gitlab-ci.d/opensbi/Dockerfile | 1 +
>  2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/.gitlab-ci.d/opensbi.yml b/.gitlab-ci.d/opensbi.yml
> index 04ed5a3ea1..9a651465d8 100644
> --- a/.gitlab-ci.d/opensbi.yml
> +++ b/.gitlab-ci.d/opensbi.yml
> @@ -42,9 +42,9 @@
>  docker-opensbi:
>extends: .opensbi_job_rules
>stage: containers
> -  image: docker:19.03.1
> +  image: docker:stable
>services:
> -- docker:19.03.1-dind
> +- docker:stable-dind
>variables:
>  GIT_DEPTH: 3
>  IMAGE_TAG: $CI_REGISTRY_IMAGE:opensbi-cross-build
> diff --git a/.gitlab-ci.d/opensbi/Dockerfile b/.gitlab-ci.d/opensbi/Dockerfile
> index 4ba8a4de86..2d151a6bc8 100644
> --- a/.gitlab-ci.d/opensbi/Dockerfile
> +++ b/.gitlab-ci.d/opensbi/Dockerfile
> @@ -16,6 +16,7 @@ RUN apt update \
>  git \
>  make \
>  wget \
> +   python3 \

nits: this should be inserted before wget to follow the alphabetical order

>  && \
>  \
>  rm -rf /var/lib/apt/lists/*
> --

Reviewed-by: Bin Meng 



Re: [PATCH v2 1/1] hw/riscv/virt.c: add cbo[mz]-block-size fdt properties

2023-03-02 Thread Bin Meng
On Thu, Mar 2, 2023 at 5:16 PM Daniel Henrique Barboza
 wrote:
>
> From: Anup Patel 
>
> The cbom-block-size fdt property property is used to inform the OS about
> the blocksize in bytes for the Zicbom cache operations. Linux documents
> it in Documentation/devicetree/bindings/riscv/cpus.yaml
> as:
>
>   riscv,cbom-block-size:
> $ref: /schemas/types.yaml#/definitions/uint32
> description:
>   The blocksize in bytes for the Zicbom cache operations.
>
> cboz-block-size has the same role but for the Zicboz extension, i.e.
> informs the size in bytes for Zicboz cache operations. Linux support
> for it is under review/approval in [1]. Patch 3 of that series describes
> cboz-block-size as:
>
>   riscv,cboz-block-size:
> $ref: /schemas/types.yaml#/definitions/uint32
> description:
>   The blocksize in bytes for the Zicboz cache operations.
>
> [1] 
> https://lore.kernel.org/all/20230224162631.405473-1-ajo...@ventanamicro.com/
>
> Cc: Andrew Jones 
> Signed-off-by: Anup Patel 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/virt.c | 11 +++
>  1 file changed, 11 insertions(+)
>

Reviewed-by: Bin Meng 



Re: [PATCH 0/4] RISCVCPUConfig related cleanups

2023-03-01 Thread Bin Meng
Hi Palmer,

On Thu, Mar 2, 2023 at 10:08 AM Palmer Dabbelt  wrote:
>
> On Fri, 24 Feb 2023 09:45:16 PST (-0800), dbarb...@ventanamicro.com wrote:
> > Hi,
> >
> > These cleanups were suggested by LIU Zhiwei during the review of the
> > RISCV_FEATURE_* cleanups, currently on version 7 [1].
> >
> > These are dependent on the patch "[PATCH v7 01/10] target/riscv: introduce
> > riscv_cpu_cfg()" from [1] because we use the riscv_cpu_cfg() API.
> >
> >
> > [1] https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg06467.html
> >
> > Daniel Henrique Barboza (4):
> >   target/riscv/csr.c: use env_archcpu() in ctr()
> >   target/riscv/csr.c: simplify mctr()
> >   target/riscv/csr.c: use riscv_cpu_cfg() to avoid env_cpu() pointers
> >   target/riscv/csr.c: avoid env_archcpu() usages when reading
> > RISCVCPUConfig
> >
> >  target/riscv/csr.c | 90 +-
> >  1 file changed, 24 insertions(+), 66 deletions(-)
>
> I just based these on that patch, which landed as d4ea711704
> ("target/riscv: introduce riscv_cpu_cfg()").  That resulted in a handful
> of merge conflicts, but everything looked pretty mechanical.  So it's
> queued up.
>

As Weiwei pointed out in
https://lore.kernel.org/qemu-devel/e40e75ff-37e0-94d3-e9e2-c159b0e2d...@iscas.ac.cn/,
patch#1 should be dropped.

But I see it was landed up in your tree @
https://github.com/palmer-dabbelt/qemu/commit/3c7d54f945f1b5b474ea35c0815a1618927c9384,
while my changes are already in tree @
https://github.com/palmer-dabbelt/qemu/commit/94e297071bc0a5965cc32c497a886f2cf9d32710.

Not sure why git doesn't figure that out ...

Regards,
Bin



Re: [PATCH v2 05/18] target/riscv: gdbstub: Do not generate CSR XML if Zicsr is disabled

2023-03-01 Thread Bin Meng
On Thu, Mar 2, 2023 at 7:43 AM Palmer Dabbelt  wrote:
>
> On Wed, 01 Mar 2023 01:55:34 PST (-0800), Bin Meng wrote:
> > On Wed, Mar 1, 2023 at 5:52 PM LIU Zhiwei  
> > wrote:
> >>
> >>
> >> On 2023/2/28 18:40, Bin Meng wrote:
> >> > There is no need to generate the CSR XML if the Zicsr extension
> >> > is not enabled.
> >>
> >> Should we generate the FPU XML or Vector XML when Zicsr is not enabled?
> >
> > Good point. I think we should disable that too.
>
> Seems reasonable.  Did you want to do that as part of a v3, or just as a
> follow-on fix?
>

I looked at this further.

The FPU / Vector XML is guarded by the " env->misa_ext" check. If
Zicsr is disabled while F or V extension is off, QEMU will error out
in riscv_cpu_realize() earlier before the gdbstub init.

So current patch should be fine.

Regards,
Bin



Re: [PATCH v6 0/8] net: Pad short frames for network backends

2023-03-01 Thread Bin Meng
Hi Cédric,

On Wed, Mar 1, 2023 at 5:13 PM Cédric Le Goater  wrote:
>
> Hello Bin,
>
> On 3/1/23 10:01, bmeng...@gmail.com wrote:
> > From: Bin Meng 
> >
> > The minimum Ethernet frame length is 60 bytes. For short frames with
> > smaller length like ARP packets (only 42 bytes), on a real world NIC
> > it can choose either padding its length to the minimum required 60
> > bytes, or sending it out directly to the wire. Such behavior can be
> > hardcoded or controled by a register bit. Similarly on the receive
> > path, NICs can choose either dropping such short frames directly or
> > handing them over to software to handle.
> >
> > On the other hand, for the network backends like SLiRP/TAP, they
> > don't expose a way to control the short frame behavior. As of today
> > they just send/receive data from/to the other end connected to them,
> > which means any sized packet is acceptable. So they can send and
> > receive short frames without any problem. It is observed that ARP
> > packets sent from SLiRP/TAP are 42 bytes, and SLiRP/TAP just send
> > these ARP packets to the other end which might be a NIC model that
> > does not allow short frames to pass through.
> >
> > To provide better compatibility, for packets sent from QEMU network
> > backends like SLiRP/TAP, we change to pad short frames before sending
> > it out to the other end, if the other end does not forbid it via the
> > nc->do_not_pad flag. This ensures a backend as an Ethernet sender
> > does not violate the spec. But with this change, the behavior of
> > dropping short frames from SLiRP/TAP interfaces in the NIC model
> > cannot be emulated because it always receives a packet that is spec
> > complaint. The capability of sending short frames from NIC models is
> > still supported and short frames can still pass through SLiRP/TAP.
> >
> > This series should be able to fix the issue as reported with some
> > NIC models before, that ARP requests get dropped, preventing the
> > guest from becoming visible on the network. It was workarounded in
> > these NIC models on the receive path, that when a short frame is
> > received, it is padded up to 60 bytes.
>
> I guess we can drop this code in ftgmac100.c also then :
>
>  /* TODO : Pad to minimum Ethernet frame length */
>  /* handle small packets.  */
>  if (size < 10) {
>  qemu_log_mask(LOG_GUEST_ERROR, "%s: dropped frame of %zd bytes\n",
>__func__, size);
>  return size;
>  }
>
> Correct ? No need to resend. I can take care of it.
>

Yes, I think so. Thanks!

Regards,
Bin



Re: [PATCH v2 05/18] target/riscv: gdbstub: Do not generate CSR XML if Zicsr is disabled

2023-03-01 Thread Bin Meng
On Wed, Mar 1, 2023 at 5:52 PM LIU Zhiwei  wrote:
>
>
> On 2023/2/28 18:40, Bin Meng wrote:
> > There is no need to generate the CSR XML if the Zicsr extension
> > is not enabled.
>
> Should we generate the FPU XML or Vector XML when Zicsr is not enabled?

Good point. I think we should disable that too.

>
> Zhiwei
>

Regards,
Bin



[PATCH v2 16/18] target/riscv: Allow debugger to access sstc CSRs

2023-02-28 Thread Bin Meng
From: Bin Meng 

At present with a debugger attached sstc CSRs can only be accssed
when CPU is in M-mode, or configured correctly.

Fix it by adjusting their predicate() routine logic so that the
static config check comes before the run-time check, as well as
adding a debugger check.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
---

(no changes since v1)

 target/riscv/csr.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a0e70f5ba0..020c3f524f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -952,6 +952,19 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
+hmode_check = true;
+}
+
+RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
 if (env->priv == PRV_M) {
 return RISCV_EXCP_NONE;
 }
@@ -972,11 +985,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
 }
 }
 
-if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
-hmode_check = true;
-}
-
-return hmode_check ? hmode(env, csrno) : smode(env, csrno);
+return RISCV_EXCP_NONE;
 }
 
 static RISCVException sstc_32(CPURISCVState *env, int csrno)
-- 
2.25.1




[PATCH v2 18/18] target/riscv: Group all predicate() routines together

2023-02-28 Thread Bin Meng
From: Bin Meng 

Move sstc()/sstc32() to where all predicate() routines live, and
smstateen_acc_ok() to near {read,write}_xenvcfg().

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
---

Changes in v2:
- move smstateen_acc_ok() to near {read,write}_xenvcfg()

 target/riscv/csr.c | 177 ++---
 1 file changed, 87 insertions(+), 90 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 785f6f4d45..3a7e0217e2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -40,42 +40,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
 }
 
-/* Predicates */
-#if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
-{
-bool virt = riscv_cpu_virt_enabled(env);
-RISCVCPU *cpu = env_archcpu(env);
-
-if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
-return RISCV_EXCP_NONE;
-}
-
-if (!(env->mstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (virt) {
-if (!(env->hstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-
-if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-}
-
-if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
-if (!(env->sstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-}
-
-return RISCV_EXCP_NONE;
-}
-#endif
-
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -399,6 +363,60 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException sstc(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+bool hmode_check = false;
+
+if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
+hmode_check = true;
+}
+
+RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
+if (env->priv == PRV_M) {
+return RISCV_EXCP_NONE;
+}
+
+/*
+ * No need of separate function for rv32 as menvcfg stores both menvcfg
+ * menvcfgh for RV32.
+ */
+if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
+  get_field(env->menvcfg, MENVCFG_STCE))) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (riscv_cpu_virt_enabled(env)) {
+if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
+  get_field(env->henvcfg, HENVCFG_STCE))) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException sstc_32(CPURISCVState *env, int csrno)
+{
+if (riscv_cpu_mxl(env) != MXL_RV32) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return sstc(env, csrno);
+}
+
 /* Checks if PointerMasking registers could be accessed */
 static RISCVException pointer_masking(CPURISCVState *env, int csrno)
 {
@@ -943,60 +961,6 @@ static RISCVException read_timeh(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
-static RISCVException sstc(CPURISCVState *env, int csrno)
-{
-RISCVCPU *cpu = env_archcpu(env);
-bool hmode_check = false;
-
-if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
-hmode_check = true;
-}
-
-RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
-if (ret != RISCV_EXCP_NONE) {
-return ret;
-}
-
-if (env->debugger) {
-return RISCV_EXCP_NONE;
-}
-
-if (env->priv == PRV_M) {
-return RISCV_EXCP_NONE;
-}
-
-/*
- * No need of separate function for rv32 as menvcfg stores both menvcfg
- * menvcfgh for RV32.
- */
-if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
-  get_field(env->menvcfg, MENVCFG_STCE))) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (riscv_cpu_virt_enabled(env)) {
-if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
-  get_field(env->henvcfg, HENVCFG_STCE))) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-}
-
-return RISCV_EXCP_NONE;
-}
-
-static RISCVException sstc_32(CPURISCVState *env, int csrno)
-{
-if (riscv_cpu_mxl(env) != MXL_RV32) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-return sstc(env, csrno);
-}
-
 static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,

[PATCH v2 12/18] target/riscv: gdbstub: Drop the vector CSRs in riscv-vector.xml

2023-02-28 Thread Bin Meng
From: Bin Meng 

It's worth noting that the vector CSR predicate() has a similar
run-time check logic to the FPU CSR. With the previous patch our
gdbstub can correctly report these vector CSRs via the CSR xml.

Commit 719d3561b269 ("target/riscv: gdb: support vector registers for rv64 & 
rv32")
inserted these vector CSRs in an ad-hoc, non-standard way in the
riscv-vector.xml. Now we can treat these CSRs no different from
other CSRs.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/gdbstub.c | 75 --
 1 file changed, 75 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index ef52f41460..6048541606 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -127,40 +127,6 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t 
*mem_buf, int n)
 return 0;
 }
 
-/*
- * Convert register index number passed by GDB to the correspond
- * vector CSR number. Vector CSRs are defined after vector registers
- * in dynamic generated riscv-vector.xml, thus the starting register index
- * of vector CSRs is 32.
- * Return 0 if register index number is out of range.
- */
-static int riscv_gdb_vector_csrno(int num_regs)
-{
-/*
- * The order of vector CSRs in the switch case
- * should match with the order defined in csr_ops[].
- */
-switch (num_regs) {
-case 32:
-return CSR_VSTART;
-case 33:
-return CSR_VXSAT;
-case 34:
-return CSR_VXRM;
-case 35:
-return CSR_VCSR;
-case 36:
-return CSR_VL;
-case 37:
-return CSR_VTYPE;
-case 38:
-return CSR_VLENB;
-default:
-/* Unknown register. */
-return 0;
-}
-}
-
 static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
 {
 uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
@@ -174,19 +140,6 @@ static int riscv_gdb_get_vector(CPURISCVState *env, 
GByteArray *buf, int n)
 return cnt;
 }
 
-int csrno = riscv_gdb_vector_csrno(n);
-
-if (!csrno) {
-return 0;
-}
-
-target_ulong val = 0;
-int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
-
-if (result == RISCV_EXCP_NONE) {
-return gdb_get_regl(buf, val);
-}
-
 return 0;
 }
 
@@ -201,19 +154,6 @@ static int riscv_gdb_set_vector(CPURISCVState *env, 
uint8_t *mem_buf, int n)
 return vlenb;
 }
 
-int csrno = riscv_gdb_vector_csrno(n);
-
-if (!csrno) {
-return 0;
-}
-
-target_ulong val = ldtul_p(mem_buf);
-int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
-
-if (result == RISCV_EXCP_NONE) {
-return sizeof(target_ulong);
-}
-
 return 0;
 }
 
@@ -361,21 +301,6 @@ static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int 
base_reg)
 num_regs++;
 }
 
-/* Define vector CSRs */
-const char *vector_csrs[7] = {
-"vstart", "vxsat", "vxrm", "vcsr",
-"vl", "vtype", "vlenb"
-};
-
-for (i = 0; i < 7; i++) {
-g_string_append_printf(s,
-   "",
-   vector_csrs[i], TARGET_LONG_BITS, base_reg++);
-num_regs++;
-}
-
 g_string_append_printf(s, "");
 
 cpu->dyn_vreg_xml = g_string_free(s, false);
-- 
2.25.1




[PATCH v2 17/18] target/riscv: Drop priv level check in mseccfg predicate()

2023-02-28 Thread Bin Meng
From: Bin Meng 

riscv_csrrw_check() already does the generic privilege level check
hence there is no need to do the specific M-mode access check in
the mseccfg predicate().

With this change debugger can access the mseccfg CSR anytime.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
---

(no changes since v1)

 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 020c3f524f..785f6f4d45 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -451,7 +451,7 @@ static RISCVException pmp(CPURISCVState *env, int csrno)
 
 static RISCVException epmp(CPURISCVState *env, int csrno)
 {
-if (env->priv == PRV_M && riscv_cpu_cfg(env)->epmp) {
+if (riscv_cpu_cfg(env)->epmp) {
 return RISCV_EXCP_NONE;
 }
 
-- 
2.25.1




[PATCH v2 15/18] target/riscv: Allow debugger to access {h, s}stateen CSRs

2023-02-28 Thread Bin Meng
From: Bin Meng 

At present {h,s}stateen CSRs are not reported in the CSR XML
hence gdb cannot access them.

Fix it by adjusting their predicate() routine logic so that the
static config check comes before the run-time check, as well as
adding a debugger check.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
---

(no changes since v1)

 target/riscv/csr.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 15b23b9b5a..a0e70f5ba0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -337,13 +337,22 @@ static RISCVException hstateen_pred(CPURISCVState *env, 
int csrno, int base)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+RISCVException ret = hmode(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
 if (env->priv < PRV_M) {
 if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 }
 
-return hmode(env, csrno);
+return RISCV_EXCP_NONE;
 }
 
 static RISCVException hstateen(CPURISCVState *env, int csrno)
@@ -366,6 +375,15 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+RISCVException ret = smode(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
 if (env->priv < PRV_M) {
 if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -378,7 +396,7 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
 }
 }
 
-return smode(env, csrno);
+return RISCV_EXCP_NONE;
 }
 
 /* Checks if PointerMasking registers could be accessed */
-- 
2.25.1




[PATCH v2 13/18] target/riscv: Allow debugger to access user timer and counter CSRs

2023-02-28 Thread Bin Meng
From: Bin Meng 

At present user timer and counter CSRs are not reported in the
CSR XML hence gdb cannot access them.

Fix it by adding a debugger check in their predicate() routine.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/csr.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 7284fd8a0d..10ae5df5e6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -131,6 +131,10 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
 
 skip_ext_pmu_check:
 
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
 if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
-- 
2.25.1




[PATCH v2 14/18] target/riscv: Allow debugger to access seed CSR

2023-02-28 Thread Bin Meng
From: Bin Meng 

At present seed CSR is not reported in the CSR XML hence gdb cannot
access it.

Fix it by adding a debugger check in its predicate() routine.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/csr.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 10ae5df5e6..15b23b9b5a 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -459,6 +459,10 @@ static RISCVException seed(CPURISCVState *env, int csrno)
 }
 
 #if !defined(CONFIG_USER_ONLY)
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
 /*
  * With a CSR read-write instruction:
  * 1) The seed CSR is always available in machine mode as normal.
-- 
2.25.1




[PATCH v2 09/18] target/riscv: Simplify getting RISCVCPU pointer from env

2023-02-28 Thread Bin Meng
Use env_archcpu() to get RISCVCPU pointer from env directly.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/csr.c | 36 
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a3e0e5755c..8e827362cc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -46,8 +46,7 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, 
int index,
uint64_t bit)
 {
 bool virt = riscv_cpu_virt_enabled(env);
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
 return RISCV_EXCP_NONE;
@@ -90,8 +89,7 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 
 static RISCVException vs(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 if (env->misa_ext & RVV ||
 cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
@@ -108,8 +106,7 @@ static RISCVException vs(CPURISCVState *env, int csrno)
 static RISCVException ctr(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 int ctr_index;
 target_ulong ctr_mask;
 int base_csrno = CSR_CYCLE;
@@ -166,8 +163,7 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 int ctr_index;
 int base_csrno = CSR_MHPMCOUNTER3;
 
@@ -195,8 +191,7 @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
 
 static RISCVException sscofpmf(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 if (!cpu->cfg.ext_sscofpmf) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -321,8 +316,7 @@ static RISCVException umode32(CPURISCVState *env, int csrno)
 
 static RISCVException mstateen(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 if (!cpu->cfg.ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -333,8 +327,7 @@ static RISCVException mstateen(CPURISCVState *env, int 
csrno)
 
 static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 if (!cpu->cfg.ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -363,8 +356,7 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
 {
 bool virt = riscv_cpu_virt_enabled(env);
 int index = csrno - CSR_SSTATEEN0;
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 if (!cpu->cfg.ext_smstateen) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -918,8 +910,7 @@ static RISCVException read_timeh(CPURISCVState *env, int 
csrno,
 
 static RISCVException sstc(CPURISCVState *env, int csrno)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 bool hmode_check = false;
 
 if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
@@ -1152,8 +1143,7 @@ static RISCVException write_ignore(CPURISCVState *env, 
int csrno,
 static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 *val = cpu->cfg.mvendorid;
 return RISCV_EXCP_NONE;
@@ -1162,8 +1152,7 @@ static RISCVException read_mvendorid(CPURISCVState *env, 
int csrno,
 static RISCVException read_marchid(CPURISCVState *env, int csrno,
target_ulong *val)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 *val = cpu->cfg.marchid;
 return RISCV_EXCP_NONE;
@@ -1172,8 +1161,7 @@ static RISCVException read_marchid(CPURISCVState *env, 
int csrno,
 static RISCVException read_mimpid(CPURISCVState *env, int csrno,
   target_ulong *val)
 {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
 
 *val = cpu->cfg.mimpid;
 return RISCV_EXCP_NONE;
-- 
2.25.1




[PATCH v2 11/18] target/riscv: gdbstub: Turn on debugger mode before calling CSR predicate()

2023-02-28 Thread Bin Meng
Since commit 94452ac4cf26 ("target/riscv: remove fflags, frm, and fcsr from 
riscv-*-fpu.xml")
the 3 FPU CSRs are removed from the XML target decription. The
original intent of that commit was based on the assumption that
the 3 FPU CSRs will show up in the riscv-csr.xml so the ones in
riscv-*-fpu.xml are redundant. But unforuantely that is not true.
As the FPU CSR predicate() has a run-time check on MSTATUS.FS,
at the time when CSR XML is generated MSTATUS.FS is unset, hence
no FPU CSRs will be reported.

The FPU CSR predicate() already considered such a case of being
accessed by a debugger. All we need to do is to turn on debugger
mode before calling predicate().

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/gdbstub.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 294f0ceb1c..ef52f41460 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -280,6 +280,10 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 int bitsize = 16 << env->misa_mxl_max;
 int i;
 
+#if !defined(CONFIG_USER_ONLY)
+env->debugger = true;
+#endif
+
 /* Until gdb knows about 128-bit registers */
 if (bitsize > 64) {
 bitsize = 64;
@@ -308,6 +312,11 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 g_string_append_printf(s, "");
 
 cpu->dyn_csr_xml = g_string_free(s, false);
+
+#if !defined(CONFIG_USER_ONLY)
+env->debugger = false;
+#endif
+
 return CSR_TABLE_SIZE;
 }
 
-- 
2.25.1




[PATCH v2 08/18] target/riscv: Simplify {read, write}_pmpcfg() a little bit

2023-02-28 Thread Bin Meng
Use the register index that has already been calculated in the
pmpcfg_csr_{read,write} call.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/csr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9264db6110..a3e0e5755c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3360,7 +3360,7 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int 
csrno,
 if (!check_pmp_reg_index(env, reg_index)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
-*val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
+*val = pmpcfg_csr_read(env, reg_index);
 return RISCV_EXCP_NONE;
 }
 
@@ -3372,7 +3372,7 @@ static RISCVException write_pmpcfg(CPURISCVState *env, 
int csrno,
 if (!check_pmp_reg_index(env, reg_index)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
-pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
+pmpcfg_csr_write(env, reg_index, val);
 return RISCV_EXCP_NONE;
 }
 
-- 
2.25.1




[PATCH v2 07/18] target/riscv: Use 'bool' type for read_only

2023-02-28 Thread Bin Meng
The read_only variable is currently declared as an 'int', but it
should really be a 'bool'.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6a82628749..9264db6110 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3775,7 +3775,7 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
RISCVCPU *cpu)
 {
 /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
-int read_only = get_field(csrno, 0xC00) == 3;
+bool read_only = get_field(csrno, 0xC00) == 3;
 int csr_min_priv = csr_ops[csrno].min_priv_ver;
 
 /* ensure the CSR extension is enabled */
-- 
2.25.1
‘



[PATCH v2 10/18] target/riscv: Avoid reporting odd-numbered pmpcfgX in the CSR XML for RV64

2023-02-28 Thread Bin Meng
At present the odd-numbered PMP configuration registers for RV64 are
reported in the CSR XML by QEMU gdbstub. However these registers do
not exist on RV64 so trying to access them from gdb results in 'E14'.

Move the pmpcfgX index check from the actual read/write routine to
the PMP CSR predicate() routine, so that non-existent pmpcfgX won't
be reported in the CSR XML for RV64.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

Changes in v2:
- keep the 'RV128 restriction check' todo comment

 target/riscv/csr.c | 24 +---
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8e827362cc..7284fd8a0d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -412,6 +412,15 @@ static int aia_hmode32(CPURISCVState *env, int csrno)
 static RISCVException pmp(CPURISCVState *env, int csrno)
 {
 if (riscv_cpu_cfg(env)->pmp) {
+if (csrno <= CSR_PMPCFG3) {
+uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+/* TODO: RV128 restriction check */
+if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
 return RISCV_EXCP_NONE;
 }
 
@@ -3331,23 +3340,11 @@ static RISCVException write_mseccfg(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
-static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
-{
-/* TODO: RV128 restriction check */
-if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
-return false;
-}
-return true;
-}
-
 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
   target_ulong *val)
 {
 uint32_t reg_index = csrno - CSR_PMPCFG0;
 
-if (!check_pmp_reg_index(env, reg_index)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
 *val = pmpcfg_csr_read(env, reg_index);
 return RISCV_EXCP_NONE;
 }
@@ -3357,9 +3354,6 @@ static RISCVException write_pmpcfg(CPURISCVState *env, 
int csrno,
 {
 uint32_t reg_index = csrno - CSR_PMPCFG0;
 
-if (!check_pmp_reg_index(env, reg_index)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
 pmpcfg_csr_write(env, reg_index, val);
 return RISCV_EXCP_NONE;
 }
-- 
2.25.1




[PATCH v2 06/18] target/riscv: Coding style fixes in csr.c

2023-02-28 Thread Bin Meng
Fix various places that violate QEMU coding style:

- correct multi-line comment format
- indent to opening parenthesis

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/csr.c | 62 --
 1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index cfd7ffc5c2..6a82628749 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -963,7 +963,7 @@ static RISCVException sstc_32(CPURISCVState *env, int csrno)
 }
 
 static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
-target_ulong *val)
+ target_ulong *val)
 {
 *val = env->vstimecmp;
 
@@ -971,7 +971,7 @@ static RISCVException read_vstimecmp(CPURISCVState *env, 
int csrno,
 }
 
 static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
-target_ulong *val)
+  target_ulong *val)
 {
 *val = env->vstimecmp >> 32;
 
@@ -979,7 +979,7 @@ static RISCVException read_vstimecmph(CPURISCVState *env, 
int csrno,
 }
 
 static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
-target_ulong val)
+  target_ulong val)
 {
 RISCVCPU *cpu = env_archcpu(env);
 
@@ -996,7 +996,7 @@ static RISCVException write_vstimecmp(CPURISCVState *env, 
int csrno,
 }
 
 static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
-target_ulong val)
+   target_ulong val)
 {
 RISCVCPU *cpu = env_archcpu(env);
 
@@ -1020,7 +1020,7 @@ static RISCVException read_stimecmp(CPURISCVState *env, 
int csrno,
 }
 
 static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
-target_ulong *val)
+ target_ulong *val)
 {
 if (riscv_cpu_virt_enabled(env)) {
 *val = env->vstimecmp >> 32;
@@ -1032,7 +1032,7 @@ static RISCVException read_stimecmph(CPURISCVState *env, 
int csrno,
 }
 
 static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
-target_ulong val)
+ target_ulong val)
 {
 RISCVCPU *cpu = env_archcpu(env);
 
@@ -1055,7 +1055,7 @@ static RISCVException write_stimecmp(CPURISCVState *env, 
int csrno,
 }
 
 static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
-target_ulong val)
+  target_ulong val)
 {
 RISCVCPU *cpu = env_archcpu(env);
 
@@ -1342,7 +1342,8 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 
 /* 'E' excludes all other extensions */
 if (val & RVE) {
-/* when we support 'E' we can do "val = RVE;" however
+/*
+ * when we support 'E' we can do "val = RVE;" however
  * for now we just drop writes if 'E' is present.
  */
 return RISCV_EXCP_NONE;
@@ -1361,7 +1362,8 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 val &= ~RVD;
 }
 
-/* Suppress 'C' if next instruction is not aligned
+/*
+ * Suppress 'C' if next instruction is not aligned
  * TODO: this should check next_pc
  */
 if ((val & RVC) && (GETPC() & ~3) != 0) {
@@ -1830,28 +1832,28 @@ static RISCVException write_mscratch(CPURISCVState 
*env, int csrno,
 }
 
 static RISCVException read_mepc(CPURISCVState *env, int csrno,
- target_ulong *val)
+target_ulong *val)
 {
 *val = env->mepc;
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException write_mepc(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
 {
 env->mepc = val;
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_mcause(CPURISCVState *env, int csrno,
- target_ulong *val)
+  target_ulong *val)
 {
 *val = env->mcause;
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException write_mcause(CPURISCVState *env, int csrno,
- target_ulong val)
+   target_ulong val)
 {
 env->mcause = val;
 return RISCV_EXCP_NONE;
@@ -1873,14 +1875,14 @@ static RISCVException write_mtval(CPURISCVState *env, 
int csrno,
 
 /* Execution environment configuration setup */
 static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
- target_ulong *val)
+   target_ulon

[PATCH v2 05/18] target/riscv: gdbstub: Do not generate CSR XML if Zicsr is disabled

2023-02-28 Thread Bin Meng
There is no need to generate the CSR XML if the Zicsr extension
is not enabled.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/gdbstub.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 704f3d6922..294f0ceb1c 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -406,7 +406,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
 g_assert_not_reached();
 }
 
-gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
- riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
- "riscv-csr.xml", 0);
+if (cpu->cfg.ext_icsr) {
+int base_reg = cs->gdb_num_regs;
+gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
+ riscv_gen_dynamic_csr_xml(cs, base_reg),
+ "riscv-csr.xml", 0);
+}
 }
-- 
2.25.1




[PATCH v2 04/18] target/riscv: gdbstub: Minor change for better readability

2023-02-28 Thread Bin Meng
Use a variable 'base_reg' to represent cs->gdb_num_regs so that
the call to ricsv_gen_dynamic_vector_xml() can be placed in one
single line for better readability.

Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/gdbstub.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index e57372db38..704f3d6922 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -385,9 +385,9 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
  32, "riscv-32bit-fpu.xml", 0);
 }
 if (env->misa_ext & RVV) {
+int base_reg = cs->gdb_num_regs;
 gdb_register_coprocessor(cs, riscv_gdb_get_vector, 
riscv_gdb_set_vector,
- ricsv_gen_dynamic_vector_xml(cs,
-  
cs->gdb_num_regs),
+ ricsv_gen_dynamic_vector_xml(cs, base_reg),
  "riscv-vector.xml", 0);
 }
 switch (env->misa_mxl_max) {
-- 
2.25.1




[PATCH v2 03/18] target/riscv: Use g_assert() for the predicate() NULL check

2023-02-28 Thread Bin Meng
At present riscv_csrrw_check() checks the CSR predicate() against
NULL and throws RISCV_EXCP_ILLEGAL_INST if it is NULL. But this is
a pure software check, and has nothing to do with the emulation of
the hardware behavior, thus it is inappropriate to return illegal
instruction exception when software forgets to install the hook.

Change to use g_assert() instead.

Signed-off-by: Bin Meng 
---

Changes in v2:
- new patch: Use assert() for the predicate() NULL check

 target/riscv/csr.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4cc2c6370f..cfd7ffc5c2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3786,11 +3786,6 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
-/* check predicate */
-if (!csr_ops[csrno].predicate) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
 /* read / write check */
 if (write_mask && read_only) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -3803,6 +3798,7 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
  * illegal instruction exception should be triggered instead of virtual
  * instruction exception. Hence this comes after the read / write check.
  */
+g_assert(csr_ops[csrno].predicate != NULL);
 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
 if (ret != RISCV_EXCP_NONE) {
 return ret;
-- 
2.25.1




[PATCH v2 02/18] target/riscv: Add some comments to clarify the priority policy of riscv_csrrw_check()

2023-02-28 Thread Bin Meng
The priority policy of riscv_csrrw_check() was once adjusted in
commit eacaf4401956 ("target/riscv: Fix priority of csr related check in 
riscv_csrrw_check")
whose commit message says the CSR existence check should come before
the access control check, but the code changes did not agree with
the commit message, that the predicate() check actually came after
the read / write check.

In fact this was intentional. Add some comments there so that people
won't bother trying to change it without a solid reason.

Signed-off-by: Bin Meng 
---

Changes in v2:
- Keep the original priority policy, instead add some comments for clarification

 target/riscv/csr.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 75a540bfcb..4cc2c6370f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3776,11 +3776,12 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 int read_only = get_field(csrno, 0xC00) == 3;
 int csr_min_priv = csr_ops[csrno].min_priv_ver;
 
-/* ensure the CSR extension is enabled. */
+/* ensure the CSR extension is enabled */
 if (!cpu->cfg.ext_icsr) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+/* privileged spec version check */
 if (env->priv_ver < csr_min_priv) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
@@ -3790,10 +3791,18 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+/* read / write check */
 if (write_mask && read_only) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+/*
+ * The predicate() not only does existence check but also does some
+ * access control check which triggers for example virtual instruction
+ * exception in some cases. When writing read-only CSRs in those cases
+ * illegal instruction exception should be triggered instead of virtual
+ * instruction exception. Hence this comes after the read / write check.
+ */
 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
 if (ret != RISCV_EXCP_NONE) {
 return ret;
-- 
2.25.1




[PATCH v2 01/18] target/riscv: gdbstub: Check priv spec version before reporting CSR

2023-02-28 Thread Bin Meng
The gdbstub CSR XML is dynamically generated according to the result
of the CSR predicate() result. This has been working fine until
commit 7100fe6c2441 ("target/riscv: Enable privileged spec version 1.12")
introduced the privilege spec version check in riscv_csrrw_check().

When debugging the 'sifive_u' machine whose priv spec is at 1.10,
gdbstub reports priv spec 1.12 CSRs like menvcfg in the XML, hence
we see "remote failure reply 'E14'" message when examining all CSRs
via "info register system" from gdb.

Add the priv spec version check in the CSR XML generation logic to
fix this issue.

Fixes: 7100fe6c2441 ("target/riscv: Enable privileged spec version 1.12")
Signed-off-by: Bin Meng 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
---

(no changes since v1)

 target/riscv/gdbstub.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 6e7bbdbd5e..e57372db38 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -290,6 +290,9 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 g_string_append_printf(s, "");
 
 for (i = 0; i < CSR_TABLE_SIZE; i++) {
+if (env->priv_ver < csr_ops[i].min_priv_ver) {
+continue;
+}
 predicate = csr_ops[i].predicate;
 if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
 if (csr_ops[i].name) {
-- 
2.25.1




  1   2   3   4   5   6   7   8   9   10   >