All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/34]  Enable build of full Xen for RISC-V
@ 2023-12-22 15:12 Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 01/34] xen/riscv: disable unnecessary configs Oleksii Kurochko
                   ` (33 more replies)
  0 siblings, 34 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Doug Goldstein, Stefano Stabellini,
	Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Jan Beulich, Julien Grall, Wei Liu, Paul Durrant,
	Roger Pau Monné, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, Shawn Anastasio, Tamas K Lengyel,
	Alexandru Isaila, Petre Pircalabu

This patch series performs all of the additions necessary to drop the
build overrides for RISCV and enable the full Xen build. Except in cases
where compatibile implementations already exist (e.g. atomic.h and
bitops.h), the newly added definitions are simple.

The patch series is based on the following patch series:
-	[PATCH v6 0/9] Introduce generic headers   [1]
- [PATCH] move __read_mostly to xen/cache.h  [2]

Right now, the patch series doesn't have a direct dependency on [2] and it
provides __read_mostly in the patch:
    [PATCH v3 26/34] xen/riscv: add definition of __read_mostly
However, it will be dropped as soon as [2] is merged or at least when the
final version of the patch [2] is provided.

[1] https://lore.kernel.org/xen-devel/cover.1703072575.git.oleksii.kurochko@gmail.com/
[2] https://lore.kernel.org/xen-devel/f25eb5c9-7c14-6e23-8535-2c66772b333e@suse.com/
 
---
Changes in V3:
 - Update the cover letter message
 - The following patches were dropped as they were merged to staging:
    [PATCH v2 03/39] xen/riscv:introduce asm/byteorder.h
    [PATCH v2 04/39] xen/riscv: add public arch-riscv.h
    [PATCH v2 05/39] xen/riscv: introduce spinlock.h
    [PATCH v2 20/39] xen/riscv: define bug frame tables in xen.lds.S
    [PATCH v2 34/39] xen: add RISCV support for pmu.h
    [PATCH v2 35/39] xen: add necessary headers to common to build full Xen for RISC-V
 - Instead of the following patches were introduced new:
    [PATCH v2 10/39] xen/riscv: introduce asm/iommu.h
    [PATCH v2 11/39] xen/riscv: introduce asm/nospec.h
 - remove "asm/"  for commit messages which start with "xen/riscv:"
 - code style updates.
 - add emulation of {cmp}xchg_* for 1 and 2 bytes types.
 - code style fixes.
 - add SPDX and footer for the newly added headers.
 - introduce generic find-next-bit.c.
 - some other mionor changes. ( details please find in a patch )
---
Changes in V2:
  - Drop the following patches as they are the part of [2]:
      [PATCH v1 06/57] xen/riscv: introduce paging.h
      [PATCH v1 08/57] xen/riscv: introduce asm/device.h
      [PATCH v1 10/57] xen/riscv: introduce asm/grant_table.h
      [PATCH v1 12/57] xen/riscv: introduce asm/hypercall.h
      [PATCH v1 13/57] xen/riscv: introduce asm/iocap.h
      [PATCH v1 15/57] xen/riscv: introduce asm/mem_access.h
      [PATCH v1 18/57] xen/riscv: introduce asm/random.h
      [PATCH v1 21/57] xen/riscv: introduce asm/xenoprof.h
      [PATCH v1 24/57] xen/riscv: introduce asm/percpu.h
      [PATCH v1 29/57] xen/riscv: introduce asm/hardirq.h
      [PATCH v1 33/57] xen/riscv: introduce asm/altp2m.h
      [PATCH v1 38/57] xen/riscv: introduce asm/monitor.h
      [PATCH v1 39/57] xen/riscv: introduce asm/numa.h
      [PATCH v1 42/57] xen/riscv: introduce asm/softirq.h
  - xen/lib.h in most of the cases were changed to xen/bug.h as
    mostly functionilty of bug.h is used.
  - align arch-riscv.h with Arm's version of it.
  - change the Author of commit with introduction of asm/atomic.h.
  - update some definition from spinlock.h.
  - code style changes.
---

Bobby Eshleman (1):
  xen/riscv: introduce atomic.h

Oleksii Kurochko (33):
  xen/riscv: disable unnecessary configs
  xen/riscv: use some asm-generic headers
  xen: add support in public/hvm/save.h for PPC and RISC-V
  xen/riscv: introduce cpufeature.h
  xen/riscv: introduce guest_atomics.h
  xen: avoid generation of empty asm/iommu.h
  xen/asm-generic: introdure nospec.h
  xen/riscv: introduce setup.h
  xen/riscv: introduce system.h
  xen/riscv: introduce bitops.h
  xen/riscv: introduce flushtlb.h
  xen/riscv: introduce smp.h
  xen/riscv: introduce cmpxchg.h
  xen/riscv: introduce io.h
  xen/lib: introduce generic find next bit operations
  xen/riscv: add compilation of generic find-next-bit.c
  xen/riscv: introduce domain.h
  xen/riscv: introduce guest_access.h
  xen/riscv: introduce irq.h
  xen/riscv: introduce p2m.h
  xen/riscv: introduce regs.h
  xen/riscv: introduce time.h
  xen/riscv: introduce event.h
  xen/riscv: introduce monitor.h
  xen/riscv: add definition of __read_mostly
  xen/riscv: define an address of frame table
  xen/riscv: add required things to current.h
  xen/riscv: add minimal stuff to page.h to build full Xen
  xen/riscv: add minimal stuff to processor.h to build full Xen
  xen/riscv: add minimal stuff to mm.h to build full Xen
  xen/rirscv: add minimal amount of stubs to build full Xen
  xen/riscv: enable full Xen build
  xen/README: add compiler and binutils versions for RISC-V64

 README                                        |   3 +
 .../gitlab-ci/riscv-fixed-randconfig.yaml     |  27 +
 xen/arch/arm/include/asm/Makefile             |   1 +
 xen/arch/ppc/include/asm/Makefile             |   1 +
 xen/arch/ppc/include/asm/nospec.h             |  15 -
 xen/arch/ppc/include/asm/p2m.h                |   3 +-
 xen/arch/riscv/Kconfig                        |   1 +
 xen/arch/riscv/Makefile                       |  17 +-
 xen/arch/riscv/arch.mk                        |   4 -
 xen/arch/riscv/configs/tiny64_defconfig       |  18 +
 xen/arch/riscv/early_printk.c                 | 168 ------
 xen/arch/riscv/include/asm/Makefile           |  14 +
 xen/arch/riscv/include/asm/atomic.h           | 384 ++++++++++++++
 xen/arch/riscv/include/asm/bitops.h           | 267 ++++++++++
 xen/arch/riscv/include/asm/cache.h            |   2 +
 xen/arch/riscv/include/asm/cmpxchg.h          | 496 ++++++++++++++++++
 xen/arch/riscv/include/asm/config.h           |  87 +--
 xen/arch/riscv/include/asm/cpufeature.h       |  23 +
 xen/arch/riscv/include/asm/current.h          |  19 +
 xen/arch/riscv/include/asm/domain.h           |  53 ++
 xen/arch/riscv/include/asm/event.h            |  40 ++
 xen/arch/riscv/include/asm/fence.h            |  22 +
 xen/arch/riscv/include/asm/flushtlb.h         |  33 ++
 xen/arch/riscv/include/asm/guest_access.h     |  29 +
 xen/arch/riscv/include/asm/guest_atomics.h    |  49 ++
 xen/arch/riscv/include/asm/io.h               | 142 +++++
 xen/arch/riscv/include/asm/irq.h              |  37 ++
 xen/arch/riscv/include/asm/mm.h               | 249 ++++++++-
 xen/arch/riscv/include/asm/monitor.h          |  26 +
 xen/arch/riscv/include/asm/p2m.h              | 102 ++++
 xen/arch/riscv/include/asm/page.h             |  22 +
 xen/arch/riscv/include/asm/processor.h        |  15 +
 xen/arch/riscv/include/asm/regs.h             |  29 +
 xen/arch/riscv/include/asm/setup.h            |  17 +
 xen/arch/riscv/include/asm/smp.h              |  28 +
 xen/arch/riscv/include/asm/system.h           |  90 ++++
 xen/arch/riscv/include/asm/time.h             |  29 +
 xen/arch/riscv/mm.c                           |  52 +-
 xen/arch/riscv/setup.c                        |   9 +-
 xen/arch/riscv/stubs.c                        | 422 +++++++++++++++
 xen/arch/riscv/traps.c                        |  25 +
 xen/common/Kconfig                            |   3 +
 xen/include/asm-generic/bitops/bitops-bits.h  |  10 +
 xen/include/asm-generic/bitops/ffs.h          |   9 +
 xen/include/asm-generic/bitops/ffz.h          |  13 +
 .../asm-generic/bitops/find-first-bit-set.h   |  17 +
 xen/include/asm-generic/bitops/fls.h          |  18 +
 xen/include/asm-generic/bitops/flsl.h         |  10 +
 xen/include/asm-generic/bitops/hweight.h      |  13 +
 xen/include/asm-generic/bitops/test-bit.h     |  16 +
 .../asm => include/asm-generic}/nospec.h      |  10 +-
 xen/include/public/hvm/save.h                 |   4 +-
 xen/include/xen/iommu.h                       |   4 +
 xen/lib/Makefile                              |   1 +
 xen/lib/find-next-bit.c                       | 281 ++++++++++
 55 files changed, 3248 insertions(+), 231 deletions(-)
 delete mode 100644 xen/arch/ppc/include/asm/nospec.h
 create mode 100644 xen/arch/riscv/include/asm/Makefile
 create mode 100644 xen/arch/riscv/include/asm/atomic.h
 create mode 100644 xen/arch/riscv/include/asm/bitops.h
 create mode 100644 xen/arch/riscv/include/asm/cmpxchg.h
 create mode 100644 xen/arch/riscv/include/asm/cpufeature.h
 create mode 100644 xen/arch/riscv/include/asm/domain.h
 create mode 100644 xen/arch/riscv/include/asm/event.h
 create mode 100644 xen/arch/riscv/include/asm/fence.h
 create mode 100644 xen/arch/riscv/include/asm/flushtlb.h
 create mode 100644 xen/arch/riscv/include/asm/guest_access.h
 create mode 100644 xen/arch/riscv/include/asm/guest_atomics.h
 create mode 100644 xen/arch/riscv/include/asm/io.h
 create mode 100644 xen/arch/riscv/include/asm/irq.h
 create mode 100644 xen/arch/riscv/include/asm/monitor.h
 create mode 100644 xen/arch/riscv/include/asm/p2m.h
 create mode 100644 xen/arch/riscv/include/asm/regs.h
 create mode 100644 xen/arch/riscv/include/asm/setup.h
 create mode 100644 xen/arch/riscv/include/asm/smp.h
 create mode 100644 xen/arch/riscv/include/asm/system.h
 create mode 100644 xen/arch/riscv/include/asm/time.h
 create mode 100644 xen/arch/riscv/stubs.c
 create mode 100644 xen/include/asm-generic/bitops/bitops-bits.h
 create mode 100644 xen/include/asm-generic/bitops/ffs.h
 create mode 100644 xen/include/asm-generic/bitops/ffz.h
 create mode 100644 xen/include/asm-generic/bitops/find-first-bit-set.h
 create mode 100644 xen/include/asm-generic/bitops/fls.h
 create mode 100644 xen/include/asm-generic/bitops/flsl.h
 create mode 100644 xen/include/asm-generic/bitops/hweight.h
 create mode 100644 xen/include/asm-generic/bitops/test-bit.h
 rename xen/{arch/arm/include/asm => include/asm-generic}/nospec.h (54%)
 create mode 100644 xen/lib/find-next-bit.c

-- 
2.43.0



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

* [PATCH v3 01/34] xen/riscv: disable unnecessary configs
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 02/34] xen/riscv: use some asm-generic headers Oleksii Kurochko
                   ` (32 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Doug Goldstein, Stefano Stabellini,
	Alistair Francis, Bob Eshleman, Connor Davis

This patch disables unnecessary configs for two cases:
1. By utilizing EXTRA_FIXED_RANDCONFIG and risc-fixed-randconfig.yaml
   file for randconfig builds (GitLab CI jobs).
2. By using tiny64_defconfig for non-randconfig builds.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - Remove EXTRA_FIXED_RANDCONFIG for non-randconfig jobs.
   For non-randconfig jobs, it is sufficient to disable configs by using the defconfig.
 - Remove double blank lines in build.yaml file before archlinux-current-gcc-riscv64-debug
---
Changes in V2:
 - update the commit message.
 - remove xen/arch/riscv/Kconfig changes.
---
 .../gitlab-ci/riscv-fixed-randconfig.yaml     | 27 +++++++++++++++++++
 xen/arch/riscv/configs/tiny64_defconfig       | 17 ++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/automation/gitlab-ci/riscv-fixed-randconfig.yaml b/automation/gitlab-ci/riscv-fixed-randconfig.yaml
index f1282b40c9..344f39c2d8 100644
--- a/automation/gitlab-ci/riscv-fixed-randconfig.yaml
+++ b/automation/gitlab-ci/riscv-fixed-randconfig.yaml
@@ -5,3 +5,30 @@
       CONFIG_EXPERT=y
       CONFIG_GRANT_TABLE=n
       CONFIG_MEM_ACCESS=n
+      CONFIG_COVERAGE=n
+      CONFIG_SCHED_CREDIT=n
+      CONFIG_SCHED_CREDIT2=n
+      CONFIG_SCHED_RTDS=n
+      CONFIG_SCHED_NULL=n
+      CONFIG_SCHED_ARINC653=n
+      CONFIG_TRACEBUFFER=n
+      CONFIG_HYPFS=n
+      CONFIG_SPECULATIVE_HARDEN_ARRAY=n
+      CONFIG_ARGO=n
+      CONFIG_HYPFS_CONFIG=n
+      CONFIG_CORE_PARKING=n
+      CONFIG_DEBUG_TRACE=n
+      CONFIG_IOREQ_SERVER=n
+      CONFIG_CRASH_DEBUG=n
+      CONFIG_KEXEC=n
+      CONFIG_LIVEPATCH=n
+      CONFIG_NUMA=n
+      CONFIG_PERF_COUNTERS=n
+      CONFIG_HAS_PMAP=n
+      CONFIG_TRACEBUFFER=n
+      CONFIG_XENOPROF=n
+      CONFIG_COMPAT=n
+      CONFIG_COVERAGE=n
+      CONFIG_UBSAN=n
+      CONFIG_NEEDS_LIBELF=n
+      CONFIG_XSM=n
diff --git a/xen/arch/riscv/configs/tiny64_defconfig b/xen/arch/riscv/configs/tiny64_defconfig
index 09defe236b..35915255e6 100644
--- a/xen/arch/riscv/configs/tiny64_defconfig
+++ b/xen/arch/riscv/configs/tiny64_defconfig
@@ -7,6 +7,23 @@
 # CONFIG_GRANT_TABLE is not set
 # CONFIG_SPECULATIVE_HARDEN_ARRAY is not set
 # CONFIG_MEM_ACCESS is not set
+# CONFIG_ARGO is not set
+# CONFIG_HYPFS_CONFIG is not set
+# CONFIG_CORE_PARKING is not set
+# CONFIG_DEBUG_TRACE is not set
+# CONFIG_IOREQ_SERVER is not set
+# CONFIG_CRASH_DEBUG is not setz
+# CONFIG_KEXEC is not set
+# CONFIG_LIVEPATCH is not set
+# CONFIG_NUMA is not set
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_HAS_PMAP is not set
+# CONFIG_TRACEBUFFER is not set
+# CONFIG_XENOPROF is not set
+# CONFIG_COMPAT is not set
+# CONFIG_COVERAGE is not set
+# CONFIG_UBSAN is not set
+# CONFIG_NEEDS_LIBELF is not set
 
 CONFIG_RISCV_64=y
 CONFIG_DEBUG=y
-- 
2.43.0



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

* [PATCH v3 02/34] xen/riscv: use some asm-generic headers
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 01/34] xen/riscv: disable unnecessary configs Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V Oleksii Kurochko
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Some headers are the same as asm-generic verions of them
so use them instead of arch-specific headers.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 As [PATCH v6 0/9] Introduce generic headers
 (https://lore.kernel.org/xen-devel/cover.1703072575.git.oleksii.kurochko@gmail.com/)
 is not stable, the list in asm/Makefile can be changed, but the changes will
 be easy.
---
Changes in V3:
 - remove monitor.h from the RISC-V asm/Makefile list.
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V2:
 - New commit introduced in V2.
---
 xen/arch/riscv/include/asm/Makefile | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/Makefile

diff --git a/xen/arch/riscv/include/asm/Makefile b/xen/arch/riscv/include/asm/Makefile
new file mode 100644
index 0000000000..adb752b804
--- /dev/null
+++ b/xen/arch/riscv/include/asm/Makefile
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+generic-y += altp2m.h
+generic-y += device.h
+generic-y += div64.h
+generic-y += hardirq.h
+generic-y += hypercall.h
+generic-y += iocap.h
+generic-y += numa.h
+generic-y += paging.h
+generic-y += percpu.h
+generic-y += random.h
+generic-y += softirq.h
+generic-y += vm_event.h
-- 
2.43.0



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

* [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 01/34] xen/riscv: disable unnecessary configs Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 02/34] xen/riscv: use some asm-generic headers Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-04 11:01   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 04/34] xen/riscv: introduce cpufeature.h Oleksii Kurochko
                   ` (30 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Andrew Cooper, George Dunlap, Jan Beulich,
	Julien Grall, Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - update the commit message.
 - For PPC and RISC-V nothing to include in public/hvm/save.h, so just comment was
   added.
---
Changes in V2:
 - remove copyright an the top of hvm/save.h as the header write now is a newly
   introduced empty header.
---
 xen/include/public/hvm/save.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xen/include/public/hvm/save.h b/xen/include/public/hvm/save.h
index ff0048e5f8..31b5cd163b 100644
--- a/xen/include/public/hvm/save.h
+++ b/xen/include/public/hvm/save.h
@@ -89,8 +89,8 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm_save_end);
 #include "../arch-x86/hvm/save.h"
 #elif defined(__arm__) || defined(__aarch64__)
 #include "../arch-arm/hvm/save.h"
-#elif defined(__powerpc64__)
-#include "../arch-ppc.h"
+#elif defined(__powerpc64__) || defined(__riscv)
+/* no specific header to include */
 #else
 #error "unsupported architecture"
 #endif
-- 
2.43.0



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

* [PATCH v3 04/34] xen/riscv: introduce cpufeature.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (2 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h Oleksii Kurochko
                   ` (29 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - add SPDX and footer
 - update declaration of cpu_nr_siblings() to return unsigned int instead of int.
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/cpufeature.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/cpufeature.h

diff --git a/xen/arch/riscv/include/asm/cpufeature.h b/xen/arch/riscv/include/asm/cpufeature.h
new file mode 100644
index 0000000000..c08b7d67ad
--- /dev/null
+++ b/xen/arch/riscv/include/asm/cpufeature.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_CPUFEATURE_H
+#define __ASM_RISCV_CPUFEATURE_H
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned int cpu_nr_siblings(unsigned int cpu)
+{
+    return 1;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_RISCV_CPUFEATURE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (3 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 04/34] xen/riscv: introduce cpufeature.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-11 15:57   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h Oleksii Kurochko
                   ` (28 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - update the commit message
 - drop TODO commit.
 - add ASSERT_UNREACHABLE for stubs guest functions.
 - Add SPDX & footer
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/guest_atomics.h | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/guest_atomics.h

diff --git a/xen/arch/riscv/include/asm/guest_atomics.h b/xen/arch/riscv/include/asm/guest_atomics.h
new file mode 100644
index 0000000000..98f7df7b6a
--- /dev/null
+++ b/xen/arch/riscv/include/asm/guest_atomics.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_GUEST_ATOMICS_H
+#define __ASM_RISCV_GUEST_ATOMICS_H
+
+#define guest_testop(name)                                                  \
+static inline int guest_##name(struct domain *d, int nr, volatile void *p)  \
+{                                                                           \
+    (void) d;                                                               \
+    (void) nr;                                                              \
+    (void) p;                                                               \
+                                                                            \
+    ASSERT_UNREACHABLE();                                                   \
+                                                                            \
+    return 0;                                                               \
+}
+
+#define guest_bitop(name)                                                   \
+static inline void guest_##name(struct domain *d, int nr, volatile void *p) \
+{                                                                           \
+    (void) d;                                                               \
+    (void) nr;                                                              \
+    (void) p;                                                               \
+    ASSERT_UNREACHABLE();                                                   \
+}
+
+guest_bitop(set_bit)
+guest_bitop(clear_bit)
+guest_bitop(change_bit)
+
+#undef guest_bitop
+
+guest_testop(test_and_set_bit)
+guest_testop(test_and_clear_bit)
+guest_testop(test_and_change_bit)
+
+#undef guest_testop
+
+#define guest_test_bit(d, nr, p) ((void)(d), test_bit(nr, p))
+
+#endif /* __ASM_RISCV_GUEST_ATOMICS_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (4 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-04 11:04   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 07/34] xen/asm-generic: introdure nospec.h Oleksii Kurochko
                   ` (27 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Jan Beulich, Paul Durrant, Roger Pau Monné

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - new patch.
---
 xen/include/xen/iommu.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index f53d045e2c..8adbf29d3b 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -337,7 +337,9 @@ extern int iommu_add_extra_reserved_device_memory(unsigned long start,
 extern int iommu_get_extra_reserved_device_memory(iommu_grdm_t *func,
                                                   void *ctxt);
 
+#ifdef CONFIG_HAS_PASSTHROUGH
 #include <asm/iommu.h>
+#endif
 
 #ifndef iommu_call
 # define iommu_call(ops, fn, args...) ((ops)->fn(args))
@@ -345,7 +347,9 @@ extern int iommu_get_extra_reserved_device_memory(iommu_grdm_t *func,
 #endif
 
 struct domain_iommu {
+#ifdef CONFIG_HAS_PASSTHROUGH
     struct arch_iommu arch;
+#endif
 
     /* iommu_ops */
     const struct iommu_ops *platform_ops;
-- 
2.43.0



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

* [PATCH v3 07/34] xen/asm-generic: introdure nospec.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (5 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-04 11:06   ` Jan Beulich
  2024-01-05 19:02   ` Shawn Anastasio
  2023-12-22 15:12 ` [PATCH v3 08/34] xen/riscv: introduce setup.h Oleksii Kurochko
                   ` (26 subsequent siblings)
  33 siblings, 2 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Stefano Stabellini, Julien Grall,
	Bertrand Marquis, Michal Orzel, Volodymyr Babchuk, Andrew Cooper,
	George Dunlap, Jan Beulich, Wei Liu, Shawn Anastasio,
	Alistair Francis, Bob Eshleman, Connor Davis

The <asm/nospec.h> header is similar between Arm, PPC, and RISC-V,
so it has been moved to asm-generic.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - new patch.
---
 xen/arch/arm/include/asm/Makefile                 |  1 +
 xen/arch/ppc/include/asm/Makefile                 |  1 +
 xen/arch/ppc/include/asm/nospec.h                 | 15 ---------------
 xen/arch/riscv/include/asm/Makefile               |  1 +
 .../include/asm => include/asm-generic}/nospec.h  | 10 +++++-----
 5 files changed, 8 insertions(+), 20 deletions(-)
 delete mode 100644 xen/arch/ppc/include/asm/nospec.h
 rename xen/{arch/arm/include/asm => include/asm-generic}/nospec.h (54%)

diff --git a/xen/arch/arm/include/asm/Makefile b/xen/arch/arm/include/asm/Makefile
index c3f4291ee2..dfb4e9e45c 100644
--- a/xen/arch/arm/include/asm/Makefile
+++ b/xen/arch/arm/include/asm/Makefile
@@ -3,6 +3,7 @@ generic-y += altp2m.h
 generic-y += device.h
 generic-y += hardirq.h
 generic-y += iocap.h
+generic-y += nospec.h
 generic-y += numa.h
 generic-y += paging.h
 generic-y += percpu.h
diff --git a/xen/arch/ppc/include/asm/Makefile b/xen/arch/ppc/include/asm/Makefile
index adb752b804..0e96ad54c3 100644
--- a/xen/arch/ppc/include/asm/Makefile
+++ b/xen/arch/ppc/include/asm/Makefile
@@ -5,6 +5,7 @@ generic-y += div64.h
 generic-y += hardirq.h
 generic-y += hypercall.h
 generic-y += iocap.h
+generic-y += nospec.h
 generic-y += numa.h
 generic-y += paging.h
 generic-y += percpu.h
diff --git a/xen/arch/ppc/include/asm/nospec.h b/xen/arch/ppc/include/asm/nospec.h
deleted file mode 100644
index b97322e48d..0000000000
--- a/xen/arch/ppc/include/asm/nospec.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/* From arch/arm/include/asm/nospec.h. */
-#ifndef __ASM_PPC_NOSPEC_H__
-#define __ASM_PPC_NOSPEC_H__
-
-static inline bool evaluate_nospec(bool condition)
-{
-    return condition;
-}
-
-static inline void block_speculation(void)
-{
-}
-
-#endif /* __ASM_PPC_NOSPEC_H__ */
diff --git a/xen/arch/riscv/include/asm/Makefile b/xen/arch/riscv/include/asm/Makefile
index adb752b804..0e96ad54c3 100644
--- a/xen/arch/riscv/include/asm/Makefile
+++ b/xen/arch/riscv/include/asm/Makefile
@@ -5,6 +5,7 @@ generic-y += div64.h
 generic-y += hardirq.h
 generic-y += hypercall.h
 generic-y += iocap.h
+generic-y += nospec.h
 generic-y += numa.h
 generic-y += paging.h
 generic-y += percpu.h
diff --git a/xen/arch/arm/include/asm/nospec.h b/xen/include/asm-generic/nospec.h
similarity index 54%
rename from xen/arch/arm/include/asm/nospec.h
rename to xen/include/asm-generic/nospec.h
index 51c7aea4f4..5ded9746f3 100644
--- a/xen/arch/arm/include/asm/nospec.h
+++ b/xen/include/asm-generic/nospec.h
@@ -1,8 +1,8 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. */
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_GENERIC_NOSPEC_H
+#define _ASM_GENERIC_NOSPEC_H
 
-#ifndef _ASM_ARM_NOSPEC_H
-#define _ASM_ARM_NOSPEC_H
+#include <xen/stdbool.h>
 
 static inline bool evaluate_nospec(bool condition)
 {
@@ -13,7 +13,7 @@ static inline void block_speculation(void)
 {
 }
 
-#endif /* _ASM_ARM_NOSPEC_H */
+#endif /* _ASM_GENERIC_NOSPEC_H */
 
 /*
  * Local variables:
-- 
2.43.0



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

* [PATCH v3 08/34] xen/riscv: introduce setup.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (6 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 07/34] xen/asm-generic: introdure nospec.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 09/34] xen/riscv: introduce system.h Oleksii Kurochko
                   ` (25 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - add SPDX
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/setup.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/setup.h

diff --git a/xen/arch/riscv/include/asm/setup.h b/xen/arch/riscv/include/asm/setup.h
new file mode 100644
index 0000000000..7613a5dbd0
--- /dev/null
+++ b/xen/arch/riscv/include/asm/setup.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_RISCV_SETUP_H__
+#define __ASM_RISCV_SETUP_H__
+
+#define max_init_domid (0)
+
+#endif /* __ASM_RISCV_SETUP_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 09/34] xen/riscv: introduce system.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (7 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 08/34] xen/riscv: introduce setup.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-11 16:00   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 10/34] xen/riscv: introduce bitops.h Oleksii Kurochko
                   ` (24 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - Add SPDX
 - fix code style issue
 - change prototype of local_irq_is_enabled to return bool.
   update the return code.
 - update the code style
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/system.h | 90 +++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/system.h

diff --git a/xen/arch/riscv/include/asm/system.h b/xen/arch/riscv/include/asm/system.h
new file mode 100644
index 0000000000..08c12158fc
--- /dev/null
+++ b/xen/arch/riscv/include/asm/system.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _ASM_RISCV_BARRIER_H
+#define _ASM_RISCV_BARRIER_H
+
+#include <xen/stdbool.h>
+
+#include <asm/csr.h>
+
+#ifndef __ASSEMBLY__
+
+#define RISCV_FENCE(p, s) \
+    __asm__ __volatile__ ( "fence " #p "," #s : : : "memory" )
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb()                    RISCV_FENCE(iorw, iorw)
+#define rmb()                   RISCV_FENCE(ir, ir)
+#define wmb()                   RISCV_FENCE(ow, ow)
+
+/* These barriers do not need to enforce ordering on devices, just memory. */
+#define smp_mb()                RISCV_FENCE(rw, rw)
+#define smp_rmb()               RISCV_FENCE(r, r)
+#define smp_wmb()               RISCV_FENCE(w, w)
+#define smp_mb__before_atomic() smp_mb()
+#define smp_mb__after_atomic()  smp_mb()
+
+/*
+#define smp_store_release(p, v)         \
+do {                                    \
+    compiletime_assert_atomic_type(*p); \
+    RISCV_FENCE(rw, w);                 \
+    WRITE_ONCE(*p, v);                  \
+} while (0)
+
+#define smp_load_acquire(p)             \
+({                                      \
+    typeof(*p) p1 = READ_ONCE(*p);      \
+    compiletime_assert_atomic_type(*p); \
+    RISCV_FENCE(r,rw);                  \
+    p1;                                 \
+})
+*/
+
+static inline unsigned long local_save_flags(void)
+{
+    return csr_read(sstatus);
+}
+
+static inline void local_irq_enable(void)
+{
+    csr_set(sstatus, SSTATUS_SIE);
+}
+
+static inline void local_irq_disable(void)
+{
+    csr_clear(sstatus, SSTATUS_SIE);
+}
+
+#define local_irq_save(x)                           \
+({                                                  \
+    x = csr_read_clear(CSR_SSTATUS, SSTATUS_SIE);   \
+    local_irq_disable();                            \
+})
+
+static inline void local_irq_restore(unsigned long flags)
+{
+	csr_set(CSR_SSTATUS, flags & SSTATUS_SIE);
+}
+
+static inline bool local_irq_is_enabled(void)
+{
+    unsigned long flags = local_save_flags();
+
+    return (flags & SSTATUS_SIE) != 0;
+}
+
+#define arch_fetch_and_add(x, v) __sync_fetch_and_add(x, v)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_BARRIER_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (8 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 09/34] xen/riscv: introduce system.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-15 16:44   ` Jan Beulich
  2024-01-18 11:03   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 11/34] xen/riscv: introduce flushtlb.h Oleksii Kurochko
                   ` (23 subsequent siblings)
  33 siblings, 2 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Taken from Linux-6.4.0-rc1

Xen's bitops.h consists of several Linux's headers:
* linux/arch/include/asm/bitops.h:
  * The following function were removed as they aren't used in Xen:
      	* test_and_change_bit
      	* test_and_set_bit_lock
      	* clear_bit_unlock
      	* __clear_bit_unlock
   * The following functions were renamed in the way how they are
     used by common code:
     	* __test_and_set_bit
     	* __test_and_clear_bit
   * The declaration and implementation of the following functios
     were updated to make Xen build happy:
	* clear_bit
	* set_bit
	* __test_and_clear_bit
	* __test_and_set_bit
* linux/include/asm-generic/bitops/find.h ( only few function
  declaration were taken, as implementation will be provided by
  Xen ).
* linux/arch/include/linux/bits.h ( taken only definitions for BIT_MASK,
  BIT_WORD, BITS_PER_BYTE )

Additionaly, the following bit ops are introduced:
* __ffs
* ffsl
* fls
* flsl
* ffs
* ffz
* find_first_bit_set
* hweight64
* test_bit

Some of the introduced bit operations are included in asm-generic,
as they exhibit similarity across multiple architectures.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - update the commit message
 - Introduce the following asm-generic bitops headers:
	create mode 100644 xen/arch/riscv/include/asm/bitops.h
	create mode 100644 xen/include/asm-generic/bitops/bitops-bits.h
	create mode 100644 xen/include/asm-generic/bitops/ffs.h
	create mode 100644 xen/include/asm-generic/bitops/ffz.h
	create mode 100644 xen/include/asm-generic/bitops/find-first-bit-set.h
	create mode 100644 xen/include/asm-generic/bitops/fls.h
	create mode 100644 xen/include/asm-generic/bitops/flsl.h
	create mode 100644 xen/include/asm-generic/bitops/hweight.h
	create mode 100644 xen/include/asm-generic/bitops/test-bit.h
 - switch some bitops functions to asm-generic's versions.
 - re-sync some macros with Linux kernel version mentioned in the commit message.
 - Xen code style fixes.
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/bitops.h           | 267 ++++++++++++++++++
 xen/include/asm-generic/bitops/bitops-bits.h  |  10 +
 xen/include/asm-generic/bitops/ffs.h          |   9 +
 xen/include/asm-generic/bitops/ffz.h          |  13 +
 .../asm-generic/bitops/find-first-bit-set.h   |  17 ++
 xen/include/asm-generic/bitops/fls.h          |  18 ++
 xen/include/asm-generic/bitops/flsl.h         |  10 +
 xen/include/asm-generic/bitops/hweight.h      |  13 +
 xen/include/asm-generic/bitops/test-bit.h     |  16 ++
 9 files changed, 373 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/bitops.h
 create mode 100644 xen/include/asm-generic/bitops/bitops-bits.h
 create mode 100644 xen/include/asm-generic/bitops/ffs.h
 create mode 100644 xen/include/asm-generic/bitops/ffz.h
 create mode 100644 xen/include/asm-generic/bitops/find-first-bit-set.h
 create mode 100644 xen/include/asm-generic/bitops/fls.h
 create mode 100644 xen/include/asm-generic/bitops/flsl.h
 create mode 100644 xen/include/asm-generic/bitops/hweight.h
 create mode 100644 xen/include/asm-generic/bitops/test-bit.h

diff --git a/xen/arch/riscv/include/asm/bitops.h b/xen/arch/riscv/include/asm/bitops.h
new file mode 100644
index 0000000000..d210f529c8
--- /dev/null
+++ b/xen/arch/riscv/include/asm/bitops.h
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2012 Regents of the University of California */
+
+#ifndef _ASM_RISCV_BITOPS_H
+#define _ASM_RISCV_BITOPS_H
+
+#include <asm/system.h>
+
+#include <asm-generic/bitops/bitops-bits.h>
+
+/* Based on linux/arch/include/linux/bits.h */
+
+#define BIT_MASK(nr)        (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr)        ((nr) / BITS_PER_LONG)
+
+#define __set_bit(n,p)      set_bit(n,p)
+#define __clear_bit(n,p)    clear_bit(n,p)
+
+/* Based on linux/arch/include/asm/bitops.h */
+
+#if ( BITS_PER_LONG == 64 )
+#define __AMO(op)   "amo" #op ".d"
+#elif ( BITS_PER_LONG == 32 )
+#define __AMO(op)   "amo" #op ".w"
+#else
+#error "Unexpected BITS_PER_LONG"
+#endif
+
+#define __test_and_op_bit_ord(op, mod, nr, addr, ord)		\
+({								\
+    unsigned long __res, __mask;				\
+    __mask = BIT_MASK(nr);					\
+    __asm__ __volatile__ (					\
+        __AMO(op) #ord " %0, %2, %1"			\
+        : "=r" (__res), "+A" (addr[BIT_WORD(nr)])	\
+        : "r" (mod(__mask))				\
+        : "memory");					\
+    ((__res & __mask) != 0);				\
+})
+
+#define __op_bit_ord(op, mod, nr, addr, ord)			\
+    __asm__ __volatile__ (					\
+        __AMO(op) #ord " zero, %1, %0"			\
+        : "+A" (addr[BIT_WORD(nr)])			\
+        : "r" (mod(BIT_MASK(nr)))			\
+        : "memory");
+
+#define __test_and_op_bit(op, mod, nr, addr) 			\
+    __test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
+#define __op_bit(op, mod, nr, addr)				\
+    __op_bit_ord(op, mod, nr, addr, )
+
+/* Bitmask modifiers */
+#define __NOP(x)	(x)
+#define __NOT(x)	(~(x))
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation may be reordered on other architectures than x86.
+ */
+static inline int __test_and_set_bit(int nr, volatile void *p)
+{
+    volatile uint32_t *addr = p;
+
+    return __test_and_op_bit(or, __NOP, nr, addr);
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation can be reordered on other architectures other than x86.
+ */
+static inline int __test_and_clear_bit(int nr, volatile void *p)
+{
+    volatile uint32_t *addr = p;
+
+    return __test_and_op_bit(and, __NOT, nr, addr);
+}
+
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Note: there are no guarantees that this function will not be reordered
+ * on non x86 architectures, so if you are writing portable code,
+ * make sure not to rely on its reordering guarantees.
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void set_bit(int nr, volatile void *p)
+{
+    volatile uint32_t *addr = p;
+
+    __op_bit(or, __NOP, nr, addr);
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * Note: there are no guarantees that this function will not be reordered
+ * on non x86 architectures, so if you are writing portable code,
+ * make sure not to rely on its reordering guarantees.
+ */
+static inline void clear_bit(int nr, volatile void *p)
+{
+    volatile uint32_t *addr = p;
+
+    __op_bit(and, __NOT, nr, addr);
+}
+
+#undef __test_and_op_bit
+#undef __op_bit
+#undef __NOP
+#undef __NOT
+#undef __AMO
+
+#define test_and_set_bit   __test_and_set_bit
+#define test_and_clear_bit __test_and_clear_bit
+
+/* Based on linux/include/asm-generic/bitops/find.h */
+
+#ifndef find_next_bit
+/**
+ * find_next_bit - find the next set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ */
+extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
+        size, unsigned long offset);
+#endif
+
+#ifndef find_next_zero_bit
+/**
+ * find_next_zero_bit - find the next cleared bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ */
+extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned
+        long size, unsigned long offset);
+#endif
+
+/**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first set bit.
+ */
+extern unsigned long find_first_bit(const unsigned long *addr,
+                    unsigned long size);
+
+/**
+ * find_first_zero_bit - find the first cleared bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit number of the first cleared bit.
+ */
+extern unsigned long find_first_zero_bit(const unsigned long *addr,
+                     unsigned long size);
+
+/**
+ * ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Returns 0 if no bit exists, otherwise returns 1-indexed bit location.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+    int num = 0;
+
+#if BITS_PER_LONG == 64
+    if ((word & 0xffffffff) == 0) {
+        num += 32;
+        word >>= 32;
+    }
+#endif
+    if ((word & 0xffff) == 0) {
+        num += 16;
+        word >>= 16;
+    }
+    if ((word & 0xff) == 0) {
+        num += 8;
+        word >>= 8;
+    }
+    if ((word & 0xf) == 0) {
+        num += 4;
+        word >>= 4;
+    }
+    if ((word & 0x3) == 0) {
+        num += 2;
+        word >>= 2;
+    }
+    if ((word & 0x1) == 0)
+        num += 1;
+    return num;
+}
+
+/**
+ * ffsl - find first bit in long.
+ * @word: The word to search
+ *
+ * Returns 0 if no bit exists, otherwise returns 1-indexed bit location.
+ */
+static inline unsigned int ffsl(unsigned long word)
+{
+    int num = 1;
+
+    if (!word)
+        return 0;
+
+#if BITS_PER_LONG == 64
+    if ((word & 0xffffffff) == 0) {
+        num += 32;
+        word >>= 32;
+    }
+#endif
+    if ((word & 0xffff) == 0) {
+        num += 16;
+        word >>= 16;
+    }
+    if ((word & 0xff) == 0) {
+        num += 8;
+        word >>= 8;
+    }
+    if ((word & 0xf) == 0) {
+        num += 4;
+        word >>= 4;
+    }
+    if ((word & 0x3) == 0) {
+        num += 2;
+        word >>= 2;
+    }
+    if ((word & 0x1) == 0)
+        num += 1;
+    return num;
+}
+
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/flsl.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/find-first-bit-set.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/test-bit.h>
+
+#endif /* _ASM_RISCV_BITOPS_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-generic/bitops/bitops-bits.h b/xen/include/asm-generic/bitops/bitops-bits.h
new file mode 100644
index 0000000000..8a57e47c63
--- /dev/null
+++ b/xen/include/asm-generic/bitops/bitops-bits.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_BITS_H_
+#define _ASM_GENERIC_BITOPS_BITS_H_
+
+#define BITOP_BITS_PER_WORD     32
+#define BITOP_MASK(nr)          (1UL << ((nr) % BITOP_BITS_PER_WORD))
+#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
+#define BITS_PER_BYTE           8
+
+#endif /* _ASM_GENERIC_BITOPS_BITS_H_ */
\ No newline at end of file
diff --git a/xen/include/asm-generic/bitops/ffs.h b/xen/include/asm-generic/bitops/ffs.h
new file mode 100644
index 0000000000..3f75fded14
--- /dev/null
+++ b/xen/include/asm-generic/bitops/ffs.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_FFS_H_
+#define _ASM_GENERIC_BITOPS_FFS_H_
+
+#include <xen/macros.h>
+
+#define ffs(x) ({ unsigned int t_ = (x); fls(ISOLATE_LSB(t_)); })
+
+#endif /* _ASM_GENERIC_BITOPS_FFS_H_ */
diff --git a/xen/include/asm-generic/bitops/ffz.h b/xen/include/asm-generic/bitops/ffz.h
new file mode 100644
index 0000000000..92c35455d5
--- /dev/null
+++ b/xen/include/asm-generic/bitops/ffz.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
+#define _ASM_GENERIC_BITOPS_FFZ_H_
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x)  __ffs(~(x))
+
+#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
\ No newline at end of file
diff --git a/xen/include/asm-generic/bitops/find-first-bit-set.h b/xen/include/asm-generic/bitops/find-first-bit-set.h
new file mode 100644
index 0000000000..8ae9751b11
--- /dev/null
+++ b/xen/include/asm-generic/bitops/find-first-bit-set.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_
+#define _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_
+
+/**
+ * find_first_set_bit - find the first set bit in @word
+ * @word: the word to search
+ *
+ * Returns the bit-number of the first set bit (first bit being 0).
+ * The input must *not* be zero.
+ */
+static inline unsigned int find_first_set_bit(unsigned long word)
+{
+        return ffsl(word) - 1;
+}
+
+#endif /* _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_ */
\ No newline at end of file
diff --git a/xen/include/asm-generic/bitops/fls.h b/xen/include/asm-generic/bitops/fls.h
new file mode 100644
index 0000000000..f232925080
--- /dev/null
+++ b/xen/include/asm-generic/bitops/fls.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_FLS_H_
+#define _ASM_GENERIC_BITOPS_FLS_H_
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static inline int fls(unsigned int x)
+{
+    return generic_fls(x);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */
\ No newline at end of file
diff --git a/xen/include/asm-generic/bitops/flsl.h b/xen/include/asm-generic/bitops/flsl.h
new file mode 100644
index 0000000000..127221056e
--- /dev/null
+++ b/xen/include/asm-generic/bitops/flsl.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_FLSL_H_
+#define _ASM_GENERIC_BITOPS_FLSL_H_
+
+static inline int flsl(unsigned long x)
+{
+    return generic_flsl(x);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_FLSL_H_ */
\ No newline at end of file
diff --git a/xen/include/asm-generic/bitops/hweight.h b/xen/include/asm-generic/bitops/hweight.h
new file mode 100644
index 0000000000..0d7577054e
--- /dev/null
+++ b/xen/include/asm-generic/bitops/hweight.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
+
+/*
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+#define hweight64(x) generic_hweight64(x)
+
+#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
diff --git a/xen/include/asm-generic/bitops/test-bit.h b/xen/include/asm-generic/bitops/test-bit.h
new file mode 100644
index 0000000000..9fa36652e3
--- /dev/null
+++ b/xen/include/asm-generic/bitops/test-bit.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_BITOPS_TESTBIT_H_
+#define _ASM_GENERIC_BITOPS_TESTBIT_H_
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline int test_bit(int nr, const volatile void *addr)
+{
+    const volatile unsigned int *p = addr;
+    return 1 & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD - 1)));
+}
+
+#endif /* _ASM_GENERIC_BITOPS_TESTBIT_H_ */
\ No newline at end of file
-- 
2.43.0



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

* [PATCH v3 11/34] xen/riscv: introduce flushtlb.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (9 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 10/34] xen/riscv: introduce bitops.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2023-12-22 15:12 ` [PATCH v3 12/34] xen/riscv: introduce smp.h Oleksii Kurochko
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - add SPDX & footer
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/flushtlb.h | 33 +++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/flushtlb.h

diff --git a/xen/arch/riscv/include/asm/flushtlb.h b/xen/arch/riscv/include/asm/flushtlb.h
new file mode 100644
index 0000000000..3bdcb08e3a
--- /dev/null
+++ b/xen/arch/riscv/include/asm/flushtlb.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_FLUSHTLB_H__
+#define __ASM_RISCV_FLUSHTLB_H__
+
+#include <xen/cpumask.h>
+
+/*
+ * Filter the given set of CPUs, removing those that definitely flushed their
+ * TLB since @page_timestamp.
+ */
+/* XXX lazy implementation just doesn't clear anything.... */
+static inline void tlbflush_filter(cpumask_t *mask, uint32_t page_timestamp) {}
+
+#define tlbflush_current_time() (0)
+
+static inline void page_set_tlbflush_timestamp(struct page_info *page)
+{
+    BUG();
+}
+
+/* Flush specified CPUs' TLBs */
+void arch_flush_tlb_mask(const cpumask_t *mask);
+
+#endif /* __ASM_RISCV_FLUSHTLB_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 12/34] xen/riscv: introduce smp.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (10 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 11/34] xen/riscv: introduce flushtlb.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-11 16:36   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h Oleksii Kurochko
                   ` (21 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - drop cpu_is_offline() as it was moved to xen/smp.h.
 - add SPDX.
 - drop unnessary #ifdef.
 - fix "No new line"
 - update the commit message
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/smp.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/smp.h

diff --git a/xen/arch/riscv/include/asm/smp.h b/xen/arch/riscv/include/asm/smp.h
new file mode 100644
index 0000000000..336db5906e
--- /dev/null
+++ b/xen/arch/riscv/include/asm/smp.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_SMP_H
+#define __ASM_RISCV_SMP_H
+
+#include <xen/cpumask.h>
+#include <xen/percpu.h>
+
+DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_mask);
+DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask);
+
+#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
+
+/*
+ * Do we, for platform reasons, need to actually keep CPUs online when we
+ * would otherwise prefer them to be off?
+ */
+#define park_offline_cpus false
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (11 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 12/34] xen/riscv: introduce smp.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-22 16:27   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 14/34] xen/riscv: introduce io.h Oleksii Kurochko
                   ` (20 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

The header was taken from Linux kernl 6.4.0-rc1.

Addionally, were updated:
* add emulation of {cmp}xchg for 1/2 byte types
* replace tabs with spaces
* replace __* varialbed with *__

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - update the commit message
 - add emulation of {cmp}xchg_... for 1 and 2 bytes types
---
Changes in V2:
	- update the comment at the top of the header.
	- change xen/lib.h to xen/bug.h.
	- sort inclusion of headers properly.
---
 xen/arch/riscv/include/asm/cmpxchg.h | 496 +++++++++++++++++++++++++++
 1 file changed, 496 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/cmpxchg.h

diff --git a/xen/arch/riscv/include/asm/cmpxchg.h b/xen/arch/riscv/include/asm/cmpxchg.h
new file mode 100644
index 0000000000..916776c403
--- /dev/null
+++ b/xen/arch/riscv/include/asm/cmpxchg.h
@@ -0,0 +1,496 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2014 Regents of the University of California */
+
+#ifndef _ASM_RISCV_CMPXCHG_H
+#define _ASM_RISCV_CMPXCHG_H
+
+#include <xen/compiler.h>
+#include <xen/lib.h>
+
+#include <asm/fence.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#define __xchg_relaxed(ptr, new, size) \
+({ \
+    __typeof__(ptr) ptr__ = (ptr); \
+    __typeof__(new) new__ = (new); \
+    __typeof__(*(ptr)) ret__; \
+    switch (size) \
+	{ \
+    case 4: \
+        asm volatile( \
+            "	amoswap.w %0, %2, %1\n" \
+            : "=r" (ret__), "+A" (*ptr__) \
+            : "r" (new__) \
+            : "memory" ); \
+        break; \
+    case 8: \
+        asm volatile( \
+            "	amoswap.d %0, %2, %1\n" \
+            : "=r" (ret__), "+A" (*ptr__) \
+            : "r" (new__) \
+            : "memory" ); \
+        break; \
+    default: \
+        ASSERT_UNREACHABLE(); \
+    } \
+    ret__; \
+})
+
+#define xchg_relaxed(ptr, x) \
+({ \
+    __typeof__(*(ptr)) x_ = (x); \
+    (__typeof__(*(ptr))) __xchg_relaxed((ptr), x_, sizeof(*(ptr))); \
+})
+
+#define __xchg_acquire(ptr, new, size) \
+({ \
+    __typeof__(ptr) ptr__ = (ptr); \
+    __typeof__(new) new__ = (new); \
+    __typeof__(*(ptr)) ret__; \
+    switch (size) \
+	{ \
+    case 4: \
+        asm volatile( \
+            "	amoswap.w %0, %2, %1\n" \
+            RISCV_ACQUIRE_BARRIER \
+            : "=r" (ret__), "+A" (*ptr__) \
+            : "r" (new__) \
+            : "memory" ); \
+        break; \
+    case 8: \
+        asm volatile( \
+            "	amoswap.d %0, %2, %1\n" \
+            RISCV_ACQUIRE_BARRIER \
+            : "=r" (ret__), "+A" (*ptr__) \
+            : "r" (new__) \
+            : "memory" ); \
+        break; \
+    default: \
+        ASSERT_UNREACHABLE(); \
+    } \
+    ret__; \
+})
+
+#define xchg_acquire(ptr, x) \
+({ \
+    __typeof__(*(ptr)) x_ = (x); \
+    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_, sizeof(*(ptr))); \
+})
+
+#define __xchg_release(ptr, new, size) \
+({ \
+    __typeof__(ptr) ptr__ = (ptr); \
+    __typeof__(new) new__ = (new); \
+    __typeof__(*(ptr)) ret__; \
+    switch (size) \
+	{ \
+    case 4: \
+        asm volatile ( \
+            RISCV_RELEASE_BARRIER \
+            "	amoswap.w %0, %2, %1\n" \
+            : "=r" (ret__), "+A" (*ptr__) \
+            : "r" (new__) \
+            : "memory"); \
+        break; \
+    case 8: \
+        asm volatile ( \
+            RISCV_RELEASE_BARRIER \
+            "	amoswap.d %0, %2, %1\n" \
+            : "=r" (ret__), "+A" (*ptr__) \
+            : "r" (new__) \
+            : "memory"); \
+        break; \
+    default: \
+        ASSERT_UNREACHABLE(); \
+    } \
+    ret__; \
+})
+
+#define xchg_release(ptr, x) \
+({ \
+    __typeof__(*(ptr)) x_ = (x); \
+    (__typeof__(*(ptr))) __xchg_release((ptr), x_, sizeof(*(ptr))); \
+})
+
+static always_inline uint32_t __xchg_case_4(volatile uint32_t *ptr,
+                                            uint32_t new)
+{
+    __typeof__(*(ptr)) ret;
+
+    asm volatile (
+        "   amoswap.w.aqrl %0, %2, %1\n"
+        : "=r" (ret), "+A" (*ptr)
+        : "r" (new)
+        : "memory" );
+
+    return ret;
+}
+
+static always_inline uint64_t __xchg_case_8(volatile uint64_t *ptr,
+                                            uint64_t new)
+{
+    __typeof__(*(ptr)) ret;
+
+    asm volatile( \
+        "   amoswap.d.aqrl %0, %2, %1\n" \
+        : "=r" (ret), "+A" (*ptr) \
+        : "r" (new) \
+        : "memory" ); \
+
+    return ret;
+}
+
+static always_inline unsigned short __cmpxchg_case_2(volatile uint32_t *ptr,
+                                                     uint32_t old,
+                                                     uint32_t new);
+
+static always_inline unsigned short __cmpxchg_case_1(volatile uint32_t *ptr,
+                                                     uint32_t old,
+                                                     uint32_t new);
+
+static inline unsigned long __xchg(volatile void *ptr, unsigned long x, int size)
+{
+    switch (size) {
+    case 1:
+        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
+    case 2:
+        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
+    case 4:
+        return __xchg_case_4(ptr, x);
+    case 8:
+        return __xchg_case_8(ptr, x);
+    default:
+        ASSERT_UNREACHABLE();
+    }
+
+    return -1;
+}
+
+#define xchg(ptr,x) \
+({ \
+    __typeof__(*(ptr)) ret__; \
+    ret__ = (__typeof__(*(ptr))) \
+            __xchg((ptr), (unsigned long)(x), sizeof(*(ptr))); \
+    ret__; \
+})
+
+#define xchg32(ptr, x) \
+({ \
+    BUILD_BUG_ON(sizeof(*(ptr)) != 4); \
+    xchg((ptr), (x)); \
+})
+
+#define xchg64(ptr, x) \
+({ \
+    BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+    xchg((ptr), (x)); \
+})
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+#define __cmpxchg_relaxed(ptr, old, new, size) \
+({ \
+    __typeof__(ptr) ptr__ = (ptr); \
+    __typeof__(*(ptr)) __old = (old); \
+    __typeof__(*(ptr)) new__ = (new); \
+    __typeof__(*(ptr)) ret__; \
+    register unsigned int __rc; \
+    switch (size) \
+	{ \
+    case 4: \
+        asm volatile( \
+            "0:	lr.w %0, %2\n" \
+            "	bne  %0, %z3, 1f\n" \
+            "	sc.w %1, %z4, %2\n" \
+            "	bnez %1, 0b\n" \
+            "1:\n" \
+            : "=&r" (ret__), "=&r" (__rc), "+A" (*ptr__) \
+            : "rJ" (__old), "rJ" (new__) \
+            : "memory"); \
+        break; \
+    case 8: \
+        asm volatile( \
+            "0:	lr.d %0, %2\n" \
+            "	bne %0, %z3, 1f\n" \
+            "	sc.d %1, %z4, %2\n" \
+            "	bnez %1, 0b\n" \
+            "1:\n" \
+            : "=&r" (ret__), "=&r" (__rc), "+A" (*ptr__) \
+            : "rJ" (__old), "rJ" (new__) \
+            : "memory"); \
+        break; \
+    default: \
+        ASSERT_UNREACHABLE(); \
+    } \
+    ret__; \
+})
+
+#define cmpxchg_relaxed(ptr, o, n) \
+({ \
+    __typeof__(*(ptr)) o_ = (o); \
+    __typeof__(*(ptr)) n_ = (n); \
+    (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \
+                    o_, n_, sizeof(*(ptr))); \
+})
+
+#define __cmpxchg_acquire(ptr, old, new, size) \
+({ \
+    __typeof__(ptr) ptr__ = (ptr); \
+    __typeof__(*(ptr)) __old = (old); \
+    __typeof__(*(ptr)) new__ = (new); \
+    __typeof__(*(ptr)) ret__; \
+    register unsigned int __rc; \
+    switch (size) \
+	{ \
+    case 4: \
+        asm volatile( \
+            "0:	lr.w %0, %2\n" \
+            "	bne  %0, %z3, 1f\n" \
+            "	sc.w %1, %z4, %2\n" \
+            "	bnez %1, 0b\n" \
+            RISCV_ACQUIRE_BARRIER \
+            "1:\n"	 \
+            : "=&r" (ret__), "=&r" (__rc), "+A" (*ptr__) \
+            : "rJ" (__old), "rJ" (new__) \
+            : "memory"); \
+        break; \
+    case 8: \
+        asm volatile( \
+            "0:	lr.d %0, %2\n" \
+            "	bne %0, %z3, 1f\n" \
+            "	sc.d %1, %z4, %2\n" \
+            "	bnez %1, 0b\n" \
+            RISCV_ACQUIRE_BARRIER \
+            "1:\n" \
+            : "=&r" (ret__), "=&r" (__rc), "+A" (*ptr__) \
+            : "rJ" (__old), "rJ" (new__) \
+            : "memory"); \
+        break; \
+    default: \
+        ASSERT_UNREACHABLE(); \
+    } \
+    ret__; \
+})
+
+#define cmpxchg_acquire(ptr, o, n) \
+({ \
+    __typeof__(*(ptr)) o_ = (o); \
+    __typeof__(*(ptr)) n_ = (n); \
+    (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), o_, n_, sizeof(*(ptr))); \
+})
+
+#define __cmpxchg_release(ptr, old, new, size) \
+({									\
+    __typeof__(ptr) ptr__ = (ptr); \
+    __typeof__(*(ptr)) __old = (old); \
+    __typeof__(*(ptr)) new__ = (new); \
+    __typeof__(*(ptr)) ret__; \
+    register unsigned int __rc; \
+    switch (size) \
+	{ \
+    case 4: \
+        asm volatile ( \
+            RISCV_RELEASE_BARRIER \
+            "0:	lr.w %0, %2\n" \
+            "	bne  %0, %z3, 1f\n" \
+            "	sc.w %1, %z4, %2\n" \
+            "	bnez %1, 0b\n" \
+            "1:\n" \
+            : "=&r" (ret__), "=&r" (__rc), "+A" (*ptr__)	\
+            : "rJ" (__old), "rJ" (new__) \
+            : "memory" ); \
+        break; \
+    case 8: \
+        asm volatile ( \
+            RISCV_RELEASE_BARRIER \
+            "0:	lr.d %0, %2\n" \
+            "	bne %0, %z3, 1f\n" \
+            "	sc.d %1, %z4, %2\n" \
+            "	bnez %1, 0b\n" \
+            "1:\n" \
+            : "=&r" (ret__), "=&r" (__rc), "+A" (*ptr__) \
+            : "rJ" (__old), "rJ" (new__) \
+            : "memory" ); \
+        break; \
+    default: \
+        ASSERT_UNREACHABLE(); \
+    } \
+    ret__; \
+})
+
+#define cmpxchg_release(ptr, o, n) \
+({ \
+    __typeof__(*(ptr)) _o_ = (o); \
+    __typeof__(*(ptr)) _n_ = (n); \
+    (__typeof__(*(ptr))) __cmpxchg_release((ptr), _o_, _n_, sizeof(*(ptr))); \
+})
+
+static always_inline uint32_t __cmpxchg_case_4(volatile uint32_t *ptr,
+                                               uint32_t old,
+                                               uint32_t new)
+{
+    uint32_t ret;
+    register uint32_t rc;
+
+    asm volatile (
+        "0: lr.w %0, %2\n"
+        "   bne  %0, %z3, 1f\n"
+        "   sc.w.rl %1, %z4, %2\n"
+        "   bnez %1, 0b\n"
+        "   fence rw, rw\n"
+        "1:\n"
+        : "=&r" (ret), "=&r" (rc), "+A" (*ptr)
+        : "rJ" (old), "rJ" (new)
+        : "memory" );
+
+    return ret;
+}
+
+static always_inline uint64_t __cmpxchg_case_8(volatile uint64_t *ptr,
+                                               uint64_t old,
+                                               uint64_t new)
+{
+    uint64_t ret;
+    register uint32_t rc;
+
+    asm volatile(
+        "0: lr.d %0, %2\n"
+        "   bne %0, %z3, 1f\n"
+        "   sc.d.rl %1, %z4, %2\n"
+        "   bnez %1, 0b\n"
+        "   fence rw, rw\n"
+        "1:\n"
+        : "=&r" (ret), "=&r" (rc), "+A" (*ptr)
+        : "rJ" (old), "rJ" (new)
+        : "memory");
+
+    return ret;
+}
+
+#define __emulate_cmpxchg_case1_2(ptr, new, read_func, cmpxchg_func, swap_byte_mask_base)\
+({                                                                              \
+    __typeof__(*(ptr)) read_val;                                                \
+    __typeof__(*(ptr)) swapped_new;                                             \
+    __typeof__(*(ptr)) ret;                                                     \
+    __typeof__(*(ptr)) new_ = (__typeof__(*(ptr)))new;                          \
+                                                                                \
+    __typeof__(ptr) aligned_ptr = (__typeof__(ptr))((unsigned long)ptr & ~3);   \
+    __typeof__(*(ptr)) mask_off = ((unsigned long)ptr & 3) * 8;                 \
+    __typeof__(*(ptr)) mask =                                                   \
+      (__typeof__(*(ptr)))swap_byte_mask_base << mask_off;                      \
+    __typeof__(*(ptr)) masked_new = (new_ << mask_off) & mask;                  \
+                                                                                \
+    do {                                                                        \
+        read_val = read_func(aligned_ptr);                                      \
+        swapped_new = read_val & ~mask;                                         \
+        swapped_new |= masked_new;                                              \
+        ret = cmpxchg_func(aligned_ptr, read_val, swapped_new);                 \
+    } while ( ret != read_val );                                                \
+                                                                                \
+    ret = MASK_EXTR(swapped_new, mask);                                         \
+    ret;                                                                        \
+})
+
+static always_inline unsigned short __cmpxchg_case_2(volatile uint32_t *ptr,
+                                                     uint32_t old,
+                                                     uint32_t new)
+{
+    (void) old;
+
+    if (((unsigned long)ptr & 3) == 3)
+    {
+#ifdef CONFIG_64BIT
+        return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
+                                         readq, __cmpxchg_case_8, 0xffffU);
+#else
+        #error "add emulation support of cmpxchg for CONFIG_32BIT"
+#endif
+    }
+    else
+        return __emulate_cmpxchg_case1_2((uint32_t *)ptr, new,
+                                         readl, __cmpxchg_case_4, 0xffffU);
+}
+
+static always_inline unsigned short __cmpxchg_case_1(volatile uint32_t *ptr,
+                                                     uint32_t old,
+                                                     uint32_t new)
+{
+    (void) old;
+
+    return __emulate_cmpxchg_case1_2((uint32_t *)ptr, new,
+                                     readl, __cmpxchg_case_4, 0xffU);
+}
+
+static always_inline unsigned long __cmpxchg(volatile void *ptr,
+                                             unsigned long old,
+                                             unsigned long new,
+                                             int size)
+{
+    switch (size)
+    {
+    case 1:
+        return __cmpxchg_case_1(ptr, old, new);
+    case 2:
+        return __cmpxchg_case_2(ptr, old, new);
+    case 4:
+        return __cmpxchg_case_4(ptr, old, new);
+    case 8:
+        return __cmpxchg_case_8(ptr, old, new);
+    default:
+        ASSERT_UNREACHABLE();
+    }
+
+    return old;
+}
+
+#define cmpxchg(ptr, o, n) \
+({ \
+    __typeof__(*(ptr)) ret__; \
+    ret__ = (__typeof__(*(ptr))) \
+            __cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), \
+                      sizeof(*(ptr))); \
+    ret__; \
+})
+
+#define cmpxchg_local(ptr, o, n) \
+    (__cmpxchg_relaxed((ptr), (o), (n), sizeof(*(ptr))))
+
+#define cmpxchg32(ptr, o, n) \
+({ \
+    BUILD_BUG_ON(sizeof(*(ptr)) != 4); \
+    cmpxchg((ptr), (o), (n)); \
+})
+
+#define cmpxchg32_local(ptr, o, n) \
+({ \
+    BUILD_BUG_ON(sizeof(*(ptr)) != 4); \
+    cmpxchg_relaxed((ptr), (o), (n)) \
+})
+
+#define cmpxchg64(ptr, o, n) \
+({ \
+    BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+    cmpxchg((ptr), (o), (n)); \
+})
+
+#define cmpxchg64_local(ptr, o, n) \
+({ \
+    BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+    cmpxchg_relaxed((ptr), (o), (n)); \
+})
+
+#endif /* _ASM_RISCV_CMPXCHG_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 14/34] xen/riscv: introduce io.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (12 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-15 16:57   ` Jan Beulich
  2023-12-22 15:12 ` [PATCH v3 15/34] xen/riscv: introduce atomic.h Oleksii Kurochko
                   ` (19 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

The header taken form Linux 6.4.0-rc1 and is based on
arch/riscv/include/asm/mmio.h.

Addionally, to the header was added definions of ioremap_*().

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - re-sync with linux kernel
 - update the commit message
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/io.h | 142 ++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/io.h

diff --git a/xen/arch/riscv/include/asm/io.h b/xen/arch/riscv/include/asm/io.h
new file mode 100644
index 0000000000..ead466eb2d
--- /dev/null
+++ b/xen/arch/riscv/include/asm/io.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * {read,write}{b,w,l,q} based on arch/arm64/include/asm/io.h
+ *   which was based on arch/arm/include/io.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2014 Regents of the University of California
+ */
+
+
+#ifndef _ASM_RISCV_IO_H
+#define _ASM_RISCV_IO_H
+
+#include <asm/byteorder.h>
+
+/*
+ * The RISC-V ISA doesn't yet specify how to query or modify PMAs, so we can't
+ * change the properties of memory regions.  This should be fixed by the
+ * upcoming platform spec.
+ */
+#define ioremap_nocache(addr, size) ioremap((addr), (size))
+#define ioremap_wc(addr, size) ioremap((addr), (size))
+#define ioremap_wt(addr, size) ioremap((addr), (size))
+
+/* Generic IO read/write.  These perform native-endian accesses. */
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+	asm volatile("sb %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+	asm volatile("sh %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+	asm volatile("sw %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_writeq __raw_writeq
+static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	asm volatile("sd %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+#endif
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+	u8 val;
+
+	asm volatile("lb %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+	u16 val;
+
+	asm volatile("lh %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+	u32 val;
+
+	asm volatile("lw %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_readq __raw_readq
+static inline u64 __raw_readq(const volatile void __iomem *addr)
+{
+	u64 val;
+
+	asm volatile("ld %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+#endif
+
+/*
+ * Unordered I/O memory access primitives.  These are even more relaxed than
+ * the relaxed versions, as they don't even order accesses between successive
+ * operations to the I/O regions.
+ */
+#define readb_cpu(c)		({ u8  __r = __raw_readb(c); __r; })
+#define readw_cpu(c)		({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
+#define readl_cpu(c)		({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
+
+#define writeb_cpu(v,c)		((void)__raw_writeb((v),(c)))
+#define writew_cpu(v,c)		((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
+#define writel_cpu(v,c)		((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
+
+#ifdef CONFIG_64BIT
+#define readq_cpu(c)		({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
+#define writeq_cpu(v,c)		((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
+#endif
+
+/*
+ * I/O memory access primitives. Reads are ordered relative to any
+ * following Normal memory access. Writes are ordered relative to any prior
+ * Normal memory access.  The memory barriers here are necessary as RISC-V
+ * doesn't define any ordering between the memory space and the I/O space.
+ */
+#define __io_br()	do {} while (0)
+#define __io_ar(v)	__asm__ __volatile__ ("fence i,r" : : : "memory");
+#define __io_bw()	__asm__ __volatile__ ("fence w,o" : : : "memory");
+#define __io_aw()	do { } while (0)
+
+#define readb(c)	({ u8  __v; __io_br(); __v = readb_cpu(c); __io_ar(__v); __v; })
+#define readw(c)	({ u16 __v; __io_br(); __v = readw_cpu(c); __io_ar(__v); __v; })
+#define readl(c)	({ u32 __v; __io_br(); __v = readl_cpu(c); __io_ar(__v); __v; })
+
+#define writeb(v,c)	({ __io_bw(); writeb_cpu((v),(c)); __io_aw(); })
+#define writew(v,c)	({ __io_bw(); writew_cpu((v),(c)); __io_aw(); })
+#define writel(v,c)	({ __io_bw(); writel_cpu((v),(c)); __io_aw(); })
+
+#ifdef CONFIG_64BIT
+#define readq(c)	({ u64 __v; __io_br(); __v = readq_cpu(c); __io_ar(__v); __v; })
+#define writeq(v,c)	({ __io_bw(); writeq_cpu((v),(c)); __io_aw(); })
+#endif
+
+#endif /* _ASM_RISCV_IO_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (13 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 14/34] xen/riscv: introduce io.h Oleksii Kurochko
@ 2023-12-22 15:12 ` Oleksii Kurochko
  2024-01-22 16:56   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 16/34] xen/lib: introduce generic find next bit operations Oleksii Kurochko
                   ` (18 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:12 UTC (permalink / raw
  To: xen-devel
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini,
	Wei Liu, Oleksii Kurochko

From: Bobby Eshleman <bobbyeshleman@gmail.com>

Additionally, this patch introduces macros in fence.h,
which are utilized in atomic.h.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
  - update the commit message
  - add SPDX for fence.h
  - code style fixes
  - Remove /* TODO: ... */ for add_sized macros. It looks correct to me.
  - re-order the patch
  - merge to this patch fence.h
---
Changes in V2:
 - Change an author of commit. I got this header from Bobby's old repo.
---
 xen/arch/riscv/include/asm/atomic.h | 384 ++++++++++++++++++++++++++++
 xen/arch/riscv/include/asm/fence.h  |  13 +
 2 files changed, 397 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/atomic.h
 create mode 100644 xen/arch/riscv/include/asm/fence.h

diff --git a/xen/arch/riscv/include/asm/atomic.h b/xen/arch/riscv/include/asm/atomic.h
new file mode 100644
index 0000000000..725326a9d1
--- /dev/null
+++ b/xen/arch/riscv/include/asm/atomic.h
@@ -0,0 +1,384 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Taken and modified from Linux.
+ * 
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2012 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ * Copyright (C) 2021 Vates SAS
+ */
+
+#ifndef _ASM_RISCV_ATOMIC_H
+#define _ASM_RISCV_ATOMIC_H
+
+#include <xen/atomic.h>
+#include <asm/cmpxchg.h>
+#include <asm/fence.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+void __bad_atomic_size(void);
+
+static always_inline void read_atomic_size(const volatile void *p,
+                                           void *res,
+                                           unsigned int size)
+{
+    switch ( size )
+    {
+    case 1: *(uint8_t *)res = readb((const uint8_t *)p); break;
+    case 2: *(uint16_t *)res = readw((const uint16_t *)p); break;
+    case 4: *(uint32_t *)res = readl((const uint32_t *)p); break;
+    case 8: *(uint32_t *)res  = readq((const uint64_t *)p); break;
+    default: __bad_atomic_size(); break;
+    }
+}
+
+#define read_atomic(p) ({                                               \
+    union { typeof(*p) val; char c[0]; } x_;                            \
+    read_atomic_size(p, x_.c, sizeof(*p));                              \
+    x_.val;                                                             \
+})
+
+
+#define write_atomic(p, x) ({                                           \
+    typeof(*p) x__ = (x);                                               \
+    switch ( sizeof(*p) )												\
+    {                                             						\
+    case 1: writeb((uint8_t)x__,  (uint8_t *)  p); break;              	\
+    case 2: writew((uint16_t)x__, (uint16_t *) p); break;              	\
+    case 4: writel((uint32_t)x__, (uint32_t *) p); break;              	\
+    case 8: writeq((uint64_t)x__, (uint64_t *) p); break;              	\
+    default: __bad_atomic_size(); break;                                \
+    }                                                                   \
+    x__;                                                                \
+})
+
+#define add_sized(p, x) ({                                              \
+    typeof(*(p)) x__ = (x);                                             \
+    switch ( sizeof(*(p)) )                                             \
+    {                                                                   \
+    case 1: writeb(read_atomic(p) + x__, (uint8_t *)(p)); break;        \
+    case 2: writew(read_atomic(p) + x__, (uint16_t *)(p)); break;       \
+    case 4: writel(read_atomic(p) + x__, (uint32_t *)(p)); break;       \
+    default: __bad_atomic_size(); break;                                \
+    }                                                                   \
+})
+
+/*
+ *  __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
+ *               non-scalar types unchanged.
+ *
+ * Prefer C11 _Generic for better compile-times and simpler code. Note: 'char'
+ * is not type-compatible with 'signed char', and we define a separate case.
+ */
+#define __scalar_type_to_expr_cases(type)               \
+    unsigned type:  (unsigned type)0,                   \
+    signed type:    (signed type)0
+
+#define __unqual_scalar_typeof(x) typeof(               \
+    _Generic((x),                                       \
+        char:  (char)0,                                 \
+        __scalar_type_to_expr_cases(char),              \
+        __scalar_type_to_expr_cases(short),             \
+        __scalar_type_to_expr_cases(int),               \
+        __scalar_type_to_expr_cases(long),              \
+        __scalar_type_to_expr_cases(long long),         \
+        default: (x)))
+
+#define READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
+#define WRITE_ONCE(x, val)                                      \
+    do {                                                        \
+        *(volatile typeof(x) *)&(x) = (val);                    \
+    } while (0)
+
+#define __atomic_acquire_fence() \
+    __asm__ __volatile__( RISCV_ACQUIRE_BARRIER "" ::: "memory" )
+
+#define __atomic_release_fence() \
+    __asm__ __volatile__( RISCV_RELEASE_BARRIER "" ::: "memory" );
+
+static inline int atomic_read(const atomic_t *v)
+{
+    return READ_ONCE(v->counter);
+}
+
+static inline int _atomic_read(atomic_t v)
+{
+    return v.counter;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+    WRITE_ONCE(v->counter, i);
+}
+
+static inline void _atomic_set(atomic_t *v, int i)
+{
+    v->counter = i;
+}
+
+static inline int atomic_sub_and_test(int i, atomic_t *v)
+{
+    return atomic_sub_return(i, v) == 0;
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+    atomic_add(1, v);
+}
+
+static inline int atomic_inc_return(atomic_t *v)
+{
+    return atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+    atomic_sub(1, v);
+}
+
+static inline int atomic_dec_return(atomic_t *v)
+{
+    return atomic_sub_return(1, v);
+}
+
+static inline int atomic_dec_and_test(atomic_t *v)
+{
+    return atomic_sub_return(1, v) == 0;
+}
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+    return atomic_add_return(i, v) < 0;
+}
+
+static inline int atomic_inc_and_test(atomic_t *v)
+{
+    return atomic_add_return(1, v) == 0;
+}
+
+/*
+ * First, the atomic ops that have no ordering constraints and therefor don't
+ * have the AQ or RL bits set.  These don't return anything, so there's only
+ * one version to worry about.
+ */
+#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix)  \
+static inline                                               \
+void atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
+{                                                           \
+    __asm__ __volatile__ (                                  \
+        "   amo" #asm_op "." #asm_type " zero, %1, %0"      \
+        : "+A" (v->counter)                                 \
+        : "r" (I)                                           \
+        : "memory" );                                       \
+}                                                           \
+
+#define ATOMIC_OPS(op, asm_op, I)                           \
+        ATOMIC_OP (op, asm_op, I, w, int,   )
+
+ATOMIC_OPS(add, add,  i)
+ATOMIC_OPS(sub, add, -i)
+ATOMIC_OPS(and, and,  i)
+ATOMIC_OPS( or,  or,  i)
+ATOMIC_OPS(xor, xor,  i)
+
+#undef ATOMIC_OP
+#undef ATOMIC_OPS
+
+/*
+ * Atomic ops that have ordered, relaxed, acquire, and release variants.
+ * There's two flavors of these: the arithmatic ops have both fetch and return
+ * versions, while the logical ops only have fetch versions.
+ */
+#define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix)    \
+static inline                                                       \
+c_type atomic##prefix##_fetch_##op##_relaxed(c_type i,              \
+                         atomic##prefix##_t *v)                     \
+{                                                                   \
+    register c_type ret;                                            \
+    __asm__ __volatile__ (                                          \
+        "   amo" #asm_op "." #asm_type " %1, %2, %0"                \
+        : "+A" (v->counter), "=r" (ret)                             \
+        : "r" (I)                                                   \
+        : "memory" );                                               \
+    return ret;                                                     \
+}                                                                   \
+static inline                                                       \
+c_type atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v) \
+{                                                                   \
+    register c_type ret;                                            \
+    __asm__ __volatile__ (                                          \
+        "   amo" #asm_op "." #asm_type ".aqrl  %1, %2, %0"          \
+        : "+A" (v->counter), "=r" (ret)                             \
+        : "r" (I)                                                   \
+        : "memory" );                                               \
+    return ret;                                                     \
+}
+
+#define ATOMIC_OP_RETURN(op, asm_op, c_op, I, asm_type, c_type, prefix) \
+static inline                                                           \
+c_type atomic##prefix##_##op##_return_relaxed(c_type i,                 \
+                          atomic##prefix##_t *v)                        \
+{                                                                       \
+        return atomic##prefix##_fetch_##op##_relaxed(i, v) c_op I;      \
+}                                                                       \
+static inline                                                           \
+c_type atomic##prefix##_##op##_return(c_type i, atomic##prefix##_t *v)  \
+{                                                                       \
+        return atomic##prefix##_fetch_##op(i, v) c_op I;                \
+}
+
+#define ATOMIC_OPS(op, asm_op, c_op, I)                                 \
+        ATOMIC_FETCH_OP( op, asm_op,       I, w, int,   )               \
+        ATOMIC_OP_RETURN(op, asm_op, c_op, I, w, int,   )
+
+ATOMIC_OPS(add, add, +,  i)
+ATOMIC_OPS(sub, add, +, -i)
+
+#define atomic_add_return_relaxed   atomic_add_return_relaxed
+#define atomic_sub_return_relaxed   atomic_sub_return_relaxed
+#define atomic_add_return   atomic_add_return
+#define atomic_sub_return   atomic_sub_return
+
+#define atomic_fetch_add_relaxed    atomic_fetch_add_relaxed
+#define atomic_fetch_sub_relaxed    atomic_fetch_sub_relaxed
+#define atomic_fetch_add    atomic_fetch_add
+#define atomic_fetch_sub    atomic_fetch_sub
+
+#undef ATOMIC_OPS
+
+#define ATOMIC_OPS(op, asm_op, I) \
+        ATOMIC_FETCH_OP(op, asm_op, I, w, int,   )
+
+ATOMIC_OPS(and, and, i)
+ATOMIC_OPS( or,  or, i)
+ATOMIC_OPS(xor, xor, i)
+
+#define atomic_fetch_and_relaxed    atomic_fetch_and_relaxed
+#define atomic_fetch_or_relaxed	    atomic_fetch_or_relaxed
+#define atomic_fetch_xor_relaxed    atomic_fetch_xor_relaxed
+#define atomic_fetch_and    atomic_fetch_and
+#define atomic_fetch_or     atomic_fetch_or
+#define atomic_fetch_xor    atomic_fetch_xor
+
+#undef ATOMIC_OPS
+
+#undef ATOMIC_FETCH_OP
+#undef ATOMIC_OP_RETURN
+
+/* This is required to provide a full barrier on success. */
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+       int prev, rc;
+
+    __asm__ __volatile__ (
+        "0: lr.w     %[p],  %[c]\n"
+        "   beq      %[p],  %[u], 1f\n"
+        "   add      %[rc], %[p], %[a]\n"
+        "   sc.w.rl  %[rc], %[rc], %[c]\n"
+        "   bnez     %[rc], 0b\n"
+        "   fence    rw, rw\n"
+        "1:\n"
+        : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
+        : [a]"r" (a), [u]"r" (u)
+        : "memory");
+    return prev;
+}
+#define atomic_fetch_add_unless atomic_fetch_add_unless
+
+/*
+ * atomic_{cmp,}xchg is required to have exactly the same ordering semantics as
+ * {cmp,}xchg and the operations that return, so they need a full barrier.
+ */
+#define ATOMIC_OP(c_t, prefix, size)                            \
+static inline                                                   \
+c_t atomic##prefix##_xchg_relaxed(atomic##prefix##_t *v, c_t n) \
+{                                                               \
+    return __xchg_relaxed(&(v->counter), n, size);              \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_xchg_acquire(atomic##prefix##_t *v, c_t n) \
+{                                                               \
+    return __xchg_acquire(&(v->counter), n, size);              \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_xchg_release(atomic##prefix##_t *v, c_t n) \
+{                                                               \
+    return __xchg_release(&(v->counter), n, size);              \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_xchg(atomic##prefix##_t *v, c_t n)         \
+{                                                               \
+    return __xchg(&(v->counter), n, size);                      \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_cmpxchg_relaxed(atomic##prefix##_t *v,     \
+                     c_t o, c_t n)                              \
+{                                                               \
+    return __cmpxchg_relaxed(&(v->counter), o, n, size);        \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_cmpxchg_acquire(atomic##prefix##_t *v,     \
+                     c_t o, c_t n)                              \
+{                                                               \
+    return __cmpxchg_acquire(&(v->counter), o, n, size);        \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_cmpxchg_release(atomic##prefix##_t *v,     \
+                     c_t o, c_t n)                              \
+{	                                                            \
+    return __cmpxchg_release(&(v->counter), o, n, size);        \
+}                                                               \
+static inline                                                   \
+c_t atomic##prefix##_cmpxchg(atomic##prefix##_t *v, c_t o, c_t n) \
+{                                                               \
+    return __cmpxchg(&(v->counter), o, n, size);                \
+}
+
+#define ATOMIC_OPS() \
+    ATOMIC_OP(int,   , 4)
+
+ATOMIC_OPS()
+
+#define atomic_xchg_relaxed atomic_xchg_relaxed
+#define atomic_xchg_acquire atomic_xchg_acquire
+#define atomic_xchg_release atomic_xchg_release
+#define atomic_xchg atomic_xchg
+#define atomic_cmpxchg_relaxed atomic_cmpxchg_relaxed
+#define atomic_cmpxchg_acquire atomic_cmpxchg_acquire
+#define atomic_cmpxchg_release atomic_cmpxchg_release
+#define atomic_cmpxchg atomic_cmpxchg
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP
+
+static inline int atomic_sub_if_positive(atomic_t *v, int offset)
+{
+       int prev, rc;
+
+    __asm__ __volatile__ (
+        "0: lr.w     %[p],  %[c]\n"
+        "   sub      %[rc], %[p], %[o]\n"
+        "   bltz     %[rc], 1f\n"
+        "   sc.w.rl  %[rc], %[rc], %[c]\n"
+        "   bnez     %[rc], 0b\n"
+        "   fence    rw, rw\n"
+        "1:\n"
+        : [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
+        : [o]"r" (offset)
+        : "memory" );
+    return prev - offset;
+}
+
+#define atomic_dec_if_positive(v)	atomic_sub_if_positive(v, 1)
+
+#endif /* _ASM_RISCV_ATOMIC_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/riscv/include/asm/fence.h b/xen/arch/riscv/include/asm/fence.h
new file mode 100644
index 0000000000..b3f6b1c20a
--- /dev/null
+++ b/xen/arch/riscv/include/asm/fence.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _ASM_RISCV_FENCE_H
+#define _ASM_RISCV_FENCE_H
+
+#ifdef CONFIG_SMP
+#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
+#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
+#else
+#define RISCV_ACQUIRE_BARRIER
+#define RISCV_RELEASE_BARRIER
+#endif
+
+#endif	/* _ASM_RISCV_FENCE_H */
-- 
2.43.0



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

* [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (14 preceding siblings ...)
  2023-12-22 15:12 ` [PATCH v3 15/34] xen/riscv: introduce atomic.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:14   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 17/34] xen/riscv: add compilation of generic find-next-bit.c Oleksii Kurochko
                   ` (17 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

find-next-bit.c is common for Arm64 and RISC-V64 so it is moved
to xen/lib.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - new patch.
---
 xen/arch/riscv/include/asm/fence.h |  11 +-
 xen/common/Kconfig                 |   3 +
 xen/lib/Makefile                   |   1 +
 xen/lib/find-next-bit.c            | 281 +++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+), 1 deletion(-)
 create mode 100644 xen/lib/find-next-bit.c

diff --git a/xen/arch/riscv/include/asm/fence.h b/xen/arch/riscv/include/asm/fence.h
index b3f6b1c20a..5d9a851ae8 100644
--- a/xen/arch/riscv/include/asm/fence.h
+++ b/xen/arch/riscv/include/asm/fence.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* SPDX-License-Identifier: GPL-2.0-only */
 #ifndef _ASM_RISCV_FENCE_H
 #define _ASM_RISCV_FENCE_H
 
@@ -11,3 +11,12 @@
 #endif
 
 #endif	/* _ASM_RISCV_FENCE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 310ad4229c..56ce34ffd4 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
 config GENERIC_BUG_FRAME
 	bool
 
+config GENERIC_FIND_NEXT_BIT
+	bool
+
 config HAS_ALTERNATIVE
 	bool
 
diff --git a/xen/lib/Makefile b/xen/lib/Makefile
index 2d9ebb945f..66237a45c5 100644
--- a/xen/lib/Makefile
+++ b/xen/lib/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
 lib-y += bsearch.o
 lib-y += ctors.o
 lib-y += ctype.o
+lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
 lib-y += list-sort.o
 lib-y += memchr.o
 lib-y += memchr_inv.o
diff --git a/xen/lib/find-next-bit.c b/xen/lib/find-next-bit.c
new file mode 100644
index 0000000000..ca6f82277e
--- /dev/null
+++ b/xen/lib/find-next-bit.c
@@ -0,0 +1,281 @@
+/* find_next_bit.c: fallback find next bit implementation
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <xen/bitops.h>
+
+#include <asm/byteorder.h>
+
+#ifndef find_next_bit
+/*
+ * Find the next set bit in a memory region.
+ */
+unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
+			    unsigned long offset)
+{
+	const unsigned long *p = addr + BIT_WORD(offset);
+	unsigned long result = offset & ~(BITS_PER_LONG-1);
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset %= BITS_PER_LONG;
+	if (offset) {
+		tmp = *(p++);
+		tmp &= (~0UL << offset);
+		if (size < BITS_PER_LONG)
+			goto found_first;
+		if (tmp)
+			goto found_middle;
+		size -= BITS_PER_LONG;
+		result += BITS_PER_LONG;
+	}
+	while (size & ~(BITS_PER_LONG-1)) {
+		if ((tmp = *(p++)))
+			goto found_middle;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp &= (~0UL >> (BITS_PER_LONG - size));
+	if (tmp == 0UL)		/* Are any bits set? */
+		return result + size;	/* Nope. */
+found_middle:
+	return result + __ffs(tmp);
+}
+EXPORT_SYMBOL(find_next_bit);
+#endif
+
+#ifndef find_next_zero_bit
+/*
+ * This implementation of find_{first,next}_zero_bit was stolen from
+ * Linus' asm-alpha/bitops.h.
+ */
+unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
+				 unsigned long offset)
+{
+	const unsigned long *p = addr + BIT_WORD(offset);
+	unsigned long result = offset & ~(BITS_PER_LONG-1);
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset %= BITS_PER_LONG;
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (BITS_PER_LONG - offset);
+		if (size < BITS_PER_LONG)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= BITS_PER_LONG;
+		result += BITS_PER_LONG;
+	}
+	while (size & ~(BITS_PER_LONG-1)) {
+		if (~(tmp = *(p++)))
+			goto found_middle;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL << size;
+	if (tmp == ~0UL)	/* Are any bits zero? */
+		return result + size;	/* Nope. */
+found_middle:
+	return result + ffz(tmp);
+}
+EXPORT_SYMBOL(find_next_zero_bit);
+#endif
+
+#ifndef find_first_bit
+/*
+ * Find the first set bit in a memory region.
+ */
+unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
+{
+	const unsigned long *p = addr;
+	unsigned long result = 0;
+	unsigned long tmp;
+
+	while (size & ~(BITS_PER_LONG-1)) {
+		if ((tmp = *(p++)))
+			goto found;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+
+	tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
+	if (tmp == 0UL)		/* Are any bits set? */
+		return result + size;	/* Nope. */
+found:
+	return result + __ffs(tmp);
+}
+EXPORT_SYMBOL(find_first_bit);
+#endif
+
+#ifndef find_first_zero_bit
+/*
+ * Find the first cleared bit in a memory region.
+ */
+unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
+{
+	const unsigned long *p = addr;
+	unsigned long result = 0;
+	unsigned long tmp;
+
+	while (size & ~(BITS_PER_LONG-1)) {
+		if (~(tmp = *(p++)))
+			goto found;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+
+	tmp = (*p) | (~0UL << size);
+	if (tmp == ~0UL)	/* Are any bits zero? */
+		return result + size;	/* Nope. */
+found:
+	return result + ffz(tmp);
+}
+EXPORT_SYMBOL(find_first_zero_bit);
+#endif
+
+#ifdef __BIG_ENDIAN
+
+/* include/linux/byteorder does not support "unsigned long" type */
+static inline unsigned long ext2_swabp(const unsigned long * x)
+{
+#if BITS_PER_LONG == 64
+	return (unsigned long) __swab64p((u64 *) x);
+#elif BITS_PER_LONG == 32
+	return (unsigned long) __swab32p((u32 *) x);
+#else
+#error BITS_PER_LONG not defined
+#endif
+}
+
+/* include/linux/byteorder doesn't support "unsigned long" type */
+static inline unsigned long ext2_swab(const unsigned long y)
+{
+#if BITS_PER_LONG == 64
+	return (unsigned long) __swab64((u64) y);
+#elif BITS_PER_LONG == 32
+	return (unsigned long) __swab32((u32) y);
+#else
+#error BITS_PER_LONG not defined
+#endif
+}
+
+#ifndef find_next_zero_bit_le
+unsigned long find_next_zero_bit_le(const void *addr, unsigned
+		long size, unsigned long offset)
+{
+	const unsigned long *p = addr;
+	unsigned long result = offset & ~(BITS_PER_LONG - 1);
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	p += BIT_WORD(offset);
+	size -= result;
+	offset &= (BITS_PER_LONG - 1UL);
+	if (offset) {
+		tmp = ext2_swabp(p++);
+		tmp |= (~0UL >> (BITS_PER_LONG - offset));
+		if (size < BITS_PER_LONG)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= BITS_PER_LONG;
+		result += BITS_PER_LONG;
+	}
+
+	while (size & ~(BITS_PER_LONG - 1)) {
+		if (~(tmp = *(p++)))
+			goto found_middle_swap;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+	tmp = ext2_swabp(p);
+found_first:
+	tmp |= ~0UL << size;
+	if (tmp == ~0UL)	/* Are any bits zero? */
+		return result + size; /* Nope. Skip ffz */
+found_middle:
+	return result + ffz(tmp);
+
+found_middle_swap:
+	return result + ffz(ext2_swab(tmp));
+}
+EXPORT_SYMBOL(find_next_zero_bit_le);
+#endif
+
+#ifndef find_next_bit_le
+unsigned long find_next_bit_le(const void *addr, unsigned
+		long size, unsigned long offset)
+{
+	const unsigned long *p = addr;
+	unsigned long result = offset & ~(BITS_PER_LONG - 1);
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	p += BIT_WORD(offset);
+	size -= result;
+	offset &= (BITS_PER_LONG - 1UL);
+	if (offset) {
+		tmp = ext2_swabp(p++);
+		tmp &= (~0UL << offset);
+		if (size < BITS_PER_LONG)
+			goto found_first;
+		if (tmp)
+			goto found_middle;
+		size -= BITS_PER_LONG;
+		result += BITS_PER_LONG;
+	}
+
+	while (size & ~(BITS_PER_LONG - 1)) {
+		tmp = *(p++);
+		if (tmp)
+			goto found_middle_swap;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+	tmp = ext2_swabp(p);
+found_first:
+	tmp &= (~0UL >> (BITS_PER_LONG - size));
+	if (tmp == 0UL)		/* Are any bits set? */
+		return result + size; /* Nope. */
+found_middle:
+	return result + __ffs(tmp);
+
+found_middle_swap:
+	return result + __ffs(ext2_swab(tmp));
+}
+EXPORT_SYMBOL(find_next_bit_le);
+#endif
+
+#endif /* __BIG_ENDIAN */
-- 
2.43.0



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

* [PATCH v3 17/34] xen/riscv: add compilation of generic find-next-bit.c
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (15 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 16/34] xen/lib: introduce generic find next bit operations Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 18/34] xen/riscv: introduce domain.h Oleksii Kurochko
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - new patch
---
 xen/arch/riscv/Kconfig                  | 1 +
 xen/arch/riscv/configs/tiny64_defconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/xen/arch/riscv/Kconfig b/xen/arch/riscv/Kconfig
index f382b36f6c..b8f8c083dc 100644
--- a/xen/arch/riscv/Kconfig
+++ b/xen/arch/riscv/Kconfig
@@ -4,6 +4,7 @@ config RISCV
 config RISCV_64
 	def_bool y
 	select 64BIT
+	select GENERIC_FIND_NEXT_BIT
 
 config ARCH_DEFCONFIG
 	string
diff --git a/xen/arch/riscv/configs/tiny64_defconfig b/xen/arch/riscv/configs/tiny64_defconfig
index 35915255e6..399128be02 100644
--- a/xen/arch/riscv/configs/tiny64_defconfig
+++ b/xen/arch/riscv/configs/tiny64_defconfig
@@ -29,3 +29,4 @@ CONFIG_RISCV_64=y
 CONFIG_DEBUG=y
 CONFIG_DEBUG_INFO=y
 CONFIG_EXPERT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
-- 
2.43.0



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

* [PATCH v3 18/34] xen/riscv: introduce domain.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (16 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 17/34] xen/riscv: add compilation of generic find-next-bit.c Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 19/34] xen/riscv: introduce guest_access.h Oleksii Kurochko
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - add SPDX
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
 - update the commit message
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/domain.h | 53 +++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/domain.h

diff --git a/xen/arch/riscv/include/asm/domain.h b/xen/arch/riscv/include/asm/domain.h
new file mode 100644
index 0000000000..0f5dc2be40
--- /dev/null
+++ b/xen/arch/riscv/include/asm/domain.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_DOMAIN_H__
+#define __ASM_RISCV_DOMAIN_H__
+
+#include <xen/xmalloc.h>
+#include <public/hvm/params.h>
+
+struct hvm_domain
+{
+    uint64_t              params[HVM_NR_PARAMS];
+};
+
+#define is_domain_direct_mapped(d) ((void)(d), 0)
+
+struct arch_vcpu_io {
+};
+
+struct arch_vcpu {
+};
+
+struct arch_domain {
+    struct hvm_domain hvm;
+};
+
+#include <xen/sched.h>
+
+static inline struct vcpu_guest_context *alloc_vcpu_guest_context(void)
+{
+    return xmalloc(struct vcpu_guest_context);
+}
+
+static inline void free_vcpu_guest_context(struct vcpu_guest_context *vgc)
+{
+    xfree(vgc);
+}
+
+struct guest_memory_policy {};
+static inline void update_guest_memory_policy(struct vcpu *v,
+                                              struct guest_memory_policy *gmp)
+{}
+
+static inline void arch_vcpu_block(struct vcpu *v) {}
+
+#endif /* __ASM_RISCV_DOMAIN_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 19/34] xen/riscv: introduce guest_access.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (17 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 18/34] xen/riscv: introduce domain.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:16   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 20/34] xen/riscv: introduce irq.h Oleksii Kurochko
                   ` (14 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

All necessary dummiy implementation of functions in this header
will be introduced in stubs.c

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - remove unnessary inclusion of types.h header.
 - drop copy_to_guest_phys. it isn't needed yet
 - add SPDX
 - add comment above guest_handle_okay()
 - update the commit message
---
Changes in V2:
 - change xen/mm.h to xen/types.h
---
 xen/arch/riscv/include/asm/guest_access.h | 29 +++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/guest_access.h

diff --git a/xen/arch/riscv/include/asm/guest_access.h b/xen/arch/riscv/include/asm/guest_access.h
new file mode 100644
index 0000000000..c55951f538
--- /dev/null
+++ b/xen/arch/riscv/include/asm/guest_access.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_GUEST_ACCESS_H__
+#define __ASM_RISCV_GUEST_ACCESS_H__
+
+unsigned long raw_copy_to_guest(void *to, const void *from, unsigned len);
+unsigned long raw_copy_from_guest(void *to, const void *from, unsigned len);
+unsigned long raw_clear_guest(void *to, unsigned int len);
+
+#define __raw_copy_to_guest raw_copy_to_guest
+#define __raw_copy_from_guest raw_copy_from_guest
+#define __raw_clear_guest raw_clear_guest
+
+/*
+ * Pre-validate a guest handle.
+ * Allows use of faster __copy_* functions.
+ */
+/* All RISCV guests are paging mode external and hence safe */
+#define guest_handle_okay(hnd, nr) (1)
+#define guest_handle_subrange_okay(hnd, first, last) (1)
+
+#endif /* __ASM_RISCV_GUEST_ACCESS_H__ */
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 20/34] xen/riscv: introduce irq.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (18 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 19/34] xen/riscv: introduce guest_access.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:18   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 21/34] xen/riscv: introduce p2m.h Oleksii Kurochko
                   ` (13 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - add SPDX
 - remove all that was wraped to HAS_DEVICETREE_... as for RISC-V it is going to be
   always selected.
 - update the commit message
---
Changes in V2:
	- add ifdef CONFIG_HAS_DEVICE_TREE for things that shouldn't be
      in case !CONFIG_HAS_DEVICE_TREE
	- use proper includes.
---
 xen/arch/riscv/include/asm/irq.h | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/irq.h

diff --git a/xen/arch/riscv/include/asm/irq.h b/xen/arch/riscv/include/asm/irq.h
new file mode 100644
index 0000000000..a4434fb8ae
--- /dev/null
+++ b/xen/arch/riscv/include/asm/irq.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_IRQ_H__
+#define __ASM_RISCV_IRQ_H__
+
+#include <xen/bug.h>
+
+/* TODO */
+#define nr_irqs 0U
+#define nr_static_irqs 0
+#define arch_hwdom_irqs(domid) 0U
+
+#define domain_pirq_to_irq(d, pirq) (pirq)
+
+#define arch_evtchn_bind_pirq(d, pirq) ((void)((d) + (pirq)))
+
+struct arch_pirq {
+};
+
+struct arch_irq_desc {
+    unsigned int type;
+};
+
+static inline void arch_move_irqs(struct vcpu *v)
+{
+    BUG();
+}
+
+#endif /* __ASM_RISCV_IRQ_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (19 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 20/34] xen/riscv: introduce irq.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-11 23:11   ` Shawn Anastasio
  2024-01-12 10:39   ` Julien Grall
  2023-12-22 15:13 ` [PATCH v3 22/34] xen/riscv: introduce regs.h Oleksii Kurochko
                   ` (12 subsequent siblings)
  33 siblings, 2 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Shawn Anastasio, Alistair Francis, Bob Eshleman,
	Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - add SPDX
 - drop unneeded for now p2m types.
 - return false in all functions implemented with BUG() inside.
 - update the commit message
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/ppc/include/asm/p2m.h   |   3 +-
 xen/arch/riscv/include/asm/p2m.h | 102 +++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 2 deletions(-)
 create mode 100644 xen/arch/riscv/include/asm/p2m.h

diff --git a/xen/arch/ppc/include/asm/p2m.h b/xen/arch/ppc/include/asm/p2m.h
index 25ba054668..3bc05b7c05 100644
--- a/xen/arch/ppc/include/asm/p2m.h
+++ b/xen/arch/ppc/include/asm/p2m.h
@@ -50,8 +50,7 @@ static inline void memory_type_changed(struct domain *d)
 static inline int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
                                                         unsigned int order)
 {
-    BUG_ON("unimplemented");
-    return 1;
+    return -EOPNOTSUPP;
 }
 
 static inline int guest_physmap_add_entry(struct domain *d,
diff --git a/xen/arch/riscv/include/asm/p2m.h b/xen/arch/riscv/include/asm/p2m.h
new file mode 100644
index 0000000000..d270ef6635
--- /dev/null
+++ b/xen/arch/riscv/include/asm/p2m.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_P2M_H__
+#define __ASM_RISCV_P2M_H__
+
+#include <asm/page-bits.h>
+
+#define paddr_bits PADDR_BITS
+
+/*
+ * List of possible type for each page in the p2m entry.
+ * The number of available bit per page in the pte for this purpose is 4 bits.
+ * So it's possible to only have 16 fields. If we run out of value in the
+ * future, it's possible to use higher value for pseudo-type and don't store
+ * them in the p2m entry.
+ */
+typedef enum {
+    p2m_invalid = 0,    /* Nothing mapped here */
+    p2m_ram_rw,         /* Normal read/write guest RAM */
+} p2m_type_t;
+
+#include <xen/p2m-common.h>
+
+static inline int get_page_and_type(struct page_info *page,
+                                    struct domain *domain,
+                                    unsigned long type)
+{
+    BUG();
+    return -EINVAL;
+}
+
+/* Look up a GFN and take a reference count on the backing page. */
+typedef unsigned int p2m_query_t;
+#define P2M_ALLOC    (1u<<0)   /* Populate PoD and paged-out entries */
+#define P2M_UNSHARE  (1u<<1)   /* Break CoW sharing */
+
+static inline struct page_info *get_page_from_gfn(
+    struct domain *d, unsigned long gfn, p2m_type_t *t, p2m_query_t q)
+{
+    BUG();
+    return NULL;
+}
+
+static inline void memory_type_changed(struct domain *d)
+{
+    BUG();
+}
+
+
+static inline int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
+                                                        unsigned int order)
+{
+    return -EOPNOTSUPP;
+}
+
+static inline int guest_physmap_add_entry(struct domain *d,
+                            gfn_t gfn,
+                            mfn_t mfn,
+                            unsigned long page_order,
+                            p2m_type_t t)
+{
+    BUG();
+    return -EINVAL;
+}
+
+/* Untyped version for RAM only, for compatibility */
+static inline int __must_check
+guest_physmap_add_page(struct domain *d, gfn_t gfn, mfn_t mfn,
+                       unsigned int page_order)
+{
+    return guest_physmap_add_entry(d, gfn, mfn, page_order, p2m_ram_rw);
+}
+
+static inline mfn_t gfn_to_mfn(struct domain *d, gfn_t gfn)
+{
+    BUG();
+    return _mfn(0);
+}
+
+static inline bool arch_acquire_resource_check(struct domain *d)
+{
+    /*
+     * The reference counting of foreign entries in set_foreign_p2m_entry()
+     * is supported on RISCV.
+     */
+    return true;
+}
+
+static inline void p2m_altp2m_check(struct vcpu *v, uint16_t idx)
+{
+    /* Not supported on RISCV. */
+}
+
+#endif /* __ASM_RISCV_P2M_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 22/34] xen/riscv: introduce regs.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (20 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 21/34] xen/riscv: introduce p2m.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-15 17:00   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 23/34] xen/riscv: introduce time.h Oleksii Kurochko
                   ` (11 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - update the commit message
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
 - remove "include <asm/current.h>" and use a forward declaration instead.
---
Changes in V2:
 - change xen/lib.h to xen/bug.h
 - remove unnecessary empty line
---
 xen/arch/riscv/include/asm/regs.h | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/regs.h

diff --git a/xen/arch/riscv/include/asm/regs.h b/xen/arch/riscv/include/asm/regs.h
new file mode 100644
index 0000000000..86bebc5810
--- /dev/null
+++ b/xen/arch/riscv/include/asm/regs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ARM_RISCV_REGS_H__
+#define __ARM_RISCV_REGS_H__
+
+#ifndef __ASSEMBLY__
+
+#include <xen/bug.h>
+
+#define hyp_mode(r)     (0)
+
+struct cpu_user_regs;
+
+static inline bool guest_mode(const struct cpu_user_regs *r)
+{
+    BUG();
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARM_RISCV_REGS_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 23/34] xen/riscv: introduce time.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (21 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 22/34] xen/riscv: introduce regs.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 24/34] xen/riscv: introduce event.h Oleksii Kurochko
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - Acked-by: Jan Beulich <jbeulich@suse.com>
 - add SPDX
 - Add new line
---
Changes in V2:
 -  change xen/lib.h to xen/bug.h
 - remove inclusion of <asm/processor.h> as it's not needed.
---
 xen/arch/riscv/include/asm/time.h | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/time.h

diff --git a/xen/arch/riscv/include/asm/time.h b/xen/arch/riscv/include/asm/time.h
new file mode 100644
index 0000000000..1f22af3bce
--- /dev/null
+++ b/xen/arch/riscv/include/asm/time.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_TIME_H__
+#define __ASM_RISCV_TIME_H__
+
+#include <xen/bug.h>
+#include <asm/csr.h>
+
+struct vcpu;
+
+/* TODO: implement */
+static inline void force_update_vcpu_system_time(struct vcpu *v) { BUG(); }
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return csr_read(CSR_TIME);
+}
+
+#endif /* __ASM_RISCV_TIME_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 24/34] xen/riscv: introduce event.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (22 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 23/34] xen/riscv: introduce time.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 25/34] xen/riscv: introduce monitor.h Oleksii Kurochko
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - add SPDX
 - add BUG() inside stubs.
 - update the commit message
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/event.h | 40 ++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/event.h

diff --git a/xen/arch/riscv/include/asm/event.h b/xen/arch/riscv/include/asm/event.h
new file mode 100644
index 0000000000..65cc5ae168
--- /dev/null
+++ b/xen/arch/riscv/include/asm/event.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_EVENT_H__
+#define __ASM_RISCV_EVENT_H__
+
+#include <xen/bug.h>
+
+void vcpu_mark_events_pending(struct vcpu *v);
+
+static inline int vcpu_event_delivery_is_enabled(struct vcpu *v)
+{
+    BUG();
+    return 0;
+}
+
+static inline int local_events_need_delivery(void)
+{
+    BUG();
+    return 0;
+}
+
+static inline void local_event_delivery_enable(void)
+{
+    BUG();
+}
+
+/* No arch specific virq definition now. Default to global. */
+static inline bool arch_virq_is_global(unsigned int virq)
+{
+    return true;
+}
+
+#endif
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 25/34] xen/riscv: introduce monitor.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (23 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 24/34] xen/riscv: introduce event.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 26/34] xen/riscv: add definition of __read_mostly Oleksii Kurochko
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Tamas K Lengyel, Alexandru Isaila,
	Petre Pircalabu, Alistair Francis, Bob Eshleman, Connor Davis

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 Taking into account conversion in [PATCH v6 0/9] Introduce generic headers
 (https://lore.kernel.org/xen-devel/cover.1703072575.git.oleksii.kurochko@gmail.com/)
 this patch can be changed
---
Changes in V3:
 - new patch.
---
 xen/arch/riscv/include/asm/monitor.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 xen/arch/riscv/include/asm/monitor.h

diff --git a/xen/arch/riscv/include/asm/monitor.h b/xen/arch/riscv/include/asm/monitor.h
new file mode 100644
index 0000000000..f4fe2c0690
--- /dev/null
+++ b/xen/arch/riscv/include/asm/monitor.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_RISCV_MONITOR_H__
+#define __ASM_RISCV_MONITOR_H__
+
+#include <xen/bug.h>
+
+#include <asm-generic/monitor.h>
+
+struct domain;
+
+static inline uint32_t arch_monitor_get_capabilities(struct domain *d)
+{
+    BUG_ON("unimplemented");
+    return 0;
+}
+
+#endif /* __ASM_RISCV_MONITOR_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.43.0



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

* [PATCH v3 26/34] xen/riscv: add definition of __read_mostly
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (24 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 25/34] xen/riscv: introduce monitor.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 27/34] xen/riscv: define an address of frame table Oleksii Kurochko
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

The definition of __read_mostly should be removed in:
https://lore.kernel.org/xen-devel/f25eb5c9-7c14-6e23-8535-2c66772b333e@suse.com/

The patch introduces it in arch-specific header to not
block enabling of full Xen build for RISC-V.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
- [PATCH] move __read_mostly to xen/cache.h  [2]

Right now, the patch series doesn't have a direct dependency on [2] and it
provides __read_mostly in the patch:
    [PATCH v3 26/34] xen/riscv: add definition of __read_mostly
However, it will be dropped as soon as [2] is merged or at least when the
final version of the patch [2] is provided.

[2] https://lore.kernel.org/xen-devel/f25eb5c9-7c14-6e23-8535-2c66772b333e@suse.com/
---
 xen/arch/riscv/include/asm/cache.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xen/arch/riscv/include/asm/cache.h b/xen/arch/riscv/include/asm/cache.h
index 69573eb051..94bd94db53 100644
--- a/xen/arch/riscv/include/asm/cache.h
+++ b/xen/arch/riscv/include/asm/cache.h
@@ -3,4 +3,6 @@
 #ifndef _ASM_RISCV_CACHE_H
 #define _ASM_RISCV_CACHE_H
 
+#define __read_mostly __section(".data.read_mostly")
+
 #endif /* _ASM_RISCV_CACHE_H */
-- 
2.43.0



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

* [PATCH v3 27/34] xen/riscv: define an address of frame table
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (25 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 26/34] xen/riscv: add definition of __read_mostly Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:32   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 28/34] xen/riscv: add required things to current.h Oleksii Kurochko
                   ` (6 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Also, the patch adds some helpful macros that assist in avoiding
the redefinition of memory layout for each MMU mode.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - drop OFFSET_BITS, and use PAGE_SHIFT instead.
 - code style fixes.
 - add comment how macros are useful.
 - move all memory related layout definitions close to comment with memory layout description.
 - make memory layout description generic for any MMU mode.
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/config.h | 85 +++++++++++++++++++----------
 1 file changed, 55 insertions(+), 30 deletions(-)

diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/asm/config.h
index f0544c6a20..fb9fc9daaa 100644
--- a/xen/arch/riscv/include/asm/config.h
+++ b/xen/arch/riscv/include/asm/config.h
@@ -6,6 +6,14 @@
 #include <xen/const.h>
 #include <xen/page-size.h>
 
+#ifdef CONFIG_RISCV_64
+#define CONFIG_PAGING_LEVELS 3
+#define RV_STAGE1_MODE SATP_MODE_SV39
+#else
+#define CONFIG_PAGING_LEVELS 2
+#define RV_STAGE1_MODE SATP_MODE_SV32
+#endif
+
 /*
  * RISC-V64 Layout:
  *
@@ -22,25 +30,56 @@
  *
  * It means that:
  *   top VA bits are simply ignored for the purpose of translating to PA.
+#endif
  *
- * ============================================================================
- *    Start addr    |   End addr        |  Size  | Slot       |area description
- * ============================================================================
- * FFFFFFFFC0800000 |  FFFFFFFFFFFFFFFF |1016 MB | L2 511     | Unused
- * FFFFFFFFC0600000 |  FFFFFFFFC0800000 |  2 MB  | L2 511     | Fixmap
- * FFFFFFFFC0200000 |  FFFFFFFFC0600000 |  4 MB  | L2 511     | FDT
- * FFFFFFFFC0000000 |  FFFFFFFFC0200000 |  2 MB  | L2 511     | Xen
- *                 ...                  |  1 GB  | L2 510     | Unused
- * 0000003200000000 |  0000007F80000000 | 309 GB | L2 200-509 | Direct map
- *                 ...                  |  1 GB  | L2 199     | Unused
- * 0000003100000000 |  00000031C0000000 |  3 GB  | L2 196-198 | Frametable
- *                 ...                  |  1 GB  | L2 195     | Unused
- * 0000003080000000 |  00000030C0000000 |  1 GB  | L2 194     | VMAP
- *                 ...                  | 194 GB | L2 0 - 193 | Unused
- * ============================================================================
+ *       SATP_MODE_SV32   | SATP_MODE_SV39   | SATP_MODE_SV48   | SATP_MODE_SV57
+ *      ==================|==================|==================|=================
+ * BA0 | FFFFFFFFFFE00000 | FFFFFFFFC0000000 | FFFFFF8000000000 | FFFF000000000000
+ * BA1 | 0000000019000000 | 0000003200000000 | 0000640000000000 | 00C8000000000000
+ * BA2 | 0000000018800000 | 0000003100000000 | 0000620000000000 | 00C4000000000000
+ * BA3 | 0000000018400000 | 0000003080000000 | 0000610000000000 | 00C2000000000000
  *
-#endif
+ * ===============================================================================
+ * Start addr     |   End addr          |  Size  | Root PT slot | Area description
+ * ===============================================================================
+ * BA0 + 0x800000 |  FFFFFFFFFFFFFFFF   |1016 MB |     511      | Unused
+ * BA0 + 0x400000 |  BA0 + 0x800000     |  2 MB  |     511      | Fixmap
+ * BA0 + 0x200000 |  BA0 + 0x400000     |  4 MB  |     511      | FDT
+ * BA0            |  BA0 + 0x200000     |  2 MB  |     511      | Xen
+ *                 ...                  |  1 GB  |     510      | Unused
+ * BA1 + 0x000000 |  BA1 + 0x4D80000000 | 309 GB |   200-509    | Direct map
+ *                 ...                  |  1 GB  |     199      | Unused
+ * BA2 + 0x000000 |  BA2 + 0xC0000000   |  3 GB  |   196-198    | Frametable
+ *                 ...                  |  1 GB  |     195      | Unused
+ * BA3 + 0x000000 |  BA3 + 0x40000000   |  1 GB  |     194      | VMAP
+ *                 ...                  | 194 GB |   0 - 193    | Unused
+ * ===============================================================================
  */
+#define VPN_BITS    (9)
+
+#define HYP_PT_ROOT_LEVEL (CONFIG_PAGING_LEVELS - 1)
+
+#ifdef CONFIG_RISCV_64
+
+#define SLOTN_ENTRY_BITS        (HYP_PT_ROOT_LEVEL * VPN_BITS + PAGE_SHIFT)
+#define SLOTN(slot)             (_AT(vaddr_t, slot) << SLOTN_ENTRY_BITS)
+#define SLOTN_ENTRY_SIZE        SLOTN(1)
+
+#define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 - GB(1)) */
+
+#define FRAMETABLE_VIRT_START   SLOTN(196)
+#define FRAMETABLE_SIZE         GB(3)
+#define FRAMETABLE_NR           (FRAMETABLE_SIZE / sizeof(*frame_table))
+#define FRAMETABLE_VIRT_END     (FRAMETABLE_VIRT_START + FRAMETABLE_SIZE - 1)
+
+#define VMAP_VIRT_START         SLOTN(194)
+#define VMAP_VIRT_SIZE          GB(1)
+
+#else
+#error "RV32 isn't supported"
+#endif
+
+#define HYPERVISOR_VIRT_START XEN_VIRT_START
 
 #if defined(CONFIG_RISCV_64)
 # define LONG_BYTEORDER 3
@@ -77,24 +116,10 @@
   name:
 #endif
 
-#ifdef CONFIG_RISCV_64
-#define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 - GB(1)) */
-#else
-#error "RV32 isn't supported"
-#endif
-
 #define SMP_CACHE_BYTES (1 << 6)
 
 #define STACK_SIZE PAGE_SIZE
 
-#ifdef CONFIG_RISCV_64
-#define CONFIG_PAGING_LEVELS 3
-#define RV_STAGE1_MODE SATP_MODE_SV39
-#else
-#define CONFIG_PAGING_LEVELS 2
-#define RV_STAGE1_MODE SATP_MODE_SV32
-#endif
-
 #define IDENT_AREA_SIZE 64
 
 #endif /* __RISCV_CONFIG_H__ */
-- 
2.43.0



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

* [PATCH v3 28/34] xen/riscv: add required things to current.h
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (26 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 27/34] xen/riscv: define an address of frame table Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:35   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen Oleksii Kurochko
                   ` (5 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Add minimal requied things to be able to build full Xen.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - add SPDX
 - drop a forward declaration of struct vcpu;
 - update guest_cpu_user_regs() macros
 - replace get_processor_id with smp_processor_id
 - update the commit message
 - code style fixes
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/current.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/xen/arch/riscv/include/asm/current.h b/xen/arch/riscv/include/asm/current.h
index d84f15dc50..1694f68c6f 100644
--- a/xen/arch/riscv/include/asm/current.h
+++ b/xen/arch/riscv/include/asm/current.h
@@ -3,6 +3,21 @@
 #ifndef __ASM_CURRENT_H
 #define __ASM_CURRENT_H
 
+#include <xen/bug.h>
+#include <xen/percpu.h>
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+
+/* Which VCPU is "current" on this PCPU. */
+DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
+
+#define current            this_cpu(curr_vcpu)
+#define set_current(vcpu)  do { current = (vcpu); } while (0)
+#define get_cpu_current(cpu)  per_cpu(curr_vcpu, cpu)
+
+#define guest_cpu_user_regs() ({ BUG(); NULL; })
+
 #define switch_stack_and_jump(stack, fn) do {               \
     asm volatile (                                          \
             "mv sp, %0\n"                                   \
@@ -10,4 +25,8 @@
     unreachable();                                          \
 } while ( false )
 
+#define get_per_cpu_offset() __per_cpu_offset[smp_processor_id()]
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_CURRENT_H */
-- 
2.43.0



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

* [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (27 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 28/34] xen/riscv: add required things to current.h Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:36   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h " Oleksii Kurochko
                   ` (4 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - update the commit message
 - add implemetation of PAGE_HYPERVISOR macros
 - add Acked-by: Jan Beulich <jbeulich@suse.com>
 - drop definition of pfn_to_addr, and paddr_to_pfn in <asm/mm.h>
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/mm.h   |  3 ---
 xen/arch/riscv/include/asm/page.h | 22 ++++++++++++++++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h
index 07c7a0abba..57026e134d 100644
--- a/xen/arch/riscv/include/asm/mm.h
+++ b/xen/arch/riscv/include/asm/mm.h
@@ -5,9 +5,6 @@
 
 #include <asm/page-bits.h>
 
-#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT)
-#define paddr_to_pfn(pa)  ((unsigned long)((pa) >> PAGE_SHIFT))
-
 extern unsigned char cpu0_boot_stack[];
 
 void setup_initial_pagetables(void);
diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h
index 95074e29b3..85176702d5 100644
--- a/xen/arch/riscv/include/asm/page.h
+++ b/xen/arch/riscv/include/asm/page.h
@@ -6,6 +6,7 @@
 #ifndef __ASSEMBLY__
 
 #include <xen/const.h>
+#include <xen/bug.h>
 #include <xen/types.h>
 
 #include <asm/mm.h>
@@ -32,6 +33,10 @@
 #define PTE_LEAF_DEFAULT            (PTE_VALID | PTE_READABLE | PTE_WRITABLE)
 #define PTE_TABLE                   (PTE_VALID)
 
+#define PAGE_HYPERVISOR_RW          (PTE_VALID | PTE_READABLE | PTE_WRITABLE)
+
+#define PAGE_HYPERVISOR             PAGE_HYPERVISOR_RW
+
 /* Calculate the offsets into the pagetables for a given VA */
 #define pt_linear_offset(lvl, va)   ((va) >> XEN_PT_LEVEL_SHIFT(lvl))
 
@@ -46,6 +51,9 @@ typedef struct {
 #endif
 } pte_t;
 
+#define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT)
+#define paddr_to_pfn(pa)  ((unsigned long)((pa) >> PAGE_SHIFT))
+
 static inline pte_t paddr_to_pte(paddr_t paddr,
                                  unsigned int permissions)
 {
@@ -62,6 +70,20 @@ static inline bool pte_is_valid(pte_t p)
     return p.pte & PTE_VALID;
 }
 
+static inline void invalidate_icache(void)
+{
+    BUG();
+}
+
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(dp, sp) memcpy(dp, sp, PAGE_SIZE)
+
+/* TODO: Flush the dcache for an entire page. */
+static inline void flush_page_to_ram(unsigned long mfn, bool sync_icache)
+{
+    BUG();
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_RISCV_PAGE_H */
-- 
2.43.0



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

* [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (28 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:39   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h " Oleksii Kurochko
                   ` (3 subsequent siblings)
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - Update the commit message
 - rename get_processor_id to smp_processor_id
 - code style fixes
 - update the cpu_relax instruction: use pause instruction instead of div %0, %0, zero
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/include/asm/processor.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h
index 6db681d805..a3bff6c9c3 100644
--- a/xen/arch/riscv/include/asm/processor.h
+++ b/xen/arch/riscv/include/asm/processor.h
@@ -12,6 +12,9 @@
 
 #ifndef __ASSEMBLY__
 
+/* TODO: need to be implemeted */
+#define smp_processor_id() 0
+
 /* On stack VCPU state */
 struct cpu_user_regs
 {
@@ -53,6 +56,18 @@ struct cpu_user_regs
     unsigned long pregs;
 };
 
+/* TODO: need to implement */
+#define cpu_to_core(cpu)   (0)
+#define cpu_to_socket(cpu) (0)
+
+static inline void cpu_relax(void)
+{
+    /* Encoding of the pause instruction */
+    __asm__ __volatile__ ( ".insn 0x100000F" );
+
+    barrier();
+}
+
 static inline void wfi(void)
 {
     __asm__ __volatile__ ("wfi");
-- 
2.43.0



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

* [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (29 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h " Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 16:32   ` Oleksii
  2024-01-23 13:03   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs " Oleksii Kurochko
                   ` (2 subsequent siblings)
  33 siblings, 2 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - update the commit message
 - introduce DIRECTMAP_VIRT_START.
 - drop changes related pfn_to_paddr() and paddr_to_pfn as they were remvoe in
   [PATCH v2 32/39] xen/riscv: add minimal stuff to asm/page.h to build full Xen
 - code style fixes.
 - drop get_page_nr  and put_page_nr as they don't need for time being
 - drop CONFIG_STATIC_MEMORY related things
 - code style fixes
---
Changes in V2:
 - define stub for arch_get_dma_bitsize(void)
---
 xen/arch/riscv/include/asm/config.h |   2 +
 xen/arch/riscv/include/asm/mm.h     | 248 ++++++++++++++++++++++++++++
 2 files changed, 250 insertions(+)

diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/asm/config.h
index fb9fc9daaa..400309f4ef 100644
--- a/xen/arch/riscv/include/asm/config.h
+++ b/xen/arch/riscv/include/asm/config.h
@@ -67,6 +67,8 @@
 
 #define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 - GB(1)) */
 
+#define DIRECTMAP_VIRT_START    SLOTN(200)
+
 #define FRAMETABLE_VIRT_START   SLOTN(196)
 #define FRAMETABLE_SIZE         GB(3)
 #define FRAMETABLE_NR           (FRAMETABLE_SIZE / sizeof(*frame_table))
diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h
index 57026e134d..14fce72fde 100644
--- a/xen/arch/riscv/include/asm/mm.h
+++ b/xen/arch/riscv/include/asm/mm.h
@@ -3,8 +3,251 @@
 #ifndef _ASM_RISCV_MM_H
 #define _ASM_RISCV_MM_H
 
+#include <public/xen.h>
+#include <xen/pdx.h>
+#include <xen/types.h>
+
+#include <asm/page.h>
 #include <asm/page-bits.h>
 
+#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
+#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
+#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
+#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
+#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
+#define vmap_to_mfn(va)     maddr_to_mfn(virt_to_maddr((vaddr_t)va))
+#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
+#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
+#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
+#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
+#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
+#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
+#define vmap_to_mfn(va)     maddr_to_mfn(virt_to_maddr((vaddr_t)va))
+#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
+
+#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK))
+#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) | DIRECTMAP_VIRT_START))
+
+/* Convert between Xen-heap virtual addresses and machine frame numbers. */
+#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
+#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) << PAGE_SHIFT)
+
+/* Convert between Xen-heap virtual addresses and page-info structures. */
+static inline struct page_info *virt_to_page(const void *v)
+{
+    BUG();
+    return NULL;
+}
+
+/*
+ * We define non-underscored wrappers for above conversion functions.
+ * These are overriden in various source files while underscored version
+ * remain intact.
+ */
+#define virt_to_mfn(va)     __virt_to_mfn(va)
+#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
+
+struct page_info
+{
+    /* Each frame can be threaded onto a doubly-linked list. */
+    struct page_list_entry list;
+
+    /* Reference count and various PGC_xxx flags and fields. */
+    unsigned long count_info;
+
+    /* Context-dependent fields follow... */
+    union {
+        /* Page is in use: ((count_info & PGC_count_mask) != 0). */
+        struct {
+            /* Type reference count and various PGT_xxx flags and fields. */
+            unsigned long type_info;
+        } inuse;
+        /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
+        union {
+            struct {
+                /*
+                 * Index of the first *possibly* unscrubbed page in the buddy.
+                 * One more bit than maximum possible order to accommodate
+                 * INVALID_DIRTY_IDX.
+                 */
+#define INVALID_DIRTY_IDX ((1UL << (MAX_ORDER + 1)) - 1)
+                unsigned long first_dirty:MAX_ORDER + 1;
+
+                /* Do TLBs need flushing for safety before next page use? */
+                bool need_tlbflush:1;
+
+#define BUDDY_NOT_SCRUBBING    0
+#define BUDDY_SCRUBBING        1
+#define BUDDY_SCRUB_ABORT      2
+                unsigned long scrub_state:2;
+            };
+
+                unsigned long val;
+            } free;
+
+    } u;
+
+    union {
+        /* Page is in use, but not as a shadow. */
+        struct {
+            /* Owner of this page (zero if page is anonymous). */
+            struct domain *domain;
+        } inuse;
+
+        /* Page is on a free list. */
+        struct {
+            /* Order-size of the free chunk this page is the head of. */
+            unsigned int order;
+        } free;
+
+    } v;
+
+    union {
+        /*
+         * Timestamp from 'TLB clock', used to avoid extra safety flushes.
+         * Only valid for: a) free pages, and b) pages with zero type count
+         */
+        uint32_t tlbflush_timestamp;
+    };
+    uint64_t pad;
+};
+
+#define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
+
+/* PDX of the first page in the frame table. */
+extern unsigned long frametable_base_pdx;
+
+/* Convert between machine frame numbers and page-info structures. */
+#define mfn_to_page(mfn)                                            \
+    (frame_table + (mfn_to_pdx(mfn) - frametable_base_pdx))
+#define page_to_mfn(pg)                                             \
+    pdx_to_mfn((unsigned long)((pg) - frame_table) + frametable_base_pdx)
+
+static inline void *page_to_virt(const struct page_info *pg)
+{
+    return mfn_to_virt(mfn_x(page_to_mfn(pg)));
+}
+
+/*
+ * Common code requires get_page_type and put_page_type.
+ * We don't care about typecounts so we just do the minimum to make it
+ * happy.
+ */
+static inline int get_page_type(struct page_info *page, unsigned long type)
+{
+    return 1;
+}
+
+static inline void put_page_type(struct page_info *page)
+{
+}
+
+static inline void put_page_and_type(struct page_info *page)
+{
+    put_page_type(page);
+    put_page(page);
+}
+
+/*
+ * RISC-V does not have an M2P, but common code expects a handful of
+ * M2P-related defines and functions. Provide dummy versions of these.
+ */
+#define INVALID_M2P_ENTRY        (~0UL)
+#define SHARED_M2P_ENTRY         (~0UL - 1UL)
+#define SHARED_M2P(_e)           ((_e) == SHARED_M2P_ENTRY)
+
+/* Xen always owns P2M on RISC-V */
+#define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn), (void)(pfn); } while (0)
+#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
+
+#define PDX_GROUP_SHIFT (16 + 5)
+
+static inline unsigned long domain_get_maximum_gpfn(struct domain *d)
+{
+    BUG();
+    return 0;
+}
+
+static inline long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+    BUG();
+    return 0;
+}
+
+/*
+ * On RISCV, all the RAM is currently direct mapped in Xen.
+ * Hence return always true.
+ */
+static inline bool arch_mfns_in_directmap(unsigned long mfn, unsigned long nr)
+{
+    return true;
+}
+
+#define PG_shift(idx)   (BITS_PER_LONG - (idx))
+#define PG_mask(x, idx) (x ## UL << PG_shift(idx))
+
+#define PGT_none          PG_mask(0, 1)  /* no special uses of this page   */
+#define PGT_writable_page PG_mask(1, 1)  /* has writable mappings?         */
+#define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or 63.                 */
+
+ /* Count of uses of this frame as its current type. */
+#define PGT_count_width   PG_shift(2)
+#define PGT_count_mask    ((1UL<<PGT_count_width)-1)
+
+/*
+ * Page needs to be scrubbed. Since this bit can only be set on a page that is
+ * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
+ */
+#define _PGC_need_scrub   _PGC_allocated
+#define PGC_need_scrub    PGC_allocated
+
+//  /* Cleared when the owning guest 'frees' this page. */
+#define _PGC_allocated    PG_shift(1)
+#define PGC_allocated     PG_mask(1, 1)
+  /* Page is Xen heap? */
+#define _PGC_xen_heap     PG_shift(2)
+#define PGC_xen_heap      PG_mask(1, 2)
+/* Page is broken? */
+#define _PGC_broken       PG_shift(7)
+#define PGC_broken        PG_mask(1, 7)
+ /* Mutually-exclusive page states: { inuse, offlining, offlined, free }. */
+#define PGC_state         PG_mask(3, 9)
+#define PGC_state_inuse   PG_mask(0, 9)
+#define PGC_state_offlining PG_mask(1, 9)
+#define PGC_state_offlined PG_mask(2, 9)
+#define PGC_state_free    PG_mask(3, 9)
+// #define page_state_is(pg, st) (((pg)->count_info&PGC_state) == PGC_state_##st)
+
+/* Count of references to this frame. */
+#define PGC_count_width   PG_shift(9)
+#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
+
+#define page_state_is(pg, st) (((pg)->count_info&PGC_state) == PGC_state_##st)
+
+#define _PGC_extra        PG_shift(10)
+#define PGC_extra         PG_mask(1, 10)
+
+#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
+#define is_xen_heap_mfn(mfn) \
+    (mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
+
+#define is_xen_fixed_mfn(mfn)                                   \
+    ((mfn_to_maddr(mfn) >= virt_to_maddr(&_start)) &&           \
+     (mfn_to_maddr(mfn) <= virt_to_maddr((vaddr_t)_end - 1)))
+
+#define page_get_owner(_p)    (_p)->v.inuse.domain
+#define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d))
+
+/* TODO: implement */
+#define mfn_valid(mfn) ({ (void) (mfn); 0; })
+
+#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
+
+#define domain_set_alloc_bitsize(d) ((void)0)
+#define domain_clamp_alloc_bitsize(d, b) (b)
+
+#define PFN_ORDER(_pfn) ((_pfn)->v.free.order)
+
 extern unsigned char cpu0_boot_stack[];
 
 void setup_initial_pagetables(void);
@@ -17,4 +260,9 @@ unsigned long calc_phys_offset(void);
 
 void turn_on_mmu(unsigned long ra);
 
+static inline unsigned int arch_get_dma_bitsize(void)
+{
+    return 32; /* TODO */
+}
+
 #endif /* _ASM_RISCV_MM_H */
-- 
2.43.0



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

* [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs to build full Xen
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (30 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h " Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 13:20   ` Jan Beulich
  2023-12-22 15:13 ` [PATCH v3 33/34] xen/riscv: enable full Xen build Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64 Oleksii Kurochko
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V3:
 - code style fixes.
 - update attribute for frametable_base_pdx  and frametable_virt_end to __ro_after_init.
   insteaf of read_mostly.
 - use BUG() instead of assert_failed/WARN for newly introduced stubs.
 - drop "#include <public/vm_event.h>" in stubs.c and use forward declaration instead.
 - drop ack_node() and end_node() as they aren't used now.
---
Changes in V2:
 - define udelay stub
 - remove 'select HAS_PDX' from RISC-V Kconfig because of
   https://lore.kernel.org/xen-devel/20231006144405.1078260-1-andrew.cooper3@citrix.com/
---
 xen/arch/riscv/Makefile       |   1 +
 xen/arch/riscv/early_printk.c | 168 --------------
 xen/arch/riscv/mm.c           |  52 ++++-
 xen/arch/riscv/setup.c        |   9 +-
 xen/arch/riscv/stubs.c        | 422 ++++++++++++++++++++++++++++++++++
 xen/arch/riscv/traps.c        |  25 ++
 6 files changed, 507 insertions(+), 170 deletions(-)
 create mode 100644 xen/arch/riscv/stubs.c

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 2fefe14e7c..5523191bb7 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -4,6 +4,7 @@ obj-y += mm.o
 obj-$(CONFIG_RISCV_64) += riscv64/
 obj-y += sbi.o
 obj-y += setup.o
+obj-y += stubs.o
 obj-y += traps.o
 
 $(TARGET): $(TARGET)-syms
diff --git a/xen/arch/riscv/early_printk.c b/xen/arch/riscv/early_printk.c
index 60742a042d..610c814f54 100644
--- a/xen/arch/riscv/early_printk.c
+++ b/xen/arch/riscv/early_printk.c
@@ -40,171 +40,3 @@ void early_printk(const char *str)
         str++;
     }
 }
-
-/*
- * The following #if 1 ... #endif should be removed after printk
- * and related stuff are ready.
- */
-#if 1
-
-#include <xen/stdarg.h>
-#include <xen/string.h>
-
-/**
- * strlen - Find the length of a string
- * @s: The string to be sized
- */
-size_t (strlen)(const char * s)
-{
-    const char *sc;
-
-    for (sc = s; *sc != '\0'; ++sc)
-        /* nothing */;
-    return sc - s;
-}
-
-/**
- * memcpy - Copy one area of memory to another
- * @dest: Where to copy to
- * @src: Where to copy from
- * @count: The size of the area.
- *
- * You should not use this function to access IO space, use memcpy_toio()
- * or memcpy_fromio() instead.
- */
-void *(memcpy)(void *dest, const void *src, size_t count)
-{
-    char *tmp = (char *) dest, *s = (char *) src;
-
-    while (count--)
-        *tmp++ = *s++;
-
-    return dest;
-}
-
-int vsnprintf(char* str, size_t size, const char* format, va_list args)
-{
-    size_t i = 0; /* Current position in the output string */
-    size_t written = 0; /* Total number of characters written */
-    char* dest = str;
-
-    while ( format[i] != '\0' && written < size - 1 )
-    {
-        if ( format[i] == '%' )
-        {
-            i++;
-
-            if ( format[i] == '\0' )
-                break;
-
-            if ( format[i] == '%' )
-            {
-                if ( written < size - 1 )
-                {
-                    dest[written] = '%';
-                    written++;
-                }
-                i++;
-                continue;
-            }
-
-            /*
-             * Handle format specifiers.
-             * For simplicity, only %s and %d are implemented here.
-             */
-
-            if ( format[i] == 's' )
-            {
-                char* arg = va_arg(args, char*);
-                size_t arglen = strlen(arg);
-
-                size_t remaining = size - written - 1;
-
-                if ( arglen > remaining )
-                    arglen = remaining;
-
-                memcpy(dest + written, arg, arglen);
-
-                written += arglen;
-                i++;
-            }
-            else if ( format[i] == 'd' )
-            {
-                int arg = va_arg(args, int);
-
-                /* Convert the integer to string representation */
-                char numstr[32]; /* Assumes a maximum of 32 digits */
-                int numlen = 0;
-                int num = arg;
-                size_t remaining;
-
-                if ( arg < 0 )
-                {
-                    if ( written < size - 1 )
-                    {
-                        dest[written] = '-';
-                        written++;
-                    }
-
-                    num = -arg;
-                }
-
-                do
-                {
-                    numstr[numlen] = '0' + num % 10;
-                    num = num / 10;
-                    numlen++;
-                } while ( num > 0 );
-
-                /* Reverse the string */
-                for (int j = 0; j < numlen / 2; j++)
-                {
-                    char tmp = numstr[j];
-                    numstr[j] = numstr[numlen - 1 - j];
-                    numstr[numlen - 1 - j] = tmp;
-                }
-
-                remaining = size - written - 1;
-
-                if ( numlen > remaining )
-                    numlen = remaining;
-
-                memcpy(dest + written, numstr, numlen);
-
-                written += numlen;
-                i++;
-            }
-        }
-        else
-        {
-            if ( written < size - 1 )
-            {
-                dest[written] = format[i];
-                written++;
-            }
-            i++;
-        }
-    }
-
-    if ( size > 0 )
-        dest[written] = '\0';
-
-    return written;
-}
-
-void printk(const char *format, ...)
-{
-    static char buf[1024];
-
-    va_list args;
-    va_start(args, format);
-
-    (void)vsnprintf(buf, sizeof(buf), format, args);
-
-    early_printk(buf);
-
-    va_end(args);
-}
-
-#endif
-
diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c
index 053f043a3d..6cf6f45f7f 100644
--- a/xen/arch/riscv/mm.c
+++ b/xen/arch/riscv/mm.c
@@ -1,19 +1,23 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
+#include <xen/bug.h>
 #include <xen/cache.h>
 #include <xen/compiler.h>
 #include <xen/init.h>
 #include <xen/kernel.h>
 #include <xen/macros.h>
+#include <xen/mm.h>
 #include <xen/pfn.h>
 
 #include <asm/early_printk.h>
 #include <asm/csr.h>
 #include <asm/current.h>
-#include <asm/mm.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 
+unsigned long __ro_after_init frametable_base_pdx;
+unsigned long __ro_after_init frametable_virt_end;
+
 struct mmu_desc {
     unsigned int num_levels;
     unsigned int pgtbl_count;
@@ -294,3 +298,49 @@ unsigned long __init calc_phys_offset(void)
     phys_offset = load_start - XEN_VIRT_START;
     return phys_offset;
 }
+
+void put_page(struct page_info *page)
+{
+    BUG();
+}
+
+unsigned long get_upper_mfn_bound(void)
+{
+    /* No memory hotplug yet, so current memory limit is the final one. */
+    return max_page - 1;
+}
+
+void arch_dump_shared_mem_info(void)
+{
+    BUG();
+}
+
+int populate_pt_range(unsigned long virt, unsigned long nr_mfns)
+{
+    BUG();
+    return -1;
+}
+
+int xenmem_add_to_physmap_one(struct domain *d, unsigned int space,
+                              union add_to_physmap_extra extra,
+                              unsigned long idx, gfn_t gfn)
+{
+    BUG();
+
+    return 0;
+}
+
+int destroy_xen_mappings(unsigned long s, unsigned long e)
+{
+    BUG();
+    return -1;
+}
+
+int map_pages_to_xen(unsigned long virt,
+                     mfn_t mfn,
+                     unsigned long nr_mfns,
+                     unsigned int flags)
+{
+    BUG();
+    return -1;
+}
diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index 6593f601c1..8944e0ecfe 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -2,9 +2,16 @@
 
 #include <xen/compile.h>
 #include <xen/init.h>
+#include <xen/mm.h>
+
+#include <public/version.h>
 
 #include <asm/early_printk.h>
-#include <asm/mm.h>
+
+void arch_get_xen_caps(xen_capabilities_info_t *info)
+{
+    assert_failed("need to be implemented");
+}
 
 /* Xen stack for bringing up the first CPU. */
 unsigned char __initdata cpu0_boot_stack[STACK_SIZE]
diff --git a/xen/arch/riscv/stubs.c b/xen/arch/riscv/stubs.c
new file mode 100644
index 0000000000..c69d5b5482
--- /dev/null
+++ b/xen/arch/riscv/stubs.c
@@ -0,0 +1,422 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <xen/cpumask.h>
+#include <xen/domain.h>
+#include <xen/irq.h>
+#include <xen/nodemask.h>
+#include <xen/time.h>
+#include <public/domctl.h>
+
+#include <asm/current.h>
+
+/* smpboot.c */
+
+cpumask_t cpu_online_map;
+cpumask_t cpu_present_map;
+cpumask_t cpu_possible_map;
+
+/* ID of the PCPU we're running on */
+DEFINE_PER_CPU(unsigned int, cpu_id);
+/* XXX these seem awfully x86ish... */
+/* representing HT siblings of each logical CPU */
+DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask);
+/* representing HT and core siblings of each logical CPU */
+DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask);
+
+nodemask_t __read_mostly node_online_map = { { [0] = 1UL } };
+
+/* time.c */
+
+unsigned long __read_mostly cpu_khz;  /* CPU clock frequency in kHz. */
+
+s_time_t get_s_time(void)
+{
+    BUG();
+}
+
+int reprogram_timer(s_time_t timeout)
+{
+    BUG();
+}
+
+void send_timer_event(struct vcpu *v)
+{
+    BUG();
+}
+
+void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds)
+{
+    BUG();
+}
+
+/* shutdown.c */
+
+void machine_restart(unsigned int delay_millisecs)
+{
+    BUG();
+}
+
+void machine_halt(void)
+{
+    BUG();
+}
+
+/* vm_event.c */
+
+struct vm_event_st;
+
+void vm_event_fill_regs(struct vm_event_st *req)
+{
+    BUG();
+}
+
+void vm_event_set_registers(struct vcpu *v, struct vm_event_st *rsp)
+{
+    BUG();
+}
+
+void vm_event_monitor_next_interrupt(struct vcpu *v)
+{
+    /* Not supported on RISCV. */
+}
+
+void vm_event_reset_vmtrace(struct vcpu *v)
+{
+    /* Not supported on RISCV. */
+}
+
+/* domctl.c */
+
+long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
+                    XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
+{
+    BUG();
+}
+
+void arch_get_domain_info(const struct domain *d,
+                          struct xen_domctl_getdomaininfo *info)
+{
+    BUG();
+}
+
+void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
+{
+    BUG();
+}
+
+/* monitor.c */
+
+int arch_monitor_domctl_event(struct domain *d,
+                              struct xen_domctl_monitor_op *mop)
+{
+    BUG();
+}
+
+/* smp.c */
+
+void arch_flush_tlb_mask(const cpumask_t *mask)
+{
+    BUG();
+}
+
+void smp_send_event_check_mask(const cpumask_t *mask)
+{
+    BUG();
+}
+
+void smp_send_call_function_mask(const cpumask_t *mask)
+{
+    BUG();
+}
+
+/* irq.c */
+
+struct pirq *alloc_pirq_struct(struct domain *d)
+{
+    BUG();
+}
+
+int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share)
+{
+    BUG();
+}
+
+void pirq_guest_unbind(struct domain *d, struct pirq *pirq)
+{
+    BUG();
+}
+
+void pirq_set_affinity(struct domain *d, int pirq, const cpumask_t *mask)
+{
+    BUG();
+}
+
+hw_irq_controller no_irq_type = {
+    .typename = "none",
+    .startup = irq_startup_none,
+    .shutdown = irq_shutdown_none,
+    .enable = irq_enable_none,
+    .disable = irq_disable_none,
+};
+
+int arch_init_one_irq_desc(struct irq_desc *desc)
+{
+    BUG();
+}
+
+void smp_send_state_dump(unsigned int cpu)
+{
+    BUG();
+}
+
+/* domain.c */
+
+DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
+unsigned long __per_cpu_offset[NR_CPUS];
+
+void context_switch(struct vcpu *prev, struct vcpu *next)
+{
+    BUG();
+}
+
+void continue_running(struct vcpu *same)
+{
+    BUG();
+}
+
+void sync_local_execstate(void)
+{
+    BUG();
+}
+
+void sync_vcpu_execstate(struct vcpu *v)
+{
+    BUG();
+}
+
+void startup_cpu_idle_loop(void)
+{
+    BUG();
+}
+
+void free_domain_struct(struct domain *d)
+{
+    BUG();
+}
+
+void dump_pageframe_info(struct domain *d)
+{
+    BUG();
+}
+
+void free_vcpu_struct(struct vcpu *v)
+{
+    BUG();
+}
+
+int arch_vcpu_create(struct vcpu *v)
+{
+    BUG();
+}
+
+void arch_vcpu_destroy(struct vcpu *v)
+{
+    BUG();
+}
+
+void vcpu_switch_to_aarch64_mode(struct vcpu *v)
+{
+    BUG();
+}
+
+int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
+{
+    BUG();
+}
+
+int arch_domain_create(struct domain *d,
+                       struct xen_domctl_createdomain *config,
+                       unsigned int flags)
+{
+    BUG();
+}
+
+int arch_domain_teardown(struct domain *d)
+{
+    BUG();
+}
+
+void arch_domain_destroy(struct domain *d)
+{
+    BUG();
+}
+
+void arch_domain_shutdown(struct domain *d)
+{
+    BUG();
+}
+
+void arch_domain_pause(struct domain *d)
+{
+    BUG();
+}
+
+void arch_domain_unpause(struct domain *d)
+{
+    BUG();
+}
+
+int arch_domain_soft_reset(struct domain *d)
+{
+    BUG();
+}
+
+void arch_domain_creation_finished(struct domain *d)
+{
+    BUG();
+}
+
+int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
+{
+    BUG();
+}
+
+int arch_initialise_vcpu(struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+    BUG();
+}
+
+int arch_vcpu_reset(struct vcpu *v)
+{
+    BUG();
+}
+
+int domain_relinquish_resources(struct domain *d)
+{
+    BUG();
+}
+
+void arch_dump_domain_info(struct domain *d)
+{
+    BUG();
+}
+
+void arch_dump_vcpu_info(struct vcpu *v)
+{
+    BUG();
+}
+
+void vcpu_mark_events_pending(struct vcpu *v)
+{
+    BUG();
+}
+
+void vcpu_update_evtchn_irq(struct vcpu *v)
+{
+    BUG();
+}
+
+void vcpu_block_unless_event_pending(struct vcpu *v)
+{
+    BUG();
+}
+
+void vcpu_kick(struct vcpu *v)
+{
+    BUG();
+}
+
+struct domain *alloc_domain_struct(void)
+{
+    BUG();
+}
+
+struct vcpu *alloc_vcpu_struct(const struct domain *d)
+{
+    BUG();
+}
+
+unsigned long
+hypercall_create_continuation(unsigned int op, const char *format, ...)
+{
+    BUG();
+}
+
+int __init parse_arch_dom0_param(const char *s, const char *e)
+{
+    BUG();
+}
+
+/* guestcopy.c */
+
+unsigned long raw_copy_to_guest(void *to, const void *from, unsigned int len)
+{
+    BUG();
+}
+
+unsigned long raw_copy_from_guest(void *to, const void __user *from,
+                                  unsigned int len)
+{
+    BUG();
+}
+
+/* sysctl.c */
+
+long arch_do_sysctl(struct xen_sysctl *sysctl,
+                    XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
+{
+    BUG();
+}
+
+void arch_do_physinfo(struct xen_sysctl_physinfo *pi)
+{
+    BUG();
+}
+
+/* p2m.c */
+
+int arch_set_paging_mempool_size(struct domain *d, uint64_t size)
+{
+    BUG();
+}
+
+int unmap_mmio_regions(struct domain *d,
+                       gfn_t start_gfn,
+                       unsigned long nr,
+                       mfn_t mfn)
+{
+    BUG();
+}
+
+int map_mmio_regions(struct domain *d,
+                     gfn_t start_gfn,
+                     unsigned long nr,
+                     mfn_t mfn)
+{
+    BUG();
+}
+
+int set_foreign_p2m_entry(struct domain *d, const struct domain *fd,
+                          unsigned long gfn, mfn_t mfn)
+{
+    BUG();
+}
+
+/* Return the size of the pool, in bytes. */
+int arch_get_paging_mempool_size(struct domain *d, uint64_t *size)
+{
+    BUG();
+}
+
+/* delay.c */
+
+void udelay(unsigned long usecs)
+{
+    BUG_ON("unimplemented");
+}
+
+/* guest_access.h */ 
+
+static inline unsigned long raw_clear_guest(void *to, unsigned int len)
+{
+    BUG_ON("unimplemented");
+}
diff --git a/xen/arch/riscv/traps.c b/xen/arch/riscv/traps.c
index ccd3593f5a..ca56df75d8 100644
--- a/xen/arch/riscv/traps.c
+++ b/xen/arch/riscv/traps.c
@@ -4,6 +4,10 @@
  *
  * RISC-V Trap handlers
  */
+
+#include <xen/lib.h>
+#include <xen/sched.h>
+
 #include <asm/processor.h>
 #include <asm/traps.h>
 
@@ -11,3 +15,24 @@ void do_trap(struct cpu_user_regs *cpu_regs)
 {
     die();
 }
+
+void vcpu_show_execution_state(struct vcpu *v)
+{
+    assert_failed("need to be implented");
+}
+
+void show_execution_state(const struct cpu_user_regs *regs)
+{
+    printk("implement show_execution_state(regs)\n");
+}
+
+void arch_hypercall_tasklet_result(struct vcpu *v, long res)
+{
+    assert_failed("need to be implented");
+}
+
+enum mc_disposition arch_do_multicall_call(struct mc_state *state)
+{
+    assert_failed("need to be implented");
+    return mc_continue;
+}
-- 
2.43.0



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

* [PATCH v3 33/34] xen/riscv: enable full Xen build
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (31 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs " Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2023-12-22 15:13 ` [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64 Oleksii Kurochko
  33 siblings, 0 replies; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Alistair Francis, Bob Eshleman, Connor Davis,
	Andrew Cooper, George Dunlap, Jan Beulich, Julien Grall,
	Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
Changes in V3:
 - Reviewed-by: Jan Beulich <jbeulich@suse.com>
 - unrealted change dropped in tiny64_defconfig
---
Changes in V2:
 - Nothing changed. Only rebase.
---
 xen/arch/riscv/Makefile | 16 +++++++++++++++-
 xen/arch/riscv/arch.mk  |  4 ----
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile
index 5523191bb7..c10d43c7e5 100644
--- a/xen/arch/riscv/Makefile
+++ b/xen/arch/riscv/Makefile
@@ -11,10 +11,24 @@ $(TARGET): $(TARGET)-syms
 	$(OBJCOPY) -O binary -S $< $@
 
 $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds
-	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< $(build_id_linker) -o $@
+	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< \
+	    $(objtree)/common/symbols-dummy.o -o $(dot-target).0
+	$(NM) -pa --format=sysv $(dot-target).0 \
+		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
+		> $(dot-target).0.S
+	$(MAKE) $(build)=$(@D) $(dot-target).0.o
+	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< \
+	    $(dot-target).0.o -o $(dot-target).1
+	$(NM) -pa --format=sysv $(dot-target).1 \
+		| $(objtree)/tools/symbols $(all_symbols) --sysv --sort \
+		> $(dot-target).1.S
+	$(MAKE) $(build)=$(@D) $(dot-target).1.o
+	$(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds -N $< $(build_id_linker) \
+	    $(dot-target).1.o -o $@
 	$(NM) -pa --format=sysv $@ \
 		| $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \
 		> $@.map
+	rm -f $(@D)/.$(@F).[0-9]*
 
 $(obj)/xen.lds: $(src)/xen.lds.S FORCE
 	$(call if_changed_dep,cpp_lds_S)
diff --git a/xen/arch/riscv/arch.mk b/xen/arch/riscv/arch.mk
index 8403f96b6f..12b1673fae 100644
--- a/xen/arch/riscv/arch.mk
+++ b/xen/arch/riscv/arch.mk
@@ -13,7 +13,3 @@ riscv-march-$(CONFIG_RISCV_ISA_C)       := $(riscv-march-y)c
 # -mcmodel=medlow would force Xen into the lower half.
 
 CFLAGS += -march=$(riscv-march-y) -mstrict-align -mcmodel=medany
-
-# TODO: Drop override when more of the build is working
-override ALL_OBJS-y = arch/$(SRCARCH)/built_in.o
-override ALL_LIBS-y =
-- 
2.43.0



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

* [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64
  2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
                   ` (32 preceding siblings ...)
  2023-12-22 15:13 ` [PATCH v3 33/34] xen/riscv: enable full Xen build Oleksii Kurochko
@ 2023-12-22 15:13 ` Oleksii Kurochko
  2024-01-23 11:22   ` Jan Beulich
  33 siblings, 1 reply; 146+ messages in thread
From: Oleksii Kurochko @ 2023-12-22 15:13 UTC (permalink / raw
  To: xen-devel
  Cc: Oleksii Kurochko, Andrew Cooper, George Dunlap, Jan Beulich,
	Julien Grall, Stefano Stabellini, Wei Liu

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
 Changes in V3:
  - new patch
---
 README | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README b/README
index c8a108449e..1015a285c0 100644
--- a/README
+++ b/README
@@ -48,6 +48,9 @@ provided by your OS distributor:
       - For ARM 64-bit:
         - GCC 5.1 or later
         - GNU Binutils 2.24 or later
+      - For RISC-V 64-bit:
+        - GCC 13.2.1 or later
+        - GNU Binutils 2.40 or later
     * POSIX compatible awk
     * Development install of zlib (e.g., zlib-dev)
     * Development install of Python 2.7 or later (e.g., python-dev)
-- 
2.43.0



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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2023-12-22 15:13 ` [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h " Oleksii Kurochko
@ 2023-12-22 16:32   ` Oleksii
  2023-12-22 18:16     ` Oleksii
  2024-01-11 16:43     ` Jan Beulich
  2024-01-23 13:03   ` Jan Beulich
  1 sibling, 2 replies; 146+ messages in thread
From: Oleksii @ 2023-12-22 16:32 UTC (permalink / raw
  To: xen-devel
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini,
	Wei Liu

On Fri, 2023-12-22 at 17:13 +0200, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - update the commit message
>  - introduce DIRECTMAP_VIRT_START.
>  - drop changes related pfn_to_paddr() and paddr_to_pfn as they were
> remvoe in
>    [PATCH v2 32/39] xen/riscv: add minimal stuff to asm/page.h to
> build full Xen
>  - code style fixes.
>  - drop get_page_nr  and put_page_nr as they don't need for time
> being
>  - drop CONFIG_STATIC_MEMORY related things
>  - code style fixes
> ---
> Changes in V2:
>  - define stub for arch_get_dma_bitsize(void)
> ---
>  xen/arch/riscv/include/asm/config.h |   2 +
>  xen/arch/riscv/include/asm/mm.h     | 248
> ++++++++++++++++++++++++++++
>  2 files changed, 250 insertions(+)
> 
> diff --git a/xen/arch/riscv/include/asm/config.h
> b/xen/arch/riscv/include/asm/config.h
> index fb9fc9daaa..400309f4ef 100644
> --- a/xen/arch/riscv/include/asm/config.h
> +++ b/xen/arch/riscv/include/asm/config.h
> @@ -67,6 +67,8 @@
>  
>  #define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 -
> GB(1)) */
>  
> +#define DIRECTMAP_VIRT_START    SLOTN(200)
> +
>  #define FRAMETABLE_VIRT_START   SLOTN(196)
>  #define FRAMETABLE_SIZE         GB(3)
>  #define FRAMETABLE_NR           (FRAMETABLE_SIZE /
> sizeof(*frame_table))
> diff --git a/xen/arch/riscv/include/asm/mm.h
> b/xen/arch/riscv/include/asm/mm.h
> index 57026e134d..14fce72fde 100644
> --- a/xen/arch/riscv/include/asm/mm.h
> +++ b/xen/arch/riscv/include/asm/mm.h
> @@ -3,8 +3,251 @@
>  #ifndef _ASM_RISCV_MM_H
>  #define _ASM_RISCV_MM_H
>  
> +#include <public/xen.h>
> +#include <xen/pdx.h>
> +#include <xen/types.h>
> +
> +#include <asm/page.h>
>  #include <asm/page-bits.h>
>  
> +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> +#define vmap_to_mfn(va)     maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
> +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> +#define vmap_to_mfn(va)     maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
> +
> +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK))
> +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) |
> DIRECTMAP_VIRT_START))
> +
> +/* Convert between Xen-heap virtual addresses and machine frame
> numbers. */
> +#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
> +#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) <<
> PAGE_SHIFT)
> +
> +/* Convert between Xen-heap virtual addresses and page-info
> structures. */
> +static inline struct page_info *virt_to_page(const void *v)
> +{
> +    BUG();
> +    return NULL;
> +}
> +
> +/*
> + * We define non-underscored wrappers for above conversion
> functions.
> + * These are overriden in various source files while underscored
> version
> + * remain intact.
> + */
> +#define virt_to_mfn(va)     __virt_to_mfn(va)
> +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
> +
> +struct page_info
> +{
> +    /* Each frame can be threaded onto a doubly-linked list. */
> +    struct page_list_entry list;
> +
> +    /* Reference count and various PGC_xxx flags and fields. */
> +    unsigned long count_info;
> +
> +    /* Context-dependent fields follow... */
> +    union {
> +        /* Page is in use: ((count_info & PGC_count_mask) != 0). */
> +        struct {
> +            /* Type reference count and various PGT_xxx flags and
> fields. */
> +            unsigned long type_info;
> +        } inuse;
> +        /* Page is on a free list: ((count_info & PGC_count_mask) ==
> 0). */
> +        union {
> +            struct {
> +                /*
> +                 * Index of the first *possibly* unscrubbed page in
> the buddy.
> +                 * One more bit than maximum possible order to
> accommodate
> +                 * INVALID_DIRTY_IDX.
> +                 */
> +#define INVALID_DIRTY_IDX ((1UL << (MAX_ORDER + 1)) - 1)
> +                unsigned long first_dirty:MAX_ORDER + 1;
> +
> +                /* Do TLBs need flushing for safety before next page
> use? */
> +                bool need_tlbflush:1;
> +
> +#define BUDDY_NOT_SCRUBBING    0
> +#define BUDDY_SCRUBBING        1
> +#define BUDDY_SCRUB_ABORT      2
> +                unsigned long scrub_state:2;
> +            };
> +
> +                unsigned long val;
> +            } free;
> +
> +    } u;
> +
> +    union {
> +        /* Page is in use, but not as a shadow. */
> +        struct {
> +            /* Owner of this page (zero if page is anonymous). */
> +            struct domain *domain;
> +        } inuse;
> +
> +        /* Page is on a free list. */
> +        struct {
> +            /* Order-size of the free chunk this page is the head
> of. */
> +            unsigned int order;
> +        } free;
> +
> +    } v;
> +
> +    union {
> +        /*
> +         * Timestamp from 'TLB clock', used to avoid extra safety
> flushes.
> +         * Only valid for: a) free pages, and b) pages with zero
> type count
> +         */
> +        uint32_t tlbflush_timestamp;
> +    };
> +    uint64_t pad;
> +};
> +
> +#define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
> +
> +/* PDX of the first page in the frame table. */
> +extern unsigned long frametable_base_pdx;
> +
> +/* Convert between machine frame numbers and page-info structures.
> */
> +#define mfn_to_page(mfn)                                           
> \
> +    (frame_table + (mfn_to_pdx(mfn) - frametable_base_pdx))
> +#define page_to_mfn(pg)                                            
> \
> +    pdx_to_mfn((unsigned long)((pg) - frame_table) +
> frametable_base_pdx)
> +
> +static inline void *page_to_virt(const struct page_info *pg)
> +{
> +    return mfn_to_virt(mfn_x(page_to_mfn(pg)));
> +}
> +
> +/*
> + * Common code requires get_page_type and put_page_type.
> + * We don't care about typecounts so we just do the minimum to make
> it
> + * happy.
> + */
> +static inline int get_page_type(struct page_info *page, unsigned
> long type)
> +{
> +    return 1;
> +}
> +
> +static inline void put_page_type(struct page_info *page)
> +{
> +}
> +
> +static inline void put_page_and_type(struct page_info *page)
> +{
> +    put_page_type(page);
> +    put_page(page);
> +}
> +
> +/*
> + * RISC-V does not have an M2P, but common code expects a handful of
> + * M2P-related defines and functions. Provide dummy versions of
> these.
> + */
> +#define INVALID_M2P_ENTRY        (~0UL)
> +#define SHARED_M2P_ENTRY         (~0UL - 1UL)
> +#define SHARED_M2P(_e)           ((_e) == SHARED_M2P_ENTRY)
> +
> +/* Xen always owns P2M on RISC-V */
> +#define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn), (void)(pfn);
> } while (0)
> +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
> +
> +#define PDX_GROUP_SHIFT (16 + 5)
> +
> +static inline unsigned long domain_get_maximum_gpfn(struct domain
> *d)
> +{
> +    BUG();
> +    return 0;
> +}
> +
> +static inline long arch_memory_op(int op,
> XEN_GUEST_HANDLE_PARAM(void) arg)
> +{
> +    BUG();
> +    return 0;
> +}
> +
> +/*
> + * On RISCV, all the RAM is currently direct mapped in Xen.
> + * Hence return always true.
> + */
> +static inline bool arch_mfns_in_directmap(unsigned long mfn,
> unsigned long nr)
> +{
> +    return true;
> +}
> +
> +#define PG_shift(idx)   (BITS_PER_LONG - (idx))
> +#define PG_mask(x, idx) (x ## UL << PG_shift(idx))
> +
> +#define PGT_none          PG_mask(0, 1)  /* no special uses of this
> page   */
> +#define PGT_writable_page PG_mask(1, 1)  /* has writable
> mappings?         */
> +#define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or
> 63.                 */
> +
> + /* Count of uses of this frame as its current type. */
> +#define PGT_count_width   PG_shift(2)
> +#define PGT_count_mask    ((1UL<<PGT_count_width)-1)
> +
> +/*
> + * Page needs to be scrubbed. Since this bit can only be set on a
> page that is
> + * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
> + */
> +#define _PGC_need_scrub   _PGC_allocated
> +#define PGC_need_scrub    PGC_allocated
> +
> +//  /* Cleared when the owning guest 'frees' this page. */
> +#define _PGC_allocated    PG_shift(1)
> +#define PGC_allocated     PG_mask(1, 1)
> +  /* Page is Xen heap? */
> +#define _PGC_xen_heap     PG_shift(2)
> +#define PGC_xen_heap      PG_mask(1, 2)
> +/* Page is broken? */
> +#define _PGC_broken       PG_shift(7)
> +#define PGC_broken        PG_mask(1, 7)
> + /* Mutually-exclusive page states: { inuse, offlining, offlined,
> free }. */
> +#define PGC_state         PG_mask(3, 9)
> +#define PGC_state_inuse   PG_mask(0, 9)
> +#define PGC_state_offlining PG_mask(1, 9)
> +#define PGC_state_offlined PG_mask(2, 9)
> +#define PGC_state_free    PG_mask(3, 9)
> +// #define page_state_is(pg, st) (((pg)->count_info&PGC_state) ==
> PGC_state_##st)
> +
> +/* Count of references to this frame. */
> +#define PGC_count_width   PG_shift(9)
> +#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
> +
> +#define page_state_is(pg, st) (((pg)->count_info&PGC_state) ==
> PGC_state_##st)
> +
> +#define _PGC_extra        PG_shift(10)
> +#define PGC_extra         PG_mask(1, 10)
> +
> +#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
> +#define is_xen_heap_mfn(mfn) \
> +    (mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
> +
> +#define is_xen_fixed_mfn(mfn)                                   \
> +    ((mfn_to_maddr(mfn) >= virt_to_maddr(&_start)) &&           \
> +     (mfn_to_maddr(mfn) <= virt_to_maddr((vaddr_t)_end - 1)))
> +
> +#define page_get_owner(_p)    (_p)->v.inuse.domain
> +#define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d))
> +
> +/* TODO: implement */
> +#define mfn_valid(mfn) ({ (void) (mfn); 0; })
> +
> +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
> +
> +#define domain_set_alloc_bitsize(d) ((void)0)
> +#define domain_clamp_alloc_bitsize(d, b) (b)
> +
> +#define PFN_ORDER(_pfn) ((_pfn)->v.free.order)
I missed saving these changes. It should be _pfn -> pfn_. (Just a
reminder for me).

Sorry for the inconvenience.

> +
>  extern unsigned char cpu0_boot_stack[];
>  
>  void setup_initial_pagetables(void);
> @@ -17,4 +260,9 @@ unsigned long calc_phys_offset(void);
>  
>  void turn_on_mmu(unsigned long ra);
>  
> +static inline unsigned int arch_get_dma_bitsize(void)
> +{
> +    return 32; /* TODO */
> +}
> +
>  #endif /* _ASM_RISCV_MM_H */



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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2023-12-22 16:32   ` Oleksii
@ 2023-12-22 18:16     ` Oleksii
  2024-01-11 16:43     ` Jan Beulich
  1 sibling, 0 replies; 146+ messages in thread
From: Oleksii @ 2023-12-22 18:16 UTC (permalink / raw
  To: xen-devel
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Jan Beulich, Julien Grall, Stefano Stabellini,
	Wei Liu

On Fri, 2023-12-22 at 18:32 +0200, Oleksii wrote:
> > +
> > +struct page_info
> > +{
> > +    /* Each frame can be threaded onto a doubly-linked list. */
> > +    struct page_list_entry list;
> > +
> > +    /* Reference count and various PGC_xxx flags and fields. */
> > +    unsigned long count_info;
> > +
> > +    /* Context-dependent fields follow... */
> > +    union {
> > +        /* Page is in use: ((count_info & PGC_count_mask) != 0).
> > */
> > +        struct {
> > +            /* Type reference count and various PGT_xxx flags and
> > fields. */
> > +            unsigned long type_info;
> > +        } inuse;
> > +        /* Page is on a free list: ((count_info & PGC_count_mask)
> > ==
> > 0). */
> > +        union {
> > +            struct {
> > +                /*
> > +                 * Index of the first *possibly* unscrubbed page
> > in
> > the buddy.
> > +                 * One more bit than maximum possible order to
> > accommodate
> > +                 * INVALID_DIRTY_IDX.
> > +                 */
> > +#define INVALID_DIRTY_IDX ((1UL << (MAX_ORDER + 1)) - 1)
> > +                unsigned long first_dirty:MAX_ORDER + 1;
> > +
> > +                /* Do TLBs need flushing for safety before next
> > page
> > use? */
> > +                bool need_tlbflush:1;
> > +
> > +#define BUDDY_NOT_SCRUBBING    0
> > +#define BUDDY_SCRUBBING        1
> > +#define BUDDY_SCRUB_ABORT      2
> > +                unsigned long scrub_state:2;
> > +            };
> > +
> > +                unsigned long val;
> > +            } free;
> > +
> > +    } u;
> > +
> > +    union {
> > +        /* Page is in use, but not as a shadow. */
> > +        struct {
> > +            /* Owner of this page (zero if page is anonymous). */
> > +            struct domain *domain;
> > +        } inuse;
> > +
> > +        /* Page is on a free list. */
> > +        struct {
> > +            /* Order-size of the free chunk this page is the head
> > of. */
> > +            unsigned int order;
> > +        } free;
> > +
> > +    } v;
> > +
> > +    union {
> > +        /*
> > +         * Timestamp from 'TLB clock', used to avoid extra safety
> > flushes.
> > +         * Only valid for: a) free pages, and b) pages with zero
> > type count
> > +         */
> > +        uint32_t tlbflush_timestamp;
> > +    };
> > +    uint64_t pad;
I think it can be removed too. The changes weren't saved. ( Just
another one reminder for me ).

Sorry for the convenience.

~ Oleksii
> 

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

* Re: [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V
  2023-12-22 15:12 ` [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V Oleksii Kurochko
@ 2024-01-04 11:01   ` Jan Beulich
  2024-01-08 14:46     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-04 11:01 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Since you change how PPC is handled, this can't go without description (i.e.
justification).

Jan

> --- a/xen/include/public/hvm/save.h
> +++ b/xen/include/public/hvm/save.h
> @@ -89,8 +89,8 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm_save_end);
>  #include "../arch-x86/hvm/save.h"
>  #elif defined(__arm__) || defined(__aarch64__)
>  #include "../arch-arm/hvm/save.h"
> -#elif defined(__powerpc64__)
> -#include "../arch-ppc.h"
> +#elif defined(__powerpc64__) || defined(__riscv)
> +/* no specific header to include */
>  #else
>  #error "unsupported architecture"
>  #endif



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

* Re: [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h
  2023-12-22 15:12 ` [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h Oleksii Kurochko
@ 2024-01-04 11:04   ` Jan Beulich
  2024-01-08 14:47     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-04 11:04 UTC (permalink / raw
  To: Oleksii Kurochko; +Cc: Paul Durrant, Roger Pau Monné, xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

The change looks okay-ish, but again needs a description: You want to
explain why you use the absolute minimum of the scopes the two (or,
in principle, possibly more) #ifdef-s cover.

Jan

> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -337,7 +337,9 @@ extern int iommu_add_extra_reserved_device_memory(unsigned long start,
>  extern int iommu_get_extra_reserved_device_memory(iommu_grdm_t *func,
>                                                    void *ctxt);
>  
> +#ifdef CONFIG_HAS_PASSTHROUGH
>  #include <asm/iommu.h>
> +#endif
>  
>  #ifndef iommu_call
>  # define iommu_call(ops, fn, args...) ((ops)->fn(args))
> @@ -345,7 +347,9 @@ extern int iommu_get_extra_reserved_device_memory(iommu_grdm_t *func,
>  #endif
>  
>  struct domain_iommu {
> +#ifdef CONFIG_HAS_PASSTHROUGH
>      struct arch_iommu arch;
> +#endif
>  
>      /* iommu_ops */
>      const struct iommu_ops *platform_ops;



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

* Re: [PATCH v3 07/34] xen/asm-generic: introdure nospec.h
  2023-12-22 15:12 ` [PATCH v3 07/34] xen/asm-generic: introdure nospec.h Oleksii Kurochko
@ 2024-01-04 11:06   ` Jan Beulich
  2024-01-04 11:13     ` Andrew Cooper
  2024-01-08 14:58     ` Oleksii
  2024-01-05 19:02   ` Shawn Anastasio
  1 sibling, 2 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-04 11:06 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, Andrew Cooper, George Dunlap, Wei Liu,
	Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> The <asm/nospec.h> header is similar between Arm, PPC, and RISC-V,
> so it has been moved to asm-generic.
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>

A word may want saying though on ...

> --- a/xen/arch/arm/include/asm/nospec.h
> +++ b/xen/include/asm-generic/nospec.h
> @@ -1,8 +1,8 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. */
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef _ASM_GENERIC_NOSPEC_H
> +#define _ASM_GENERIC_NOSPEC_H

... the removal of the copyright line.

Jan


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

* Re: [PATCH v3 07/34] xen/asm-generic: introdure nospec.h
  2024-01-04 11:06   ` Jan Beulich
@ 2024-01-04 11:13     ` Andrew Cooper
  2024-01-04 12:03       ` Jan Beulich
  2024-01-08 14:58     ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Andrew Cooper @ 2024-01-04 11:13 UTC (permalink / raw
  To: Jan Beulich, Oleksii Kurochko
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, George Dunlap, Wei Liu, Shawn Anastasio,
	Alistair Francis, Bob Eshleman, Connor Davis, xen-devel

On 04/01/2024 11:06 am, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>> The <asm/nospec.h> header is similar between Arm, PPC, and RISC-V,
>> so it has been moved to asm-generic.
>>
>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
>
> A word may want saying though on ...
>
>> --- a/xen/arch/arm/include/asm/nospec.h
>> +++ b/xen/include/asm-generic/nospec.h
>> @@ -1,8 +1,8 @@
>> -/* SPDX-License-Identifier: GPL-2.0 */
>> -/* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. */
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef _ASM_GENERIC_NOSPEC_H
>> +#define _ASM_GENERIC_NOSPEC_H
> ... the removal of the copyright line.

That isn't a removal of ARM's copyright line.

The two files are similar enough to trigger git-diff's "this was a
rename" logic (see the a vs b paths), despite not being a rename.

It's unfortunate rendering in this case.

~Andrew


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

* Re: [PATCH v3 07/34] xen/asm-generic: introdure nospec.h
  2024-01-04 11:13     ` Andrew Cooper
@ 2024-01-04 12:03       ` Jan Beulich
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-04 12:03 UTC (permalink / raw
  To: Andrew Cooper
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, George Dunlap, Wei Liu, Shawn Anastasio,
	Alistair Francis, Bob Eshleman, Connor Davis, xen-devel,
	Oleksii Kurochko

On 04.01.2024 12:13, Andrew Cooper wrote:
> On 04/01/2024 11:06 am, Jan Beulich wrote:
>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>> The <asm/nospec.h> header is similar between Arm, PPC, and RISC-V,
>>> so it has been moved to asm-generic.
>>>
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>> Acked-by: Jan Beulich <jbeulich@suse.com>
>>
>> A word may want saying though on ...
>>
>>> --- a/xen/arch/arm/include/asm/nospec.h
>>> +++ b/xen/include/asm-generic/nospec.h
>>> @@ -1,8 +1,8 @@
>>> -/* SPDX-License-Identifier: GPL-2.0 */
>>> -/* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. */
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +#ifndef _ASM_GENERIC_NOSPEC_H
>>> +#define _ASM_GENERIC_NOSPEC_H
>> ... the removal of the copyright line.
> 
> That isn't a removal of ARM's copyright line.
> 
> The two files are similar enough to trigger git-diff's "this was a
> rename" logic (see the a vs b paths), despite not being a rename.
> 
> It's unfortunate rendering in this case.

Hmm, well, might be. If I had done such a change, I surely wouldn't have
created the file anew, but rather moved one of the existing instances.
Even if it was PPC's that was moved, that was (likely) cloned from Arm's
as well.

Jan


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

* Re: [PATCH v3 07/34] xen/asm-generic: introdure nospec.h
  2023-12-22 15:12 ` [PATCH v3 07/34] xen/asm-generic: introdure nospec.h Oleksii Kurochko
  2024-01-04 11:06   ` Jan Beulich
@ 2024-01-05 19:02   ` Shawn Anastasio
  1 sibling, 0 replies; 146+ messages in thread
From: Shawn Anastasio @ 2024-01-05 19:02 UTC (permalink / raw
  To: Oleksii Kurochko, xen-devel
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, Andrew Cooper, George Dunlap, Jan Beulich,
	Wei Liu, Alistair Francis, Bob Eshleman, Connor Davis

Hi Oleksii,

On 12/22/23 9:12 AM, Oleksii Kurochko wrote:
> The <asm/nospec.h> header is similar between Arm, PPC, and RISC-V,
> so it has been moved to asm-generic.
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Acked-by: Shawn Anastasio <sanastasio@raptorengineering.com>

Thanks,
Shawn


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

* Re: [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V
  2024-01-04 11:01   ` Jan Beulich
@ 2024-01-08 14:46     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-08 14:46 UTC (permalink / raw
  To: Jan Beulich
  Cc: Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On Thu, 2024-01-04 at 12:01 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> 
> Since you change how PPC is handled, this can't go without
> description (i.e.
> justification).
I thought adding a comment in the code would be sufficient. I can
include something similar in the commit message as well.


~ Oleksii

> 
> > --- a/xen/include/public/hvm/save.h
> > +++ b/xen/include/public/hvm/save.h
> > @@ -89,8 +89,8 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct
> > hvm_save_end);
> >  #include "../arch-x86/hvm/save.h"
> >  #elif defined(__arm__) || defined(__aarch64__)
> >  #include "../arch-arm/hvm/save.h"
> > -#elif defined(__powerpc64__)
> > -#include "../arch-ppc.h"
> > +#elif defined(__powerpc64__) || defined(__riscv)
> > +/* no specific header to include */
> >  #else
> >  #error "unsupported architecture"
> >  #endif
> 



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

* Re: [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h
  2024-01-04 11:04   ` Jan Beulich
@ 2024-01-08 14:47     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-08 14:47 UTC (permalink / raw
  To: Jan Beulich; +Cc: Paul Durrant, Roger Pau Monné, xen-devel

On Thu, 2024-01-04 at 12:04 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> 
> The change looks okay-ish, but again needs a description: You want to
> explain why you use the absolute minimum of the scopes the two (or,
> in principle, possibly more) #ifdef-s cover.
Sure, I'll add a description to the commit message.

~ Oleksii

> > --- a/xen/include/xen/iommu.h
> > +++ b/xen/include/xen/iommu.h
> > @@ -337,7 +337,9 @@ extern int
> > iommu_add_extra_reserved_device_memory(unsigned long start,
> >  extern int iommu_get_extra_reserved_device_memory(iommu_grdm_t
> > *func,
> >                                                    void *ctxt);
> >  
> > +#ifdef CONFIG_HAS_PASSTHROUGH
> >  #include <asm/iommu.h>
> > +#endif
> >  
> >  #ifndef iommu_call
> >  # define iommu_call(ops, fn, args...) ((ops)->fn(args))
> > @@ -345,7 +347,9 @@ extern int
> > iommu_get_extra_reserved_device_memory(iommu_grdm_t *func,
> >  #endif
> >  
> >  struct domain_iommu {
> > +#ifdef CONFIG_HAS_PASSTHROUGH
> >      struct arch_iommu arch;
> > +#endif
> >  
> >      /* iommu_ops */
> >      const struct iommu_ops *platform_ops;
> 



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

* Re: [PATCH v3 07/34] xen/asm-generic: introdure nospec.h
  2024-01-04 11:06   ` Jan Beulich
  2024-01-04 11:13     ` Andrew Cooper
@ 2024-01-08 14:58     ` Oleksii
  1 sibling, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-08 14:58 UTC (permalink / raw
  To: Jan Beulich
  Cc: Stefano Stabellini, Julien Grall, Bertrand Marquis, Michal Orzel,
	Volodymyr Babchuk, Andrew Cooper, George Dunlap, Wei Liu,
	Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel

On Thu, 2024-01-04 at 12:06 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > The <asm/nospec.h> header is similar between Arm, PPC, and RISC-V,
> > so it has been moved to asm-generic.
> > 
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> 
> Acked-by: Jan Beulich <jbeulich@suse.com>
> 
> A word may want saying though on ...
> 
> > --- a/xen/arch/arm/include/asm/nospec.h
> > +++ b/xen/include/asm-generic/nospec.h
> > @@ -1,8 +1,8 @@
> > -/* SPDX-License-Identifier: GPL-2.0 */
> > -/* Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights
> > Reserved. */
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#ifndef _ASM_GENERIC_NOSPEC_H
> > +#define _ASM_GENERIC_NOSPEC_H
> 
> ... the removal of the copyright line.
It was automatically decided by Git to do it this way.

I'll try to make it generate a new file instead of moving/renaming
Arm's nospec.h.

~ Oleksii


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

* Re: [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h
  2023-12-22 15:12 ` [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h Oleksii Kurochko
@ 2024-01-11 15:57   ` Jan Beulich
  2024-01-15  9:26     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-11 15:57 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - update the commit message

There (still) is none - what is the above about?

> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/guest_atomics.h
> @@ -0,0 +1,49 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __ASM_RISCV_GUEST_ATOMICS_H
> +#define __ASM_RISCV_GUEST_ATOMICS_H
> +
> +#define guest_testop(name)                                                  \
> +static inline int guest_##name(struct domain *d, int nr, volatile void *p)  \
> +{                                                                           \
> +    (void) d;                                                               \
> +    (void) nr;                                                              \
> +    (void) p;                                                               \

What are these and ...

> +    ASSERT_UNREACHABLE();                                                   \
> +                                                                            \
> +    return 0;                                                               \
> +}
> +
> +#define guest_bitop(name)                                                   \
> +static inline void guest_##name(struct domain *d, int nr, volatile void *p) \
> +{                                                                           \
> +    (void) d;                                                               \
> +    (void) nr;                                                              \
> +    (void) p;                                                               \

... these about? If there's a reason for having them, then (nit) there
are stray blanks.

Jan


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

* Re: [PATCH v3 09/34] xen/riscv: introduce system.h
  2023-12-22 15:12 ` [PATCH v3 09/34] xen/riscv: introduce system.h Oleksii Kurochko
@ 2024-01-11 16:00   ` Jan Beulich
  2024-01-15  9:28     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-11 16:00 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/system.h
> @@ -0,0 +1,90 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef _ASM_RISCV_BARRIER_H
> +#define _ASM_RISCV_BARRIER_H

s/BARRIER/SYSTEM/ ?

With that taken care of (which I'd be happy to do while committing)
Acked-by: Jan Beulich <jbeulich@suse.com>

> +#include <xen/stdbool.h>
> +
> +#include <asm/csr.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +#define RISCV_FENCE(p, s) \
> +    __asm__ __volatile__ ( "fence " #p "," #s : : : "memory" )
> +
> +/* These barriers need to enforce ordering on both devices or memory. */
> +#define mb()                    RISCV_FENCE(iorw, iorw)
> +#define rmb()                   RISCV_FENCE(ir, ir)
> +#define wmb()                   RISCV_FENCE(ow, ow)
> +
> +/* These barriers do not need to enforce ordering on devices, just memory. */
> +#define smp_mb()                RISCV_FENCE(rw, rw)
> +#define smp_rmb()               RISCV_FENCE(r, r)
> +#define smp_wmb()               RISCV_FENCE(w, w)
> +#define smp_mb__before_atomic() smp_mb()
> +#define smp_mb__after_atomic()  smp_mb()
> +
> +/*
> +#define smp_store_release(p, v)         \
> +do {                                    \
> +    compiletime_assert_atomic_type(*p); \
> +    RISCV_FENCE(rw, w);                 \
> +    WRITE_ONCE(*p, v);                  \
> +} while (0)
> +
> +#define smp_load_acquire(p)             \
> +({                                      \
> +    typeof(*p) p1 = READ_ONCE(*p);      \
> +    compiletime_assert_atomic_type(*p); \
> +    RISCV_FENCE(r,rw);                  \
> +    p1;                                 \
> +})
> +*/
> +
> +static inline unsigned long local_save_flags(void)
> +{
> +    return csr_read(sstatus);
> +}
> +
> +static inline void local_irq_enable(void)
> +{
> +    csr_set(sstatus, SSTATUS_SIE);
> +}
> +
> +static inline void local_irq_disable(void)
> +{
> +    csr_clear(sstatus, SSTATUS_SIE);
> +}
> +
> +#define local_irq_save(x)                           \
> +({                                                  \
> +    x = csr_read_clear(CSR_SSTATUS, SSTATUS_SIE);   \
> +    local_irq_disable();                            \
> +})
> +
> +static inline void local_irq_restore(unsigned long flags)
> +{
> +	csr_set(CSR_SSTATUS, flags & SSTATUS_SIE);
> +}
> +
> +static inline bool local_irq_is_enabled(void)
> +{
> +    unsigned long flags = local_save_flags();
> +
> +    return (flags & SSTATUS_SIE) != 0;

Just as a remark - when the resulting type is bool, we generally
prefer to omit the "!= 0".

Jan


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

* Re: [PATCH v3 12/34] xen/riscv: introduce smp.h
  2023-12-22 15:12 ` [PATCH v3 12/34] xen/riscv: introduce smp.h Oleksii Kurochko
@ 2024-01-11 16:36   ` Jan Beulich
  2024-01-15  9:35     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-11 16:36 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - drop cpu_is_offline() as it was moved to xen/smp.h.

Hmm.

>  - add SPDX.
>  - drop unnessary #ifdef.
>  - fix "No new line"
>  - update the commit message

And another hmm.

> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/smp.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __ASM_RISCV_SMP_H
> +#define __ASM_RISCV_SMP_H
> +
> +#include <xen/cpumask.h>
> +#include <xen/percpu.h>
> +
> +DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_mask);
> +DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask);
> +
> +#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))

This clearly wasn't dropped (yet).

Jan


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2023-12-22 16:32   ` Oleksii
  2023-12-22 18:16     ` Oleksii
@ 2024-01-11 16:43     ` Jan Beulich
  2024-01-15 10:36       ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-11 16:43 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 17:32, Oleksii wrote:
>> +#define PFN_ORDER(_pfn) ((_pfn)->v.free.order)
> I missed saving these changes. It should be _pfn -> pfn_. (Just a
> reminder for me).

And what purpose would the trailing underscore serve here?

Jan


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2023-12-22 15:13 ` [PATCH v3 21/34] xen/riscv: introduce p2m.h Oleksii Kurochko
@ 2024-01-11 23:11   ` Shawn Anastasio
  2024-01-15  9:37     ` Oleksii
  2024-01-12 10:39   ` Julien Grall
  1 sibling, 1 reply; 146+ messages in thread
From: Shawn Anastasio @ 2024-01-11 23:11 UTC (permalink / raw
  To: Oleksii Kurochko, xen-devel; +Cc: Alistair Francis, Bob Eshleman, Connor Davis

Hi Oleksii,

On 12/22/23 9:13 AM, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - add SPDX
>  - drop unneeded for now p2m types.
>  - return false in all functions implemented with BUG() inside.
>  - update the commit message
> ---
> Changes in V2:
>  - Nothing changed. Only rebase.
> ---
>  xen/arch/ppc/include/asm/p2m.h   |   3 +-
>  xen/arch/riscv/include/asm/p2m.h | 102 +++++++++++++++++++++++++++++++
>  2 files changed, 103 insertions(+), 2 deletions(-)
>  create mode 100644 xen/arch/riscv/include/asm/p2m.h
> 
> diff --git a/xen/arch/ppc/include/asm/p2m.h b/xen/arch/ppc/include/asm/p2m.h
> index 25ba054668..3bc05b7c05 100644
> --- a/xen/arch/ppc/include/asm/p2m.h
> +++ b/xen/arch/ppc/include/asm/p2m.h
> @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct domain *d)
>  static inline int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
>                                                          unsigned int order)
>  {
> -    BUG_ON("unimplemented");
> -    return 1;
> +    return -EOPNOTSUPP;
>  }
>

Was this change included by mistake? I'm not sure why this patch should
touch PPC's p2m.h.

Thanks,
Shawn


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2023-12-22 15:13 ` [PATCH v3 21/34] xen/riscv: introduce p2m.h Oleksii Kurochko
  2024-01-11 23:11   ` Shawn Anastasio
@ 2024-01-12 10:39   ` Julien Grall
  2024-01-12 11:06     ` Jan Beulich
  2024-01-15 10:35     ` Oleksii
  1 sibling, 2 replies; 146+ messages in thread
From: Julien Grall @ 2024-01-12 10:39 UTC (permalink / raw
  To: Oleksii Kurochko, xen-devel
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis

Hi Oleksii,

On 22/12/2023 15:13, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>   - add SPDX
>   - drop unneeded for now p2m types.
>   - return false in all functions implemented with BUG() inside.
>   - update the commit message
> ---
> Changes in V2:
>   - Nothing changed. Only rebase.
> ---
>   xen/arch/ppc/include/asm/p2m.h   |   3 +-
>   xen/arch/riscv/include/asm/p2m.h | 102 +++++++++++++++++++++++++++++++
>   2 files changed, 103 insertions(+), 2 deletions(-)
>   create mode 100644 xen/arch/riscv/include/asm/p2m.h
> 
> diff --git a/xen/arch/ppc/include/asm/p2m.h b/xen/arch/ppc/include/asm/p2m.h
> index 25ba054668..3bc05b7c05 100644
> --- a/xen/arch/ppc/include/asm/p2m.h
> +++ b/xen/arch/ppc/include/asm/p2m.h
> @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct domain *d)
>   static inline int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
>                                                           unsigned int order)
>   {
> -    BUG_ON("unimplemented");
> -    return 1;
> +    return -EOPNOTSUPP;
>   }
>   
>   static inline int guest_physmap_add_entry(struct domain *d,
> diff --git a/xen/arch/riscv/include/asm/p2m.h b/xen/arch/riscv/include/asm/p2m.h
> new file mode 100644
> index 0000000000..d270ef6635
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/p2m.h
> @@ -0,0 +1,102 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __ASM_RISCV_P2M_H__
> +#define __ASM_RISCV_P2M_H__
> +
> +#include <asm/page-bits.h>
> +
> +#define paddr_bits PADDR_BITS
> +
> +/*
> + * List of possible type for each page in the p2m entry.
> + * The number of available bit per page in the pte for this purpose is 4 bits.
> + * So it's possible to only have 16 fields. If we run out of value in the
> + * future, it's possible to use higher value for pseudo-type and don't store
> + * them in the p2m entry.
> + */

This looks like a verbatim copy from Arm. Did you actually check RISC-V 
has 4 bits available in the PTE to store this value?

> +typedef enum {
> +    p2m_invalid = 0,    /* Nothing mapped here */
> +    p2m_ram_rw,         /* Normal read/write guest RAM */

s/guest/domain/ as this also applies for dom0.

> +} p2m_type_t;
> +
> +#include <xen/p2m-common.h>
> +
> +static inline int get_page_and_type(struct page_info *page,
> +                                    struct domain *domain,
> +                                    unsigned long type)
> +{
> +    BUG();

I understand your goal with the BUG() but I find it risky. This is not a 
problem right now, it is more when we will decide to have RISC-V 
supported. You will have to go through all the BUG() to figure out which 
one are warrant or not.

To reduce the load, I would recommend to switch to ASSERT_UNREACHABLE() 
(or maybe introduced a different macro) that would lead to a crash on 
debug build but propagate the error normally on production build.

Of course, if you can't propagate an error, then the right course of 
action is a BUG(). But I expect this case to be limited.

[...]

> +static inline mfn_t gfn_to_mfn(struct domain *d, gfn_t gfn)
> +{
> +    BUG();
> +    return _mfn(0);

This wants to be INVALID_MFN.

[...]


-- 
Julien Grall


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-12 10:39   ` Julien Grall
@ 2024-01-12 11:06     ` Jan Beulich
  2024-01-12 11:09       ` Julien Grall
  2024-01-15 10:35     ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-12 11:06 UTC (permalink / raw
  To: Julien Grall, Oleksii Kurochko
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel

On 12.01.2024 11:39, Julien Grall wrote:
> On 22/12/2023 15:13, Oleksii Kurochko wrote:
>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>> ---
>> Changes in V3:
>>   - add SPDX
>>   - drop unneeded for now p2m types.
>>   - return false in all functions implemented with BUG() inside.
>>   - update the commit message
>> ---
>> Changes in V2:
>>   - Nothing changed. Only rebase.
>> ---
>>   xen/arch/ppc/include/asm/p2m.h   |   3 +-
>>   xen/arch/riscv/include/asm/p2m.h | 102 +++++++++++++++++++++++++++++++
>>   2 files changed, 103 insertions(+), 2 deletions(-)
>>   create mode 100644 xen/arch/riscv/include/asm/p2m.h
>>
>> diff --git a/xen/arch/ppc/include/asm/p2m.h b/xen/arch/ppc/include/asm/p2m.h
>> index 25ba054668..3bc05b7c05 100644
>> --- a/xen/arch/ppc/include/asm/p2m.h
>> +++ b/xen/arch/ppc/include/asm/p2m.h
>> @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct domain *d)
>>   static inline int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
>>                                                           unsigned int order)
>>   {
>> -    BUG_ON("unimplemented");
>> -    return 1;
>> +    return -EOPNOTSUPP;
>>   }
>>   
>>   static inline int guest_physmap_add_entry(struct domain *d,
>> diff --git a/xen/arch/riscv/include/asm/p2m.h b/xen/arch/riscv/include/asm/p2m.h
>> new file mode 100644
>> index 0000000000..d270ef6635
>> --- /dev/null
>> +++ b/xen/arch/riscv/include/asm/p2m.h
>> @@ -0,0 +1,102 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef __ASM_RISCV_P2M_H__
>> +#define __ASM_RISCV_P2M_H__
>> +
>> +#include <asm/page-bits.h>
>> +
>> +#define paddr_bits PADDR_BITS
>> +
>> +/*
>> + * List of possible type for each page in the p2m entry.
>> + * The number of available bit per page in the pte for this purpose is 4 bits.
>> + * So it's possible to only have 16 fields. If we run out of value in the
>> + * future, it's possible to use higher value for pseudo-type and don't store
>> + * them in the p2m entry.
>> + */
> 
> This looks like a verbatim copy from Arm. Did you actually check RISC-V 
> has 4 bits available in the PTE to store this value?
> 
>> +typedef enum {
>> +    p2m_invalid = 0,    /* Nothing mapped here */
>> +    p2m_ram_rw,         /* Normal read/write guest RAM */
> 
> s/guest/domain/ as this also applies for dom0.
> 
>> +} p2m_type_t;
>> +
>> +#include <xen/p2m-common.h>
>> +
>> +static inline int get_page_and_type(struct page_info *page,
>> +                                    struct domain *domain,
>> +                                    unsigned long type)
>> +{
>> +    BUG();
> 
> I understand your goal with the BUG() but I find it risky. This is not a 
> problem right now, it is more when we will decide to have RISC-V 
> supported. You will have to go through all the BUG() to figure out which 
> one are warrant or not.
> 
> To reduce the load, I would recommend to switch to ASSERT_UNREACHABLE() 
> (or maybe introduced a different macro) that would lead to a crash on 
> debug build but propagate the error normally on production build.

Elsewhere BUG_ON("unimplemented") is used to indicate such cases.
Can't this be used here (and then uniformly elsewhere) as well?

Jan


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-12 11:06     ` Jan Beulich
@ 2024-01-12 11:09       ` Julien Grall
  0 siblings, 0 replies; 146+ messages in thread
From: Julien Grall @ 2024-01-12 11:09 UTC (permalink / raw
  To: Jan Beulich, Oleksii Kurochko
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel

Hi Jan,

On 12/01/2024 11:06, Jan Beulich wrote:
> On 12.01.2024 11:39, Julien Grall wrote:
>> On 22/12/2023 15:13, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> ---
>>> Changes in V3:
>>>    - add SPDX
>>>    - drop unneeded for now p2m types.
>>>    - return false in all functions implemented with BUG() inside.
>>>    - update the commit message
>>> ---
>>> Changes in V2:
>>>    - Nothing changed. Only rebase.
>>> ---
>>>    xen/arch/ppc/include/asm/p2m.h   |   3 +-
>>>    xen/arch/riscv/include/asm/p2m.h | 102 +++++++++++++++++++++++++++++++
>>>    2 files changed, 103 insertions(+), 2 deletions(-)
>>>    create mode 100644 xen/arch/riscv/include/asm/p2m.h
>>>
>>> diff --git a/xen/arch/ppc/include/asm/p2m.h b/xen/arch/ppc/include/asm/p2m.h
>>> index 25ba054668..3bc05b7c05 100644
>>> --- a/xen/arch/ppc/include/asm/p2m.h
>>> +++ b/xen/arch/ppc/include/asm/p2m.h
>>> @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct domain *d)
>>>    static inline int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
>>>                                                            unsigned int order)
>>>    {
>>> -    BUG_ON("unimplemented");
>>> -    return 1;
>>> +    return -EOPNOTSUPP;
>>>    }
>>>    
>>>    static inline int guest_physmap_add_entry(struct domain *d,
>>> diff --git a/xen/arch/riscv/include/asm/p2m.h b/xen/arch/riscv/include/asm/p2m.h
>>> new file mode 100644
>>> index 0000000000..d270ef6635
>>> --- /dev/null
>>> +++ b/xen/arch/riscv/include/asm/p2m.h
>>> @@ -0,0 +1,102 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +#ifndef __ASM_RISCV_P2M_H__
>>> +#define __ASM_RISCV_P2M_H__
>>> +
>>> +#include <asm/page-bits.h>
>>> +
>>> +#define paddr_bits PADDR_BITS
>>> +
>>> +/*
>>> + * List of possible type for each page in the p2m entry.
>>> + * The number of available bit per page in the pte for this purpose is 4 bits.
>>> + * So it's possible to only have 16 fields. If we run out of value in the
>>> + * future, it's possible to use higher value for pseudo-type and don't store
>>> + * them in the p2m entry.
>>> + */
>>
>> This looks like a verbatim copy from Arm. Did you actually check RISC-V
>> has 4 bits available in the PTE to store this value?
>>
>>> +typedef enum {
>>> +    p2m_invalid = 0,    /* Nothing mapped here */
>>> +    p2m_ram_rw,         /* Normal read/write guest RAM */
>>
>> s/guest/domain/ as this also applies for dom0.
>>
>>> +} p2m_type_t;
>>> +
>>> +#include <xen/p2m-common.h>
>>> +
>>> +static inline int get_page_and_type(struct page_info *page,
>>> +                                    struct domain *domain,
>>> +                                    unsigned long type)
>>> +{
>>> +    BUG();
>>
>> I understand your goal with the BUG() but I find it risky. This is not a
>> problem right now, it is more when we will decide to have RISC-V
>> supported. You will have to go through all the BUG() to figure out which
>> one are warrant or not.
>>
>> To reduce the load, I would recommend to switch to ASSERT_UNREACHABLE()
>> (or maybe introduced a different macro) that would lead to a crash on
>> debug build but propagate the error normally on production build.
> 
> Elsewhere BUG_ON("unimplemented") is used to indicate such cases.
> Can't this be used here (and then uniformly elsewhere) as well?

I would prefer something that can be compiled out in production build. 
But I would be Ok with BUG_ON("...") this is at least clearer than a 
plain BUG().

-- 
Julien Grall


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

* Re: [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h
  2024-01-11 15:57   ` Jan Beulich
@ 2024-01-15  9:26     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-15  9:26 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Thu, 2024-01-11 at 16:57 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - update the commit message
> 
> There (still) is none - what is the above about?
Missed something. I'll double check during providing the next patch
version.
> 
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/guest_atomics.h
> > @@ -0,0 +1,49 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#ifndef __ASM_RISCV_GUEST_ATOMICS_H
> > +#define __ASM_RISCV_GUEST_ATOMICS_H
> > +
> > +#define
> > guest_testop(name)                                                 
> > \
> > +static inline int guest_##name(struct domain *d, int nr, volatile
> > void *p)  \
> > +{                                                                 
> >           \
> > +    (void)
> > d;                                                               \
> > +    (void)
> > nr;                                                              \
> > +    (void)
> > p;                                                               \
> 
> What are these and ...
> 
> > +   
> > ASSERT_UNREACHABLE();                                              
> >      \
> > +                                                                  
> >           \
> > +    return
> > 0;                                                               \
> > +}
> > +
> > +#define
> > guest_bitop(name)                                                  
> > \
> > +static inline void guest_##name(struct domain *d, int nr, volatile
> > void *p) \
> > +{                                                                 
> >           \
> > +    (void)
> > d;                                                               \
> > +    (void)
> > nr;                                                              \
> > +    (void)
> > p;                                                               \
> 
> ... these about? If there's a reason for having them, then (nit)
> there
> are stray blanks.
It is only one reason for that to show that args are unused for time
being.
But I think I can drop these changes.


~ Oleksii

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

* Re: [PATCH v3 09/34] xen/riscv: introduce system.h
  2024-01-11 16:00   ` Jan Beulich
@ 2024-01-15  9:28     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-15  9:28 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Thu, 2024-01-11 at 17:00 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/system.h
> > @@ -0,0 +1,90 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +
> > +#ifndef _ASM_RISCV_BARRIER_H
> > +#define _ASM_RISCV_BARRIER_H
> 
> s/BARRIER/SYSTEM/ ?
Yes, it should be SYSTEM. Thanks for noticing that.

> 
> With that taken care of (which I'd be happy to do while committing)
> Acked-by: Jan Beulich <jbeulich@suse.com>
Thanks a lot. I'll be happy with that.

> 
> > +#include <xen/stdbool.h>
> > +
> > +#include <asm/csr.h>
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +#define RISCV_FENCE(p, s) \
> > +    __asm__ __volatile__ ( "fence " #p "," #s : : : "memory" )
> > +
> > +/* These barriers need to enforce ordering on both devices or
> > memory. */
> > +#define mb()                    RISCV_FENCE(iorw, iorw)
> > +#define rmb()                   RISCV_FENCE(ir, ir)
> > +#define wmb()                   RISCV_FENCE(ow, ow)
> > +
> > +/* These barriers do not need to enforce ordering on devices, just
> > memory. */
> > +#define smp_mb()                RISCV_FENCE(rw, rw)
> > +#define smp_rmb()               RISCV_FENCE(r, r)
> > +#define smp_wmb()               RISCV_FENCE(w, w)
> > +#define smp_mb__before_atomic() smp_mb()
> > +#define smp_mb__after_atomic()  smp_mb()
> > +
> > +/*
> > +#define smp_store_release(p, v)         \
> > +do {                                    \
> > +    compiletime_assert_atomic_type(*p); \
> > +    RISCV_FENCE(rw, w);                 \
> > +    WRITE_ONCE(*p, v);                  \
> > +} while (0)
> > +
> > +#define smp_load_acquire(p)             \
> > +({                                      \
> > +    typeof(*p) p1 = READ_ONCE(*p);      \
> > +    compiletime_assert_atomic_type(*p); \
> > +    RISCV_FENCE(r,rw);                  \
> > +    p1;                                 \
> > +})
> > +*/
> > +
> > +static inline unsigned long local_save_flags(void)
> > +{
> > +    return csr_read(sstatus);
> > +}
> > +
> > +static inline void local_irq_enable(void)
> > +{
> > +    csr_set(sstatus, SSTATUS_SIE);
> > +}
> > +
> > +static inline void local_irq_disable(void)
> > +{
> > +    csr_clear(sstatus, SSTATUS_SIE);
> > +}
> > +
> > +#define local_irq_save(x)                           \
> > +({                                                  \
> > +    x = csr_read_clear(CSR_SSTATUS, SSTATUS_SIE);   \
> > +    local_irq_disable();                            \
> > +})
> > +
> > +static inline void local_irq_restore(unsigned long flags)
> > +{
> > +	csr_set(CSR_SSTATUS, flags & SSTATUS_SIE);
> > +}
> > +
> > +static inline bool local_irq_is_enabled(void)
> > +{
> > +    unsigned long flags = local_save_flags();
> > +
> > +    return (flags & SSTATUS_SIE) != 0;
> 
> Just as a remark - when the resulting type is bool, we generally
> prefer to omit the "!= 0".
Thanks. I'll take into account that.

~ Oleksii

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

* Re: [PATCH v3 12/34] xen/riscv: introduce smp.h
  2024-01-11 16:36   ` Jan Beulich
@ 2024-01-15  9:35     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-15  9:35 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Thu, 2024-01-11 at 17:36 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - drop cpu_is_offline() as it was moved to xen/smp.h.
> 
> Hmm.
> 
> >  - add SPDX.
> >  - drop unnessary #ifdef.
> >  - fix "No new line"
> >  - update the commit message
> 
> And another hmm.
It was removed word "asm/" before smp.h, but yes it is not correct to
write commit "message" should be "title".
I'll be more precise next time.

> 
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/smp.h
> > @@ -0,0 +1,28 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#ifndef __ASM_RISCV_SMP_H
> > +#define __ASM_RISCV_SMP_H
> > +
> > +#include <xen/cpumask.h>
> > +#include <xen/percpu.h>
> > +
> > +DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_mask);
> > +DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask);
> > +
> > +#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
> 
> This clearly wasn't dropped (yet).
It looks like it was rebasing issue.
I'll handle that in the next patch version.
Thanks.

~ Oleksii


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-11 23:11   ` Shawn Anastasio
@ 2024-01-15  9:37     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-15  9:37 UTC (permalink / raw
  To: Shawn Anastasio, xen-devel; +Cc: Alistair Francis, Bob Eshleman, Connor Davis

On Thu, 2024-01-11 at 17:11 -0600, Shawn Anastasio wrote:
> Hi Oleksii,
> 
> On 12/22/23 9:13 AM, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - add SPDX
> >  - drop unneeded for now p2m types.
> >  - return false in all functions implemented with BUG() inside.
> >  - update the commit message
> > ---
> > Changes in V2:
> >  - Nothing changed. Only rebase.
> > ---
> >  xen/arch/ppc/include/asm/p2m.h   |   3 +-
> >  xen/arch/riscv/include/asm/p2m.h | 102
> > +++++++++++++++++++++++++++++++
> >  2 files changed, 103 insertions(+), 2 deletions(-)
> >  create mode 100644 xen/arch/riscv/include/asm/p2m.h
> > 
> > diff --git a/xen/arch/ppc/include/asm/p2m.h
> > b/xen/arch/ppc/include/asm/p2m.h
> > index 25ba054668..3bc05b7c05 100644
> > --- a/xen/arch/ppc/include/asm/p2m.h
> > +++ b/xen/arch/ppc/include/asm/p2m.h
> > @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct
> > domain *d)
> >  static inline int guest_physmap_mark_populate_on_demand(struct
> > domain *d, unsigned long gfn,
> >                                                          unsigned
> > int order)
> >  {
> > -    BUG_ON("unimplemented");
> > -    return 1;
> > +    return -EOPNOTSUPP;
> >  }
> > 
> 
> Was this change included by mistake? I'm not sure why this patch
> should
> touch PPC's p2m.h.
I think you are right. It's mistake. RISC-V has the similar p2m.h so I
faulty changed PPC version too.

Thanks.

~ Oleksii


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-12 10:39   ` Julien Grall
  2024-01-12 11:06     ` Jan Beulich
@ 2024-01-15 10:35     ` Oleksii
  2024-01-15 11:01       ` Jan Beulich
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-15 10:35 UTC (permalink / raw
  To: Julien Grall, xen-devel
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis

Hi Julien,

On Fri, 2024-01-12 at 10:39 +0000, Julien Grall wrote:
> Hi Oleksii,
> 
> On 22/12/2023 15:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >   - add SPDX
> >   - drop unneeded for now p2m types.
> >   - return false in all functions implemented with BUG() inside.
> >   - update the commit message
> > ---
> > Changes in V2:
> >   - Nothing changed. Only rebase.
> > ---
> >   xen/arch/ppc/include/asm/p2m.h   |   3 +-
> >   xen/arch/riscv/include/asm/p2m.h | 102
> > +++++++++++++++++++++++++++++++
> >   2 files changed, 103 insertions(+), 2 deletions(-)
> >   create mode 100644 xen/arch/riscv/include/asm/p2m.h
> > 
> > diff --git a/xen/arch/ppc/include/asm/p2m.h
> > b/xen/arch/ppc/include/asm/p2m.h
> > index 25ba054668..3bc05b7c05 100644
> > --- a/xen/arch/ppc/include/asm/p2m.h
> > +++ b/xen/arch/ppc/include/asm/p2m.h
> > @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct
> > domain *d)
> >   static inline int guest_physmap_mark_populate_on_demand(struct
> > domain *d, unsigned long gfn,
> >                                                           unsigned
> > int order)
> >   {
> > -    BUG_ON("unimplemented");
> > -    return 1;
> > +    return -EOPNOTSUPP;
> >   }
> >   
> >   static inline int guest_physmap_add_entry(struct domain *d,
> > diff --git a/xen/arch/riscv/include/asm/p2m.h
> > b/xen/arch/riscv/include/asm/p2m.h
> > new file mode 100644
> > index 0000000000..d270ef6635
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/p2m.h
> > @@ -0,0 +1,102 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#ifndef __ASM_RISCV_P2M_H__
> > +#define __ASM_RISCV_P2M_H__
> > +
> > +#include <asm/page-bits.h>
> > +
> > +#define paddr_bits PADDR_BITS
> > +
> > +/*
> > + * List of possible type for each page in the p2m entry.
> > + * The number of available bit per page in the pte for this
> > purpose is 4 bits.
> > + * So it's possible to only have 16 fields. If we run out of value
> > in the
> > + * future, it's possible to use higher value for pseudo-type and
> > don't store
> > + * them in the p2m entry.
> > + */
> 
> This looks like a verbatim copy from Arm. Did you actually check
> RISC-V 
> has 4 bits available in the PTE to store this value?
Thanks for noticing that, in RISC-V it is available only 2 bits ( bits
8 and 9), so I'll update the comment:
53                   10 9    8 7 6 5 4 3 2 1 0
 Physical Page Number     RSV  D A G U X W R V

It seems that I missed something in the Arm code/architecture.As far as I recall, in Arm, bits 5-8 are ignored by the MMU, and they
are expected
to be used by the hypervisor for its purpose.
However, in the code, I notice that these bits are utilized for storing
a reference counter.

Could you confirm if my understanding is correct?
Additionally, I am curious about where the PTE bits are used to store
one of the values of the enum `p2m_type_t`.

> 
> > +typedef enum {
> > +    p2m_invalid = 0,    /* Nothing mapped here */
> > +    p2m_ram_rw,         /* Normal read/write guest RAM */
> 
> s/guest/domain/ as this also applies for dom0.
Thanks. I'll update that.
> 
> > +} p2m_type_t;
> > +
> > +#include <xen/p2m-common.h>
> > +
> > +static inline int get_page_and_type(struct page_info *page,
> > +                                    struct domain *domain,
> > +                                    unsigned long type)
> > +{
> > +    BUG();
> 
> I understand your goal with the BUG() but I find it risky. This is
> not a 
> problem right now, it is more when we will decide to have RISC-V 
> supported. You will have to go through all the BUG() to figure out
> which 
> one are warrant or not.
> 
> To reduce the load, I would recommend to switch to
> ASSERT_UNREACHABLE() 
> (or maybe introduced a different macro) that would lead to a crash on
> debug build but propagate the error normally on production build.
> 
> Of course, if you can't propagate an error, then the right course of 
> action is a BUG(). But I expect this case to be limited.
Thanks.

I'm currently transitioning to using ASSERT_UNREACHABLE() or BUG_ON()
throughout the codebase, and this is one of the instances where I
overlooked the update.

> 
> [...]
> 
> > +static inline mfn_t gfn_to_mfn(struct domain *d, gfn_t gfn)
> > +{
> > +    BUG();
> > +    return _mfn(0);
> 
> This wants to be INVALID_MFN.
> 
> [...]
> 

~ Oleksii


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-01-11 16:43     ` Jan Beulich
@ 2024-01-15 10:36       ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-15 10:36 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Thu, 2024-01-11 at 17:43 +0100, Jan Beulich wrote:
> On 22.12.2023 17:32, Oleksii wrote:
> > > +#define PFN_ORDER(_pfn) ((_pfn)->v.free.order)
> > I missed saving these changes. It should be _pfn -> pfn_. (Just a
> > reminder for me).
> 
> And what purpose would the trailing underscore serve here?
There is no any. I'll use just pfn. Thanks for noticing that.

~ Oleksii


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-15 10:35     ` Oleksii
@ 2024-01-15 11:01       ` Jan Beulich
  2024-01-16  9:44         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-15 11:01 UTC (permalink / raw
  To: Oleksii
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel, Julien Grall

On 15.01.2024 11:35, Oleksii wrote:
> Hi Julien,
> 
> On Fri, 2024-01-12 at 10:39 +0000, Julien Grall wrote:
>> Hi Oleksii,
>>
>> On 22/12/2023 15:13, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> ---
>>> Changes in V3:
>>>   - add SPDX
>>>   - drop unneeded for now p2m types.
>>>   - return false in all functions implemented with BUG() inside.
>>>   - update the commit message
>>> ---
>>> Changes in V2:
>>>   - Nothing changed. Only rebase.
>>> ---
>>>   xen/arch/ppc/include/asm/p2m.h   |   3 +-
>>>   xen/arch/riscv/include/asm/p2m.h | 102
>>> +++++++++++++++++++++++++++++++
>>>   2 files changed, 103 insertions(+), 2 deletions(-)
>>>   create mode 100644 xen/arch/riscv/include/asm/p2m.h
>>>
>>> diff --git a/xen/arch/ppc/include/asm/p2m.h
>>> b/xen/arch/ppc/include/asm/p2m.h
>>> index 25ba054668..3bc05b7c05 100644
>>> --- a/xen/arch/ppc/include/asm/p2m.h
>>> +++ b/xen/arch/ppc/include/asm/p2m.h
>>> @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct
>>> domain *d)
>>>   static inline int guest_physmap_mark_populate_on_demand(struct
>>> domain *d, unsigned long gfn,
>>>                                                           unsigned
>>> int order)
>>>   {
>>> -    BUG_ON("unimplemented");
>>> -    return 1;
>>> +    return -EOPNOTSUPP;
>>>   }
>>>   
>>>   static inline int guest_physmap_add_entry(struct domain *d,
>>> diff --git a/xen/arch/riscv/include/asm/p2m.h
>>> b/xen/arch/riscv/include/asm/p2m.h
>>> new file mode 100644
>>> index 0000000000..d270ef6635
>>> --- /dev/null
>>> +++ b/xen/arch/riscv/include/asm/p2m.h
>>> @@ -0,0 +1,102 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +#ifndef __ASM_RISCV_P2M_H__
>>> +#define __ASM_RISCV_P2M_H__
>>> +
>>> +#include <asm/page-bits.h>
>>> +
>>> +#define paddr_bits PADDR_BITS
>>> +
>>> +/*
>>> + * List of possible type for each page in the p2m entry.
>>> + * The number of available bit per page in the pte for this
>>> purpose is 4 bits.
>>> + * So it's possible to only have 16 fields. If we run out of value
>>> in the
>>> + * future, it's possible to use higher value for pseudo-type and
>>> don't store
>>> + * them in the p2m entry.
>>> + */
>>
>> This looks like a verbatim copy from Arm. Did you actually check
>> RISC-V 
>> has 4 bits available in the PTE to store this value?
> Thanks for noticing that, in RISC-V it is available only 2 bits ( bits
> 8 and 9), so I'll update the comment:
> 53                   10 9    8 7 6 5 4 3 2 1 0
>  Physical Page Number     RSV  D A G U X W R V

It's RSW (Reserved for Supervisor softWare use), not RSV, which is pretty
important in this context.

> It seems that I missed something in the Arm code/architecture.As far as I recall, in Arm, bits 5-8 are ignored by the MMU, and they
> are expected
> to be used by the hypervisor for its purpose.
> However, in the code, I notice that these bits are utilized for storing
> a reference counter.

Why "however"? Hardware still is going to ignore these bits.

Jan


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2023-12-22 15:12 ` [PATCH v3 10/34] xen/riscv: introduce bitops.h Oleksii Kurochko
@ 2024-01-15 16:44   ` Jan Beulich
  2024-01-16 13:06     ` Oleksii
  2024-01-18 11:03   ` Jan Beulich
  1 sibling, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-15 16:44 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/bitops.h
> @@ -0,0 +1,267 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2012 Regents of the University of California */
> +
> +#ifndef _ASM_RISCV_BITOPS_H
> +#define _ASM_RISCV_BITOPS_H
> +
> +#include <asm/system.h>
> +
> +#include <asm-generic/bitops/bitops-bits.h>
> +
> +/* Based on linux/arch/include/linux/bits.h */
> +
> +#define BIT_MASK(nr)        (1UL << ((nr) % BITS_PER_LONG))
> +#define BIT_WORD(nr)        ((nr) / BITS_PER_LONG)
> +
> +#define __set_bit(n,p)      set_bit(n,p)
> +#define __clear_bit(n,p)    clear_bit(n,p)
> +
> +/* Based on linux/arch/include/asm/bitops.h */
> +
> +#if ( BITS_PER_LONG == 64 )
> +#define __AMO(op)   "amo" #op ".d"
> +#elif ( BITS_PER_LONG == 32 )
> +#define __AMO(op)   "amo" #op ".w"
> +#else
> +#error "Unexpected BITS_PER_LONG"
> +#endif
> +
> +#define __test_and_op_bit_ord(op, mod, nr, addr, ord)		\
> +({								\
> +    unsigned long __res, __mask;				\
> +    __mask = BIT_MASK(nr);					\
> +    __asm__ __volatile__ (					\
> +        __AMO(op) #ord " %0, %2, %1"			\
> +        : "=r" (__res), "+A" (addr[BIT_WORD(nr)])	\
> +        : "r" (mod(__mask))				\
> +        : "memory");					\
> +    ((__res & __mask) != 0);				\
> +})

Despite the taking from Linux I think the overall result wants to be
consistent formatting-wise: You switched to blank indentation (which
is fine), but you left tabs as padding for the line continuation
characters.

> +#define __op_bit_ord(op, mod, nr, addr, ord)			\
> +    __asm__ __volatile__ (					\
> +        __AMO(op) #ord " zero, %1, %0"			\
> +        : "+A" (addr[BIT_WORD(nr)])			\
> +        : "r" (mod(BIT_MASK(nr)))			\
> +        : "memory");
> +
> +#define __test_and_op_bit(op, mod, nr, addr) 			\

(At least) here you even use a mix.

> +    __test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
> +#define __op_bit(op, mod, nr, addr)				\
> +    __op_bit_ord(op, mod, nr, addr, )
> +
> +/* Bitmask modifiers */
> +#define __NOP(x)	(x)
> +#define __NOT(x)	(~(x))
> +
> +/**
> + * __test_and_set_bit - Set a bit and return its old value
> + * @nr: Bit to set
> + * @addr: Address to count from
> + *
> + * This operation may be reordered on other architectures than x86.
> + */
> +static inline int __test_and_set_bit(int nr, volatile void *p)
> +{
> +    volatile uint32_t *addr = p;
> +
> +    return __test_and_op_bit(or, __NOP, nr, addr);
> +}
> +
> +/**
> + * __test_and_clear_bit - Clear a bit and return its old value
> + * @nr: Bit to clear
> + * @addr: Address to count from
> + *
> + * This operation can be reordered on other architectures other than x86.
> + */
> +static inline int __test_and_clear_bit(int nr, volatile void *p)
> +{
> +    volatile uint32_t *addr = p;
> +
> +    return __test_and_op_bit(and, __NOT, nr, addr);
> +}
> +
> +/**
> + * set_bit - Atomically set a bit in memory
> + * @nr: the bit to set
> + * @addr: the address to start counting from
> + *
> + * Note: there are no guarantees that this function will not be reordered
> + * on non x86 architectures, so if you are writing portable code,
> + * make sure not to rely on its reordering guarantees.
> + *
> + * Note that @nr may be almost arbitrarily large; this function is not
> + * restricted to acting on a single-word quantity.
> + */
> +static inline void set_bit(int nr, volatile void *p)
> +{
> +    volatile uint32_t *addr = p;
> +
> +    __op_bit(or, __NOP, nr, addr);
> +}
> +
> +/**
> + * clear_bit - Clears a bit in memory
> + * @nr: Bit to clear
> + * @addr: Address to start counting from
> + *
> + * Note: there are no guarantees that this function will not be reordered
> + * on non x86 architectures, so if you are writing portable code,
> + * make sure not to rely on its reordering guarantees.
> + */
> +static inline void clear_bit(int nr, volatile void *p)
> +{
> +    volatile uint32_t *addr = p;
> +
> +    __op_bit(and, __NOT, nr, addr);
> +}
> +
> +#undef __test_and_op_bit
> +#undef __op_bit
> +#undef __NOP
> +#undef __NOT
> +#undef __AMO
> +
> +#define test_and_set_bit   __test_and_set_bit
> +#define test_and_clear_bit __test_and_clear_bit

I realize test-and-change have no present users, despite being made
available by Arm and x86, but I think they would better be provided
right away, rather than someone introducing a use then needing to
fiddle with RISC-V (and apparently also PPC) code.

I'm also puzzled by this aliasing: Aren't there cheaper non-atomic
insn forms that could be used for the double-underscore-prefixed
variants?

> +/* Based on linux/include/asm-generic/bitops/find.h */
> +
> +#ifndef find_next_bit

What is this to guard against?

> +/**
> + * find_next_bit - find the next set bit in a memory region
> + * @addr: The address to base the search on
> + * @offset: The bitnumber to start searching at
> + * @size: The bitmap size in bits
> + */
> +extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
> +        size, unsigned long offset);
> +#endif
> +
> +#ifndef find_next_zero_bit
> +/**
> + * find_next_zero_bit - find the next cleared bit in a memory region
> + * @addr: The address to base the search on
> + * @offset: The bitnumber to start searching at
> + * @size: The bitmap size in bits
> + */
> +extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned
> +        long size, unsigned long offset);
> +#endif
> +
> +/**
> + * find_first_bit - find the first set bit in a memory region
> + * @addr: The address to start the search at
> + * @size: The maximum size to search
> + *
> + * Returns the bit number of the first set bit.
> + */
> +extern unsigned long find_first_bit(const unsigned long *addr,
> +                    unsigned long size);
> +
> +/**
> + * find_first_zero_bit - find the first cleared bit in a memory region
> + * @addr: The address to start the search at
> + * @size: The maximum size to search
> + *
> + * Returns the bit number of the first cleared bit.
> + */
> +extern unsigned long find_first_zero_bit(const unsigned long *addr,
> +                     unsigned long size);
> +
> +/**
> + * ffs - find first bit in word.
> + * @word: The word to search
> + *
> + * Returns 0 if no bit exists, otherwise returns 1-indexed bit location.
> + */
> +static inline unsigned long __ffs(unsigned long word)
> +{
> +    int num = 0;

I understand it's this way in Linux, so there may be reasons to keep it
like that. Generally though we'd prefer unsigned here, and the type of
a variable used for the return value of a function would also better be
in sync with the function's return type (which I don't think needs to
be "unsigned long" either; "unsigned int" would apparently suffice).

> +#if BITS_PER_LONG == 64
> +    if ((word & 0xffffffff) == 0) {
> +        num += 32;
> +        word >>= 32;
> +    }

You're ending up with neither Xen nor Linux style this way. May I
suggest to settle on either?

> +#endif
> +    if ((word & 0xffff) == 0) {
> +        num += 16;
> +        word >>= 16;
> +    }
> +    if ((word & 0xff) == 0) {
> +        num += 8;
> +        word >>= 8;
> +    }
> +    if ((word & 0xf) == 0) {
> +        num += 4;
> +        word >>= 4;
> +    }
> +    if ((word & 0x3) == 0) {
> +        num += 2;
> +        word >>= 2;
> +    }
> +    if ((word & 0x1) == 0)
> +        num += 1;
> +    return num;
> +}
> +
> +/**
> + * ffsl - find first bit in long.
> + * @word: The word to search
> + *
> + * Returns 0 if no bit exists, otherwise returns 1-indexed bit location.
> + */
> +static inline unsigned int ffsl(unsigned long word)
> +{
> +    int num = 1;
> +
> +    if (!word)
> +        return 0;
> +
> +#if BITS_PER_LONG == 64
> +    if ((word & 0xffffffff) == 0) {
> +        num += 32;
> +        word >>= 32;
> +    }
> +#endif
> +    if ((word & 0xffff) == 0) {
> +        num += 16;
> +        word >>= 16;
> +    }
> +    if ((word & 0xff) == 0) {
> +        num += 8;
> +        word >>= 8;
> +    }
> +    if ((word & 0xf) == 0) {
> +        num += 4;
> +        word >>= 4;
> +    }
> +    if ((word & 0x3) == 0) {
> +        num += 2;
> +        word >>= 2;
> +    }
> +    if ((word & 0x1) == 0)
> +        num += 1;
> +    return num;
> +}

What's RISC-V-specific about the above? IOW why ...

> +#include <asm-generic/bitops/fls.h>
> +#include <asm-generic/bitops/flsl.h>
> +#include <asm-generic/bitops/ffs.h>
> +#include <asm-generic/bitops/ffz.h>

... can't those two also come from respective generic headers?

> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/bitops-bits.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
> +#define _ASM_GENERIC_BITOPS_BITS_H_
> +
> +#define BITOP_BITS_PER_WORD     32
> +#define BITOP_MASK(nr)          (1UL << ((nr) % BITOP_BITS_PER_WORD))

Why 1UL and not just 1U, when bits per word is 32?

> +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
> +#define BITS_PER_BYTE           8
> +
> +#endif /* _ASM_GENERIC_BITOPS_BITS_H_ */
> \ No newline at end of file

Nit: I did comment on such before (and there's at least one more
further down).

> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/ffs.h
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_FFS_H_
> +#define _ASM_GENERIC_BITOPS_FFS_H_
> +
> +#include <xen/macros.h>
> +
> +#define ffs(x) ({ unsigned int t_ = (x); fls(ISOLATE_LSB(t_)); })
> +
> +#endif /* _ASM_GENERIC_BITOPS_FFS_H_ */
> diff --git a/xen/include/asm-generic/bitops/ffz.h b/xen/include/asm-generic/bitops/ffz.h
> new file mode 100644
> index 0000000000..92c35455d5
> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/ffz.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
> +#define _ASM_GENERIC_BITOPS_FFZ_H_
> +
> +/*
> + * ffz - find first zero in word.
> + * @word: The word to search
> + *
> + * Undefined if no zero exists, so code should check against ~0UL first.
> + */
> +#define ffz(x)  __ffs(~(x))

For a generic header I'd like to see consistency: ffz() may expand to
ffs(), and __ffz() may expand to __ffs(). A mix like you have it above
wants at least explaining in the description. (I don't understand
anyway why both ffs() and __ffs() would be needed. We don't have any
__ffs() on x86 afaics.)

> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/find-first-bit-set.h

This file name, if it really needs to be this long, wants to match ...

> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_
> +#define _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_
> +
> +/**
> + * find_first_set_bit - find the first set bit in @word
> + * @word: the word to search
> + *
> + * Returns the bit-number of the first set bit (first bit being 0).
> + * The input must *not* be zero.
> + */
> +static inline unsigned int find_first_set_bit(unsigned long word)

... the function implemented herein.

> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/fls.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_FLS_H_
> +#define _ASM_GENERIC_BITOPS_FLS_H_
> +
> +/**
> + * fls - find last (most-significant) bit set
> + * @x: the word to search
> + *
> + * This is defined the same way as ffs.
> + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
> + */
> +
> +static inline int fls(unsigned int x)
> +{
> +    return generic_fls(x);
> +}

Seing this, why would e.g. ffsl() not use generic_ffsl() then?

> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/hweight.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
> +#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
> +
> +/*
> + * hweightN - returns the hamming weight of a N-bit word
> + * @x: the word to weigh
> + *
> + * The Hamming Weight of a number is the total number of bits set in it.
> + */
> +#define hweight64(x) generic_hweight64(x)
> +
> +#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */

Do we really need this? An arch not having suitable insns (RISC-V has,
iirc) can easily have this one #define (or the ip to four ones when
also covering the other widths) in its asm header.

> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/test-bit.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_TESTBIT_H_
> +#define _ASM_GENERIC_BITOPS_TESTBIT_H_
> +
> +/**
> + * test_bit - Determine whether a bit is set
> + * @nr: bit number to test
> + * @addr: Address to start counting from
> + */
> +static inline int test_bit(int nr, const volatile void *addr)
> +{
> +    const volatile unsigned int *p = addr;

With BITOP_BITS_PER_WORD I think you really mean uint32_t here.
Also you want to make sure asm-generic/bitops/bitops-bits.h is
really in use here, or else an arch overriding / not using that
header may end up screwed.

Jan

> +    return 1 & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD - 1)));
> +}
> +
> +#endif /* _ASM_GENERIC_BITOPS_TESTBIT_H_ */
> \ No newline at end of file



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

* Re: [PATCH v3 14/34] xen/riscv: introduce io.h
  2023-12-22 15:12 ` [PATCH v3 14/34] xen/riscv: introduce io.h Oleksii Kurochko
@ 2024-01-15 16:57   ` Jan Beulich
  2024-01-16 15:20     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-15 16:57 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/io.h
> @@ -0,0 +1,142 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * {read,write}{b,w,l,q} based on arch/arm64/include/asm/io.h
> + *   which was based on arch/arm/include/io.h
> + *
> + * Copyright (C) 1996-2000 Russell King
> + * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2014 Regents of the University of California
> + */
> +
> +
> +#ifndef _ASM_RISCV_IO_H
> +#define _ASM_RISCV_IO_H
> +
> +#include <asm/byteorder.h>
> +
> +/*
> + * The RISC-V ISA doesn't yet specify how to query or modify PMAs, so we can't
> + * change the properties of memory regions.  This should be fixed by the
> + * upcoming platform spec.
> + */
> +#define ioremap_nocache(addr, size) ioremap((addr), (size))
> +#define ioremap_wc(addr, size) ioremap((addr), (size))
> +#define ioremap_wt(addr, size) ioremap((addr), (size))

Nit: No need for the inner parentheses.

> +/* Generic IO read/write.  These perform native-endian accesses. */
> +#define __raw_writeb __raw_writeb
> +static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
> +{
> +	asm volatile("sb %0, 0(%1)" : : "r" (val), "r" (addr));
> +}
> +
> +#define __raw_writew __raw_writew
> +static inline void __raw_writew(u16 val, volatile void __iomem *addr)
> +{
> +	asm volatile("sh %0, 0(%1)" : : "r" (val), "r" (addr));
> +}
> +
> +#define __raw_writel __raw_writel
> +static inline void __raw_writel(u32 val, volatile void __iomem *addr)
> +{
> +	asm volatile("sw %0, 0(%1)" : : "r" (val), "r" (addr));
> +}
> +
> +#ifdef CONFIG_64BIT
> +#define __raw_writeq __raw_writeq
> +static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
> +{
> +	asm volatile("sd %0, 0(%1)" : : "r" (val), "r" (addr));
> +}
> +#endif
> +
> +#define __raw_readb __raw_readb
> +static inline u8 __raw_readb(const volatile void __iomem *addr)
> +{
> +	u8 val;
> +
> +	asm volatile("lb %0, 0(%1)" : "=r" (val) : "r" (addr));
> +	return val;
> +}
> +
> +#define __raw_readw __raw_readw
> +static inline u16 __raw_readw(const volatile void __iomem *addr)
> +{
> +	u16 val;
> +
> +	asm volatile("lh %0, 0(%1)" : "=r" (val) : "r" (addr));
> +	return val;
> +}
> +
> +#define __raw_readl __raw_readl
> +static inline u32 __raw_readl(const volatile void __iomem *addr)
> +{
> +	u32 val;
> +
> +	asm volatile("lw %0, 0(%1)" : "=r" (val) : "r" (addr));
> +	return val;
> +}
> +
> +#ifdef CONFIG_64BIT
> +#define __raw_readq __raw_readq
> +static inline u64 __raw_readq(const volatile void __iomem *addr)
> +{
> +	u64 val;
> +
> +	asm volatile("ld %0, 0(%1)" : "=r" (val) : "r" (addr));
> +	return val;
> +}
> +#endif
> +
> +/*
> + * Unordered I/O memory access primitives.  These are even more relaxed than
> + * the relaxed versions, as they don't even order accesses between successive
> + * operations to the I/O regions.
> + */
> +#define readb_cpu(c)		({ u8  __r = __raw_readb(c); __r; })
> +#define readw_cpu(c)		({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
> +#define readl_cpu(c)		({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
> +
> +#define writeb_cpu(v,c)		((void)__raw_writeb((v),(c)))
> +#define writew_cpu(v,c)		((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
> +#define writel_cpu(v,c)		((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
> +
> +#ifdef CONFIG_64BIT
> +#define readq_cpu(c)		({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
> +#define writeq_cpu(v,c)		((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
> +#endif

How come there are endianness assumptions here on the MMIO accessed?

As a file-wide remark: While I don't mind you using u<N> here for now,
presumably to stay close to Linux, eventually - as we make progress with
the conversion to uint<N>_t - this will need to diverge anyway.

> +/*
> + * I/O memory access primitives. Reads are ordered relative to any
> + * following Normal memory access. Writes are ordered relative to any prior
> + * Normal memory access.  The memory barriers here are necessary as RISC-V
> + * doesn't define any ordering between the memory space and the I/O space.
> + */
> +#define __io_br()	do {} while (0)

Nit: Why are this and ...

> +#define __io_ar(v)	__asm__ __volatile__ ("fence i,r" : : : "memory");
> +#define __io_bw()	__asm__ __volatile__ ("fence w,o" : : : "memory");
> +#define __io_aw()	do { } while (0)

... this not expanding exactly the same?

Jan


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

* Re: [PATCH v3 22/34] xen/riscv: introduce regs.h
  2023-12-22 15:13 ` [PATCH v3 22/34] xen/riscv: introduce regs.h Oleksii Kurochko
@ 2024-01-15 17:00   ` Jan Beulich
  2024-01-16  9:46     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-15 17:00 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - update the commit message
>  - add Acked-by: Jan Beulich <jbeulich@suse.com>

I see none above the --- marker.

Jan


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-15 11:01       ` Jan Beulich
@ 2024-01-16  9:44         ` Oleksii
  2024-01-16 17:12           ` Julien Grall
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-16  9:44 UTC (permalink / raw
  To: Jan Beulich
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel, Julien Grall

On Mon, 2024-01-15 at 12:01 +0100, Jan Beulich wrote:
> On 15.01.2024 11:35, Oleksii wrote:
> > Hi Julien,
> > 
> > On Fri, 2024-01-12 at 10:39 +0000, Julien Grall wrote:
> > > Hi Oleksii,
> > > 
> > > On 22/12/2023 15:13, Oleksii Kurochko wrote:
> > > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > > ---
> > > > Changes in V3:
> > > >   - add SPDX
> > > >   - drop unneeded for now p2m types.
> > > >   - return false in all functions implemented with BUG()
> > > > inside.
> > > >   - update the commit message
> > > > ---
> > > > Changes in V2:
> > > >   - Nothing changed. Only rebase.
> > > > ---
> > > >   xen/arch/ppc/include/asm/p2m.h   |   3 +-
> > > >   xen/arch/riscv/include/asm/p2m.h | 102
> > > > +++++++++++++++++++++++++++++++
> > > >   2 files changed, 103 insertions(+), 2 deletions(-)
> > > >   create mode 100644 xen/arch/riscv/include/asm/p2m.h
> > > > 
> > > > diff --git a/xen/arch/ppc/include/asm/p2m.h
> > > > b/xen/arch/ppc/include/asm/p2m.h
> > > > index 25ba054668..3bc05b7c05 100644
> > > > --- a/xen/arch/ppc/include/asm/p2m.h
> > > > +++ b/xen/arch/ppc/include/asm/p2m.h
> > > > @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct
> > > > domain *d)
> > > >   static inline int
> > > > guest_physmap_mark_populate_on_demand(struct
> > > > domain *d, unsigned long gfn,
> > > >                                                          
> > > > unsigned
> > > > int order)
> > > >   {
> > > > -    BUG_ON("unimplemented");
> > > > -    return 1;
> > > > +    return -EOPNOTSUPP;
> > > >   }
> > > >   
> > > >   static inline int guest_physmap_add_entry(struct domain *d,
> > > > diff --git a/xen/arch/riscv/include/asm/p2m.h
> > > > b/xen/arch/riscv/include/asm/p2m.h
> > > > new file mode 100644
> > > > index 0000000000..d270ef6635
> > > > --- /dev/null
> > > > +++ b/xen/arch/riscv/include/asm/p2m.h
> > > > @@ -0,0 +1,102 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > +#ifndef __ASM_RISCV_P2M_H__
> > > > +#define __ASM_RISCV_P2M_H__
> > > > +
> > > > +#include <asm/page-bits.h>
> > > > +
> > > > +#define paddr_bits PADDR_BITS
> > > > +
> > > > +/*
> > > > + * List of possible type for each page in the p2m entry.
> > > > + * The number of available bit per page in the pte for this
> > > > purpose is 4 bits.
> > > > + * So it's possible to only have 16 fields. If we run out of
> > > > value
> > > > in the
> > > > + * future, it's possible to use higher value for pseudo-type
> > > > and
> > > > don't store
> > > > + * them in the p2m entry.
> > > > + */
> > > 
> > > This looks like a verbatim copy from Arm. Did you actually check
> > > RISC-V 
> > > has 4 bits available in the PTE to store this value?
> > Thanks for noticing that, in RISC-V it is available only 2 bits (
> > bits
> > 8 and 9), so I'll update the comment:
> > 53                   10 9    8 7 6 5 4 3 2 1 0
> >  Physical Page Number     RSV  D A G U X W R V
> 
> It's RSW (Reserved for Supervisor softWare use), not RSV, which is
> pretty
> important in this context.
Yes, you are right it is RSW. Thanks for the correction.

> 
> > It seems that I missed something in the Arm code/architecture.As
> > far as I recall, in Arm, bits 5-8 are ignored by the MMU, and they
> > are expected
> > to be used by the hypervisor for its purpose.
> > However, in the code, I notice that these bits are utilized for
> > storing
> > a reference counter.
> 
> Why "however"? Hardware still is going to ignore these bits.
Sure, these bits are ignored by hardware. What I meant is that,
according to the code, these bits are used for storing a reference
counter, not p2m_type_t. I guess I am missing something...

~ Oleksii


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

* Re: [PATCH v3 22/34] xen/riscv: introduce regs.h
  2024-01-15 17:00   ` Jan Beulich
@ 2024-01-16  9:46     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-16  9:46 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-01-15 at 18:00 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - update the commit message
> >  - add Acked-by: Jan Beulich <jbeulich@suse.com>
> 
> I see none above the --- marker.
Thanks for noticing. I'll add in the next patch version.

~ Oleksii


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-15 16:44   ` Jan Beulich
@ 2024-01-16 13:06     ` Oleksii
  2024-01-16 13:24       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-16 13:06 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-01-15 at 17:44 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/bitops.h
> > @@ -0,0 +1,267 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/* Copyright (C) 2012 Regents of the University of California */
> > +
> > +#ifndef _ASM_RISCV_BITOPS_H
> > +#define _ASM_RISCV_BITOPS_H
> > +
> > +#include <asm/system.h>
> > +
> > +#include <asm-generic/bitops/bitops-bits.h>
> > +
> > +/* Based on linux/arch/include/linux/bits.h */
> > +
> > +#define BIT_MASK(nr)        (1UL << ((nr) % BITS_PER_LONG))
> > +#define BIT_WORD(nr)        ((nr) / BITS_PER_LONG)
> > +
> > +#define __set_bit(n,p)      set_bit(n,p)
> > +#define __clear_bit(n,p)    clear_bit(n,p)
> > +
> > +/* Based on linux/arch/include/asm/bitops.h */
> > +
> > +#if ( BITS_PER_LONG == 64 )
> > +#define __AMO(op)   "amo" #op ".d"
> > +#elif ( BITS_PER_LONG == 32 )
> > +#define __AMO(op)   "amo" #op ".w"
> > +#else
> > +#error "Unexpected BITS_PER_LONG"
> > +#endif
> > +
> > +#define __test_and_op_bit_ord(op, mod, nr, addr, ord)		\
> > +({								\
> > +    unsigned long __res, __mask;				\
> > +    __mask = BIT_MASK(nr);					\
> > +    __asm__ __volatile__ (					\
> > +        __AMO(op) #ord " %0, %2, %1"			\
> > +        : "=r" (__res), "+A" (addr[BIT_WORD(nr)])	\
> > +        : "r" (mod(__mask))				\
> > +        : "memory");					\
> > +    ((__res & __mask) != 0);				\
> > +})
> 
> Despite the taking from Linux I think the overall result wants to be
> consistent formatting-wise: You switched to blank indentation (which
> is fine), but you left tabs as padding for the line continuation
> characters.
I think it is because of my IDE. I will be consistent in next patch
version.

Thanks.

> 
> > +#define __op_bit_ord(op, mod, nr, addr, ord)			\
> > +    __asm__ __volatile__ (					\
> > +        __AMO(op) #ord " zero, %1, %0"			\
> > +        : "+A" (addr[BIT_WORD(nr)])			\
> > +        : "r" (mod(BIT_MASK(nr)))			\
> > +        : "memory");
> > +
> > +#define __test_and_op_bit(op, mod, nr, addr) 			\
> 
> (At least) here you even use a mix.
> 
> > +    __test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
> > +#define __op_bit(op, mod, nr, addr)				\
> > +    __op_bit_ord(op, mod, nr, addr, )
> > +
> > +/* Bitmask modifiers */
> > +#define __NOP(x)	(x)
> > +#define __NOT(x)	(~(x))
> > +
> > +/**
> > + * __test_and_set_bit - Set a bit and return its old value
> > + * @nr: Bit to set
> > + * @addr: Address to count from
> > + *
> > + * This operation may be reordered on other architectures than
> > x86.
> > + */
> > +static inline int __test_and_set_bit(int nr, volatile void *p)
> > +{
> > +    volatile uint32_t *addr = p;
> > +
> > +    return __test_and_op_bit(or, __NOP, nr, addr);
> > +}
> > +
> > +/**
> > + * __test_and_clear_bit - Clear a bit and return its old value
> > + * @nr: Bit to clear
> > + * @addr: Address to count from
> > + *
> > + * This operation can be reordered on other architectures other
> > than x86.
> > + */
> > +static inline int __test_and_clear_bit(int nr, volatile void *p)
> > +{
> > +    volatile uint32_t *addr = p;
> > +
> > +    return __test_and_op_bit(and, __NOT, nr, addr);
> > +}
> > +
> > +/**
> > + * set_bit - Atomically set a bit in memory
> > + * @nr: the bit to set
> > + * @addr: the address to start counting from
> > + *
> > + * Note: there are no guarantees that this function will not be
> > reordered
> > + * on non x86 architectures, so if you are writing portable code,
> > + * make sure not to rely on its reordering guarantees.
> > + *
> > + * Note that @nr may be almost arbitrarily large; this function is
> > not
> > + * restricted to acting on a single-word quantity.
> > + */
> > +static inline void set_bit(int nr, volatile void *p)
> > +{
> > +    volatile uint32_t *addr = p;
> > +
> > +    __op_bit(or, __NOP, nr, addr);
> > +}
> > +
> > +/**
> > + * clear_bit - Clears a bit in memory
> > + * @nr: Bit to clear
> > + * @addr: Address to start counting from
> > + *
> > + * Note: there are no guarantees that this function will not be
> > reordered
> > + * on non x86 architectures, so if you are writing portable code,
> > + * make sure not to rely on its reordering guarantees.
> > + */
> > +static inline void clear_bit(int nr, volatile void *p)
> > +{
> > +    volatile uint32_t *addr = p;
> > +
> > +    __op_bit(and, __NOT, nr, addr);
> > +}
> > +
> > +#undef __test_and_op_bit
> > +#undef __op_bit
> > +#undef __NOP
> > +#undef __NOT
> > +#undef __AMO
> > +
> > +#define test_and_set_bit   __test_and_set_bit
> > +#define test_and_clear_bit __test_and_clear_bit
> 
> I realize test-and-change have no present users, despite being made
> available by Arm and x86, but I think they would better be provided
> right away, rather than someone introducing a use then needing to
> fiddle with RISC-V (and apparently also PPC) code.
Sure, it makes sense. I'll add test-and-change too.

> 
> I'm also puzzled by this aliasing: Aren't there cheaper non-atomic
> insn forms that could be used for the double-underscore-prefixed
> variants?
It will be cheaper, but I assume that this API should be safe in the
case of SMP where different CPUs can access the same variable or
similar cases with simultaneous access to the variable.

> 
> > +/* Based on linux/include/asm-generic/bitops/find.h */
> > +
> > +#ifndef find_next_bit
> 
> What is this to guard against?
This was copied from Linux, but in case of Xen it can be dropped.

> 
> > +/**
> > + * find_next_bit - find the next set bit in a memory region
> > + * @addr: The address to base the search on
> > + * @offset: The bitnumber to start searching at
> > + * @size: The bitmap size in bits
> > + */
> > +extern unsigned long find_next_bit(const unsigned long *addr,
> > unsigned long
> > +        size, unsigned long offset);
> > +#endif
> > +
> > +#ifndef find_next_zero_bit
> > +/**
> > + * find_next_zero_bit - find the next cleared bit in a memory
> > region
> > + * @addr: The address to base the search on
> > + * @offset: The bitnumber to start searching at
> > + * @size: The bitmap size in bits
> > + */
> > +extern unsigned long find_next_zero_bit(const unsigned long *addr,
> > unsigned
> > +        long size, unsigned long offset);
> > +#endif
> > +
> > +/**
> > + * find_first_bit - find the first set bit in a memory region
> > + * @addr: The address to start the search at
> > + * @size: The maximum size to search
> > + *
> > + * Returns the bit number of the first set bit.
> > + */
> > +extern unsigned long find_first_bit(const unsigned long *addr,
> > +                    unsigned long size);
> > +
> > +/**
> > + * find_first_zero_bit - find the first cleared bit in a memory
> > region
> > + * @addr: The address to start the search at
> > + * @size: The maximum size to search
> > + *
> > + * Returns the bit number of the first cleared bit.
> > + */
> > +extern unsigned long find_first_zero_bit(const unsigned long
> > *addr,
> > +                     unsigned long size);
> > +
> > +/**
> > + * ffs - find first bit in word.
> > + * @word: The word to search
> > + *
> > + * Returns 0 if no bit exists, otherwise returns 1-indexed bit
> > location.
> > + */
> > +static inline unsigned long __ffs(unsigned long word)
> > +{
> > +    int num = 0;
> 
> I understand it's this way in Linux, so there may be reasons to keep
> it
> like that. Generally though we'd prefer unsigned here, and the type
> of
> a variable used for the return value of a function would also better
> be
> in sync with the function's return type (which I don't think needs to
> be "unsigned long" either; "unsigned int" would apparently suffice).
> 
> > +#if BITS_PER_LONG == 64
> > +    if ((word & 0xffffffff) == 0) {
> > +        num += 32;
> > +        word >>= 32;
> > +    }
> 
> You're ending up with neither Xen nor Linux style this way. May I
> suggest to settle on either?

Will it fine to rework header from Linux to Xen style? Does it make
sense?
I think this file can be reworked to Xen style as I don't expect that
it will be changed since it will be merged.

> 
> > +#endif
> > +    if ((word & 0xffff) == 0) {
> > +        num += 16;
> > +        word >>= 16;
> > +    }
> > +    if ((word & 0xff) == 0) {
> > +        num += 8;
> > +        word >>= 8;
> > +    }
> > +    if ((word & 0xf) == 0) {
> > +        num += 4;
> > +        word >>= 4;
> > +    }
> > +    if ((word & 0x3) == 0) {
> > +        num += 2;
> > +        word >>= 2;
> > +    }
> > +    if ((word & 0x1) == 0)
> > +        num += 1;
> > +    return num;
> > +}
> > +
> > +/**
> > + * ffsl - find first bit in long.
> > + * @word: The word to search
> > + *
> > + * Returns 0 if no bit exists, otherwise returns 1-indexed bit
> > location.
> > + */
> > +static inline unsigned int ffsl(unsigned long word)
> > +{
> > +    int num = 1;
> > +
> > +    if (!word)
> > +        return 0;
> > +
> > +#if BITS_PER_LONG == 64
> > +    if ((word & 0xffffffff) == 0) {
> > +        num += 32;
> > +        word >>= 32;
> > +    }
> > +#endif
> > +    if ((word & 0xffff) == 0) {
> > +        num += 16;
> > +        word >>= 16;
> > +    }
> > +    if ((word & 0xff) == 0) {
> > +        num += 8;
> > +        word >>= 8;
> > +    }
> > +    if ((word & 0xf) == 0) {
> > +        num += 4;
> > +        word >>= 4;
> > +    }
> > +    if ((word & 0x3) == 0) {
> > +        num += 2;
> > +        word >>= 2;
> > +    }
> > +    if ((word & 0x1) == 0)
> > +        num += 1;
> > +    return num;
> > +}
> 
> What's RISC-V-specific about the above? IOW why ...
> 
> > +#include <asm-generic/bitops/fls.h>
> > +#include <asm-generic/bitops/flsl.h>
> > +#include <asm-generic/bitops/ffs.h>
> > +#include <asm-generic/bitops/ffz.h>
> 
> ... can't those two also come from respective generic headers?
Sure it can. Originally, I don't introduce it as generic headers
because RISC-V is only one who isn using C generic version.

I found that there is already present such generic function in
xen/bitops.h. I think it makes sense to re-use them.

> 
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/bitops-bits.h
> > @@ -0,0 +1,10 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
> > +#define _ASM_GENERIC_BITOPS_BITS_H_
> > +
> > +#define BITOP_BITS_PER_WORD     32
> > +#define BITOP_MASK(nr)          (1UL << ((nr) %
> > BITOP_BITS_PER_WORD))
> 
> Why 1UL and not just 1U, when bits per word is 32?
There is no specific reason, should 1U. ( I originally used
BITOPS_BITS_PER_LONG ) and with introduction of asm-generic bitops
decided to follow what other archs provide.

Regarding to the second part of the question, I don't understand it
fully. Considering BITOP_BIT_PER_WORD definition for other archs ( ARM
and PPC ) it is expected that word is 32 bits.

> 
> > +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
> > +#define BITS_PER_BYTE           8
> > +
> > +#endif /* _ASM_GENERIC_BITOPS_BITS_H_ */
> > \ No newline at end of file
> 
> Nit: I did comment on such before (and there's at least one more
> further down).
Thanks.
I'll add a newline.

> 
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/ffs.h
> > @@ -0,0 +1,9 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_FFS_H_
> > +#define _ASM_GENERIC_BITOPS_FFS_H_
> > +
> > +#include <xen/macros.h>
> > +
> > +#define ffs(x) ({ unsigned int t_ = (x); fls(ISOLATE_LSB(t_)); })
> > +
> > +#endif /* _ASM_GENERIC_BITOPS_FFS_H_ */
> > diff --git a/xen/include/asm-generic/bitops/ffz.h
> > b/xen/include/asm-generic/bitops/ffz.h
> > new file mode 100644
> > index 0000000000..92c35455d5
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/ffz.h
> > @@ -0,0 +1,13 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
> > +#define _ASM_GENERIC_BITOPS_FFZ_H_
> > +
> > +/*
> > + * ffz - find first zero in word.
> > + * @word: The word to search
> > + *
> > + * Undefined if no zero exists, so code should check against ~0UL
> > first.
> > + */
> > +#define ffz(x)  __ffs(~(x))
> 
> For a generic header I'd like to see consistency: ffz() may expand to
> ffs(), and __ffz() may expand to __ffs(). A mix like you have it
> above
> wants at least explaining in the description. (I don't understand
> anyway why both ffs() and __ffs() would be needed. We don't have any
> __ffs() on x86 afaics.)
Then it looks to me that ffs() should be used instead.
ffz() was defined with __ffs() because Arm and PPC are defined so.
> 
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/find-first-bit-set.h
> 
> This file name, if it really needs to be this long, wants to match
> ...
> 
> > @@ -0,0 +1,17 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_
> > +#define _ASM_GENERIC_BITOPS_FIND_FIRST_BIT_SET_H_
> > +
> > +/**
> > + * find_first_set_bit - find the first set bit in @word
> > + * @word: the word to search
> > + *
> > + * Returns the bit-number of the first set bit (first bit being
> > 0).
> > + * The input must *not* be zero.
> > + */
> > +static inline unsigned int find_first_set_bit(unsigned long word)
> 
> ... the function implemented herein.
Thanks. I'll update the file name.
> 
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/fls.h
> > @@ -0,0 +1,18 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_FLS_H_
> > +#define _ASM_GENERIC_BITOPS_FLS_H_
> > +
> > +/**
> > + * fls - find last (most-significant) bit set
> > + * @x: the word to search
> > + *
> > + * This is defined the same way as ffs.
> > + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
> > + */
> > +
> > +static inline int fls(unsigned int x)
> > +{
> > +    return generic_fls(x);
> > +}
> 
> Seing this, why would e.g. ffsl() not use generic_ffsl() then?
> 
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/hweight.h
> > @@ -0,0 +1,13 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
> > +#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
> > +
> > +/*
> > + * hweightN - returns the hamming weight of a N-bit word
> > + * @x: the word to weigh
> > + *
> > + * The Hamming Weight of a number is the total number of bits set
> > in it.
> > + */
> > +#define hweight64(x) generic_hweight64(x)
> > +
> > +#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
> 
> Do we really need this? An arch not having suitable insns (RISC-V
> has,
> iirc) can easily have this one #define (or the ip to four ones when
> also covering the other widths) in its asm header.
> 
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/test-bit.h
> > @@ -0,0 +1,16 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_TESTBIT_H_
> > +#define _ASM_GENERIC_BITOPS_TESTBIT_H_
> > +
> > +/**
> > + * test_bit - Determine whether a bit is set
> > + * @nr: bit number to test
> > + * @addr: Address to start counting from
> > + */
> > +static inline int test_bit(int nr, const volatile void *addr)
> > +{
> > +    const volatile unsigned int *p = addr;
> 
> With BITOP_BITS_PER_WORD I think you really mean uint32_t here.
Isn't it the same: 'unsigned int' and 'uint32_t'?

> Also you want to make sure asm-generic/bitops/bitops-bits.h is
> really in use here, or else an arch overriding / not using that
> header may end up screwed.
I am not really understand what do you mean. Could you please explain a
little bit more.

~ Oleksii
> 
> Jan
> 
> > +    return 1 & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD -
> > 1)));
> > +}
> > +
> > +#endif /* _ASM_GENERIC_BITOPS_TESTBIT_H_ */
> > \ No newline at end of file
> 



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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-16 13:06     ` Oleksii
@ 2024-01-16 13:24       ` Jan Beulich
  2024-01-17 11:13         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-16 13:24 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 16.01.2024 14:06, Oleksii wrote:
> On Mon, 2024-01-15 at 17:44 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>> +#define test_and_set_bit   __test_and_set_bit
>>> +#define test_and_clear_bit __test_and_clear_bit
>>
>> I realize test-and-change have no present users, despite being made
>> available by Arm and x86, but I think they would better be provided
>> right away, rather than someone introducing a use then needing to
>> fiddle with RISC-V (and apparently also PPC) code.
> Sure, it makes sense. I'll add test-and-change too.
> 
>> I'm also puzzled by this aliasing: Aren't there cheaper non-atomic
>> insn forms that could be used for the double-underscore-prefixed
>> variants?
> It will be cheaper, but I assume that this API should be safe in the
> case of SMP where different CPUs can access the same variable or
> similar cases with simultaneous access to the variable.

Of course, that's what test_and_...() are for. __test_and_...() are
for cases where there's no concurrency, when hence the cheaper forms
can be used. Thus my asking about the aliasing done above.

>>> +#if BITS_PER_LONG == 64
>>> +    if ((word & 0xffffffff) == 0) {
>>> +        num += 32;
>>> +        word >>= 32;
>>> +    }
>>
>> You're ending up with neither Xen nor Linux style this way. May I
>> suggest to settle on either?
> 
> Will it fine to rework header from Linux to Xen style? Does it make
> sense?
> I think this file can be reworked to Xen style as I don't expect that
> it will be changed since it will be merged.

You may keep Linux style or fully switch to Xen style - which one is
largely up to you. All I'm asking is to avoid introducing further
mixed-style source files.

>>> --- /dev/null
>>> +++ b/xen/include/asm-generic/bitops/bitops-bits.h
>>> @@ -0,0 +1,10 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
>>> +#define _ASM_GENERIC_BITOPS_BITS_H_
>>> +
>>> +#define BITOP_BITS_PER_WORD     32
>>> +#define BITOP_MASK(nr)          (1UL << ((nr) %
>>> BITOP_BITS_PER_WORD))
>>
>> Why 1UL and not just 1U, when bits per word is 32?
> There is no specific reason, should 1U. ( I originally used
> BITOPS_BITS_PER_LONG ) and with introduction of asm-generic bitops
> decided to follow what other archs provide.
> 
> Regarding to the second part of the question, I don't understand it
> fully. Considering BITOP_BIT_PER_WORD definition for other archs ( ARM
> and PPC ) it is expected that word is 32 bits.

The 2nd part was explaining why I'm asking. It wasn't another question.

>>> --- /dev/null
>>> +++ b/xen/include/asm-generic/bitops/test-bit.h
>>> @@ -0,0 +1,16 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +#ifndef _ASM_GENERIC_BITOPS_TESTBIT_H_
>>> +#define _ASM_GENERIC_BITOPS_TESTBIT_H_
>>> +
>>> +/**
>>> + * test_bit - Determine whether a bit is set
>>> + * @nr: bit number to test
>>> + * @addr: Address to start counting from
>>> + */
>>> +static inline int test_bit(int nr, const volatile void *addr)
>>> +{
>>> +    const volatile unsigned int *p = addr;
>>
>> With BITOP_BITS_PER_WORD I think you really mean uint32_t here.
> Isn't it the same: 'unsigned int' and 'uint32_t'?

No, or else there wouldn't have been a need to introduce uint<N>_t (and
others) in C99. It just so happens that right now all architectures Xen
can be built for have sizeof(int) == 4 and CHAR_BITS == 8. In an arch-
specific header I would see this as less of an issue, but in a generic
header we'd better avoid encoding wrong assumptions. The one assumption
we generally make is that sizeof(int) >= 4 and CHAR_BITS >= 8 (albeit I
bet really in various places we assume CHAR_BITS == 8).

>> Also you want to make sure asm-generic/bitops/bitops-bits.h is
>> really in use here, or else an arch overriding / not using that
>> header may end up screwed.
> I am not really understand what do you mean. Could you please explain a
> little bit more.

Whichever type you use here, it needs to be in sync with
BITOP_BITS_PER_WORD. Hence you want to include the _local_ bitops-bits.h
here, such that in case of an inconsistent override by an arch the
compiler would complain about the two differring #define-s. (IOW an
arch overriding BITOP_BITS_PER_WORD cannot re-use this header as-is.)

The same may, btw, be true for others of the new headers you add - the
same #include would therefore be needed there as well.

Jan


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

* Re: [PATCH v3 14/34] xen/riscv: introduce io.h
  2024-01-15 16:57   ` Jan Beulich
@ 2024-01-16 15:20     ` Oleksii
  2024-01-16 16:09       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-16 15:20 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-01-15 at 17:57 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/io.h
> > @@ -0,0 +1,142 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * {read,write}{b,w,l,q} based on arch/arm64/include/asm/io.h
> > + *   which was based on arch/arm/include/io.h
> > + *
> > + * Copyright (C) 1996-2000 Russell King
> > + * Copyright (C) 2012 ARM Ltd.
> > + * Copyright (C) 2014 Regents of the University of California
> > + */
> > +
> > +
> > +#ifndef _ASM_RISCV_IO_H
> > +#define _ASM_RISCV_IO_H
> > +
> > +#include <asm/byteorder.h>
> > +
> > +/*
> > + * The RISC-V ISA doesn't yet specify how to query or modify PMAs,
> > so we can't
> > + * change the properties of memory regions.  This should be fixed
> > by the
> > + * upcoming platform spec.
> > + */
> > +#define ioremap_nocache(addr, size) ioremap((addr), (size))
> > +#define ioremap_wc(addr, size) ioremap((addr), (size))
> > +#define ioremap_wt(addr, size) ioremap((addr), (size))
> 
> Nit: No need for the inner parentheses.
Thanks. I'll update that place.

> 
> > +/* Generic IO read/write.  These perform native-endian accesses.
> > */
> > +#define __raw_writeb __raw_writeb
> > +static inline void __raw_writeb(u8 val, volatile void __iomem
> > *addr)
> > +{
> > +	asm volatile("sb %0, 0(%1)" : : "r" (val), "r" (addr));
> > +}
> > +
> > +#define __raw_writew __raw_writew
> > +static inline void __raw_writew(u16 val, volatile void __iomem
> > *addr)
> > +{
> > +	asm volatile("sh %0, 0(%1)" : : "r" (val), "r" (addr));
> > +}
> > +
> > +#define __raw_writel __raw_writel
> > +static inline void __raw_writel(u32 val, volatile void __iomem
> > *addr)
> > +{
> > +	asm volatile("sw %0, 0(%1)" : : "r" (val), "r" (addr));
> > +}
> > +
> > +#ifdef CONFIG_64BIT
> > +#define __raw_writeq __raw_writeq
> > +static inline void __raw_writeq(u64 val, volatile void __iomem
> > *addr)
> > +{
> > +	asm volatile("sd %0, 0(%1)" : : "r" (val), "r" (addr));
> > +}
> > +#endif
> > +
> > +#define __raw_readb __raw_readb
> > +static inline u8 __raw_readb(const volatile void __iomem *addr)
> > +{
> > +	u8 val;
> > +
> > +	asm volatile("lb %0, 0(%1)" : "=r" (val) : "r" (addr));
> > +	return val;
> > +}
> > +
> > +#define __raw_readw __raw_readw
> > +static inline u16 __raw_readw(const volatile void __iomem *addr)
> > +{
> > +	u16 val;
> > +
> > +	asm volatile("lh %0, 0(%1)" : "=r" (val) : "r" (addr));
> > +	return val;
> > +}
> > +
> > +#define __raw_readl __raw_readl
> > +static inline u32 __raw_readl(const volatile void __iomem *addr)
> > +{
> > +	u32 val;
> > +
> > +	asm volatile("lw %0, 0(%1)" : "=r" (val) : "r" (addr));
> > +	return val;
> > +}
> > +
> > +#ifdef CONFIG_64BIT
> > +#define __raw_readq __raw_readq
> > +static inline u64 __raw_readq(const volatile void __iomem *addr)
> > +{
> > +	u64 val;
> > +
> > +	asm volatile("ld %0, 0(%1)" : "=r" (val) : "r" (addr));
> > +	return val;
> > +}
> > +#endif
> > +
> > +/*
> > + * Unordered I/O memory access primitives.  These are even more
> > relaxed than
> > + * the relaxed versions, as they don't even order accesses between
> > successive
> > + * operations to the I/O regions.
> > + */
> > +#define readb_cpu(c)		({ u8  __r = __raw_readb(c); __r;
> > })
> > +#define readw_cpu(c)		({ u16 __r = le16_to_cpu((__force
> > __le16)__raw_readw(c)); __r; })
> > +#define readl_cpu(c)		({ u32 __r = le32_to_cpu((__force
> > __le32)__raw_readl(c)); __r; })
> > +
> > +#define
> > writeb_cpu(v,c)		((void)__raw_writeb((v),(c)))
> > +#define
> > writew_cpu(v,c)		((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
> > +#define
> > writel_cpu(v,c)		((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
> > +
> > +#ifdef CONFIG_64BIT
> > +#define readq_cpu(c)		({ u64 __r = le64_to_cpu((__force
> > __le64)__raw_readq(c)); __r; })
> > +#define
> > writeq_cpu(v,c)		((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
> > +#endif
> 
> How come there are endianness assumptions here on the MMIO accessed?
It is a hard story.

As you might expect it was copy from Linux Kernel where it was decided
to follow only LE way:
https://patchwork.kernel.org/project/linux-riscv/patch/20190411115623.5749-3-hch@lst.de/
One of the answers of the author of the commit:
    And we don't know if Linux will be around if that ever changes.
    The point is:
     a) the current RISC-V spec is LE only
     b) the current linux port is LE only except for this little bit
    There is no point in leaving just this bitrotting code around.  It
    just confuses developers, (very very slightly) slows down compiles
    and will bitrot.  It also won't be any significant help to a future
    developer down the road doing a hypothetical BE RISC-V Linux port.

From the specs [1, p.5 ] it is mentioned that:
   The base ISA has been defined to have a little-endian memory system, 
   with big-endian or bi-endian as non-standard variants.

And in [3, p.6]:
   RISC-V base ISAs have either little-endian or big-endian memory 
   systems, with the privileged architecture further defining bi-endian 
   operation. Instructions are stored in memory as a sequence of 16-bit 
   little-endian parcels, regardless of memory system endianness. Parcels
   forming one instruction are stored at increasing halfword addresses, 
   with the lowest-addressed parcel holding the lowest-numbered bits in 
   the instruction specification.
   
    We originally chose little-endian byte ordering for the RISC-V memory
   system because little-endian systems are currently dominant 
   commercially (all x86 systems; iOS, Android, and Windows for ARM). A 
   minor point is that we have also found little-endian memory systems to
   be more natural for hardware designers. However, certain application 
   areas, such as IP networking, operate on big-endian data structures, 
   and certain legacy code bases have been built assuming big-endian 
   processors, so we have defined big-endian and bi-endian variants of 
   RISC-V.
   
    We have to fix the order in which instruction parcels are stored in 
   memory, independent of memory system endianness, to ensure that the 
   length-encoding bits always appear first in halfword address order. 
   This allows the length of a variable-length instruction to be quickly 
   determined by an instruction-fetch unit by examining only the first few
   bits of the first 16-bit instruction parcel.

[ this part is from source [2] which I can't find in [3] for some
uknown reason ]
   We further make the instruction parcels themselves little-endian to
   decouple the instruction encoding from the memory system endianness
   altogether. This design benefits both software tooling and bi-endian
   hardware. Otherwise, for instance, a RISC-V assembler or disassembler
   would always need to know the intended active endianness, despite that
   in bi-endian systems, the endianness mode might change dynamically
   during execution. In contrast, by giving instructions a fixed
   endianness, it is sometimes possible for carefully written software to
   be endianness-agnostic even in binary form, much like position-
   independent code.
   
   The choice to have instructions be only little-endian does have
   consequences, however, for RISC-V software that encodes or decodes
   machine instructions. Big-endian JIT compilers, for example, must swap
   the byte order when storing to instruction memory.
   
   Once we had decided to fix on a little-endian instruction encoding,
   this naturally led to placing the length-encoding bits in the LSB
   positions of the instruction format to avoid breaking up opcode fields.


[1] https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
[2] https://five-embeddev.com/riscv-isa-manual/latest/intro.html
[3] https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
> 
> As a file-wide remark: While I don't mind you using u<N> here for
> now,
> presumably to stay close to Linux, eventually - as we make progress
> with
> the conversion to uint<N>_t - this will need to diverge anyway.
Then I'll use uint<N>_t everywhere from the start. I am pretty sure
this file doesn't require sync often, so we can use  Xen style instead
of Linux.

> 
> > +/*
> > + * I/O memory access primitives. Reads are ordered relative to any
> > + * following Normal memory access. Writes are ordered relative to
> > any prior
> > + * Normal memory access.  The memory barriers here are necessary
> > as RISC-V
> > + * doesn't define any ordering between the memory space and the
> > I/O space.
> > + */
> > +#define __io_br()	do {} while (0)
> 
> Nit: Why are this and ...
> 
> > +#define __io_ar(v)	__asm__ __volatile__ ("fence i,r" : : :
> > "memory");
> > +#define __io_bw()	__asm__ __volatile__ ("fence w,o" : : :
> > "memory");
> > +#define __io_aw()	do { } while (0)
> 
> ... this not expanding exactly the same?
I don't know the specific reason, it was done so in Linux kernel in
case when CONFIG_MMIOWB isn't supported:
https://elixir.bootlin.com/linux/latest/source/include/asm-generic/mmiowb.h#L61

https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/asm/mmio.h#L136



~ Oleksii


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

* Re: [PATCH v3 14/34] xen/riscv: introduce io.h
  2024-01-16 15:20     ` Oleksii
@ 2024-01-16 16:09       ` Jan Beulich
  2024-01-31 17:30         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-16 16:09 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 16.01.2024 16:20, Oleksii wrote:
> On Mon, 2024-01-15 at 17:57 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>> +/*
>>> + * Unordered I/O memory access primitives.  These are even more
>>> relaxed than
>>> + * the relaxed versions, as they don't even order accesses between
>>> successive
>>> + * operations to the I/O regions.
>>> + */
>>> +#define readb_cpu(c)		({ u8  __r = __raw_readb(c); __r;
>>> })
>>> +#define readw_cpu(c)		({ u16 __r = le16_to_cpu((__force
>>> __le16)__raw_readw(c)); __r; })
>>> +#define readl_cpu(c)		({ u32 __r = le32_to_cpu((__force
>>> __le32)__raw_readl(c)); __r; })
>>> +
>>> +#define
>>> writeb_cpu(v,c)		((void)__raw_writeb((v),(c)))
>>> +#define
>>> writew_cpu(v,c)		((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
>>> +#define
>>> writel_cpu(v,c)		((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
>>> +
>>> +#ifdef CONFIG_64BIT
>>> +#define readq_cpu(c)		({ u64 __r = le64_to_cpu((__force
>>> __le64)__raw_readq(c)); __r; })
>>> +#define
>>> writeq_cpu(v,c)		((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
>>> +#endif
>>
>> How come there are endianness assumptions here on the MMIO accessed?
> It is a hard story.
> 
> As you might expect it was copy from Linux Kernel where it was decided
> to follow only LE way:
> https://patchwork.kernel.org/project/linux-riscv/patch/20190411115623.5749-3-hch@lst.de/
> One of the answers of the author of the commit:
>     And we don't know if Linux will be around if that ever changes.
>     The point is:
>      a) the current RISC-V spec is LE only
>      b) the current linux port is LE only except for this little bit
>     There is no point in leaving just this bitrotting code around.  It
>     just confuses developers, (very very slightly) slows down compiles
>     and will bitrot.  It also won't be any significant help to a future
>     developer down the road doing a hypothetical BE RISC-V Linux port.

Reads to me like a justification to _omit_ the cpu_to_le<N>().

Jan


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-16  9:44         ` Oleksii
@ 2024-01-16 17:12           ` Julien Grall
  2024-01-17  9:32             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Julien Grall @ 2024-01-16 17:12 UTC (permalink / raw
  To: Oleksii, Jan Beulich
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel

Hi Oleksii,

On 16/01/2024 09:44, Oleksii wrote:
> On Mon, 2024-01-15 at 12:01 +0100, Jan Beulich wrote:
>> On 15.01.2024 11:35, Oleksii wrote:
>>> Hi Julien,
>>>
>>> On Fri, 2024-01-12 at 10:39 +0000, Julien Grall wrote:
>>>> Hi Oleksii,
>>>>
>>>> On 22/12/2023 15:13, Oleksii Kurochko wrote:
>>>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>>>> ---
>>>>> Changes in V3:
>>>>>    - add SPDX
>>>>>    - drop unneeded for now p2m types.
>>>>>    - return false in all functions implemented with BUG()
>>>>> inside.
>>>>>    - update the commit message
>>>>> ---
>>>>> Changes in V2:
>>>>>    - Nothing changed. Only rebase.
>>>>> ---
>>>>>    xen/arch/ppc/include/asm/p2m.h   |   3 +-
>>>>>    xen/arch/riscv/include/asm/p2m.h | 102
>>>>> +++++++++++++++++++++++++++++++
>>>>>    2 files changed, 103 insertions(+), 2 deletions(-)
>>>>>    create mode 100644 xen/arch/riscv/include/asm/p2m.h
>>>>>
>>>>> diff --git a/xen/arch/ppc/include/asm/p2m.h
>>>>> b/xen/arch/ppc/include/asm/p2m.h
>>>>> index 25ba054668..3bc05b7c05 100644
>>>>> --- a/xen/arch/ppc/include/asm/p2m.h
>>>>> +++ b/xen/arch/ppc/include/asm/p2m.h
>>>>> @@ -50,8 +50,7 @@ static inline void memory_type_changed(struct
>>>>> domain *d)
>>>>>    static inline int
>>>>> guest_physmap_mark_populate_on_demand(struct
>>>>> domain *d, unsigned long gfn,
>>>>>                                                           
>>>>> unsigned
>>>>> int order)
>>>>>    {
>>>>> -    BUG_ON("unimplemented");
>>>>> -    return 1;
>>>>> +    return -EOPNOTSUPP;
>>>>>    }
>>>>>    
>>>>>    static inline int guest_physmap_add_entry(struct domain *d,
>>>>> diff --git a/xen/arch/riscv/include/asm/p2m.h
>>>>> b/xen/arch/riscv/include/asm/p2m.h
>>>>> new file mode 100644
>>>>> index 0000000000..d270ef6635
>>>>> --- /dev/null
>>>>> +++ b/xen/arch/riscv/include/asm/p2m.h
>>>>> @@ -0,0 +1,102 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>>>> +#ifndef __ASM_RISCV_P2M_H__
>>>>> +#define __ASM_RISCV_P2M_H__
>>>>> +
>>>>> +#include <asm/page-bits.h>
>>>>> +
>>>>> +#define paddr_bits PADDR_BITS
>>>>> +
>>>>> +/*
>>>>> + * List of possible type for each page in the p2m entry.
>>>>> + * The number of available bit per page in the pte for this
>>>>> purpose is 4 bits.
>>>>> + * So it's possible to only have 16 fields. If we run out of
>>>>> value
>>>>> in the
>>>>> + * future, it's possible to use higher value for pseudo-type
>>>>> and
>>>>> don't store
>>>>> + * them in the p2m entry.
>>>>> + */
>>>>
>>>> This looks like a verbatim copy from Arm. Did you actually check
>>>> RISC-V
>>>> has 4 bits available in the PTE to store this value?
>>> Thanks for noticing that, in RISC-V it is available only 2 bits (
>>> bits
>>> 8 and 9), so I'll update the comment:
>>> 53                   10 9    8 7 6 5 4 3 2 1 0
>>>   Physical Page Number     RSV  D A G U X W R V
>>
>> It's RSW (Reserved for Supervisor softWare use), not RSV, which is
>> pretty
>> important in this context.
> Yes, you are right it is RSW. Thanks for the correction.
> 
>>
>>> It seems that I missed something in the Arm code/architecture.As
>>> far as I recall, in Arm, bits 5-8 are ignored by the MMU, and they
>>> are expected
>>> to be used by the hypervisor for its purpose.
>>> However, in the code, I notice that these bits are utilized for
>>> storing
>>> a reference counter.
>>
>> Why "however"? Hardware still is going to ignore these bits.
> Sure, these bits are ignored by hardware. What I meant is that,
> according to the code, these bits are used for storing a reference
> counter, not p2m_type_t. I guess I am missing something...

I can only guess where you saw the field used for reference counting. 
This was the domain map page infrastruture, right?

If so, this is for stage-1 page-table (aka hypervisor table) and not the 
stage-2 (e.g. P2M). For the latter, we would use the p2m_type_t.

Cheers,

-- 
Julien Grall


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

* Re: [PATCH v3 21/34] xen/riscv: introduce p2m.h
  2024-01-16 17:12           ` Julien Grall
@ 2024-01-17  9:32             ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-17  9:32 UTC (permalink / raw
  To: Julien Grall, Jan Beulich
  Cc: Shawn Anastasio, Alistair Francis, Bob Eshleman, Connor Davis,
	xen-devel

Hi Julien,

On Tue, 2024-01-16 at 17:12 +0000, Julien Grall wrote:
> Hi Oleksii,
> 
> On 16/01/2024 09:44, Oleksii wrote:
> > On Mon, 2024-01-15 at 12:01 +0100, Jan Beulich wrote:
> > > On 15.01.2024 11:35, Oleksii wrote:
> > > > Hi Julien,
> > > > 
> > > > On Fri, 2024-01-12 at 10:39 +0000, Julien Grall wrote:
> > > > > Hi Oleksii,
> > > > > 
> > > > > On 22/12/2023 15:13, Oleksii Kurochko wrote:
> > > > > > Signed-off-by: Oleksii Kurochko
> > > > > > <oleksii.kurochko@gmail.com>
> > > > > > ---
> > > > > > Changes in V3:
> > > > > >    - add SPDX
> > > > > >    - drop unneeded for now p2m types.
> > > > > >    - return false in all functions implemented with BUG()
> > > > > > inside.
> > > > > >    - update the commit message
> > > > > > ---
> > > > > > Changes in V2:
> > > > > >    - Nothing changed. Only rebase.
> > > > > > ---
> > > > > >    xen/arch/ppc/include/asm/p2m.h   |   3 +-
> > > > > >    xen/arch/riscv/include/asm/p2m.h | 102
> > > > > > +++++++++++++++++++++++++++++++
> > > > > >    2 files changed, 103 insertions(+), 2 deletions(-)
> > > > > >    create mode 100644 xen/arch/riscv/include/asm/p2m.h
> > > > > > 
> > > > > > diff --git a/xen/arch/ppc/include/asm/p2m.h
> > > > > > b/xen/arch/ppc/include/asm/p2m.h
> > > > > > index 25ba054668..3bc05b7c05 100644
> > > > > > --- a/xen/arch/ppc/include/asm/p2m.h
> > > > > > +++ b/xen/arch/ppc/include/asm/p2m.h
> > > > > > @@ -50,8 +50,7 @@ static inline void
> > > > > > memory_type_changed(struct
> > > > > > domain *d)
> > > > > >    static inline int
> > > > > > guest_physmap_mark_populate_on_demand(struct
> > > > > > domain *d, unsigned long gfn,
> > > > > >                                                           
> > > > > > unsigned
> > > > > > int order)
> > > > > >    {
> > > > > > -    BUG_ON("unimplemented");
> > > > > > -    return 1;
> > > > > > +    return -EOPNOTSUPP;
> > > > > >    }
> > > > > >    
> > > > > >    static inline int guest_physmap_add_entry(struct domain
> > > > > > *d,
> > > > > > diff --git a/xen/arch/riscv/include/asm/p2m.h
> > > > > > b/xen/arch/riscv/include/asm/p2m.h
> > > > > > new file mode 100644
> > > > > > index 0000000000..d270ef6635
> > > > > > --- /dev/null
> > > > > > +++ b/xen/arch/riscv/include/asm/p2m.h
> > > > > > @@ -0,0 +1,102 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > > > +#ifndef __ASM_RISCV_P2M_H__
> > > > > > +#define __ASM_RISCV_P2M_H__
> > > > > > +
> > > > > > +#include <asm/page-bits.h>
> > > > > > +
> > > > > > +#define paddr_bits PADDR_BITS
> > > > > > +
> > > > > > +/*
> > > > > > + * List of possible type for each page in the p2m entry.
> > > > > > + * The number of available bit per page in the pte for
> > > > > > this
> > > > > > purpose is 4 bits.
> > > > > > + * So it's possible to only have 16 fields. If we run out
> > > > > > of
> > > > > > value
> > > > > > in the
> > > > > > + * future, it's possible to use higher value for pseudo-
> > > > > > type
> > > > > > and
> > > > > > don't store
> > > > > > + * them in the p2m entry.
> > > > > > + */
> > > > > 
> > > > > This looks like a verbatim copy from Arm. Did you actually
> > > > > check
> > > > > RISC-V
> > > > > has 4 bits available in the PTE to store this value?
> > > > Thanks for noticing that, in RISC-V it is available only 2 bits
> > > > (
> > > > bits
> > > > 8 and 9), so I'll update the comment:
> > > > 53                   10 9    8 7 6 5 4 3 2 1 0
> > > >   Physical Page Number     RSV  D A G U X W R V
> > > 
> > > It's RSW (Reserved for Supervisor softWare use), not RSV, which
> > > is
> > > pretty
> > > important in this context.
> > Yes, you are right it is RSW. Thanks for the correction.
> > 
> > > 
> > > > It seems that I missed something in the Arm
> > > > code/architecture.As
> > > > far as I recall, in Arm, bits 5-8 are ignored by the MMU, and
> > > > they
> > > > are expected
> > > > to be used by the hypervisor for its purpose.
> > > > However, in the code, I notice that these bits are utilized for
> > > > storing
> > > > a reference counter.
> > > 
> > > Why "however"? Hardware still is going to ignore these bits.
> > Sure, these bits are ignored by hardware. What I meant is that,
> > according to the code, these bits are used for storing a reference
> > counter, not p2m_type_t. I guess I am missing something...
> 
> I can only guess where you saw the field used for reference counting.
> This was the domain map page infrastruture, right?
Yes, you are right.
> 
> If so, this is for stage-1 page-table (aka hypervisor table) and not
> the 
> stage-2 (e.g. P2M). For the latter, we would use the p2m_type_t.
I confused stage-1 & stage-2. Now everything fell into place. Thanks.

~ Oleksii


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-16 13:24       ` Jan Beulich
@ 2024-01-17 11:13         ` Oleksii
  2024-01-17 11:17           ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-17 11:13 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-16 at 14:24 +0100, Jan Beulich wrote:
> On 16.01.2024 14:06, Oleksii wrote:
> > On Mon, 2024-01-15 at 17:44 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > +#define test_and_set_bit   __test_and_set_bit
> > > > +#define test_and_clear_bit __test_and_clear_bit
> > > 
> > > I realize test-and-change have no present users, despite being
> > > made
> > > available by Arm and x86, but I think they would better be
> > > provided
> > > right away, rather than someone introducing a use then needing to
> > > fiddle with RISC-V (and apparently also PPC) code.
> > Sure, it makes sense. I'll add test-and-change too.
> > 
> > > I'm also puzzled by this aliasing: Aren't there cheaper non-
> > > atomic
> > > insn forms that could be used for the double-underscore-prefixed
> > > variants?
> > It will be cheaper, but I assume that this API should be safe in
> > the
> > case of SMP where different CPUs can access the same variable or
> > similar cases with simultaneous access to the variable.
> 
> Of course, that's what test_and_...() are for. __test_and_...() are
> for cases where there's no concurrency, when hence the cheaper forms
> can be used. Thus my asking about the aliasing done above.
Then it makes sense to update __test_and...() to use non-atomic insn.
I'll do that in the next patch version.

Thanks for explanation.

> 
> > > > +#if BITS_PER_LONG == 64
> > > > +    if ((word & 0xffffffff) == 0) {
> > > > +        num += 32;
> > > > +        word >>= 32;
> > > > +    }
> > > 
> > > You're ending up with neither Xen nor Linux style this way. May I
> > > suggest to settle on either?
> > 
> > Will it fine to rework header from Linux to Xen style? Does it make
> > sense?
> > I think this file can be reworked to Xen style as I don't expect
> > that
> > it will be changed since it will be merged.
> 
> You may keep Linux style or fully switch to Xen style - which one is
> largely up to you. All I'm asking is to avoid introducing further
> mixed-style source files.
I'll be consistent in code style.

> 
> > > > --- /dev/null
> > > > +++ b/xen/include/asm-generic/bitops/bitops-bits.h
> > > > @@ -0,0 +1,10 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
> > > > +#define _ASM_GENERIC_BITOPS_BITS_H_
> > > > +
> > > > +#define BITOP_BITS_PER_WORD     32
> > > > +#define BITOP_MASK(nr)          (1UL << ((nr) %
> > > > BITOP_BITS_PER_WORD))
> > > 
> > > Why 1UL and not just 1U, when bits per word is 32?
> > There is no specific reason, should 1U. ( I originally used
> > BITOPS_BITS_PER_LONG ) and with introduction of asm-generic bitops
> > decided to follow what other archs provide.
> > 
> > Regarding to the second part of the question, I don't understand it
> > fully. Considering BITOP_BIT_PER_WORD definition for other archs (
> > ARM
> > and PPC ) it is expected that word is 32 bits.
> 
> The 2nd part was explaining why I'm asking. It wasn't another
> question.
> 
> > > > --- /dev/null
> > > > +++ b/xen/include/asm-generic/bitops/test-bit.h
> > > > @@ -0,0 +1,16 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +#ifndef _ASM_GENERIC_BITOPS_TESTBIT_H_
> > > > +#define _ASM_GENERIC_BITOPS_TESTBIT_H_
> > > > +
> > > > +/**
> > > > + * test_bit - Determine whether a bit is set
> > > > + * @nr: bit number to test
> > > > + * @addr: Address to start counting from
> > > > + */
> > > > +static inline int test_bit(int nr, const volatile void *addr)
> > > > +{
> > > > +    const volatile unsigned int *p = addr;
> > > 
> > > With BITOP_BITS_PER_WORD I think you really mean uint32_t here.
> > Isn't it the same: 'unsigned int' and 'uint32_t'?
> 
> No, or else there wouldn't have been a need to introduce uint<N>_t
> (and
> others) in C99. It just so happens that right now all architectures
> Xen
> can be built for have sizeof(int) == 4 and CHAR_BITS == 8. In an
> arch-
> specific header I would see this as less of an issue, but in a
> generic
> header we'd better avoid encoding wrong assumptions. The one
> assumption
> we generally make is that sizeof(int) >= 4 and CHAR_BITS >= 8 (albeit
> I
> bet really in various places we assume CHAR_BITS == 8).
In this case we have to switch to uint<N>_t.
Thanks for the explanation. I'll update this part of code in the next
patch version.

> 
> > > Also you want to make sure asm-generic/bitops/bitops-bits.h is
> > > really in use here, or else an arch overriding / not using that
> > > header may end up screwed.
> > I am not really understand what do you mean. Could you please
> > explain a
> > little bit more.
> 
> Whichever type you use here, it needs to be in sync with
> BITOP_BITS_PER_WORD. Hence you want to include the _local_ bitops-
> bits.h
> here, such that in case of an inconsistent override by an arch the
> compiler would complain about the two differring #define-s. (IOW an
> arch overriding BITOP_BITS_PER_WORD cannot re-use this header as-is.)
> 
> The same may, btw, be true for others of the new headers you add -
> the
> same #include would therefore be needed there as well.
Now it clear to me.


It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD, and
BITS_PER_BYTE are defined in {arm, ppc, riscv}/include/asm/bitops.h.
I expected that any architecture planning to use asm-
generic/bitops/bitops-bits.h would include it at the beginning of
<arch>/include/asm/bitops.h, similar to what is done for RISC-V:
   #ifndef _ASM_RISCV_BITOPS_H
   #define _ASM_RISCV_BITOPS_H
   
   #include <asm/system.h>
   
   #include <asm-generic/bitops/bitops-bits.h>
   ...

But in this case, to allow architecture overrides macros, it is
necessary to update asm-generic/bitops/bitops-bits.h:
    #ifndef BITOP_BITS_PER_WORD
    #define BITOP_BITS_PER_WORD     32
    #endif
   ...
Therefore,  if an architecture needs to override something, it will add
#define ... before #include <asm-generic/bitops/bitops-bits.h>.

Does it make sense?

~ Oleksii




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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-17 11:13         ` Oleksii
@ 2024-01-17 11:17           ` Jan Beulich
  2024-01-17 11:37             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-17 11:17 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 17.01.2024 12:13, Oleksii wrote:
> On Tue, 2024-01-16 at 14:24 +0100, Jan Beulich wrote:
>> On 16.01.2024 14:06, Oleksii wrote:
>>> On Mon, 2024-01-15 at 17:44 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>>>> --- /dev/null
>>>>> +++ b/xen/include/asm-generic/bitops/test-bit.h
>>>>> @@ -0,0 +1,16 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>> +#ifndef _ASM_GENERIC_BITOPS_TESTBIT_H_
>>>>> +#define _ASM_GENERIC_BITOPS_TESTBIT_H_
>>>>> +
>>>>> +/**
>>>>> + * test_bit - Determine whether a bit is set
>>>>> + * @nr: bit number to test
>>>>> + * @addr: Address to start counting from
>>>>> + */
>>>>> +static inline int test_bit(int nr, const volatile void *addr)
>>>>> +{
>>>>> +    const volatile unsigned int *p = addr;
>>>>
>>>> With BITOP_BITS_PER_WORD I think you really mean uint32_t here.
>>> Isn't it the same: 'unsigned int' and 'uint32_t'?
>>
>> No, or else there wouldn't have been a need to introduce uint<N>_t
>> (and
>> others) in C99. It just so happens that right now all architectures
>> Xen
>> can be built for have sizeof(int) == 4 and CHAR_BITS == 8. In an
>> arch-
>> specific header I would see this as less of an issue, but in a
>> generic
>> header we'd better avoid encoding wrong assumptions. The one
>> assumption
>> we generally make is that sizeof(int) >= 4 and CHAR_BITS >= 8 (albeit
>> I
>> bet really in various places we assume CHAR_BITS == 8).
> In this case we have to switch to uint<N>_t.
> Thanks for the explanation. I'll update this part of code in the next
> patch version.
> 
>>
>>>> Also you want to make sure asm-generic/bitops/bitops-bits.h is
>>>> really in use here, or else an arch overriding / not using that
>>>> header may end up screwed.
>>> I am not really understand what do you mean. Could you please
>>> explain a
>>> little bit more.
>>
>> Whichever type you use here, it needs to be in sync with
>> BITOP_BITS_PER_WORD. Hence you want to include the _local_ bitops-
>> bits.h
>> here, such that in case of an inconsistent override by an arch the
>> compiler would complain about the two differring #define-s. (IOW an
>> arch overriding BITOP_BITS_PER_WORD cannot re-use this header as-is.)
>>
>> The same may, btw, be true for others of the new headers you add -
>> the
>> same #include would therefore be needed there as well.
> Now it clear to me.
> 
> 
> It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD, and
> BITS_PER_BYTE are defined in {arm, ppc, riscv}/include/asm/bitops.h.
> I expected that any architecture planning to use asm-
> generic/bitops/bitops-bits.h would include it at the beginning of
> <arch>/include/asm/bitops.h, similar to what is done for RISC-V:
>    #ifndef _ASM_RISCV_BITOPS_H
>    #define _ASM_RISCV_BITOPS_H
>    
>    #include <asm/system.h>
>    
>    #include <asm-generic/bitops/bitops-bits.h>
>    ...
> 
> But in this case, to allow architecture overrides macros, it is
> necessary to update asm-generic/bitops/bitops-bits.h:
>     #ifndef BITOP_BITS_PER_WORD
>     #define BITOP_BITS_PER_WORD     32
>     #endif
>    ...
> Therefore,  if an architecture needs to override something, it will add
> #define ... before #include <asm-generic/bitops/bitops-bits.h>.
> 
> Does it make sense?

Sure. But then the arch also needs to provide a corresponding typedef
(and bitops-bits.h the fallback one), for use wherever you use any of
those #define-s.

Jan


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-17 11:17           ` Jan Beulich
@ 2024-01-17 11:37             ` Oleksii
  2024-01-17 13:42               ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-17 11:37 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

> > > 
> > > > > Also you want to make sure asm-generic/bitops/bitops-bits.h
> > > > > is
> > > > > really in use here, or else an arch overriding / not using
> > > > > that
> > > > > header may end up screwed.
> > > > I am not really understand what do you mean. Could you please
> > > > explain a
> > > > little bit more.
> > > 
> > > Whichever type you use here, it needs to be in sync with
> > > BITOP_BITS_PER_WORD. Hence you want to include the _local_
> > > bitops-
> > > bits.h
> > > here, such that in case of an inconsistent override by an arch
> > > the
> > > compiler would complain about the two differring #define-s. (IOW
> > > an
> > > arch overriding BITOP_BITS_PER_WORD cannot re-use this header as-
> > > is.)
> > > 
> > > The same may, btw, be true for others of the new headers you add
> > > -
> > > the
> > > same #include would therefore be needed there as well.
> > Now it clear to me.
> > 
> > 
> > It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD, and
> > BITS_PER_BYTE are defined in {arm, ppc,
> > riscv}/include/asm/bitops.h.
> > I expected that any architecture planning to use asm-
> > generic/bitops/bitops-bits.h would include it at the beginning of
> > <arch>/include/asm/bitops.h, similar to what is done for RISC-V:
> >    #ifndef _ASM_RISCV_BITOPS_H
> >    #define _ASM_RISCV_BITOPS_H
> >    
> >    #include <asm/system.h>
> >    
> >    #include <asm-generic/bitops/bitops-bits.h>
> >    ...
> > 
> > But in this case, to allow architecture overrides macros, it is
> > necessary to update asm-generic/bitops/bitops-bits.h:
> >     #ifndef BITOP_BITS_PER_WORD
> >     #define BITOP_BITS_PER_WORD     32
> >     #endif
> >    ...
> > Therefore,  if an architecture needs to override something, it will
> > add
> > #define ... before #include <asm-generic/bitops/bitops-bits.h>.
> > 
> > Does it make sense?
> 
> Sure. But then the arch also needs to provide a corresponding typedef
> (and bitops-bits.h the fallback one), for use wherever you use any of
> those #define-s.
Which one typedef is needed to provide?
<asm-generic/bitops/bitops-bits.h> contains only macros.


~ Oleksii


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-17 11:37             ` Oleksii
@ 2024-01-17 13:42               ` Jan Beulich
  2024-01-18  9:43                 ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-17 13:42 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 17.01.2024 12:37, Oleksii wrote:
>>>>
>>>>>> Also you want to make sure asm-generic/bitops/bitops-bits.h
>>>>>> is
>>>>>> really in use here, or else an arch overriding / not using
>>>>>> that
>>>>>> header may end up screwed.
>>>>> I am not really understand what do you mean. Could you please
>>>>> explain a
>>>>> little bit more.
>>>>
>>>> Whichever type you use here, it needs to be in sync with
>>>> BITOP_BITS_PER_WORD. Hence you want to include the _local_
>>>> bitops-
>>>> bits.h
>>>> here, such that in case of an inconsistent override by an arch
>>>> the
>>>> compiler would complain about the two differring #define-s. (IOW
>>>> an
>>>> arch overriding BITOP_BITS_PER_WORD cannot re-use this header as-
>>>> is.)
>>>>
>>>> The same may, btw, be true for others of the new headers you add
>>>> -
>>>> the
>>>> same #include would therefore be needed there as well.
>>> Now it clear to me.
>>>
>>>
>>> It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD, and
>>> BITS_PER_BYTE are defined in {arm, ppc,
>>> riscv}/include/asm/bitops.h.
>>> I expected that any architecture planning to use asm-
>>> generic/bitops/bitops-bits.h would include it at the beginning of
>>> <arch>/include/asm/bitops.h, similar to what is done for RISC-V:
>>>    #ifndef _ASM_RISCV_BITOPS_H
>>>    #define _ASM_RISCV_BITOPS_H
>>>    
>>>    #include <asm/system.h>
>>>    
>>>    #include <asm-generic/bitops/bitops-bits.h>
>>>    ...
>>>
>>> But in this case, to allow architecture overrides macros, it is
>>> necessary to update asm-generic/bitops/bitops-bits.h:
>>>     #ifndef BITOP_BITS_PER_WORD
>>>     #define BITOP_BITS_PER_WORD     32
>>>     #endif
>>>    ...
>>> Therefore,  if an architecture needs to override something, it will
>>> add
>>> #define ... before #include <asm-generic/bitops/bitops-bits.h>.
>>>
>>> Does it make sense?
>>
>> Sure. But then the arch also needs to provide a corresponding typedef
>> (and bitops-bits.h the fallback one), for use wherever you use any of
>> those #define-s.
> Which one typedef is needed to provide?
> <asm-generic/bitops/bitops-bits.h> contains only macros.

A new one, to replace where right now you use "unsigned int" and I
initially said you need to use "uint32_t" instead. With what you said
earlier, uint32_t won't work there (anymore).

Jan


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-17 13:42               ` Jan Beulich
@ 2024-01-18  9:43                 ` Oleksii
  2024-01-18 11:01                   ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-18  9:43 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-17 at 14:42 +0100, Jan Beulich wrote:
> On 17.01.2024 12:37, Oleksii wrote:
> > > > > 
> > > > > > > Also you want to make sure asm-generic/bitops/bitops-
> > > > > > > bits.h
> > > > > > > is
> > > > > > > really in use here, or else an arch overriding / not
> > > > > > > using
> > > > > > > that
> > > > > > > header may end up screwed.
> > > > > > I am not really understand what do you mean. Could you
> > > > > > please
> > > > > > explain a
> > > > > > little bit more.
> > > > > 
> > > > > Whichever type you use here, it needs to be in sync with
> > > > > BITOP_BITS_PER_WORD. Hence you want to include the _local_
> > > > > bitops-
> > > > > bits.h
> > > > > here, such that in case of an inconsistent override by an
> > > > > arch
> > > > > the
> > > > > compiler would complain about the two differring #define-s.
> > > > > (IOW
> > > > > an
> > > > > arch overriding BITOP_BITS_PER_WORD cannot re-use this header
> > > > > as-
> > > > > is.)
> > > > > 
> > > > > The same may, btw, be true for others of the new headers you
> > > > > add
> > > > > -
> > > > > the
> > > > > same #include would therefore be needed there as well.
> > > > Now it clear to me.
> > > > 
> > > > 
> > > > It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD, and
> > > > BITS_PER_BYTE are defined in {arm, ppc,
> > > > riscv}/include/asm/bitops.h.
> > > > I expected that any architecture planning to use asm-
> > > > generic/bitops/bitops-bits.h would include it at the beginning
> > > > of
> > > > <arch>/include/asm/bitops.h, similar to what is done for RISC-
> > > > V:
> > > >    #ifndef _ASM_RISCV_BITOPS_H
> > > >    #define _ASM_RISCV_BITOPS_H
> > > >    
> > > >    #include <asm/system.h>
> > > >    
> > > >    #include <asm-generic/bitops/bitops-bits.h>
> > > >    ...
> > > > 
> > > > But in this case, to allow architecture overrides macros, it is
> > > > necessary to update asm-generic/bitops/bitops-bits.h:
> > > >     #ifndef BITOP_BITS_PER_WORD
> > > >     #define BITOP_BITS_PER_WORD     32
> > > >     #endif
> > > >    ...
> > > > Therefore,  if an architecture needs to override something, it
> > > > will
> > > > add
> > > > #define ... before #include <asm-generic/bitops/bitops-bits.h>.
> > > > 
> > > > Does it make sense?
> > > 
> > > Sure. But then the arch also needs to provide a corresponding
> > > typedef
> > > (and bitops-bits.h the fallback one), for use wherever you use
> > > any of
> > > those #define-s.
> > Which one typedef is needed to provide?
> > <asm-generic/bitops/bitops-bits.h> contains only macros.
> 
> A new one, to replace where right now you use "unsigned int" and I
> initially said you need to use "uint32_t" instead. With what you said
> earlier, uint32_t won't work there (anymore).
Wouldn't it be enough just to "#include <xen/types.h>" in headers where
"uint32_t" is used?

~ Olkesii



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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-18  9:43                 ` Oleksii
@ 2024-01-18 11:01                   ` Jan Beulich
  2024-01-19  9:16                     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-18 11:01 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 18.01.2024 10:43, Oleksii wrote:
> On Wed, 2024-01-17 at 14:42 +0100, Jan Beulich wrote:
>> On 17.01.2024 12:37, Oleksii wrote:
>>>>>>
>>>>>>>> Also you want to make sure asm-generic/bitops/bitops-
>>>>>>>> bits.h
>>>>>>>> is
>>>>>>>> really in use here, or else an arch overriding / not
>>>>>>>> using
>>>>>>>> that
>>>>>>>> header may end up screwed.
>>>>>>> I am not really understand what do you mean. Could you
>>>>>>> please
>>>>>>> explain a
>>>>>>> little bit more.
>>>>>>
>>>>>> Whichever type you use here, it needs to be in sync with
>>>>>> BITOP_BITS_PER_WORD. Hence you want to include the _local_
>>>>>> bitops-
>>>>>> bits.h
>>>>>> here, such that in case of an inconsistent override by an
>>>>>> arch
>>>>>> the
>>>>>> compiler would complain about the two differring #define-s.
>>>>>> (IOW
>>>>>> an
>>>>>> arch overriding BITOP_BITS_PER_WORD cannot re-use this header
>>>>>> as-
>>>>>> is.)
>>>>>>
>>>>>> The same may, btw, be true for others of the new headers you
>>>>>> add
>>>>>> -
>>>>>> the
>>>>>> same #include would therefore be needed there as well.
>>>>> Now it clear to me.
>>>>>
>>>>>
>>>>> It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD, and
>>>>> BITS_PER_BYTE are defined in {arm, ppc,
>>>>> riscv}/include/asm/bitops.h.
>>>>> I expected that any architecture planning to use asm-
>>>>> generic/bitops/bitops-bits.h would include it at the beginning
>>>>> of
>>>>> <arch>/include/asm/bitops.h, similar to what is done for RISC-
>>>>> V:
>>>>>    #ifndef _ASM_RISCV_BITOPS_H
>>>>>    #define _ASM_RISCV_BITOPS_H
>>>>>    
>>>>>    #include <asm/system.h>
>>>>>    
>>>>>    #include <asm-generic/bitops/bitops-bits.h>
>>>>>    ...
>>>>>
>>>>> But in this case, to allow architecture overrides macros, it is
>>>>> necessary to update asm-generic/bitops/bitops-bits.h:
>>>>>     #ifndef BITOP_BITS_PER_WORD
>>>>>     #define BITOP_BITS_PER_WORD     32
>>>>>     #endif
>>>>>    ...
>>>>> Therefore,  if an architecture needs to override something, it
>>>>> will
>>>>> add
>>>>> #define ... before #include <asm-generic/bitops/bitops-bits.h>.
>>>>>
>>>>> Does it make sense?
>>>>
>>>> Sure. But then the arch also needs to provide a corresponding
>>>> typedef
>>>> (and bitops-bits.h the fallback one), for use wherever you use
>>>> any of
>>>> those #define-s.
>>> Which one typedef is needed to provide?
>>> <asm-generic/bitops/bitops-bits.h> contains only macros.
>>
>> A new one, to replace where right now you use "unsigned int" and I
>> initially said you need to use "uint32_t" instead. With what you said
>> earlier, uint32_t won't work there (anymore).
> Wouldn't it be enough just to "#include <xen/types.h>" in headers where
> "uint32_t" is used?

No, my point wasn't to make uint32_t available. We need a _separate_
typedef which matches the #define-s. Otherwise, if an arch defines
BITOP_BITS_PER_WORD to, say, 64, this generic code would do the wrong
thing.

Jan


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2023-12-22 15:12 ` [PATCH v3 10/34] xen/riscv: introduce bitops.h Oleksii Kurochko
  2024-01-15 16:44   ` Jan Beulich
@ 2024-01-18 11:03   ` Jan Beulich
  2024-01-19  9:09     ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-18 11:03 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/include/asm-generic/bitops/bitops-bits.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
> +#define _ASM_GENERIC_BITOPS_BITS_H_
> +
> +#define BITOP_BITS_PER_WORD     32
> +#define BITOP_MASK(nr)          (1UL << ((nr) % BITOP_BITS_PER_WORD))
> +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
> +#define BITS_PER_BYTE           8

Btw, I can't spot a use of BITS_PER_BYTE. Why do you add it? And if
it really needed adding, it surely wouldn't belong here.

Jan


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-18 11:03   ` Jan Beulich
@ 2024-01-19  9:09     ` Oleksii
  2024-01-19  9:14       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-19  9:09 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Thu, 2024-01-18 at 12:03 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/include/asm-generic/bitops/bitops-bits.h
> > @@ -0,0 +1,10 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
> > +#define _ASM_GENERIC_BITOPS_BITS_H_
> > +
> > +#define BITOP_BITS_PER_WORD     32
> > +#define BITOP_MASK(nr)          (1UL << ((nr) %
> > BITOP_BITS_PER_WORD))
> > +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
> > +#define BITS_PER_BYTE           8
> 
> Btw, I can't spot a use of BITS_PER_BYTE. Why do you add it? And if
> it really needed adding, it surely wouldn't belong here.
It is used in common/bitmap.c and ns16550.c, and inside some arch code,
but it is not used by RISC-V right now.

Would it be better to define it in config.h?

~ Oleksii


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-19  9:09     ` Oleksii
@ 2024-01-19  9:14       ` Jan Beulich
  2024-01-19  9:30         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-19  9:14 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 19.01.2024 10:09, Oleksii wrote:
> On Thu, 2024-01-18 at 12:03 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>> --- /dev/null
>>> +++ b/xen/include/asm-generic/bitops/bitops-bits.h
>>> @@ -0,0 +1,10 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
>>> +#define _ASM_GENERIC_BITOPS_BITS_H_
>>> +
>>> +#define BITOP_BITS_PER_WORD     32
>>> +#define BITOP_MASK(nr)          (1UL << ((nr) %
>>> BITOP_BITS_PER_WORD))
>>> +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
>>> +#define BITS_PER_BYTE           8
>>
>> Btw, I can't spot a use of BITS_PER_BYTE. Why do you add it? And if
>> it really needed adding, it surely wouldn't belong here.
> It is used in common/bitmap.c and ns16550.c, and inside some arch code,
> but it is not used by RISC-V right now.
> 
> Would it be better to define it in config.h?

Yes, perhaps. Imo this shouldn't have a "generic" fallback; every arch
should explicitly state this (along with e.g. BITS_PER_LONG).

Jan


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-18 11:01                   ` Jan Beulich
@ 2024-01-19  9:16                     ` Oleksii
  2024-01-19  9:20                       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-19  9:16 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Thu, 2024-01-18 at 12:01 +0100, Jan Beulich wrote:
> On 18.01.2024 10:43, Oleksii wrote:
> > On Wed, 2024-01-17 at 14:42 +0100, Jan Beulich wrote:
> > > On 17.01.2024 12:37, Oleksii wrote:
> > > > > > > 
> > > > > > > > > Also you want to make sure asm-generic/bitops/bitops-
> > > > > > > > > bits.h
> > > > > > > > > is
> > > > > > > > > really in use here, or else an arch overriding / not
> > > > > > > > > using
> > > > > > > > > that
> > > > > > > > > header may end up screwed.
> > > > > > > > I am not really understand what do you mean. Could you
> > > > > > > > please
> > > > > > > > explain a
> > > > > > > > little bit more.
> > > > > > > 
> > > > > > > Whichever type you use here, it needs to be in sync with
> > > > > > > BITOP_BITS_PER_WORD. Hence you want to include the
> > > > > > > _local_
> > > > > > > bitops-
> > > > > > > bits.h
> > > > > > > here, such that in case of an inconsistent override by an
> > > > > > > arch
> > > > > > > the
> > > > > > > compiler would complain about the two differring #define-
> > > > > > > s.
> > > > > > > (IOW
> > > > > > > an
> > > > > > > arch overriding BITOP_BITS_PER_WORD cannot re-use this
> > > > > > > header
> > > > > > > as-
> > > > > > > is.)
> > > > > > > 
> > > > > > > The same may, btw, be true for others of the new headers
> > > > > > > you
> > > > > > > add
> > > > > > > -
> > > > > > > the
> > > > > > > same #include would therefore be needed there as well.
> > > > > > Now it clear to me.
> > > > > > 
> > > > > > 
> > > > > > It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD,
> > > > > > and
> > > > > > BITS_PER_BYTE are defined in {arm, ppc,
> > > > > > riscv}/include/asm/bitops.h.
> > > > > > I expected that any architecture planning to use asm-
> > > > > > generic/bitops/bitops-bits.h would include it at the
> > > > > > beginning
> > > > > > of
> > > > > > <arch>/include/asm/bitops.h, similar to what is done for
> > > > > > RISC-
> > > > > > V:
> > > > > >    #ifndef _ASM_RISCV_BITOPS_H
> > > > > >    #define _ASM_RISCV_BITOPS_H
> > > > > >    
> > > > > >    #include <asm/system.h>
> > > > > >    
> > > > > >    #include <asm-generic/bitops/bitops-bits.h>
> > > > > >    ...
> > > > > > 
> > > > > > But in this case, to allow architecture overrides macros,
> > > > > > it is
> > > > > > necessary to update asm-generic/bitops/bitops-bits.h:
> > > > > >     #ifndef BITOP_BITS_PER_WORD
> > > > > >     #define BITOP_BITS_PER_WORD     32
> > > > > >     #endif
> > > > > >    ...
> > > > > > Therefore,  if an architecture needs to override something,
> > > > > > it
> > > > > > will
> > > > > > add
> > > > > > #define ... before #include <asm-generic/bitops/bitops-
> > > > > > bits.h>.
> > > > > > 
> > > > > > Does it make sense?
> > > > > 
> > > > > Sure. But then the arch also needs to provide a corresponding
> > > > > typedef
> > > > > (and bitops-bits.h the fallback one), for use wherever you
> > > > > use
> > > > > any of
> > > > > those #define-s.
> > > > Which one typedef is needed to provide?
> > > > <asm-generic/bitops/bitops-bits.h> contains only macros.
> > > 
> > > A new one, to replace where right now you use "unsigned int" and
> > > I
> > > initially said you need to use "uint32_t" instead. With what you
> > > said
> > > earlier, uint32_t won't work there (anymore).
> > Wouldn't it be enough just to "#include <xen/types.h>" in headers
> > where
> > "uint32_t" is used?
> 
> No, my point wasn't to make uint32_t available. We need a _separate_
> typedef which matches the #define-s. Otherwise, if an arch defines
> BITOP_BITS_PER_WORD to, say, 64, this generic code would do the wrong
> thing.
Oh, yeah this is true.

We have to introduce in bitops-bits.h:
   typedef uint_32t bitops_type; 

And then use it in function such as test_bit:
   static inline int test_bit(int nr, const volatile void *addr)
   {
       const volatile bitops_type *p = addr;
       return 1 & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD -
   1)));
   }

Thanks for clarification.

~ Oleksii


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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-19  9:16                     ` Oleksii
@ 2024-01-19  9:20                       ` Jan Beulich
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-19  9:20 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 19.01.2024 10:16, Oleksii wrote:
> On Thu, 2024-01-18 at 12:01 +0100, Jan Beulich wrote:
>> On 18.01.2024 10:43, Oleksii wrote:
>>> On Wed, 2024-01-17 at 14:42 +0100, Jan Beulich wrote:
>>>> On 17.01.2024 12:37, Oleksii wrote:
>>>>>>>>
>>>>>>>>>> Also you want to make sure asm-generic/bitops/bitops-
>>>>>>>>>> bits.h
>>>>>>>>>> is
>>>>>>>>>> really in use here, or else an arch overriding / not
>>>>>>>>>> using
>>>>>>>>>> that
>>>>>>>>>> header may end up screwed.
>>>>>>>>> I am not really understand what do you mean. Could you
>>>>>>>>> please
>>>>>>>>> explain a
>>>>>>>>> little bit more.
>>>>>>>>
>>>>>>>> Whichever type you use here, it needs to be in sync with
>>>>>>>> BITOP_BITS_PER_WORD. Hence you want to include the
>>>>>>>> _local_
>>>>>>>> bitops-
>>>>>>>> bits.h
>>>>>>>> here, such that in case of an inconsistent override by an
>>>>>>>> arch
>>>>>>>> the
>>>>>>>> compiler would complain about the two differring #define-
>>>>>>>> s.
>>>>>>>> (IOW
>>>>>>>> an
>>>>>>>> arch overriding BITOP_BITS_PER_WORD cannot re-use this
>>>>>>>> header
>>>>>>>> as-
>>>>>>>> is.)
>>>>>>>>
>>>>>>>> The same may, btw, be true for others of the new headers
>>>>>>>> you
>>>>>>>> add
>>>>>>>> -
>>>>>>>> the
>>>>>>>> same #include would therefore be needed there as well.
>>>>>>> Now it clear to me.
>>>>>>>
>>>>>>>
>>>>>>> It seems like BITOP_BITS_PER_WORD, BITOP_MASK, BITOP_WORD,
>>>>>>> and
>>>>>>> BITS_PER_BYTE are defined in {arm, ppc,
>>>>>>> riscv}/include/asm/bitops.h.
>>>>>>> I expected that any architecture planning to use asm-
>>>>>>> generic/bitops/bitops-bits.h would include it at the
>>>>>>> beginning
>>>>>>> of
>>>>>>> <arch>/include/asm/bitops.h, similar to what is done for
>>>>>>> RISC-
>>>>>>> V:
>>>>>>>    #ifndef _ASM_RISCV_BITOPS_H
>>>>>>>    #define _ASM_RISCV_BITOPS_H
>>>>>>>    
>>>>>>>    #include <asm/system.h>
>>>>>>>    
>>>>>>>    #include <asm-generic/bitops/bitops-bits.h>
>>>>>>>    ...
>>>>>>>
>>>>>>> But in this case, to allow architecture overrides macros,
>>>>>>> it is
>>>>>>> necessary to update asm-generic/bitops/bitops-bits.h:
>>>>>>>     #ifndef BITOP_BITS_PER_WORD
>>>>>>>     #define BITOP_BITS_PER_WORD     32
>>>>>>>     #endif
>>>>>>>    ...
>>>>>>> Therefore,  if an architecture needs to override something,
>>>>>>> it
>>>>>>> will
>>>>>>> add
>>>>>>> #define ... before #include <asm-generic/bitops/bitops-
>>>>>>> bits.h>.
>>>>>>>
>>>>>>> Does it make sense?
>>>>>>
>>>>>> Sure. But then the arch also needs to provide a corresponding
>>>>>> typedef
>>>>>> (and bitops-bits.h the fallback one), for use wherever you
>>>>>> use
>>>>>> any of
>>>>>> those #define-s.
>>>>> Which one typedef is needed to provide?
>>>>> <asm-generic/bitops/bitops-bits.h> contains only macros.
>>>>
>>>> A new one, to replace where right now you use "unsigned int" and
>>>> I
>>>> initially said you need to use "uint32_t" instead. With what you
>>>> said
>>>> earlier, uint32_t won't work there (anymore).
>>> Wouldn't it be enough just to "#include <xen/types.h>" in headers
>>> where
>>> "uint32_t" is used?
>>
>> No, my point wasn't to make uint32_t available. We need a _separate_
>> typedef which matches the #define-s. Otherwise, if an arch defines
>> BITOP_BITS_PER_WORD to, say, 64, this generic code would do the wrong
>> thing.
> Oh, yeah this is true.
> 
> We have to introduce in bitops-bits.h:
>    typedef uint_32t bitops_type; 

Perhaps e.g.

typedef uint32_t bitops_uint_t;

though.

Jan

> And then use it in function such as test_bit:
>    static inline int test_bit(int nr, const volatile void *addr)
>    {
>        const volatile bitops_type *p = addr;
>        return 1 & (p[BITOP_WORD(nr)] >> (nr & (BITOP_BITS_PER_WORD -
>    1)));
>    }
> 
> Thanks for clarification.
> 
> ~ Oleksii



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

* Re: [PATCH v3 10/34] xen/riscv: introduce bitops.h
  2024-01-19  9:14       ` Jan Beulich
@ 2024-01-19  9:30         ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-19  9:30 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Fri, 2024-01-19 at 10:14 +0100, Jan Beulich wrote:
> On 19.01.2024 10:09, Oleksii wrote:
> > On Thu, 2024-01-18 at 12:03 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > --- /dev/null
> > > > +++ b/xen/include/asm-generic/bitops/bitops-bits.h
> > > > @@ -0,0 +1,10 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +#ifndef _ASM_GENERIC_BITOPS_BITS_H_
> > > > +#define _ASM_GENERIC_BITOPS_BITS_H_
> > > > +
> > > > +#define BITOP_BITS_PER_WORD     32
> > > > +#define BITOP_MASK(nr)          (1UL << ((nr) %
> > > > BITOP_BITS_PER_WORD))
> > > > +#define BITOP_WORD(nr)          ((nr) / BITOP_BITS_PER_WORD)
> > > > +#define BITS_PER_BYTE           8
> > > 
> > > Btw, I can't spot a use of BITS_PER_BYTE. Why do you add it? And
> > > if
> > > it really needed adding, it surely wouldn't belong here.
> > It is used in common/bitmap.c and ns16550.c, and inside some arch
> > code,
> > but it is not used by RISC-V right now.
> > 
> > Would it be better to define it in config.h?
> 
> Yes, perhaps. Imo this shouldn't have a "generic" fallback; every
> arch
> should explicitly state this (along with e.g. BITS_PER_LONG).
Got it. Thanks.

~ Oleksii


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2023-12-22 15:12 ` [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h Oleksii Kurochko
@ 2024-01-22 16:27   ` Jan Beulich
  2024-01-23 10:15     ` Oleksii
  2024-01-30 14:57     ` Oleksii
  0 siblings, 2 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-22 16:27 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/cmpxchg.h
> @@ -0,0 +1,496 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright (C) 2014 Regents of the University of California */
> +
> +#ifndef _ASM_RISCV_CMPXCHG_H
> +#define _ASM_RISCV_CMPXCHG_H
> +
> +#include <xen/compiler.h>
> +#include <xen/lib.h>
> +
> +#include <asm/fence.h>
> +#include <asm/io.h>
> +#include <asm/system.h>
> +
> +#define __xchg_relaxed(ptr, new, size) \
> +({ \
> +    __typeof__(ptr) ptr__ = (ptr); \
> +    __typeof__(new) new__ = (new); \
> +    __typeof__(*(ptr)) ret__; \

I expect the types of new and *ptr want to actually match. Which
you then want to enforce, so that issues at use sites would either
be reported by the compiler, or be permitted by a type conversion
of new.

> +    switch (size) \
> +	{ \

Nit: Hard tab left here. (Also again you want to either stick to
Linux style or fully switch to Xen style.)

> +    case 4: \
> +        asm volatile( \
> +            "	amoswap.w %0, %2, %1\n" \

I don't think a leading tab (or leading whitespace in general) is
needed in single-line-output asm()s. The trailing \n also isn't
needed if I'm not mistaken.

> +            : "=r" (ret__), "+A" (*ptr__) \
> +            : "r" (new__) \
> +            : "memory" ); \
> +        break; \
> +    case 8: \
> +        asm volatile( \
> +            "	amoswap.d %0, %2, %1\n" \
> +            : "=r" (ret__), "+A" (*ptr__) \
> +            : "r" (new__) \
> +            : "memory" ); \
> +        break; \
> +    default: \
> +        ASSERT_UNREACHABLE(); \

If at all possible this wants to trigger a build failure, not a runtime
one.

> +    } \
> +    ret__; \
> +})
> +
> +#define xchg_relaxed(ptr, x) \
> +({ \
> +    __typeof__(*(ptr)) x_ = (x); \
> +    (__typeof__(*(ptr))) __xchg_relaxed((ptr), x_, sizeof(*(ptr))); \

Nit: Stray blank after cast. For readability I'd also suggest to
drop parentheses in cases like the first argument passed to
__xchg_relaxed() here.

> +})

For both: What does "relaxed" describe? I'm asking because it's not
really clear whether the memory clobbers are actually needed.

> +#define __xchg_acquire(ptr, new, size) \
> +({ \
> +    __typeof__(ptr) ptr__ = (ptr); \
> +    __typeof__(new) new__ = (new); \
> +    __typeof__(*(ptr)) ret__; \
> +    switch (size) \
> +	{ \
> +    case 4: \
> +        asm volatile( \
> +            "	amoswap.w %0, %2, %1\n" \
> +            RISCV_ACQUIRE_BARRIER \
> +            : "=r" (ret__), "+A" (*ptr__) \
> +            : "r" (new__) \
> +            : "memory" ); \
> +        break; \
> +    case 8: \
> +        asm volatile( \
> +            "	amoswap.d %0, %2, %1\n" \
> +            RISCV_ACQUIRE_BARRIER \
> +            : "=r" (ret__), "+A" (*ptr__) \
> +            : "r" (new__) \
> +            : "memory" ); \
> +        break; \
> +    default: \
> +        ASSERT_UNREACHABLE(); \
> +    } \
> +    ret__; \
> +})

If I'm not mistaken this differs from __xchg_relaxed() only in the use
of RISCV_ACQUIRE_BARRIER, and ...

> +#define xchg_acquire(ptr, x) \
> +({ \
> +    __typeof__(*(ptr)) x_ = (x); \
> +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_, sizeof(*(ptr))); \
> +})
> +
> +#define __xchg_release(ptr, new, size) \
> +({ \
> +    __typeof__(ptr) ptr__ = (ptr); \
> +    __typeof__(new) new__ = (new); \
> +    __typeof__(*(ptr)) ret__; \
> +    switch (size) \
> +	{ \
> +    case 4: \
> +        asm volatile ( \
> +            RISCV_RELEASE_BARRIER \
> +            "	amoswap.w %0, %2, %1\n" \
> +            : "=r" (ret__), "+A" (*ptr__) \
> +            : "r" (new__) \
> +            : "memory"); \
> +        break; \
> +    case 8: \
> +        asm volatile ( \
> +            RISCV_RELEASE_BARRIER \
> +            "	amoswap.d %0, %2, %1\n" \
> +            : "=r" (ret__), "+A" (*ptr__) \
> +            : "r" (new__) \
> +            : "memory"); \
> +        break; \
> +    default: \
> +        ASSERT_UNREACHABLE(); \
> +    } \
> +    ret__; \
> +})

this only in the use of RISCV_RELEASE_BARRIER. If so they likely want
folding, to limit redundancy and make eventual updating easier. (Same
for the cmpxchg helper further down, as it seems.)

> +#define xchg_release(ptr, x) \
> +({ \
> +    __typeof__(*(ptr)) x_ = (x); \
> +    (__typeof__(*(ptr))) __xchg_release((ptr), x_, sizeof(*(ptr))); \
> +})
> +
> +static always_inline uint32_t __xchg_case_4(volatile uint32_t *ptr,
> +                                            uint32_t new)
> +{
> +    __typeof__(*(ptr)) ret;
> +
> +    asm volatile (
> +        "   amoswap.w.aqrl %0, %2, %1\n"
> +        : "=r" (ret), "+A" (*ptr)
> +        : "r" (new)
> +        : "memory" );
> +
> +    return ret;
> +}
> +
> +static always_inline uint64_t __xchg_case_8(volatile uint64_t *ptr,
> +                                            uint64_t new)
> +{
> +    __typeof__(*(ptr)) ret;
> +
> +    asm volatile( \
> +        "   amoswap.d.aqrl %0, %2, %1\n" \
> +        : "=r" (ret), "+A" (*ptr) \
> +        : "r" (new) \
> +        : "memory" ); \
> +
> +    return ret;
> +}
> +
> +static always_inline unsigned short __cmpxchg_case_2(volatile uint32_t *ptr,
> +                                                     uint32_t old,
> +                                                     uint32_t new);

Don't you consistently mean uint16_t here (incl the return type) and ...

> +static always_inline unsigned short __cmpxchg_case_1(volatile uint32_t *ptr,
> +                                                     uint32_t old,
> +                                                     uint32_t new);

... uint8_t here?

> +static inline unsigned long __xchg(volatile void *ptr, unsigned long x, int size)
> +{
> +    switch (size) {
> +    case 1:
> +        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
> +    case 2:
> +        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);

How are these going to work? You'll compare against ~0, and if the value
in memory isn't ~0, memory won't be updated; you will only (correctly)
return the value found in memory.

Or wait - looking at __cmpxchg_case_{1,2}() far further down, you ignore
"old" there. Which apparently means they'll work for the use here, but
not for the use in __cmpxchg().

> +    case 4:
> +        return __xchg_case_4(ptr, x);
> +    case 8:
> +        return __xchg_case_8(ptr, x);
> +    default:
> +        ASSERT_UNREACHABLE();
> +    }
> +
> +    return -1;
> +}
> +
> +#define xchg(ptr,x) \
> +({ \
> +    __typeof__(*(ptr)) ret__; \
> +    ret__ = (__typeof__(*(ptr))) \
> +            __xchg((ptr), (unsigned long)(x), sizeof(*(ptr))); \
> +    ret__; \
> +})
> +
> +#define xchg32(ptr, x) \
> +({ \
> +    BUILD_BUG_ON(sizeof(*(ptr)) != 4); \
> +    xchg((ptr), (x)); \
> +})
> +
> +#define xchg64(ptr, x) \
> +({ \
> +    BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
> +    xchg((ptr), (x)); \
> +})

What are these two (and their cmpxchg counterparts) needed for?

> +/*
> + * Atomic compare and exchange.  Compare OLD with MEM, if identical,
> + * store NEW in MEM.  Return the initial value in MEM.  Success is
> + * indicated by comparing RETURN with OLD.
> + */
> +#define __cmpxchg_relaxed(ptr, old, new, size) \
> +({ \
> +    __typeof__(ptr) ptr__ = (ptr); \
> +    __typeof__(*(ptr)) __old = (old); \

Leftover leading underscores?

> +    __typeof__(*(ptr)) new__ = (new); \

Related to my earlier comment on types needing to be compatible - see
how here you're using "ptr" throughout.

> +    __typeof__(*(ptr)) ret__; \
> +    register unsigned int __rc; \

More leftover leading underscores?

> +static always_inline unsigned short __cmpxchg_case_2(volatile uint32_t *ptr,
> +                                                     uint32_t old,
> +                                                     uint32_t new)
> +{
> +    (void) old;
> +
> +    if (((unsigned long)ptr & 3) == 3)
> +    {
> +#ifdef CONFIG_64BIT
> +        return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
> +                                         readq, __cmpxchg_case_8, 0xffffU);

What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of what the
if() above checks for? Isn't it more reasonable to require aligned
16-bit quantities here? Or if mis-aligned addresses are okay, you could
as well emulate using __cmpxchg_case_4().

Also you shouldn't be casting away volatile (here and below). Avoiding
the casts (by suitable using volatile void * parameter types) would
likely be best.

Jan


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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2023-12-22 15:12 ` [PATCH v3 15/34] xen/riscv: introduce atomic.h Oleksii Kurochko
@ 2024-01-22 16:56   ` Jan Beulich
  2024-01-23 10:21     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-22 16:56 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:12, Oleksii Kurochko wrote:
> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/atomic.h
> @@ -0,0 +1,384 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Taken and modified from Linux.
> + * 
> + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + * Copyright (C) 2021 Vates SAS
> + */
> +
> +#ifndef _ASM_RISCV_ATOMIC_H
> +#define _ASM_RISCV_ATOMIC_H
> +
> +#include <xen/atomic.h>
> +#include <asm/cmpxchg.h>
> +#include <asm/fence.h>
> +#include <asm/io.h>
> +#include <asm/system.h>
> +
> +void __bad_atomic_size(void);
> +
> +static always_inline void read_atomic_size(const volatile void *p,
> +                                           void *res,
> +                                           unsigned int size)
> +{
> +    switch ( size )
> +    {
> +    case 1: *(uint8_t *)res = readb((const uint8_t *)p); break;
> +    case 2: *(uint16_t *)res = readw((const uint16_t *)p); break;
> +    case 4: *(uint32_t *)res = readl((const uint32_t *)p); break;
> +    case 8: *(uint32_t *)res  = readq((const uint64_t *)p); break;

Just like const, you should also avoid casting away volatile.

> +    default: __bad_atomic_size(); break;
> +    }
> +}
> +
> +#define read_atomic(p) ({                                               \
> +    union { typeof(*p) val; char c[0]; } x_;                            \
> +    read_atomic_size(p, x_.c, sizeof(*p));                              \
> +    x_.val;                                                             \
> +})
> +
> +

Nit: No double blank lines please.

> +#define write_atomic(p, x) ({                                           \
> +    typeof(*p) x__ = (x);                                               \
> +    switch ( sizeof(*p) )												\
> +    {                                             						\

These lines look excessively long, possibly as a result of leaving hard tabs
in place.

Overall some of the style comments on the earlier patch seem to apply here
as well.

> --- /dev/null
> +++ b/xen/arch/riscv/include/asm/fence.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#ifndef _ASM_RISCV_FENCE_H
> +#define _ASM_RISCV_FENCE_H
> +
> +#ifdef CONFIG_SMP
> +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
> +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
> +#else
> +#define RISCV_ACQUIRE_BARRIER
> +#define RISCV_RELEASE_BARRIER
> +#endif

Do you really care about the !SMP case? On x86 at least we stopped special-
casing that configuration many years ago (the few cases where for typically
build reasons it matters, using CONFIG_NR_CPUS is sufficient). If you care
about it, there needs to be somewhere you actually #define CONFIG_SMP.

Jan


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-22 16:27   ` Jan Beulich
@ 2024-01-23 10:15     ` Oleksii
  2024-01-23 10:28       ` Jan Beulich
  2024-01-30 14:57     ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 10:15 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/cmpxchg.h
> > @@ -0,0 +1,496 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/* Copyright (C) 2014 Regents of the University of California */
> > +
> > +#ifndef _ASM_RISCV_CMPXCHG_H
> > +#define _ASM_RISCV_CMPXCHG_H
> > +
> > +#include <xen/compiler.h>
> > +#include <xen/lib.h>
> > +
> > +#include <asm/fence.h>
> > +#include <asm/io.h>
> > +#include <asm/system.h>
> > +
> > +#define __xchg_relaxed(ptr, new, size) \
> > +({ \
> > +    __typeof__(ptr) ptr__ = (ptr); \
> > +    __typeof__(new) new__ = (new); \
> > +    __typeof__(*(ptr)) ret__; \
> 
> I expect the types of new and *ptr want to actually match. Which
> you then want to enforce, so that issues at use sites would either
> be reported by the compiler, or be permitted by a type conversion
> of new.
I am OK to make the same type for new and ret__, but it looks like
__xchg_relaxed() is used only inside xchg_relaxed() where 'new' is
declared with the same type as *ptr.

> 
> > +    switch (size) \
> > +	{ \
> 
> Nit: Hard tab left here. (Also again you want to either stick to
> Linux style or fully switch to Xen style.)
Thanks. I'll update that.

> 
> > +    case 4: \
> > +        asm volatile( \
> > +            "	amoswap.w %0, %2, %1\n" \
> 
> I don't think a leading tab (or leading whitespace in general) is
> needed in single-line-output asm()s. The trailing \n also isn't
> needed if I'm not mistaken.
I just wanted to align it with "=r", but for sure a leading tab or
whitespace can be dropped.

> 
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory" ); \
> > +        break; \
> > +    case 8: \
> > +        asm volatile( \
> > +            "	amoswap.d %0, %2, %1\n" \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory" ); \
> > +        break; \
> > +    default: \
> > +        ASSERT_UNREACHABLE(); \
> 
> If at all possible this wants to trigger a build failure, not a
> runtime
> one.
I'll update that with BUILD_BUG_ON(size > 8);
> 
> > +    } \
> > +    ret__; \
> > +})
> > +
> > +#define xchg_relaxed(ptr, x) \
> > +({ \
> > +    __typeof__(*(ptr)) x_ = (x); \
> > +    (__typeof__(*(ptr))) __xchg_relaxed((ptr), x_,
> > sizeof(*(ptr))); \
> 
> Nit: Stray blank after cast. For readability I'd also suggest to
> drop parentheses in cases like the first argument passed to
> __xchg_relaxed() here.
Thanks. I'll take that into account.

> 
> > +})
> 
> For both: What does "relaxed" describe? I'm asking because it's not
> really clear whether the memory clobbers are actually needed.
> 
> > +#define __xchg_acquire(ptr, new, size) \
> > +({ \
> > +    __typeof__(ptr) ptr__ = (ptr); \
> > +    __typeof__(new) new__ = (new); \
> > +    __typeof__(*(ptr)) ret__; \
> > +    switch (size) \
> > +	{ \
> > +    case 4: \
> > +        asm volatile( \
> > +            "	amoswap.w %0, %2, %1\n" \
> > +            RISCV_ACQUIRE_BARRIER \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory" ); \
> > +        break; \
> > +    case 8: \
> > +        asm volatile( \
> > +            "	amoswap.d %0, %2, %1\n" \
> > +            RISCV_ACQUIRE_BARRIER \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory" ); \
> > +        break; \
> > +    default: \
> > +        ASSERT_UNREACHABLE(); \
> > +    } \
> > +    ret__; \
> > +})
> 
> If I'm not mistaken this differs from __xchg_relaxed() only in the
> use
> of RISCV_ACQUIRE_BARRIER, and ...
> 
> > +#define xchg_acquire(ptr, x) \
> > +({ \
> > +    __typeof__(*(ptr)) x_ = (x); \
> > +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
> > sizeof(*(ptr))); \
> > +})
> > +
> > +#define __xchg_release(ptr, new, size) \
> > +({ \
> > +    __typeof__(ptr) ptr__ = (ptr); \
> > +    __typeof__(new) new__ = (new); \
> > +    __typeof__(*(ptr)) ret__; \
> > +    switch (size) \
> > +	{ \
> > +    case 4: \
> > +        asm volatile ( \
> > +            RISCV_RELEASE_BARRIER \
> > +            "	amoswap.w %0, %2, %1\n" \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory"); \
> > +        break; \
> > +    case 8: \
> > +        asm volatile ( \
> > +            RISCV_RELEASE_BARRIER \
> > +            "	amoswap.d %0, %2, %1\n" \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory"); \
> > +        break; \
> > +    default: \
> > +        ASSERT_UNREACHABLE(); \
> > +    } \
> > +    ret__; \
> > +})
> 
> this only in the use of RISCV_RELEASE_BARRIER. If so they likely want
> folding, to limit redundancy and make eventual updating easier. (Same
> for the cmpxchg helper further down, as it seems.)
Yes, you are right. The difference is only in RISCV_RELEASE_BARRIER and
it is an absence of RISCV_RELEASE_BARRIER is a reason why we have
"relaxed" versions.

I am not sure that I understand what you mean by folding here. Do you
mean that there is no any sense to have to separate macros and it is
needed only one with RISCV_RELEASE_BARRIER?

> 
> > +#define xchg_release(ptr, x) \
> > +({ \
> > +    __typeof__(*(ptr)) x_ = (x); \
> > +    (__typeof__(*(ptr))) __xchg_release((ptr), x_,
> > sizeof(*(ptr))); \
> > +})
> > +
> > +static always_inline uint32_t __xchg_case_4(volatile uint32_t
> > *ptr,
> > +                                            uint32_t new)
> > +{
> > +    __typeof__(*(ptr)) ret;
> > +
> > +    asm volatile (
> > +        "   amoswap.w.aqrl %0, %2, %1\n"
> > +        : "=r" (ret), "+A" (*ptr)
> > +        : "r" (new)
> > +        : "memory" );
> > +
> > +    return ret;
> > +}
> > +
> > +static always_inline uint64_t __xchg_case_8(volatile uint64_t
> > *ptr,
> > +                                            uint64_t new)
> > +{
> > +    __typeof__(*(ptr)) ret;
> > +
> > +    asm volatile( \
> > +        "   amoswap.d.aqrl %0, %2, %1\n" \
> > +        : "=r" (ret), "+A" (*ptr) \
> > +        : "r" (new) \
> > +        : "memory" ); \
> > +
> > +    return ret;
> > +}
> > +
> > +static always_inline unsigned short __cmpxchg_case_2(volatile
> > uint32_t *ptr,
> > +                                                     uint32_t old,
> > +                                                     uint32_t
> > new);
> 
> Don't you consistently mean uint16_t here (incl the return type) and
> ...
> 
> > +static always_inline unsigned short __cmpxchg_case_1(volatile
> > uint32_t *ptr,
> > +                                                     uint32_t old,
> > +                                                     uint32_t
> > new);
> 
> ... uint8_t here?
The idea was that we emulate __cmpxchg_case_1 and __cmpxchg_case_2
using 4 bytes cmpxchg and __cmpxchg_case_4 expects uint32_t.

> 
> > +static inline unsigned long __xchg(volatile void *ptr, unsigned
> > long x, int size)
> > +{
> > +    switch (size) {
> > +    case 1:
> > +        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
> > +    case 2:
> > +        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
> 
> How are these going to work? You'll compare against ~0, and if the
> value
> in memory isn't ~0, memory won't be updated; you will only
> (correctly)
> return the value found in memory.
> 
> Or wait - looking at __cmpxchg_case_{1,2}() far further down, you
> ignore
> "old" there. Which apparently means they'll work for the use here,
> but
> not for the use in __cmpxchg().
Yes, the trick is that old is ignored and is read in
__emulate_cmpxchg_case1_2() before __cmpxchg_case_4 is called:
    do {                                                              
        read_val = read_func(aligned_ptr);                            
        swapped_new = read_val & ~mask;                               
        swapped_new |= masked_new;                                    
        ret = cmpxchg_func(aligned_ptr, read_val, swapped_new);       
    } while ( ret != read_val );                                      
read_val it is 'old'.

But now I am not 100% sure that it is correct for __cmpxchg...

> 
> > +    case 4:
> > +        return __xchg_case_4(ptr, x);
> > +    case 8:
> > +        return __xchg_case_8(ptr, x);
> > +    default:
> > +        ASSERT_UNREACHABLE();
> > +    }
> > +
> > +    return -1;
> > +}
> > +
> > +#define xchg(ptr,x) \
> > +({ \
> > +    __typeof__(*(ptr)) ret__; \
> > +    ret__ = (__typeof__(*(ptr))) \
> > +            __xchg((ptr), (unsigned long)(x), sizeof(*(ptr))); \
> > +    ret__; \
> > +})
> > +
> > +#define xchg32(ptr, x) \
> > +({ \
> > +    BUILD_BUG_ON(sizeof(*(ptr)) != 4); \
> > +    xchg((ptr), (x)); \
> > +})
> > +
> > +#define xchg64(ptr, x) \
> > +({ \
> > +    BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
> > +    xchg((ptr), (x)); \
> > +})
> 
> What are these two (and their cmpxchg counterparts) needed for?
It was copied from Linux, but it looks like they can be really dropped,
I can't find where it is used, so I'll drop them.

> 
> > +/*
> > + * Atomic compare and exchange.  Compare OLD with MEM, if
> > identical,
> > + * store NEW in MEM.  Return the initial value in MEM.  Success is
> > + * indicated by comparing RETURN with OLD.
> > + */
> > +#define __cmpxchg_relaxed(ptr, old, new, size) \
> > +({ \
> > +    __typeof__(ptr) ptr__ = (ptr); \
> > +    __typeof__(*(ptr)) __old = (old); \
> 
> Leftover leading underscores?
> 
> > +    __typeof__(*(ptr)) new__ = (new); \
> 
> Related to my earlier comment on types needing to be compatible - see
> how here you're using "ptr" throughout.
> 
> > +    __typeof__(*(ptr)) ret__; \
> > +    register unsigned int __rc; \
> 
> More leftover leading underscores?
Missed to drop underscores. Thanks. I'll drop them in next version.
> 
> > +static always_inline unsigned short __cmpxchg_case_2(volatile
> > uint32_t *ptr,
> > +                                                     uint32_t old,
> > +                                                     uint32_t new)
> > +{
> > +    (void) old;
> > +
> > +    if (((unsigned long)ptr & 3) == 3)
> > +    {
> > +#ifdef CONFIG_64BIT
> > +        return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
> > +                                         readq, __cmpxchg_case_8,
> > 0xffffU);
> 
> What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of what
> the
> if() above checks for? Isn't it more reasonable to require aligned
> 16-bit quantities here? Or if mis-aligned addresses are okay, you
> could
> as well emulate using __cmpxchg_case_4().
Yes, it will be more reasonable. I'll use IS_ALIGNED instead.

> 
> Also you shouldn't be casting away volatile (here and below).
> Avoiding
> the casts (by suitable using volatile void * parameter types) would
> likely be best.
Thanks. I'll update the function prototype.

~ Oleksii


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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-22 16:56   ` Jan Beulich
@ 2024-01-23 10:21     ` Oleksii
  2024-01-23 10:30       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 10:21 UTC (permalink / raw
  To: Jan Beulich
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
> On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/atomic.h
> > @@ -0,0 +1,384 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Taken and modified from Linux.
> > + * 
> > + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
> > + * Copyright (C) 2012 Regents of the University of California
> > + * Copyright (C) 2017 SiFive
> > + * Copyright (C) 2021 Vates SAS
> > + */
> > +
> > +#ifndef _ASM_RISCV_ATOMIC_H
> > +#define _ASM_RISCV_ATOMIC_H
> > +
> > +#include <xen/atomic.h>
> > +#include <asm/cmpxchg.h>
> > +#include <asm/fence.h>
> > +#include <asm/io.h>
> > +#include <asm/system.h>
> > +
> > +void __bad_atomic_size(void);
> > +
> > +static always_inline void read_atomic_size(const volatile void *p,
> > +                                           void *res,
> > +                                           unsigned int size)
> > +{
> > +    switch ( size )
> > +    {
> > +    case 1: *(uint8_t *)res = readb((const uint8_t *)p); break;
> > +    case 2: *(uint16_t *)res = readw((const uint16_t *)p); break;
> > +    case 4: *(uint32_t *)res = readl((const uint32_t *)p); break;
> > +    case 8: *(uint32_t *)res  = readq((const uint64_t *)p); break;
> 
> Just like const, you should also avoid casting away volatile.
Thanks. I will drop casting.

> 
> > +    default: __bad_atomic_size(); break;
> > +    }
> > +}
> > +
> > +#define read_atomic(p)
> > ({                                               \
> > +    union { typeof(*p) val; char c[0]; }
> > x_;                            \
> > +    read_atomic_size(p, x_.c,
> > sizeof(*p));                              \
> > +   
> > x_.val;                                                            
> > \
> > +})
> > +
> > +
> 
> Nit: No double blank lines please.
Sure. I'll drtop one blank line.
> 
> > +#define write_atomic(p, x)
> > ({                                           \
> > +    typeof(*p) x__ =
> > (x);                                               \
> > +    switch ( sizeof(*p)
> > )												\
> > +   
> > {                                             						\
> 
> These lines look excessively long, possibly as a result of leaving
> hard tabs
> in place.
> 
> Overall some of the style comments on the earlier patch seem to apply
> here
> as well.
> 
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/fence.h
> > @@ -0,0 +1,13 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +#ifndef _ASM_RISCV_FENCE_H
> > +#define _ASM_RISCV_FENCE_H
> > +
> > +#ifdef CONFIG_SMP
> > +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
> > +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
> > +#else
> > +#define RISCV_ACQUIRE_BARRIER
> > +#define RISCV_RELEASE_BARRIER
> > +#endif
> 
> Do you really care about the !SMP case? On x86 at least we stopped
> special-
> casing that configuration many years ago (the few cases where for
> typically
> build reasons it matters, using CONFIG_NR_CPUS is sufficient). If you
> care
> about it, there needs to be somewhere you actually #define
> CONFIG_SMP.
Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS? I missed that
CONFIG_SMP is present in Linux, but not in Xen.

~ Oleksii


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-23 10:15     ` Oleksii
@ 2024-01-23 10:28       ` Jan Beulich
  2024-01-23 12:18         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 10:28 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 11:15, Oleksii wrote:
> On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory" ); \
>>> +        break; \
>>> +    case 8: \
>>> +        asm volatile( \
>>> +            "	amoswap.d %0, %2, %1\n" \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory" ); \
>>> +        break; \
>>> +    default: \
>>> +        ASSERT_UNREACHABLE(); \
>>
>> If at all possible this wants to trigger a build failure, not a
>> runtime
>> one.
> I'll update that with BUILD_BUG_ON(size > 8);

What about size accidentally being e.g. 5? I'm also not sure you'll be
able to use BUILD_BUG_ON() here: That'll depend on what use sites there
are. And if all present ones are okay in this regard, you'd still set
out a trap for someone else to fall into later. We have a common
approach for this, which currently is under re-work. See
https://lists.xen.org/archives/html/xen-devel/2024-01/msg01115.html.

>>> +    } \
>>> +    ret__; \
>>> +})
>>> +
>>> +#define xchg_relaxed(ptr, x) \
>>> +({ \
>>> +    __typeof__(*(ptr)) x_ = (x); \
>>> +    (__typeof__(*(ptr))) __xchg_relaxed((ptr), x_,
>>> sizeof(*(ptr))); \
>>
>> Nit: Stray blank after cast. For readability I'd also suggest to
>> drop parentheses in cases like the first argument passed to
>> __xchg_relaxed() here.
> Thanks. I'll take that into account.
> 
>>
>>> +})
>>
>> For both: What does "relaxed" describe? I'm asking because it's not
>> really clear whether the memory clobbers are actually needed.
>>
>>> +#define __xchg_acquire(ptr, new, size) \
>>> +({ \
>>> +    __typeof__(ptr) ptr__ = (ptr); \
>>> +    __typeof__(new) new__ = (new); \
>>> +    __typeof__(*(ptr)) ret__; \
>>> +    switch (size) \
>>> +	{ \
>>> +    case 4: \
>>> +        asm volatile( \
>>> +            "	amoswap.w %0, %2, %1\n" \
>>> +            RISCV_ACQUIRE_BARRIER \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory" ); \
>>> +        break; \
>>> +    case 8: \
>>> +        asm volatile( \
>>> +            "	amoswap.d %0, %2, %1\n" \
>>> +            RISCV_ACQUIRE_BARRIER \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory" ); \
>>> +        break; \
>>> +    default: \
>>> +        ASSERT_UNREACHABLE(); \
>>> +    } \
>>> +    ret__; \
>>> +})
>>
>> If I'm not mistaken this differs from __xchg_relaxed() only in the
>> use
>> of RISCV_ACQUIRE_BARRIER, and ...
>>
>>> +#define xchg_acquire(ptr, x) \
>>> +({ \
>>> +    __typeof__(*(ptr)) x_ = (x); \
>>> +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
>>> sizeof(*(ptr))); \
>>> +})
>>> +
>>> +#define __xchg_release(ptr, new, size) \
>>> +({ \
>>> +    __typeof__(ptr) ptr__ = (ptr); \
>>> +    __typeof__(new) new__ = (new); \
>>> +    __typeof__(*(ptr)) ret__; \
>>> +    switch (size) \
>>> +	{ \
>>> +    case 4: \
>>> +        asm volatile ( \
>>> +            RISCV_RELEASE_BARRIER \
>>> +            "	amoswap.w %0, %2, %1\n" \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory"); \
>>> +        break; \
>>> +    case 8: \
>>> +        asm volatile ( \
>>> +            RISCV_RELEASE_BARRIER \
>>> +            "	amoswap.d %0, %2, %1\n" \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory"); \
>>> +        break; \
>>> +    default: \
>>> +        ASSERT_UNREACHABLE(); \
>>> +    } \
>>> +    ret__; \
>>> +})
>>
>> this only in the use of RISCV_RELEASE_BARRIER. If so they likely want
>> folding, to limit redundancy and make eventual updating easier. (Same
>> for the cmpxchg helper further down, as it seems.)
> Yes, you are right. The difference is only in RISCV_RELEASE_BARRIER and
> it is an absence of RISCV_RELEASE_BARRIER is a reason why we have
> "relaxed" versions.
> 
> I am not sure that I understand what you mean by folding here. Do you
> mean that there is no any sense to have to separate macros and it is
> needed only one with RISCV_RELEASE_BARRIER?

No. You should parameterize the folded common macro for the derived
macros to simply pass in the barriers needed, with empty macro
arguments indicating "this barrier not needed".

>>> +#define xchg_release(ptr, x) \
>>> +({ \
>>> +    __typeof__(*(ptr)) x_ = (x); \
>>> +    (__typeof__(*(ptr))) __xchg_release((ptr), x_,
>>> sizeof(*(ptr))); \
>>> +})
>>> +
>>> +static always_inline uint32_t __xchg_case_4(volatile uint32_t
>>> *ptr,
>>> +                                            uint32_t new)
>>> +{
>>> +    __typeof__(*(ptr)) ret;
>>> +
>>> +    asm volatile (
>>> +        "   amoswap.w.aqrl %0, %2, %1\n"
>>> +        : "=r" (ret), "+A" (*ptr)
>>> +        : "r" (new)
>>> +        : "memory" );
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static always_inline uint64_t __xchg_case_8(volatile uint64_t
>>> *ptr,
>>> +                                            uint64_t new)
>>> +{
>>> +    __typeof__(*(ptr)) ret;
>>> +
>>> +    asm volatile( \
>>> +        "   amoswap.d.aqrl %0, %2, %1\n" \
>>> +        : "=r" (ret), "+A" (*ptr) \
>>> +        : "r" (new) \
>>> +        : "memory" ); \
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static always_inline unsigned short __cmpxchg_case_2(volatile
>>> uint32_t *ptr,
>>> +                                                     uint32_t old,
>>> +                                                     uint32_t
>>> new);
>>
>> Don't you consistently mean uint16_t here (incl the return type) and
>> ...
>>
>>> +static always_inline unsigned short __cmpxchg_case_1(volatile
>>> uint32_t *ptr,
>>> +                                                     uint32_t old,
>>> +                                                     uint32_t
>>> new);
>>
>> ... uint8_t here?
> The idea was that we emulate __cmpxchg_case_1 and __cmpxchg_case_2
> using 4 bytes cmpxchg and __cmpxchg_case_4 expects uint32_t.

I consider this wrong. The functions would better be type-correct.

>>> +static inline unsigned long __xchg(volatile void *ptr, unsigned
>>> long x, int size)
>>> +{
>>> +    switch (size) {
>>> +    case 1:
>>> +        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
>>> +    case 2:
>>> +        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
>>
>> How are these going to work? You'll compare against ~0, and if the
>> value
>> in memory isn't ~0, memory won't be updated; you will only
>> (correctly)
>> return the value found in memory.
>>
>> Or wait - looking at __cmpxchg_case_{1,2}() far further down, you
>> ignore
>> "old" there. Which apparently means they'll work for the use here,
>> but
>> not for the use in __cmpxchg().
> Yes, the trick is that old is ignored and is read in
> __emulate_cmpxchg_case1_2() before __cmpxchg_case_4 is called:
>     do {                                                              
>         read_val = read_func(aligned_ptr);                            
>         swapped_new = read_val & ~mask;                               
>         swapped_new |= masked_new;                                    
>         ret = cmpxchg_func(aligned_ptr, read_val, swapped_new);       
>     } while ( ret != read_val );                                      
> read_val it is 'old'.
> 
> But now I am not 100% sure that it is correct for __cmpxchg...

It just can't be correct - you can't ignore "old" there. I think you
want simple cmpxchg primitives, which xchg then uses in a loop (while
cmpxchg uses them plainly).

>>> +static always_inline unsigned short __cmpxchg_case_2(volatile
>>> uint32_t *ptr,
>>> +                                                     uint32_t old,
>>> +                                                     uint32_t new)
>>> +{
>>> +    (void) old;
>>> +
>>> +    if (((unsigned long)ptr & 3) == 3)
>>> +    {
>>> +#ifdef CONFIG_64BIT
>>> +        return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
>>> +                                         readq, __cmpxchg_case_8,
>>> 0xffffU);
>>
>> What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of what
>> the
>> if() above checks for? Isn't it more reasonable to require aligned
>> 16-bit quantities here? Or if mis-aligned addresses are okay, you
>> could
>> as well emulate using __cmpxchg_case_4().
> Yes, it will be more reasonable. I'll use IS_ALIGNED instead.

Not sure I get your use of "instead" here correctly. There's more
to change here than just the if() condition.

Jan


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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-23 10:21     ` Oleksii
@ 2024-01-23 10:30       ` Jan Beulich
  2024-01-23 12:24         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 10:30 UTC (permalink / raw
  To: Oleksii
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 11:21, Oleksii wrote:
> On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>> --- /dev/null
>>> +++ b/xen/arch/riscv/include/asm/fence.h
>>> @@ -0,0 +1,13 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>> +#ifndef _ASM_RISCV_FENCE_H
>>> +#define _ASM_RISCV_FENCE_H
>>> +
>>> +#ifdef CONFIG_SMP
>>> +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
>>> +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
>>> +#else
>>> +#define RISCV_ACQUIRE_BARRIER
>>> +#define RISCV_RELEASE_BARRIER
>>> +#endif
>>
>> Do you really care about the !SMP case? On x86 at least we stopped
>> special-
>> casing that configuration many years ago (the few cases where for
>> typically
>> build reasons it matters, using CONFIG_NR_CPUS is sufficient). If you
>> care
>> about it, there needs to be somewhere you actually #define
>> CONFIG_SMP.
> Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS?

You can. Question is whether there's a point in doing so. Do you
expect people to actually want to run Xen on single-CPU systems?
They're generally not overly well suited for virtualization ...

Jan


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2023-12-22 15:13 ` [PATCH v3 16/34] xen/lib: introduce generic find next bit operations Oleksii Kurochko
@ 2024-01-23 11:14   ` Jan Beulich
  2024-01-23 12:34     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:14 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> --- a/xen/arch/riscv/include/asm/fence.h
> +++ b/xen/arch/riscv/include/asm/fence.h
> @@ -1,4 +1,4 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* SPDX-License-Identifier: GPL-2.0-only */
>  #ifndef _ASM_RISCV_FENCE_H
>  #define _ASM_RISCV_FENCE_H
>  
> @@ -11,3 +11,12 @@
>  #endif
>  
>  #endif	/* _ASM_RISCV_FENCE_H */
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */

Surely all of this wants doing in the previous patch, where the header
is introduced?

> --- a/xen/common/Kconfig
> +++ b/xen/common/Kconfig
> @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
>  config GENERIC_BUG_FRAME
>  	bool
>  
> +config GENERIC_FIND_NEXT_BIT
> +	bool

There's no need for this, as ...

> --- a/xen/lib/Makefile
> +++ b/xen/lib/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
>  lib-y += bsearch.o
>  lib-y += ctors.o
>  lib-y += ctype.o
> +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o

... you're moving this to lib/. Or have you encountered any issue
with building this uniformly, and you forgot to mention this in
the description?

> --- /dev/null
> +++ b/xen/lib/find-next-bit.c
> @@ -0,0 +1,281 @@
> +/* find_next_bit.c: fallback find next bit implementation
> + *
> + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
> + * Written by David Howells (dhowells@redhat.com)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +#include <xen/bitops.h>
> +
> +#include <asm/byteorder.h>
> +
> +#ifndef find_next_bit
> +/*
> + * Find the next set bit in a memory region.
> + */
> +unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
> +			    unsigned long offset)
> +{
> +	const unsigned long *p = addr + BIT_WORD(offset);
> +	unsigned long result = offset & ~(BITS_PER_LONG-1);
> +	unsigned long tmp;
> +
> +	if (offset >= size)
> +		return size;
> +	size -= result;
> +	offset %= BITS_PER_LONG;
> +	if (offset) {
> +		tmp = *(p++);
> +		tmp &= (~0UL << offset);
> +		if (size < BITS_PER_LONG)
> +			goto found_first;
> +		if (tmp)
> +			goto found_middle;
> +		size -= BITS_PER_LONG;
> +		result += BITS_PER_LONG;
> +	}
> +	while (size & ~(BITS_PER_LONG-1)) {
> +		if ((tmp = *(p++)))
> +			goto found_middle;
> +		result += BITS_PER_LONG;
> +		size -= BITS_PER_LONG;
> +	}
> +	if (!size)
> +		return result;
> +	tmp = *p;
> +
> +found_first:
> +	tmp &= (~0UL >> (BITS_PER_LONG - size));
> +	if (tmp == 0UL)		/* Are any bits set? */
> +		return result + size;	/* Nope. */
> +found_middle:
> +	return result + __ffs(tmp);
> +}
> +EXPORT_SYMBOL(find_next_bit);
> +#endif
> +
> +#ifndef find_next_zero_bit
> +/*
> + * This implementation of find_{first,next}_zero_bit was stolen from
> + * Linus' asm-alpha/bitops.h.
> + */
> +unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
> +				 unsigned long offset)
> +{
> +	const unsigned long *p = addr + BIT_WORD(offset);
> +	unsigned long result = offset & ~(BITS_PER_LONG-1);
> +	unsigned long tmp;
> +
> +	if (offset >= size)
> +		return size;
> +	size -= result;
> +	offset %= BITS_PER_LONG;
> +	if (offset) {
> +		tmp = *(p++);
> +		tmp |= ~0UL >> (BITS_PER_LONG - offset);
> +		if (size < BITS_PER_LONG)
> +			goto found_first;
> +		if (~tmp)
> +			goto found_middle;
> +		size -= BITS_PER_LONG;
> +		result += BITS_PER_LONG;
> +	}
> +	while (size & ~(BITS_PER_LONG-1)) {
> +		if (~(tmp = *(p++)))
> +			goto found_middle;
> +		result += BITS_PER_LONG;
> +		size -= BITS_PER_LONG;
> +	}
> +	if (!size)
> +		return result;
> +	tmp = *p;
> +
> +found_first:
> +	tmp |= ~0UL << size;
> +	if (tmp == ~0UL)	/* Are any bits zero? */
> +		return result + size;	/* Nope. */
> +found_middle:
> +	return result + ffz(tmp);
> +}
> +EXPORT_SYMBOL(find_next_zero_bit);
> +#endif
> +
> +#ifndef find_first_bit
> +/*
> + * Find the first set bit in a memory region.
> + */
> +unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
> +{
> +	const unsigned long *p = addr;
> +	unsigned long result = 0;
> +	unsigned long tmp;
> +
> +	while (size & ~(BITS_PER_LONG-1)) {
> +		if ((tmp = *(p++)))
> +			goto found;
> +		result += BITS_PER_LONG;
> +		size -= BITS_PER_LONG;
> +	}
> +	if (!size)
> +		return result;
> +
> +	tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
> +	if (tmp == 0UL)		/* Are any bits set? */
> +		return result + size;	/* Nope. */
> +found:
> +	return result + __ffs(tmp);
> +}
> +EXPORT_SYMBOL(find_first_bit);
> +#endif
> +
> +#ifndef find_first_zero_bit
> +/*
> + * Find the first cleared bit in a memory region.
> + */
> +unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
> +{
> +	const unsigned long *p = addr;
> +	unsigned long result = 0;
> +	unsigned long tmp;
> +
> +	while (size & ~(BITS_PER_LONG-1)) {
> +		if (~(tmp = *(p++)))
> +			goto found;
> +		result += BITS_PER_LONG;
> +		size -= BITS_PER_LONG;
> +	}
> +	if (!size)
> +		return result;
> +
> +	tmp = (*p) | (~0UL << size);
> +	if (tmp == ~0UL)	/* Are any bits zero? */
> +		return result + size;	/* Nope. */
> +found:
> +	return result + ffz(tmp);
> +}
> +EXPORT_SYMBOL(find_first_zero_bit);
> +#endif
> +
> +#ifdef __BIG_ENDIAN
> +
> +/* include/linux/byteorder does not support "unsigned long" type */
> +static inline unsigned long ext2_swabp(const unsigned long * x)
> +{
> +#if BITS_PER_LONG == 64
> +	return (unsigned long) __swab64p((u64 *) x);
> +#elif BITS_PER_LONG == 32
> +	return (unsigned long) __swab32p((u32 *) x);
> +#else
> +#error BITS_PER_LONG not defined
> +#endif
> +}
> +
> +/* include/linux/byteorder doesn't support "unsigned long" type */
> +static inline unsigned long ext2_swab(const unsigned long y)
> +{
> +#if BITS_PER_LONG == 64
> +	return (unsigned long) __swab64((u64) y);
> +#elif BITS_PER_LONG == 32
> +	return (unsigned long) __swab32((u32) y);
> +#else
> +#error BITS_PER_LONG not defined
> +#endif
> +}
> +
> +#ifndef find_next_zero_bit_le
> +unsigned long find_next_zero_bit_le(const void *addr, unsigned
> +		long size, unsigned long offset)
> +{
> +	const unsigned long *p = addr;
> +	unsigned long result = offset & ~(BITS_PER_LONG - 1);
> +	unsigned long tmp;
> +
> +	if (offset >= size)
> +		return size;
> +	p += BIT_WORD(offset);
> +	size -= result;
> +	offset &= (BITS_PER_LONG - 1UL);
> +	if (offset) {
> +		tmp = ext2_swabp(p++);
> +		tmp |= (~0UL >> (BITS_PER_LONG - offset));
> +		if (size < BITS_PER_LONG)
> +			goto found_first;
> +		if (~tmp)
> +			goto found_middle;
> +		size -= BITS_PER_LONG;
> +		result += BITS_PER_LONG;
> +	}
> +
> +	while (size & ~(BITS_PER_LONG - 1)) {
> +		if (~(tmp = *(p++)))
> +			goto found_middle_swap;
> +		result += BITS_PER_LONG;
> +		size -= BITS_PER_LONG;
> +	}
> +	if (!size)
> +		return result;
> +	tmp = ext2_swabp(p);
> +found_first:
> +	tmp |= ~0UL << size;
> +	if (tmp == ~0UL)	/* Are any bits zero? */
> +		return result + size; /* Nope. Skip ffz */
> +found_middle:
> +	return result + ffz(tmp);
> +
> +found_middle_swap:
> +	return result + ffz(ext2_swab(tmp));
> +}
> +EXPORT_SYMBOL(find_next_zero_bit_le);
> +#endif
> +
> +#ifndef find_next_bit_le
> +unsigned long find_next_bit_le(const void *addr, unsigned
> +		long size, unsigned long offset)
> +{
> +	const unsigned long *p = addr;
> +	unsigned long result = offset & ~(BITS_PER_LONG - 1);
> +	unsigned long tmp;
> +
> +	if (offset >= size)
> +		return size;
> +	p += BIT_WORD(offset);
> +	size -= result;
> +	offset &= (BITS_PER_LONG - 1UL);
> +	if (offset) {
> +		tmp = ext2_swabp(p++);
> +		tmp &= (~0UL << offset);
> +		if (size < BITS_PER_LONG)
> +			goto found_first;
> +		if (tmp)
> +			goto found_middle;
> +		size -= BITS_PER_LONG;
> +		result += BITS_PER_LONG;
> +	}
> +
> +	while (size & ~(BITS_PER_LONG - 1)) {
> +		tmp = *(p++);
> +		if (tmp)
> +			goto found_middle_swap;
> +		result += BITS_PER_LONG;
> +		size -= BITS_PER_LONG;
> +	}
> +	if (!size)
> +		return result;
> +	tmp = ext2_swabp(p);
> +found_first:
> +	tmp &= (~0UL >> (BITS_PER_LONG - size));
> +	if (tmp == 0UL)		/* Are any bits set? */
> +		return result + size; /* Nope. */
> +found_middle:
> +	return result + __ffs(tmp);
> +
> +found_middle_swap:
> +	return result + __ffs(ext2_swab(tmp));
> +}
> +EXPORT_SYMBOL(find_next_bit_le);
> +#endif
> +
> +#endif /* __BIG_ENDIAN */

I was going to ask that you convince git to actually present a proper
diff, to make visible what changes. But other than the description says
you don't really move the file, you copy it. Judging from further titles
there's also nowhere you'd make Arm actually use this now generic code.

Jan


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

* Re: [PATCH v3 19/34] xen/riscv: introduce guest_access.h
  2023-12-22 15:13 ` [PATCH v3 19/34] xen/riscv: introduce guest_access.h Oleksii Kurochko
@ 2024-01-23 11:16   ` Jan Beulich
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:16 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> All necessary dummiy implementation of functions in this header
> will be introduced in stubs.c
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>

Acked-by: Jan Beulich <jbeulich@suse.com>




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

* Re: [PATCH v3 20/34] xen/riscv: introduce irq.h
  2023-12-22 15:13 ` [PATCH v3 20/34] xen/riscv: introduce irq.h Oleksii Kurochko
@ 2024-01-23 11:18   ` Jan Beulich
  2024-01-23 12:25     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:18 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> +static inline void arch_move_irqs(struct vcpu *v)
> +{
> +    BUG();
> +}

As I think you said you're doing the conversion already - with this
becoming the "canonical" BUG_ON("unimplemented"):
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan


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

* Re: [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64
  2023-12-22 15:13 ` [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64 Oleksii Kurochko
@ 2024-01-23 11:22   ` Jan Beulich
  2024-01-23 14:49     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:22 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
>  Changes in V3:
>   - new patch
> ---
>  README | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/README b/README
> index c8a108449e..1015a285c0 100644
> --- a/README
> +++ b/README
> @@ -48,6 +48,9 @@ provided by your OS distributor:
>        - For ARM 64-bit:
>          - GCC 5.1 or later
>          - GNU Binutils 2.24 or later
> +      - For RISC-V 64-bit:
> +        - GCC 13.2.1 or later
> +        - GNU Binutils 2.40 or later

That's pretty new. For gcc that's even newer than the newest release.
If older versions really won't do, I don't think you can leave this
unjustified (by having an empty description). Till now gcc 13.2 has
served me well, and iirc 13.1, 12.3, and 12.2 were fine, too.

Jan


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

* Re: [PATCH v3 27/34] xen/riscv: define an address of frame table
  2023-12-22 15:13 ` [PATCH v3 27/34] xen/riscv: define an address of frame table Oleksii Kurochko
@ 2024-01-23 11:32   ` Jan Beulich
  2024-01-23 16:50     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:32 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> Also, the patch adds some helpful macros that assist in avoiding
> the redefinition of memory layout for each MMU mode.
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - drop OFFSET_BITS, and use PAGE_SHIFT instead.
>  - code style fixes.
>  - add comment how macros are useful.
>  - move all memory related layout definitions close to comment with memory layout description.
>  - make memory layout description generic for any MMU mode.
> ---
> Changes in V2:
>  - Nothing changed. Only rebase.
> ---
>  xen/arch/riscv/include/asm/config.h | 85 +++++++++++++++++++----------
>  1 file changed, 55 insertions(+), 30 deletions(-)
> 
> diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/asm/config.h
> index f0544c6a20..fb9fc9daaa 100644
> --- a/xen/arch/riscv/include/asm/config.h
> +++ b/xen/arch/riscv/include/asm/config.h
> @@ -6,6 +6,14 @@
>  #include <xen/const.h>
>  #include <xen/page-size.h>
>  
> +#ifdef CONFIG_RISCV_64
> +#define CONFIG_PAGING_LEVELS 3
> +#define RV_STAGE1_MODE SATP_MODE_SV39
> +#else
> +#define CONFIG_PAGING_LEVELS 2
> +#define RV_STAGE1_MODE SATP_MODE_SV32
> +#endif
> +
>  /*
>   * RISC-V64 Layout:
>   *
> @@ -22,25 +30,56 @@
>   *
>   * It means that:
>   *   top VA bits are simply ignored for the purpose of translating to PA.
> +#endif
>   *
> - * ============================================================================
> - *    Start addr    |   End addr        |  Size  | Slot       |area description
> - * ============================================================================
> - * FFFFFFFFC0800000 |  FFFFFFFFFFFFFFFF |1016 MB | L2 511     | Unused
> - * FFFFFFFFC0600000 |  FFFFFFFFC0800000 |  2 MB  | L2 511     | Fixmap
> - * FFFFFFFFC0200000 |  FFFFFFFFC0600000 |  4 MB  | L2 511     | FDT
> - * FFFFFFFFC0000000 |  FFFFFFFFC0200000 |  2 MB  | L2 511     | Xen
> - *                 ...                  |  1 GB  | L2 510     | Unused
> - * 0000003200000000 |  0000007F80000000 | 309 GB | L2 200-509 | Direct map
> - *                 ...                  |  1 GB  | L2 199     | Unused
> - * 0000003100000000 |  00000031C0000000 |  3 GB  | L2 196-198 | Frametable
> - *                 ...                  |  1 GB  | L2 195     | Unused
> - * 0000003080000000 |  00000030C0000000 |  1 GB  | L2 194     | VMAP
> - *                 ...                  | 194 GB | L2 0 - 193 | Unused
> - * ============================================================================
> + *       SATP_MODE_SV32   | SATP_MODE_SV39   | SATP_MODE_SV48   | SATP_MODE_SV57
> + *      ==================|==================|==================|=================
> + * BA0 | FFFFFFFFFFE00000 | FFFFFFFFC0000000 | FFFFFF8000000000 | FFFF000000000000
> + * BA1 | 0000000019000000 | 0000003200000000 | 0000640000000000 | 00C8000000000000
> + * BA2 | 0000000018800000 | 0000003100000000 | 0000620000000000 | 00C4000000000000
> + * BA3 | 0000000018400000 | 0000003080000000 | 0000610000000000 | 00C2000000000000
>   *
> -#endif
> + * ===============================================================================
> + * Start addr     |   End addr          |  Size  | Root PT slot | Area description
> + * ===============================================================================
> + * BA0 + 0x800000 |  FFFFFFFFFFFFFFFF   |1016 MB |     511      | Unused
> + * BA0 + 0x400000 |  BA0 + 0x800000     |  2 MB  |     511      | Fixmap
> + * BA0 + 0x200000 |  BA0 + 0x400000     |  4 MB  |     511      | FDT
> + * BA0            |  BA0 + 0x200000     |  2 MB  |     511      | Xen
> + *                 ...                  |  1 GB  |     510      | Unused
> + * BA1 + 0x000000 |  BA1 + 0x4D80000000 | 309 GB |   200-509    | Direct map

This definitely can't be right for SV32. Others may be problematic,
too, like ...

> + *                 ...                  |  1 GB  |     199      | Unused
> + * BA2 + 0x000000 |  BA2 + 0xC0000000   |  3 GB  |   196-198    | Frametable

... this one. Otoh I'd expect both to potentially be much larger in
SV48 and SV57 modes.

> + *                 ...                  |  1 GB  |     195      | Unused
> + * BA3 + 0x000000 |  BA3 + 0x40000000   |  1 GB  |     194      | VMAP
> + *                 ...                  | 194 GB |   0 - 193    | Unused
> + * ===============================================================================
>   */
> +#define VPN_BITS    (9)

This need to move ...

> +#define HYP_PT_ROOT_LEVEL (CONFIG_PAGING_LEVELS - 1)
> +
> +#ifdef CONFIG_RISCV_64

... here, I think, for not being applicable to SV32?

> +#define SLOTN_ENTRY_BITS        (HYP_PT_ROOT_LEVEL * VPN_BITS + PAGE_SHIFT)
> +#define SLOTN(slot)             (_AT(vaddr_t, slot) << SLOTN_ENTRY_BITS)
> +#define SLOTN_ENTRY_SIZE        SLOTN(1)

Do you have any example of how/where this going to be used?

> +#define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 - GB(1)) */

Won't /* -GB(1) */ do, thus allowing the line to also be padded such that
it matches neighboring ones in layout?

Jan

> +#define FRAMETABLE_VIRT_START   SLOTN(196)
> +#define FRAMETABLE_SIZE         GB(3)
> +#define FRAMETABLE_NR           (FRAMETABLE_SIZE / sizeof(*frame_table))
> +#define FRAMETABLE_VIRT_END     (FRAMETABLE_VIRT_START + FRAMETABLE_SIZE - 1)
> +
> +#define VMAP_VIRT_START         SLOTN(194)
> +#define VMAP_VIRT_SIZE          GB(1)
>[...]



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

* Re: [PATCH v3 28/34] xen/riscv: add required things to current.h
  2023-12-22 15:13 ` [PATCH v3 28/34] xen/riscv: add required things to current.h Oleksii Kurochko
@ 2024-01-23 11:35   ` Jan Beulich
  2024-01-23 16:52     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:35 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:> --- a/xen/arch/riscv/include/asm/current.h
> +++ b/xen/arch/riscv/include/asm/current.h
> @@ -3,6 +3,21 @@
>  #ifndef __ASM_CURRENT_H
>  #define __ASM_CURRENT_H
>  
> +#include <xen/bug.h>
> +#include <xen/percpu.h>
> +#include <asm/processor.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +/* Which VCPU is "current" on this PCPU. */
> +DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
> +
> +#define current            this_cpu(curr_vcpu)
> +#define set_current(vcpu)  do { current = (vcpu); } while (0)
> +#define get_cpu_current(cpu)  per_cpu(curr_vcpu, cpu)
> +
> +#define guest_cpu_user_regs() ({ BUG(); NULL; })

Again with this changed to the "canonical" placeholder:
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan


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

* Re: [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen
  2023-12-22 15:13 ` [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen Oleksii Kurochko
@ 2024-01-23 11:36   ` Jan Beulich
  2024-01-23 16:54     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:36 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
> ---
> Changes in V3:
>  - update the commit message

Once again I find this puzzling, considering there's no commit message
at all.

Jan


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2023-12-22 15:13 ` [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h " Oleksii Kurochko
@ 2024-01-23 11:39   ` Jan Beulich
  2024-01-23 17:08     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 11:39 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - Update the commit message

??? (again)

> @@ -53,6 +56,18 @@ struct cpu_user_regs
>      unsigned long pregs;
>  };
>  
> +/* TODO: need to implement */
> +#define cpu_to_core(cpu)   (0)
> +#define cpu_to_socket(cpu) (0)
> +
> +static inline void cpu_relax(void)
> +{
> +    /* Encoding of the pause instruction */
> +    __asm__ __volatile__ ( ".insn 0x100000F" );

binutils 2.40 knows "pause" - why use .insn then?

> +    barrier();

Why?

Jan


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-23 10:28       ` Jan Beulich
@ 2024-01-23 12:18         ` Oleksii
  2024-01-23 13:27           ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 12:18 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 11:28 +0100, Jan Beulich wrote:
> On 23.01.2024 11:15, Oleksii wrote:
> > On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory" ); \
> > > > +        break; \
> > > > +    case 8: \
> > > > +        asm volatile( \
> > > > +            "	amoswap.d %0, %2, %1\n" \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory" ); \
> > > > +        break; \
> > > > +    default: \
> > > > +        ASSERT_UNREACHABLE(); \
> > > 
> > > If at all possible this wants to trigger a build failure, not a
> > > runtime
> > > one.
> > I'll update that with BUILD_BUG_ON(size > 8);
> 
> What about size accidentally being e.g. 5? I'm also not sure you'll
> be
> able to use BUILD_BUG_ON() here: That'll depend on what use sites
> there
> are. And if all present ones are okay in this regard, you'd still set
> out a trap for someone else to fall into later. We have a common
> approach for this, which currently is under re-work. See
> https://lists.xen.org/archives/html/xen-devel/2024-01/msg01115.html.
Thanks. I'll use that.

> 
> > > > +    } \
> > > > +    ret__; \
> > > > +})
> > > > +
> > > > +#define xchg_relaxed(ptr, x) \
> > > > +({ \
> > > > +    __typeof__(*(ptr)) x_ = (x); \
> > > > +    (__typeof__(*(ptr))) __xchg_relaxed((ptr), x_,
> > > > sizeof(*(ptr))); \
> > > 
> > > Nit: Stray blank after cast. For readability I'd also suggest to
> > > drop parentheses in cases like the first argument passed to
> > > __xchg_relaxed() here.
> > Thanks. I'll take that into account.
> > 
> > > 
> > > > +})
> > > 
> > > For both: What does "relaxed" describe? I'm asking because it's
> > > not
> > > really clear whether the memory clobbers are actually needed.
> > > 
> > > > +#define __xchg_acquire(ptr, new, size) \
> > > > +({ \
> > > > +    __typeof__(ptr) ptr__ = (ptr); \
> > > > +    __typeof__(new) new__ = (new); \
> > > > +    __typeof__(*(ptr)) ret__; \
> > > > +    switch (size) \
> > > > +	{ \
> > > > +    case 4: \
> > > > +        asm volatile( \
> > > > +            "	amoswap.w %0, %2, %1\n" \
> > > > +            RISCV_ACQUIRE_BARRIER \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory" ); \
> > > > +        break; \
> > > > +    case 8: \
> > > > +        asm volatile( \
> > > > +            "	amoswap.d %0, %2, %1\n" \
> > > > +            RISCV_ACQUIRE_BARRIER \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory" ); \
> > > > +        break; \
> > > > +    default: \
> > > > +        ASSERT_UNREACHABLE(); \
> > > > +    } \
> > > > +    ret__; \
> > > > +})
> > > 
> > > If I'm not mistaken this differs from __xchg_relaxed() only in
> > > the
> > > use
> > > of RISCV_ACQUIRE_BARRIER, and ...
> > > 
> > > > +#define xchg_acquire(ptr, x) \
> > > > +({ \
> > > > +    __typeof__(*(ptr)) x_ = (x); \
> > > > +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
> > > > sizeof(*(ptr))); \
> > > > +})
> > > > +
> > > > +#define __xchg_release(ptr, new, size) \
> > > > +({ \
> > > > +    __typeof__(ptr) ptr__ = (ptr); \
> > > > +    __typeof__(new) new__ = (new); \
> > > > +    __typeof__(*(ptr)) ret__; \
> > > > +    switch (size) \
> > > > +	{ \
> > > > +    case 4: \
> > > > +        asm volatile ( \
> > > > +            RISCV_RELEASE_BARRIER \
> > > > +            "	amoswap.w %0, %2, %1\n" \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory"); \
> > > > +        break; \
> > > > +    case 8: \
> > > > +        asm volatile ( \
> > > > +            RISCV_RELEASE_BARRIER \
> > > > +            "	amoswap.d %0, %2, %1\n" \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory"); \
> > > > +        break; \
> > > > +    default: \
> > > > +        ASSERT_UNREACHABLE(); \
> > > > +    } \
> > > > +    ret__; \
> > > > +})
> > > 
> > > this only in the use of RISCV_RELEASE_BARRIER. If so they likely
> > > want
> > > folding, to limit redundancy and make eventual updating easier.
> > > (Same
> > > for the cmpxchg helper further down, as it seems.)
> > Yes, you are right. The difference is only in RISCV_RELEASE_BARRIER
> > and
> > it is an absence of RISCV_RELEASE_BARRIER is a reason why we have
> > "relaxed" versions.
> > 
> > I am not sure that I understand what you mean by folding here. Do
> > you
> > mean that there is no any sense to have to separate macros and it
> > is
> > needed only one with RISCV_RELEASE_BARRIER?
> 
> No. You should parameterize the folded common macro for the derived
> macros to simply pass in the barriers needed, with empty macro
> arguments indicating "this barrier not needed".
Now it makes sense to me. Thank you for explanation.

> 
> > > > +#define xchg_release(ptr, x) \
> > > > +({ \
> > > > +    __typeof__(*(ptr)) x_ = (x); \
> > > > +    (__typeof__(*(ptr))) __xchg_release((ptr), x_,
> > > > sizeof(*(ptr))); \
> > > > +})
> > > > +
> > > > +static always_inline uint32_t __xchg_case_4(volatile uint32_t
> > > > *ptr,
> > > > +                                            uint32_t new)
> > > > +{
> > > > +    __typeof__(*(ptr)) ret;
> > > > +
> > > > +    asm volatile (
> > > > +        "   amoswap.w.aqrl %0, %2, %1\n"
> > > > +        : "=r" (ret), "+A" (*ptr)
> > > > +        : "r" (new)
> > > > +        : "memory" );
> > > > +
> > > > +    return ret;
> > > > +}
> > > > +
> > > > +static always_inline uint64_t __xchg_case_8(volatile uint64_t
> > > > *ptr,
> > > > +                                            uint64_t new)
> > > > +{
> > > > +    __typeof__(*(ptr)) ret;
> > > > +
> > > > +    asm volatile( \
> > > > +        "   amoswap.d.aqrl %0, %2, %1\n" \
> > > > +        : "=r" (ret), "+A" (*ptr) \
> > > > +        : "r" (new) \
> > > > +        : "memory" ); \
> > > > +
> > > > +    return ret;
> > > > +}
> > > > +
> > > > +static always_inline unsigned short __cmpxchg_case_2(volatile
> > > > uint32_t *ptr,
> > > > +                                                     uint32_t
> > > > old,
> > > > +                                                     uint32_t
> > > > new);
> > > 
> > > Don't you consistently mean uint16_t here (incl the return type)
> > > and
> > > ...
> > > 
> > > > +static always_inline unsigned short __cmpxchg_case_1(volatile
> > > > uint32_t *ptr,
> > > > +                                                     uint32_t
> > > > old,
> > > > +                                                     uint32_t
> > > > new);
> > > 
> > > ... uint8_t here?
> > The idea was that we emulate __cmpxchg_case_1 and __cmpxchg_case_2
> > using 4 bytes cmpxchg and __cmpxchg_case_4 expects uint32_t.
> 
> I consider this wrong. The functions would better be type-correct.
> 
> > > > +static inline unsigned long __xchg(volatile void *ptr,
> > > > unsigned
> > > > long x, int size)
> > > > +{
> > > > +    switch (size) {
> > > > +    case 1:
> > > > +        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
> > > > +    case 2:
> > > > +        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
> > > 
> > > How are these going to work? You'll compare against ~0, and if
> > > the
> > > value
> > > in memory isn't ~0, memory won't be updated; you will only
> > > (correctly)
> > > return the value found in memory.
> > > 
> > > Or wait - looking at __cmpxchg_case_{1,2}() far further down, you
> > > ignore
> > > "old" there. Which apparently means they'll work for the use
> > > here,
> > > but
> > > not for the use in __cmpxchg().
> > Yes, the trick is that old is ignored and is read in
> > __emulate_cmpxchg_case1_2() before __cmpxchg_case_4 is called:
> >     do
> > {                                                              
> >         read_val =
> > read_func(aligned_ptr);                            
> >         swapped_new = read_val &
> > ~mask;                               
> >         swapped_new |=
> > masked_new;                                    
> >         ret = cmpxchg_func(aligned_ptr, read_val,
> > swapped_new);       
> >     } while ( ret != read_val
> > );                                      
> > read_val it is 'old'.
> > 
> > But now I am not 100% sure that it is correct for __cmpxchg...
> 
> It just can't be correct - you can't ignore "old" there. I think you
> want simple cmpxchg primitives, which xchg then uses in a loop (while
> cmpxchg uses them plainly).
But xchg doesn't require 'old' value, so it should be ignored in some
way by cmpxchg.

> 
> > > > +static always_inline unsigned short __cmpxchg_case_2(volatile
> > > > uint32_t *ptr,
> > > > +                                                     uint32_t
> > > > old,
> > > > +                                                     uint32_t
> > > > new)
> > > > +{
> > > > +    (void) old;
> > > > +
> > > > +    if (((unsigned long)ptr & 3) == 3)
> > > > +    {
> > > > +#ifdef CONFIG_64BIT
> > > > +        return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
> > > > +                                         readq,
> > > > __cmpxchg_case_8,
> > > > 0xffffU);
> > > 
> > > What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of
> > > what
> > > the
> > > if() above checks for? Isn't it more reasonable to require
> > > aligned
> > > 16-bit quantities here? Or if mis-aligned addresses are okay, you
> > > could
> > > as well emulate using __cmpxchg_case_4().
> > Yes, it will be more reasonable. I'll use IS_ALIGNED instead.
> 
> Not sure I get your use of "instead" here correctly. There's more
> to change here than just the if() condition.
I meant something like:

if ( IS_ALIGNED(ptr, 16) )
    __emulate_cmpxchg_case1_2(...);
else
    assert_failed("ptr isn't aligned\n");

I have to check if it is necessary to have an mis-aligned address for
CAS intstuctions.

If mis-aligned address is okay then it looks like we can use always 
__cmpxchng_case_4 without checking if a ptr is ALIGNED or not. Or I
started to loose something...

~ Oleksii

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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-23 10:30       ` Jan Beulich
@ 2024-01-23 12:24         ` Oleksii
  2024-01-23 13:30           ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 12:24 UTC (permalink / raw
  To: Jan Beulich
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 11:30 +0100, Jan Beulich wrote:
> On 23.01.2024 11:21, Oleksii wrote:
> > On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > --- /dev/null
> > > > +++ b/xen/arch/riscv/include/asm/fence.h
> > > > @@ -0,0 +1,13 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > > +#ifndef _ASM_RISCV_FENCE_H
> > > > +#define _ASM_RISCV_FENCE_H
> > > > +
> > > > +#ifdef CONFIG_SMP
> > > > +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
> > > > +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
> > > > +#else
> > > > +#define RISCV_ACQUIRE_BARRIER
> > > > +#define RISCV_RELEASE_BARRIER
> > > > +#endif
> > > 
> > > Do you really care about the !SMP case? On x86 at least we
> > > stopped
> > > special-
> > > casing that configuration many years ago (the few cases where for
> > > typically
> > > build reasons it matters, using CONFIG_NR_CPUS is sufficient). If
> > > you
> > > care
> > > about it, there needs to be somewhere you actually #define
> > > CONFIG_SMP.
> > Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS?
> 
> You can. Question is whether there's a point in doing so. Do you
> expect people to actually want to run Xen on single-CPU systems?
> They're generally not overly well suited for virtualization ...
Just to clarify.

Do you mean physically single based CPU?
Then I don't expect to run Xen on such systems and it is not nesessary
to define *_BARRIER in this case. Should we have to add build error
notification that we don't support single-CPU systems in this header?

If you are speaking about we have ,let it be, 4 CPUs and only 1 CPU is
currently supported by Xen then it still makes sense.

~ Oleksii


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

* Re: [PATCH v3 20/34] xen/riscv: introduce irq.h
  2024-01-23 11:18   ` Jan Beulich
@ 2024-01-23 12:25     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-23 12:25 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 12:18 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > +static inline void arch_move_irqs(struct vcpu *v)
> > +{
> > +    BUG();
> > +}
> 
> As I think you said you're doing the conversion already - with this
> becoming the "canonical" BUG_ON("unimplemented"):
> Acked-by: Jan Beulich <jbeulich@suse.com>
Missed that, I'll update that in my next patch version.

Thanks.

~ Oleksii


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-23 11:14   ` Jan Beulich
@ 2024-01-23 12:34     ` Oleksii
  2024-01-23 13:37       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 12:34 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > --- a/xen/arch/riscv/include/asm/fence.h
> > +++ b/xen/arch/riscv/include/asm/fence.h
> > @@ -1,4 +1,4 @@
> > -/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> >  #ifndef _ASM_RISCV_FENCE_H
> >  #define _ASM_RISCV_FENCE_H
> >  
> > @@ -11,3 +11,12 @@
> >  #endif
> >  
> >  #endif	/* _ASM_RISCV_FENCE_H */
> > +
> > +/*
> > + * Local variables:
> > + * mode: C
> > + * c-file-style: "BSD"
> > + * c-basic-offset: 4
> > + * indent-tabs-mode: nil
> > + * End:
> > + */
> 
> Surely all of this wants doing in the previous patch, where the
> header
> is introduced?
Yes, it should be in the previous patch. I'll do the proper rebase.

> 
> > --- a/xen/common/Kconfig
> > +++ b/xen/common/Kconfig
> > @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
> >  config GENERIC_BUG_FRAME
> >  	bool
> >  
> > +config GENERIC_FIND_NEXT_BIT
> > +	bool
> 
> There's no need for this, as ...
> 
> > --- a/xen/lib/Makefile
> > +++ b/xen/lib/Makefile
> > @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
> >  lib-y += bsearch.o
> >  lib-y += ctors.o
> >  lib-y += ctype.o
> > +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
> 
> ... you're moving this to lib/. Or have you encountered any issue
> with building this uniformly, and you forgot to mention this in
> the description?
I didn't check. My intention was to provide opportunity to check if an
architecture want to use generic version or not. Otherwise, I expected
that we will have multiple definiotion of the funcion.

But considering that they are all defined under #ifdef...#endif we can
remove the declaration of the config GENERIC_FIND_NEXT_BIT.
> 
> > --- /dev/null
> > +++ b/xen/lib/find-next-bit.c
> > @@ -0,0 +1,281 @@
> > +/* find_next_bit.c: fallback find next bit implementation
> > + *
> > + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
> > + * Written by David Howells (dhowells@redhat.com)
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License
> > + * as published by the Free Software Foundation; either version
> > + * 2 of the License, or (at your option) any later version.
> > + */
> > +#include <xen/bitops.h>
> > +
> > +#include <asm/byteorder.h>
> > +
> > +#ifndef find_next_bit
> > +/*
> > + * Find the next set bit in a memory region.
> > + */
> > +unsigned long find_next_bit(const unsigned long *addr, unsigned
> > long size,
> > +			    unsigned long offset)
> > +{
> > +	const unsigned long *p = addr + BIT_WORD(offset);
> > +	unsigned long result = offset & ~(BITS_PER_LONG-1);
> > +	unsigned long tmp;
> > +
> > +	if (offset >= size)
> > +		return size;
> > +	size -= result;
> > +	offset %= BITS_PER_LONG;
> > +	if (offset) {
> > +		tmp = *(p++);
> > +		tmp &= (~0UL << offset);
> > +		if (size < BITS_PER_LONG)
> > +			goto found_first;
> > +		if (tmp)
> > +			goto found_middle;
> > +		size -= BITS_PER_LONG;
> > +		result += BITS_PER_LONG;
> > +	}
> > +	while (size & ~(BITS_PER_LONG-1)) {
> > +		if ((tmp = *(p++)))
> > +			goto found_middle;
> > +		result += BITS_PER_LONG;
> > +		size -= BITS_PER_LONG;
> > +	}
> > +	if (!size)
> > +		return result;
> > +	tmp = *p;
> > +
> > +found_first:
> > +	tmp &= (~0UL >> (BITS_PER_LONG - size));
> > +	if (tmp == 0UL)		/* Are any bits set? */
> > +		return result + size;	/* Nope. */
> > +found_middle:
> > +	return result + __ffs(tmp);
> > +}
> > +EXPORT_SYMBOL(find_next_bit);
> > +#endif
> > +
> > +#ifndef find_next_zero_bit
> > +/*
> > + * This implementation of find_{first,next}_zero_bit was stolen
> > from
> > + * Linus' asm-alpha/bitops.h.
> > + */
> > +unsigned long find_next_zero_bit(const unsigned long *addr,
> > unsigned long size,
> > +				 unsigned long offset)
> > +{
> > +	const unsigned long *p = addr + BIT_WORD(offset);
> > +	unsigned long result = offset & ~(BITS_PER_LONG-1);
> > +	unsigned long tmp;
> > +
> > +	if (offset >= size)
> > +		return size;
> > +	size -= result;
> > +	offset %= BITS_PER_LONG;
> > +	if (offset) {
> > +		tmp = *(p++);
> > +		tmp |= ~0UL >> (BITS_PER_LONG - offset);
> > +		if (size < BITS_PER_LONG)
> > +			goto found_first;
> > +		if (~tmp)
> > +			goto found_middle;
> > +		size -= BITS_PER_LONG;
> > +		result += BITS_PER_LONG;
> > +	}
> > +	while (size & ~(BITS_PER_LONG-1)) {
> > +		if (~(tmp = *(p++)))
> > +			goto found_middle;
> > +		result += BITS_PER_LONG;
> > +		size -= BITS_PER_LONG;
> > +	}
> > +	if (!size)
> > +		return result;
> > +	tmp = *p;
> > +
> > +found_first:
> > +	tmp |= ~0UL << size;
> > +	if (tmp == ~0UL)	/* Are any bits zero? */
> > +		return result + size;	/* Nope. */
> > +found_middle:
> > +	return result + ffz(tmp);
> > +}
> > +EXPORT_SYMBOL(find_next_zero_bit);
> > +#endif
> > +
> > +#ifndef find_first_bit
> > +/*
> > + * Find the first set bit in a memory region.
> > + */
> > +unsigned long find_first_bit(const unsigned long *addr, unsigned
> > long size)
> > +{
> > +	const unsigned long *p = addr;
> > +	unsigned long result = 0;
> > +	unsigned long tmp;
> > +
> > +	while (size & ~(BITS_PER_LONG-1)) {
> > +		if ((tmp = *(p++)))
> > +			goto found;
> > +		result += BITS_PER_LONG;
> > +		size -= BITS_PER_LONG;
> > +	}
> > +	if (!size)
> > +		return result;
> > +
> > +	tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
> > +	if (tmp == 0UL)		/* Are any bits set? */
> > +		return result + size;	/* Nope. */
> > +found:
> > +	return result + __ffs(tmp);
> > +}
> > +EXPORT_SYMBOL(find_first_bit);
> > +#endif
> > +
> > +#ifndef find_first_zero_bit
> > +/*
> > + * Find the first cleared bit in a memory region.
> > + */
> > +unsigned long find_first_zero_bit(const unsigned long *addr,
> > unsigned long size)
> > +{
> > +	const unsigned long *p = addr;
> > +	unsigned long result = 0;
> > +	unsigned long tmp;
> > +
> > +	while (size & ~(BITS_PER_LONG-1)) {
> > +		if (~(tmp = *(p++)))
> > +			goto found;
> > +		result += BITS_PER_LONG;
> > +		size -= BITS_PER_LONG;
> > +	}
> > +	if (!size)
> > +		return result;
> > +
> > +	tmp = (*p) | (~0UL << size);
> > +	if (tmp == ~0UL)	/* Are any bits zero? */
> > +		return result + size;	/* Nope. */
> > +found:
> > +	return result + ffz(tmp);
> > +}
> > +EXPORT_SYMBOL(find_first_zero_bit);
> > +#endif
> > +
> > +#ifdef __BIG_ENDIAN
> > +
> > +/* include/linux/byteorder does not support "unsigned long" type
> > */
> > +static inline unsigned long ext2_swabp(const unsigned long * x)
> > +{
> > +#if BITS_PER_LONG == 64
> > +	return (unsigned long) __swab64p((u64 *) x);
> > +#elif BITS_PER_LONG == 32
> > +	return (unsigned long) __swab32p((u32 *) x);
> > +#else
> > +#error BITS_PER_LONG not defined
> > +#endif
> > +}
> > +
> > +/* include/linux/byteorder doesn't support "unsigned long" type */
> > +static inline unsigned long ext2_swab(const unsigned long y)
> > +{
> > +#if BITS_PER_LONG == 64
> > +	return (unsigned long) __swab64((u64) y);
> > +#elif BITS_PER_LONG == 32
> > +	return (unsigned long) __swab32((u32) y);
> > +#else
> > +#error BITS_PER_LONG not defined
> > +#endif
> > +}
> > +
> > +#ifndef find_next_zero_bit_le
> > +unsigned long find_next_zero_bit_le(const void *addr, unsigned
> > +		long size, unsigned long offset)
> > +{
> > +	const unsigned long *p = addr;
> > +	unsigned long result = offset & ~(BITS_PER_LONG - 1);
> > +	unsigned long tmp;
> > +
> > +	if (offset >= size)
> > +		return size;
> > +	p += BIT_WORD(offset);
> > +	size -= result;
> > +	offset &= (BITS_PER_LONG - 1UL);
> > +	if (offset) {
> > +		tmp = ext2_swabp(p++);
> > +		tmp |= (~0UL >> (BITS_PER_LONG - offset));
> > +		if (size < BITS_PER_LONG)
> > +			goto found_first;
> > +		if (~tmp)
> > +			goto found_middle;
> > +		size -= BITS_PER_LONG;
> > +		result += BITS_PER_LONG;
> > +	}
> > +
> > +	while (size & ~(BITS_PER_LONG - 1)) {
> > +		if (~(tmp = *(p++)))
> > +			goto found_middle_swap;
> > +		result += BITS_PER_LONG;
> > +		size -= BITS_PER_LONG;
> > +	}
> > +	if (!size)
> > +		return result;
> > +	tmp = ext2_swabp(p);
> > +found_first:
> > +	tmp |= ~0UL << size;
> > +	if (tmp == ~0UL)	/* Are any bits zero? */
> > +		return result + size; /* Nope. Skip ffz */
> > +found_middle:
> > +	return result + ffz(tmp);
> > +
> > +found_middle_swap:
> > +	return result + ffz(ext2_swab(tmp));
> > +}
> > +EXPORT_SYMBOL(find_next_zero_bit_le);
> > +#endif
> > +
> > +#ifndef find_next_bit_le
> > +unsigned long find_next_bit_le(const void *addr, unsigned
> > +		long size, unsigned long offset)
> > +{
> > +	const unsigned long *p = addr;
> > +	unsigned long result = offset & ~(BITS_PER_LONG - 1);
> > +	unsigned long tmp;
> > +
> > +	if (offset >= size)
> > +		return size;
> > +	p += BIT_WORD(offset);
> > +	size -= result;
> > +	offset &= (BITS_PER_LONG - 1UL);
> > +	if (offset) {
> > +		tmp = ext2_swabp(p++);
> > +		tmp &= (~0UL << offset);
> > +		if (size < BITS_PER_LONG)
> > +			goto found_first;
> > +		if (tmp)
> > +			goto found_middle;
> > +		size -= BITS_PER_LONG;
> > +		result += BITS_PER_LONG;
> > +	}
> > +
> > +	while (size & ~(BITS_PER_LONG - 1)) {
> > +		tmp = *(p++);
> > +		if (tmp)
> > +			goto found_middle_swap;
> > +		result += BITS_PER_LONG;
> > +		size -= BITS_PER_LONG;
> > +	}
> > +	if (!size)
> > +		return result;
> > +	tmp = ext2_swabp(p);
> > +found_first:
> > +	tmp &= (~0UL >> (BITS_PER_LONG - size));
> > +	if (tmp == 0UL)		/* Are any bits set? */
> > +		return result + size; /* Nope. */
> > +found_middle:
> > +	return result + __ffs(tmp);
> > +
> > +found_middle_swap:
> > +	return result + __ffs(ext2_swab(tmp));
> > +}
> > +EXPORT_SYMBOL(find_next_bit_le);
> > +#endif
> > +
> > +#endif /* __BIG_ENDIAN */
> 
> I was going to ask that you convince git to actually present a proper
> diff, to make visible what changes. But other than the description
> says
> you don't really move the file, you copy it. Judging from further
> titles
> there's also nowhere you'd make Arm actually use this now generic
> code.
I wanted to do it separately, outside this patch series to simplify
review and not have Arm specific changes in RISC-V patch series.

Regarding a proper diff, you would like me to make git shows that it
was copy from Arm and it is not newly created file. Am I understand you
correctly?

~ Oleksii


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2023-12-22 15:13 ` [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h " Oleksii Kurochko
  2023-12-22 16:32   ` Oleksii
@ 2024-01-23 13:03   ` Jan Beulich
  2024-01-23 17:27     ` Oleksii
  2024-02-02 17:30     ` Oleksii
  1 sibling, 2 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 13:03 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V3:
>  - update the commit message

??? (yet again)

> --- a/xen/arch/riscv/include/asm/mm.h
> +++ b/xen/arch/riscv/include/asm/mm.h
> @@ -3,8 +3,251 @@
>  #ifndef _ASM_RISCV_MM_H
>  #define _ASM_RISCV_MM_H
>  
> +#include <public/xen.h>
> +#include <xen/pdx.h>
> +#include <xen/types.h>
> +
> +#include <asm/page.h>
>  #include <asm/page-bits.h>
>  
> +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> +#define vmap_to_mfn(va)     maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))

Everything you have above ...

> +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> +#define vmap_to_mfn(va)     maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))

... appears a 2nd time right afterwards.

> +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK))
> +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) | DIRECTMAP_VIRT_START))
> +
> +/* Convert between Xen-heap virtual addresses and machine frame numbers. */
> +#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
> +#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) << PAGE_SHIFT)

These would imo better use maddr_to_mfn() and mfn_to_maddr(), rather than
kind of open-coding them. The former could also use PFN_DOWN() as an
alternative.

> +/* Convert between Xen-heap virtual addresses and page-info structures. */
> +static inline struct page_info *virt_to_page(const void *v)
> +{
> +    BUG();
> +    return NULL;
> +}
> +
> +/*
> + * We define non-underscored wrappers for above conversion functions.
> + * These are overriden in various source files while underscored version
> + * remain intact.
> + */
> +#define virt_to_mfn(va)     __virt_to_mfn(va)
> +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)

Is this really still needed? Would be pretty nice if in a new port we
could get to start cleanly right away (i.e. by not needing per-file
overrides, but using type-safe expansions here right away).

> +struct page_info
> +{
> +    /* Each frame can be threaded onto a doubly-linked list. */
> +    struct page_list_entry list;
> +
> +    /* Reference count and various PGC_xxx flags and fields. */
> +    unsigned long count_info;
> +
> +    /* Context-dependent fields follow... */
> +    union {
> +        /* Page is in use: ((count_info & PGC_count_mask) != 0). */
> +        struct {
> +            /* Type reference count and various PGT_xxx flags and fields. */
> +            unsigned long type_info;
> +        } inuse;
> +        /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
> +        union {
> +            struct {
> +                /*
> +                 * Index of the first *possibly* unscrubbed page in the buddy.
> +                 * One more bit than maximum possible order to accommodate
> +                 * INVALID_DIRTY_IDX.
> +                 */
> +#define INVALID_DIRTY_IDX ((1UL << (MAX_ORDER + 1)) - 1)
> +                unsigned long first_dirty:MAX_ORDER + 1;
> +
> +                /* Do TLBs need flushing for safety before next page use? */
> +                bool need_tlbflush:1;
> +
> +#define BUDDY_NOT_SCRUBBING    0
> +#define BUDDY_SCRUBBING        1
> +#define BUDDY_SCRUB_ABORT      2
> +                unsigned long scrub_state:2;
> +            };
> +
> +                unsigned long val;
> +            } free;

Indentation is wrong (and thus misleading) for these two lines.

> +
> +    } u;

Nit: I don't see the value of the trailing blank line inside the
union.

> +    union {
> +        /* Page is in use, but not as a shadow. */

I question the appicability of "shadow" here.

> +        struct {
> +            /* Owner of this page (zero if page is anonymous). */
> +            struct domain *domain;
> +        } inuse;
> +
> +        /* Page is on a free list. */
> +        struct {
> +            /* Order-size of the free chunk this page is the head of. */
> +            unsigned int order;
> +        } free;
> +
> +    } v;
> +
> +    union {
> +        /*
> +         * Timestamp from 'TLB clock', used to avoid extra safety flushes.
> +         * Only valid for: a) free pages, and b) pages with zero type count
> +         */
> +        uint32_t tlbflush_timestamp;
> +    };
> +    uint64_t pad;
> +};
> +
> +#define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
> +
> +/* PDX of the first page in the frame table. */
> +extern unsigned long frametable_base_pdx;

From this I conclude memory on RISC-V systems may not start at (or near) 0?

> +/* Convert between machine frame numbers and page-info structures. */
> +#define mfn_to_page(mfn)                                            \
> +    (frame_table + (mfn_to_pdx(mfn) - frametable_base_pdx))
> +#define page_to_mfn(pg)                                             \
> +    pdx_to_mfn((unsigned long)((pg) - frame_table) + frametable_base_pdx)
> +
> +static inline void *page_to_virt(const struct page_info *pg)
> +{
> +    return mfn_to_virt(mfn_x(page_to_mfn(pg)));
> +}
> +
> +/*
> + * Common code requires get_page_type and put_page_type.
> + * We don't care about typecounts so we just do the minimum to make it
> + * happy.
> + */
> +static inline int get_page_type(struct page_info *page, unsigned long type)
> +{
> +    return 1;
> +}
> +
> +static inline void put_page_type(struct page_info *page)
> +{
> +}
> +
> +static inline void put_page_and_type(struct page_info *page)
> +{
> +    put_page_type(page);
> +    put_page(page);
> +}
> +
> +/*
> + * RISC-V does not have an M2P, but common code expects a handful of
> + * M2P-related defines and functions. Provide dummy versions of these.
> + */
> +#define INVALID_M2P_ENTRY        (~0UL)
> +#define SHARED_M2P_ENTRY         (~0UL - 1UL)
> +#define SHARED_M2P(_e)           ((_e) == SHARED_M2P_ENTRY)
> +
> +/* Xen always owns P2M on RISC-V */
> +#define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn), (void)(pfn); } while (0)

Nit: Stray blank again after cast.

> +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))

What's the relation of the comment with these two #define-s?

> +#define PDX_GROUP_SHIFT (16 + 5)
> +
> +static inline unsigned long domain_get_maximum_gpfn(struct domain *d)
> +{
> +    BUG();
> +    return 0;
> +}
> +
> +static inline long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg)
> +{
> +    BUG();
> +    return 0;
> +}
> +
> +/*
> + * On RISCV, all the RAM is currently direct mapped in Xen.
> + * Hence return always true.
> + */
> +static inline bool arch_mfns_in_directmap(unsigned long mfn, unsigned long nr)
> +{
> +    return true;
> +}
> +
> +#define PG_shift(idx)   (BITS_PER_LONG - (idx))
> +#define PG_mask(x, idx) (x ## UL << PG_shift(idx))
> +
> +#define PGT_none          PG_mask(0, 1)  /* no special uses of this page   */
> +#define PGT_writable_page PG_mask(1, 1)  /* has writable mappings?         */
> +#define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or 63.                 */
> +
> + /* Count of uses of this frame as its current type. */
> +#define PGT_count_width   PG_shift(2)
> +#define PGT_count_mask    ((1UL<<PGT_count_width)-1)

Nit: Style (missing blanks around binary operators). Also a few more
times further down.

> +/*
> + * Page needs to be scrubbed. Since this bit can only be set on a page that is
> + * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
> + */
> +#define _PGC_need_scrub   _PGC_allocated
> +#define PGC_need_scrub    PGC_allocated
> +
> +//  /* Cleared when the owning guest 'frees' this page. */

Why a commented out comment?

> +#define _PGC_allocated    PG_shift(1)
> +#define PGC_allocated     PG_mask(1, 1)
> +  /* Page is Xen heap? */
> +#define _PGC_xen_heap     PG_shift(2)
> +#define PGC_xen_heap      PG_mask(1, 2)
> +/* Page is broken? */
> +#define _PGC_broken       PG_shift(7)
> +#define PGC_broken        PG_mask(1, 7)
> + /* Mutually-exclusive page states: { inuse, offlining, offlined, free }. */

Can similar comments in this block please all be similarly indented
(or not)?

> +#define PGC_state         PG_mask(3, 9)
> +#define PGC_state_inuse   PG_mask(0, 9)
> +#define PGC_state_offlining PG_mask(1, 9)
> +#define PGC_state_offlined PG_mask(2, 9)
> +#define PGC_state_free    PG_mask(3, 9)
> +// #define page_state_is(pg, st) (((pg)->count_info&PGC_state) == PGC_state_##st)

???

> +/* Count of references to this frame. */
> +#define PGC_count_width   PG_shift(9)
> +#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
> +
> +#define page_state_is(pg, st) (((pg)->count_info&PGC_state) == PGC_state_##st)

And here it then "properly" appears?

> +#define _PGC_extra        PG_shift(10)
> +#define PGC_extra         PG_mask(1, 10)
> +
> +#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
> +#define is_xen_heap_mfn(mfn) \
> +    (mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
> +
> +#define is_xen_fixed_mfn(mfn)                                   \
> +    ((mfn_to_maddr(mfn) >= virt_to_maddr(&_start)) &&           \
> +     (mfn_to_maddr(mfn) <= virt_to_maddr((vaddr_t)_end - 1)))

Why does _start need prefixing wuth & and _end prefixing with a cast?
First and foremost both want to be consistent. And then preferably
with as little extra clutter as possible.

> +#define page_get_owner(_p)    (_p)->v.inuse.domain
> +#define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d))
> +
> +/* TODO: implement */
> +#define mfn_valid(mfn) ({ (void) (mfn); 0; })
> +
> +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))

This appeared further up already.

> +#define domain_set_alloc_bitsize(d) ((void)0)

Better ((void)(d)) ? And then ...

> +#define domain_clamp_alloc_bitsize(d, b) (b)

... ((void)(d), (b)) here?

Jan


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

* Re: [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs to build full Xen
  2023-12-22 15:13 ` [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs " Oleksii Kurochko
@ 2024-01-23 13:20   ` Jan Beulich
  2024-01-23 17:31     ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 13:20 UTC (permalink / raw
  To: Oleksii Kurochko
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 22.12.2023 16:13, Oleksii Kurochko wrote:
> --- a/xen/arch/riscv/early_printk.c
> +++ b/xen/arch/riscv/early_printk.c
> @@ -40,171 +40,3 @@ void early_printk(const char *str)
>          str++;
>      }
>  }
> -
> -/*
> - * The following #if 1 ... #endif should be removed after printk
> - * and related stuff are ready.
> - */
> -#if 1
> -
> -#include <xen/stdarg.h>
> -#include <xen/string.h>
> -
> -/**
> - * strlen - Find the length of a string
> - * @s: The string to be sized
> - */
> -size_t (strlen)(const char * s)
> -{
> -    const char *sc;
> -
> -    for (sc = s; *sc != '\0'; ++sc)
> -        /* nothing */;
> -    return sc - s;
> -}
> -
> -/**
> - * memcpy - Copy one area of memory to another
> - * @dest: Where to copy to
> - * @src: Where to copy from
> - * @count: The size of the area.
> - *
> - * You should not use this function to access IO space, use memcpy_toio()
> - * or memcpy_fromio() instead.
> - */
> -void *(memcpy)(void *dest, const void *src, size_t count)
> -{
> -    char *tmp = (char *) dest, *s = (char *) src;
> -
> -    while (count--)
> -        *tmp++ = *s++;
> -
> -    return dest;
> -}
> -
> -int vsnprintf(char* str, size_t size, const char* format, va_list args)
> -{
> -    size_t i = 0; /* Current position in the output string */
> -    size_t written = 0; /* Total number of characters written */
> -    char* dest = str;
> -
> -    while ( format[i] != '\0' && written < size - 1 )
> -    {
> -        if ( format[i] == '%' )
> -        {
> -            i++;
> -
> -            if ( format[i] == '\0' )
> -                break;
> -
> -            if ( format[i] == '%' )
> -            {
> -                if ( written < size - 1 )
> -                {
> -                    dest[written] = '%';
> -                    written++;
> -                }
> -                i++;
> -                continue;
> -            }
> -
> -            /*
> -             * Handle format specifiers.
> -             * For simplicity, only %s and %d are implemented here.
> -             */
> -
> -            if ( format[i] == 's' )
> -            {
> -                char* arg = va_arg(args, char*);
> -                size_t arglen = strlen(arg);
> -
> -                size_t remaining = size - written - 1;
> -
> -                if ( arglen > remaining )
> -                    arglen = remaining;
> -
> -                memcpy(dest + written, arg, arglen);
> -
> -                written += arglen;
> -                i++;
> -            }
> -            else if ( format[i] == 'd' )
> -            {
> -                int arg = va_arg(args, int);
> -
> -                /* Convert the integer to string representation */
> -                char numstr[32]; /* Assumes a maximum of 32 digits */
> -                int numlen = 0;
> -                int num = arg;
> -                size_t remaining;
> -
> -                if ( arg < 0 )
> -                {
> -                    if ( written < size - 1 )
> -                    {
> -                        dest[written] = '-';
> -                        written++;
> -                    }
> -
> -                    num = -arg;
> -                }
> -
> -                do
> -                {
> -                    numstr[numlen] = '0' + num % 10;
> -                    num = num / 10;
> -                    numlen++;
> -                } while ( num > 0 );
> -
> -                /* Reverse the string */
> -                for (int j = 0; j < numlen / 2; j++)
> -                {
> -                    char tmp = numstr[j];
> -                    numstr[j] = numstr[numlen - 1 - j];
> -                    numstr[numlen - 1 - j] = tmp;
> -                }
> -
> -                remaining = size - written - 1;
> -
> -                if ( numlen > remaining )
> -                    numlen = remaining;
> -
> -                memcpy(dest + written, numstr, numlen);
> -
> -                written += numlen;
> -                i++;
> -            }
> -        }
> -        else
> -        {
> -            if ( written < size - 1 )
> -            {
> -                dest[written] = format[i];
> -                written++;
> -            }
> -            i++;
> -        }
> -    }
> -
> -    if ( size > 0 )
> -        dest[written] = '\0';
> -
> -    return written;
> -}
> -
> -void printk(const char *format, ...)
> -{
> -    static char buf[1024];
> -
> -    va_list args;
> -    va_start(args, format);
> -
> -    (void)vsnprintf(buf, sizeof(buf), format, args);
> -
> -    early_printk(buf);
> -
> -    va_end(args);
> -}
> -
> -#endif
> -

Aren't you transiently breaking the build by removing these here, rather
than in the next patch?

> --- /dev/null
> +++ b/xen/arch/riscv/stubs.c
> @@ -0,0 +1,422 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#include <xen/cpumask.h>
> +#include <xen/domain.h>
> +#include <xen/irq.h>
> +#include <xen/nodemask.h>
> +#include <xen/time.h>
> +#include <public/domctl.h>
> +
> +#include <asm/current.h>
> +
> +/* smpboot.c */
> +
> +cpumask_t cpu_online_map;
> +cpumask_t cpu_present_map;
> +cpumask_t cpu_possible_map;
> +
> +/* ID of the PCPU we're running on */
> +DEFINE_PER_CPU(unsigned int, cpu_id);
> +/* XXX these seem awfully x86ish... */
> +/* representing HT siblings of each logical CPU */
> +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask);
> +/* representing HT and core siblings of each logical CPU */
> +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask);
> +
> +nodemask_t __read_mostly node_online_map = { { [0] = 1UL } };
> +
> +/* time.c */
> +
> +unsigned long __read_mostly cpu_khz;  /* CPU clock frequency in kHz. */

__ro_after_init?

> +s_time_t get_s_time(void)
> +{
> +    BUG();
> +}
> +
> +int reprogram_timer(s_time_t timeout)
> +{
> +    BUG();
> +}
> +
> +void send_timer_event(struct vcpu *v)
> +{
> +    BUG();
> +}
> +
> +void domain_set_time_offset(struct domain *d, int64_t time_offset_seconds)
> +{
> +    BUG();
> +}
> +
> +/* shutdown.c */
> +
> +void machine_restart(unsigned int delay_millisecs)
> +{
> +    BUG();
> +}
> +
> +void machine_halt(void)
> +{
> +    BUG();
> +}
> +
> +/* vm_event.c */
> +
> +struct vm_event_st;
> +
> +void vm_event_fill_regs(struct vm_event_st *req)
> +{
> +    BUG();
> +}
> +
> +void vm_event_set_registers(struct vcpu *v, struct vm_event_st *rsp)
> +{
> +    BUG();
> +}
> +
> +void vm_event_monitor_next_interrupt(struct vcpu *v)
> +{
> +    /* Not supported on RISCV. */
> +}
> +
> +void vm_event_reset_vmtrace(struct vcpu *v)
> +{
> +    /* Not supported on RISCV. */
> +}

Judging from the comments these last two are in their final shape.
Wouldn't it make sense to put them in vm_event.c right away then? And
then perhaps together with the two stubs?

Yet then - Arm gets away without vm_event_reset_vmtrace()? Can you
explain why the same isn't true for RISC-V?

> @@ -11,3 +15,24 @@ void do_trap(struct cpu_user_regs *cpu_regs)
>  {
>      die();
>  }
> +
> +void vcpu_show_execution_state(struct vcpu *v)
> +{
> +    assert_failed("need to be implented");

Just to mention it again - the expectation is that all instances will
use the same "canonical" pattern for identifying yet-to-be-implemented
functions.

Jan


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-23 12:18         ` Oleksii
@ 2024-01-23 13:27           ` Jan Beulich
  2024-01-24  9:15             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 13:27 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 13:18, Oleksii wrote:
> On Tue, 2024-01-23 at 11:28 +0100, Jan Beulich wrote:
>> On 23.01.2024 11:15, Oleksii wrote:
>>> On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>>>> +static inline unsigned long __xchg(volatile void *ptr,
>>>>> unsigned
>>>>> long x, int size)
>>>>> +{
>>>>> +    switch (size) {
>>>>> +    case 1:
>>>>> +        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
>>>>> +    case 2:
>>>>> +        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
>>>>
>>>> How are these going to work? You'll compare against ~0, and if
>>>> the
>>>> value
>>>> in memory isn't ~0, memory won't be updated; you will only
>>>> (correctly)
>>>> return the value found in memory.
>>>>
>>>> Or wait - looking at __cmpxchg_case_{1,2}() far further down, you
>>>> ignore
>>>> "old" there. Which apparently means they'll work for the use
>>>> here,
>>>> but
>>>> not for the use in __cmpxchg().
>>> Yes, the trick is that old is ignored and is read in
>>> __emulate_cmpxchg_case1_2() before __cmpxchg_case_4 is called:
>>>     do
>>> {                                                              
>>>         read_val =
>>> read_func(aligned_ptr);                            
>>>         swapped_new = read_val &
>>> ~mask;                               
>>>         swapped_new |=
>>> masked_new;                                    
>>>         ret = cmpxchg_func(aligned_ptr, read_val,
>>> swapped_new);       
>>>     } while ( ret != read_val
>>> );                                      
>>> read_val it is 'old'.
>>>
>>> But now I am not 100% sure that it is correct for __cmpxchg...
>>
>> It just can't be correct - you can't ignore "old" there. I think you
>> want simple cmpxchg primitives, which xchg then uses in a loop (while
>> cmpxchg uses them plainly).
> But xchg doesn't require 'old' value, so it should be ignored in some
> way by cmpxchg.

Well, no. If you have only cmpxchg, I think your only choice is - as
said - to read the old value and then loop over cmpxchg until that
succeeds. Not really different from other operations which need
emulating using cmpxchg.

>>>>> +static always_inline unsigned short __cmpxchg_case_2(volatile
>>>>> uint32_t *ptr,
>>>>> +                                                     uint32_t
>>>>> old,
>>>>> +                                                     uint32_t
>>>>> new)
>>>>> +{
>>>>> +    (void) old;
>>>>> +
>>>>> +    if (((unsigned long)ptr & 3) == 3)
>>>>> +    {
>>>>> +#ifdef CONFIG_64BIT
>>>>> +        return __emulate_cmpxchg_case1_2((uint64_t *)ptr, new,
>>>>> +                                         readq,
>>>>> __cmpxchg_case_8,
>>>>> 0xffffU);
>>>>
>>>> What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of
>>>> what
>>>> the
>>>> if() above checks for? Isn't it more reasonable to require
>>>> aligned
>>>> 16-bit quantities here? Or if mis-aligned addresses are okay, you
>>>> could
>>>> as well emulate using __cmpxchg_case_4().
>>> Yes, it will be more reasonable. I'll use IS_ALIGNED instead.
>>
>> Not sure I get your use of "instead" here correctly. There's more
>> to change here than just the if() condition.
> I meant something like:
> 
> if ( IS_ALIGNED(ptr, 16) )
>     __emulate_cmpxchg_case1_2(...);
> else
>     assert_failed("ptr isn't aligned\n");

Except that you'd better not use assert_failed() directly anywhere,
and the above is easier as

    ASSERT(IS_ALIGNED(ptr, 16));
    __emulate_cmpxchg_case1_2(...);

anyway (leaving aside that I guess you mean 2, not 16).

Jan


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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-23 12:24         ` Oleksii
@ 2024-01-23 13:30           ` Jan Beulich
  2024-01-24  9:23             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 13:30 UTC (permalink / raw
  To: Oleksii
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 13:24, Oleksii wrote:
> On Tue, 2024-01-23 at 11:30 +0100, Jan Beulich wrote:
>> On 23.01.2024 11:21, Oleksii wrote:
>>> On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>>>> --- /dev/null
>>>>> +++ b/xen/arch/riscv/include/asm/fence.h
>>>>> @@ -0,0 +1,13 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>>>> +#ifndef _ASM_RISCV_FENCE_H
>>>>> +#define _ASM_RISCV_FENCE_H
>>>>> +
>>>>> +#ifdef CONFIG_SMP
>>>>> +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
>>>>> +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
>>>>> +#else
>>>>> +#define RISCV_ACQUIRE_BARRIER
>>>>> +#define RISCV_RELEASE_BARRIER
>>>>> +#endif
>>>>
>>>> Do you really care about the !SMP case? On x86 at least we
>>>> stopped
>>>> special-
>>>> casing that configuration many years ago (the few cases where for
>>>> typically
>>>> build reasons it matters, using CONFIG_NR_CPUS is sufficient). If
>>>> you
>>>> care
>>>> about it, there needs to be somewhere you actually #define
>>>> CONFIG_SMP.
>>> Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS?
>>
>> You can. Question is whether there's a point in doing so. Do you
>> expect people to actually want to run Xen on single-CPU systems?
>> They're generally not overly well suited for virtualization ...
> Just to clarify.
> 
> Do you mean physically single based CPU?
> Then I don't expect to run Xen on such systems and it is not nesessary
> to define *_BARRIER in this case. Should we have to add build error
> notification that we don't support single-CPU systems in this header?
> 
> If you are speaking about we have ,let it be, 4 CPUs and only 1 CPU is
> currently supported by Xen then it still makes sense.

No, that's still not what I mean. The question is: Is it useful for you
to _special case_ the NR_CPUS=1 case? Or is it instead simpler to handle
NR_CPUS=1 the same as NR_CPUS>1 (accepting less than ideal performance,
on the basis that in reality nobody's expected to use such in production
anyway)?

Jan


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-23 12:34     ` Oleksii
@ 2024-01-23 13:37       ` Jan Beulich
  2024-01-24  9:34         ` Oleksii
  2024-01-26  9:44         ` Oleksii
  0 siblings, 2 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 13:37 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 13:34, Oleksii wrote:
> On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> --- a/xen/common/Kconfig
>>> +++ b/xen/common/Kconfig
>>> @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
>>>  config GENERIC_BUG_FRAME
>>>  	bool
>>>  
>>> +config GENERIC_FIND_NEXT_BIT
>>> +	bool
>>
>> There's no need for this, as ...
>>
>>> --- a/xen/lib/Makefile
>>> +++ b/xen/lib/Makefile
>>> @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
>>>  lib-y += bsearch.o
>>>  lib-y += ctors.o
>>>  lib-y += ctype.o
>>> +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
>>
>> ... you're moving this to lib/. Or have you encountered any issue
>> with building this uniformly, and you forgot to mention this in
>> the description?
> I didn't check. My intention was to provide opportunity to check if an
> architecture want to use generic version or not. Otherwise, I expected
> that we will have multiple definiotion of the funcion.
> 
> But considering that they are all defined under #ifdef...#endif we can
> remove the declaration of the config GENERIC_FIND_NEXT_BIT.

What #ifdef / #endif would matter here? Whats in lib/ is intended to be
generic anyway. And what is in the resulting lib.a won't be used by an
arch if it has an arch-specific implementation. Problems could arise if
an arch had an inline function colliding with the out-of-line one. But
that's about the old case where I could see a need to make the building
of one of the objects conditional. And you'll note that withing this
Makefile there are pretty few conditionals.

>>> --- /dev/null
>>> +++ b/xen/lib/find-next-bit.c
>>>[...]
>>
>> I was going to ask that you convince git to actually present a proper
>> diff, to make visible what changes. But other than the description
>> says
>> you don't really move the file, you copy it. Judging from further
>> titles
>> there's also nowhere you'd make Arm actually use this now generic
>> code.
> I wanted to do it separately, outside this patch series to simplify
> review and not have Arm specific changes in RISC-V patch series.

Then do it the other way around: Make a separate _prereq_ change truly
moving the file.

> Regarding a proper diff, you would like me to make git shows that it
> was copy from Arm and it is not newly created file. Am I understand you
> correctly?

Not quite, I think. Git has move detection (and we've seen that in
action in other patches of yours). So when truly moving a file, what
(if anything) is changed is easily visible.

Jan


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

* Re: [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64
  2024-01-23 11:22   ` Jan Beulich
@ 2024-01-23 14:49     ` Oleksii
  2024-01-23 17:05       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 14:49 UTC (permalink / raw
  To: Jan Beulich
  Cc: Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On Tue, 2024-01-23 at 12:22 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> >  Changes in V3:
> >   - new patch
> > ---
> >  README | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/README b/README
> > index c8a108449e..1015a285c0 100644
> > --- a/README
> > +++ b/README
> > @@ -48,6 +48,9 @@ provided by your OS distributor:
> >        - For ARM 64-bit:
> >          - GCC 5.1 or later
> >          - GNU Binutils 2.24 or later
> > +      - For RISC-V 64-bit:
> > +        - GCC 13.2.1 or later
> > +        - GNU Binutils 2.40 or later
> 
> That's pretty new. For gcc that's even newer than the newest release.
> If older versions really won't do, I don't think you can leave this
> unjustified (by having an empty description). Till now gcc 13.2 has
> served me well, and iirc 13.1, 12.3, and 12.2 were fine, too.
It can be 12.2.0 for GCC and 2.39 for GNU Binutils. ( it is toolchain
which is used by contrainer for RISC-V in Xen ). I'll update versions
then.

But could you please explain again why it can't be 13.2.1 ( it is a
version which I have in my distribution, so it is the reason why I used
this version in README file ) ?

~ Oleksii



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

* Re: [PATCH v3 27/34] xen/riscv: define an address of frame table
  2024-01-23 11:32   ` Jan Beulich
@ 2024-01-23 16:50     ` Oleksii
  2024-01-24  8:07       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 16:50 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 12:32 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Also, the patch adds some helpful macros that assist in avoiding
> > the redefinition of memory layout for each MMU mode.
> > 
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - drop OFFSET_BITS, and use PAGE_SHIFT instead.
> >  - code style fixes.
> >  - add comment how macros are useful.
> >  - move all memory related layout definitions close to comment with
> > memory layout description.
> >  - make memory layout description generic for any MMU mode.
> > ---
> > Changes in V2:
> >  - Nothing changed. Only rebase.
> > ---
> >  xen/arch/riscv/include/asm/config.h | 85 +++++++++++++++++++------
> > ----
> >  1 file changed, 55 insertions(+), 30 deletions(-)
> > 
> > diff --git a/xen/arch/riscv/include/asm/config.h
> > b/xen/arch/riscv/include/asm/config.h
> > index f0544c6a20..fb9fc9daaa 100644
> > --- a/xen/arch/riscv/include/asm/config.h
> > +++ b/xen/arch/riscv/include/asm/config.h
> > @@ -6,6 +6,14 @@
> >  #include <xen/const.h>
> >  #include <xen/page-size.h>
> >  
> > +#ifdef CONFIG_RISCV_64
> > +#define CONFIG_PAGING_LEVELS 3
> > +#define RV_STAGE1_MODE SATP_MODE_SV39
> > +#else
> > +#define CONFIG_PAGING_LEVELS 2
> > +#define RV_STAGE1_MODE SATP_MODE_SV32
> > +#endif
> > +
> >  /*
> >   * RISC-V64 Layout:
> >   *
> > @@ -22,25 +30,56 @@
> >   *
> >   * It means that:
> >   *   top VA bits are simply ignored for the purpose of translating
> > to PA.
> > +#endif
> >   *
> > - *
> > ===================================================================
> > =========
> > - *    Start addr    |   End addr        |  Size  | Slot      
> > |area description
> > - *
> > ===================================================================
> > =========
> > - * FFFFFFFFC0800000 |  FFFFFFFFFFFFFFFF |1016 MB | L2 511     |
> > Unused
> > - * FFFFFFFFC0600000 |  FFFFFFFFC0800000 |  2 MB  | L2 511     |
> > Fixmap
> > - * FFFFFFFFC0200000 |  FFFFFFFFC0600000 |  4 MB  | L2 511     |
> > FDT
> > - * FFFFFFFFC0000000 |  FFFFFFFFC0200000 |  2 MB  | L2 511     |
> > Xen
> > - *                 ...                  |  1 GB  | L2 510     |
> > Unused
> > - * 0000003200000000 |  0000007F80000000 | 309 GB | L2 200-509 |
> > Direct map
> > - *                 ...                  |  1 GB  | L2 199     |
> > Unused
> > - * 0000003100000000 |  00000031C0000000 |  3 GB  | L2 196-198 |
> > Frametable
> > - *                 ...                  |  1 GB  | L2 195     |
> > Unused
> > - * 0000003080000000 |  00000030C0000000 |  1 GB  | L2 194     |
> > VMAP
> > - *                 ...                  | 194 GB | L2 0 - 193 |
> > Unused
> > - *
> > ===================================================================
> > =========
> > + *       SATP_MODE_SV32   | SATP_MODE_SV39   | SATP_MODE_SV48   |
> > SATP_MODE_SV57
> > + *     
> > ==================|==================|==================|==========
> > =======
> > + * BA0 | FFFFFFFFFFE00000 | FFFFFFFFC0000000 | FFFFFF8000000000 |
> > FFFF000000000000
> > + * BA1 | 0000000019000000 | 0000003200000000 | 0000640000000000 |
> > 00C8000000000000
> > + * BA2 | 0000000018800000 | 0000003100000000 | 0000620000000000 |
> > 00C4000000000000
> > + * BA3 | 0000000018400000 | 0000003080000000 | 0000610000000000 |
> > 00C2000000000000
> >   *
> > -#endif
> > + *
> > ===================================================================
> > ============
> > + * Start addr     |   End addr          |  Size  | Root PT slot |
> > Area description
> > + *
> > ===================================================================
> > ============
> > + * BA0 + 0x800000 |  FFFFFFFFFFFFFFFF   |1016 MB |     511      |
> > Unused
> > + * BA0 + 0x400000 |  BA0 + 0x800000     |  2 MB  |     511      |
> > Fixmap
> > + * BA0 + 0x200000 |  BA0 + 0x400000     |  4 MB  |     511      |
> > FDT
> > + * BA0            |  BA0 + 0x200000     |  2 MB  |     511      |
> > Xen
> > + *                 ...                  |  1 GB  |     510      |
> > Unused
> > + * BA1 + 0x000000 |  BA1 + 0x4D80000000 | 309 GB |   200-509    |
> > Direct map
> 
> This definitely can't be right for SV32. Others may be problematic,
> too, like ...
> 
> > + *                 ...                  |  1 GB  |     199      |
> > Unused
> > + * BA2 + 0x000000 |  BA2 + 0xC0000000   |  3 GB  |   196-198    |
> > Frametable
> 
> ... this one. Otoh I'd expect both to potentially be much larger in
> SV48 and SV57 modes.
Regarding Sv32, it looks to me the only BA0 and End addr at the first
line isn't correct as address size is 32.

Regarding other modes, yes, it should be changed Size column. Also, the
size of frame table should be recalculated.

Do we really need size column?

Wouldn't it be enough only have PT slot number?

Would it be better to have separate table for each mode?

Probably, it would be more useful to print memory map to Xen console.

> 
> > + *                 ...                  |  1 GB  |     195      |
> > Unused
> > + * BA3 + 0x000000 |  BA3 + 0x40000000   |  1 GB  |     194      |
> > VMAP
> > + *                 ...                  | 194 GB |   0 - 193    |
> > Unused
> > + *
> > ===================================================================
> > ============
> >   */
> > +#define VPN_BITS    (9)
> 
> This need to move ...
> 
> > +#define HYP_PT_ROOT_LEVEL (CONFIG_PAGING_LEVELS - 1)
> > +
> > +#ifdef CONFIG_RISCV_64
> 
> ... here, I think, for not being applicable to SV32?
You are right, it is not applicable for Sv32. In case of Sv32, it
should be 10.
But I am not sure that it is correct only to move this definition as
RISCV-64 can also use Sv32. So it looks like VPN_BITS should be "#ifdef
RV_STAGE1_MODE == Sv32".

> 
> > +#define SLOTN_ENTRY_BITS        (HYP_PT_ROOT_LEVEL * VPN_BITS +
> > PAGE_SHIFT)
> > +#define SLOTN(slot)             (_AT(vaddr_t, slot) <<
> > SLOTN_ENTRY_BITS)
> > +#define SLOTN_ENTRY_SIZE        SLOTN(1)
> 
> Do you have any example of how/where this going to be used?
Yes, it will be used to define DIRECTMAP_SIZE:
#define DIRECTMAP_SIZE          (SLOTN_ENTRY_SIZE * (509-200))
> 
> > +#define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 -
> > GB(1)) */
> 
> Won't /* -GB(1) */ do, thus allowing the line to also be padded such
> that
> it matches neighboring ones in layout?
Could you please clarify what do you mean by padded here? The intention
was to show that 1 GB is used for Xen, FDT and fixmap.

~ Oleksii
> 
> > +#define FRAMETABLE_VIRT_START   SLOTN(196)
> > +#define FRAMETABLE_SIZE         GB(3)
> > +#define FRAMETABLE_NR           (FRAMETABLE_SIZE /
> > sizeof(*frame_table))
> > +#define FRAMETABLE_VIRT_END     (FRAMETABLE_VIRT_START +
> > FRAMETABLE_SIZE - 1)
> > +
> > +#define VMAP_VIRT_START         SLOTN(194)
> > +#define VMAP_VIRT_SIZE          GB(1)
> > [...]
> 



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

* Re: [PATCH v3 28/34] xen/riscv: add required things to current.h
  2024-01-23 11:35   ` Jan Beulich
@ 2024-01-23 16:52     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-23 16:52 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 12:35 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:> ---
> a/xen/arch/riscv/include/asm/current.h
> > +++ b/xen/arch/riscv/include/asm/current.h
> > @@ -3,6 +3,21 @@
> >  #ifndef __ASM_CURRENT_H
> >  #define __ASM_CURRENT_H
> >  
> > +#include <xen/bug.h>
> > +#include <xen/percpu.h>
> > +#include <asm/processor.h>
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +/* Which VCPU is "current" on this PCPU. */
> > +DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
> > +
> > +#define current            this_cpu(curr_vcpu)
> > +#define set_current(vcpu)  do { current = (vcpu); } while (0)
> > +#define get_cpu_current(cpu)  per_cpu(curr_vcpu, cpu)
> > +
> > +#define guest_cpu_user_regs() ({ BUG(); NULL; })
> 
> Again with this changed to the "canonical" placeholder:
> Acked-by: Jan Beulich <jbeulich@suse.com>
Thanks. I'll updarte BUG() part.

~ Oleksii


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

* Re: [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen
  2024-01-23 11:36   ` Jan Beulich
@ 2024-01-23 16:54     ` Oleksii
  2024-01-24  8:09       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 16:54 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 12:36 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > Acked-by: Jan Beulich <jbeulich@suse.com>
> > ---
> > Changes in V3:
> >  - update the commit message
> 
> Once again I find this puzzling, considering there's no commit
> message
> at all.
By the I meant that asm/page.h was changed to page.h

~ Oleksii


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

* Re: [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64
  2024-01-23 14:49     ` Oleksii
@ 2024-01-23 17:05       ` Jan Beulich
  2024-01-23 17:34         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-23 17:05 UTC (permalink / raw
  To: Oleksii
  Cc: Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On 23.01.2024 15:49, Oleksii wrote:
> On Tue, 2024-01-23 at 12:22 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> ---
>>>  Changes in V3:
>>>   - new patch
>>> ---
>>>  README | 3 +++
>>>  1 file changed, 3 insertions(+)
>>>
>>> diff --git a/README b/README
>>> index c8a108449e..1015a285c0 100644
>>> --- a/README
>>> +++ b/README
>>> @@ -48,6 +48,9 @@ provided by your OS distributor:
>>>        - For ARM 64-bit:
>>>          - GCC 5.1 or later
>>>          - GNU Binutils 2.24 or later
>>> +      - For RISC-V 64-bit:
>>> +        - GCC 13.2.1 or later
>>> +        - GNU Binutils 2.40 or later
>>
>> That's pretty new. For gcc that's even newer than the newest release.
>> If older versions really won't do, I don't think you can leave this
>> unjustified (by having an empty description). Till now gcc 13.2 has
>> served me well, and iirc 13.1, 12.3, and 12.2 were fine, too.
> It can be 12.2.0 for GCC and 2.39 for GNU Binutils. ( it is toolchain
> which is used by contrainer for RISC-V in Xen ). I'll update versions
> then.
> 
> But could you please explain again why it can't be 13.2.1 ( it is a
> version which I have in my distribution, so it is the reason why I used
> this version in README file ) ?

13.2.1 is a pre-release of 13.3.0. Only versions ending in .0 are upstream
released versions these days. And I think it would be helpful if the
minimum version also was the first in a major-version series, i.e. I'd
generally prefer naming <N>.1.0 (or <N>.1 for simplicity; see Arm's entry).
Of course if no such suitable version exists (because of being buggy), then
specifying another one is okay. As to x.y.1 - nobody will then really know
which version it is, because every distro will ship its own variant.

Jan


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2024-01-23 11:39   ` Jan Beulich
@ 2024-01-23 17:08     ` Oleksii
  2024-01-24  8:19       ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 17:08 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 12:39 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - Update the commit message
> 
> ??? (again)
The same as with previous. asm/processor.h was changed to processor.h

> 
> > @@ -53,6 +56,18 @@ struct cpu_user_regs
> >      unsigned long pregs;
> >  };
> >  
> > +/* TODO: need to implement */
> > +#define cpu_to_core(cpu)   (0)
> > +#define cpu_to_socket(cpu) (0)
> > +
> > +static inline void cpu_relax(void)
> > +{
> > +    /* Encoding of the pause instruction */
> > +    __asm__ __volatile__ ( ".insn 0x100000F" );
> 
> binutils 2.40 knows "pause" - why use .insn then?
I thought that for this instruction it is needed to have extension
ZIHINTPAUSE ( according to Linux Kernel source code [1] ) and to cover
older version.
But looking at [2] and considering that I announced that we expected
binutils >= 2.40 ( or 2.39 as I mentioned as an reply to patch to
README file ) it can be used pause instruction.

> 
> > +    barrier();
> 
> Why?
Just to be aligned with Linux kernel implemetation from where this
function was taken.

~ Oleksii

[1]
https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/asm/vdso/processor.h#L9

[2]https://elixir.bootlin.com/linux/latest/source/arch/riscv/Kconfig#L582


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-01-23 13:03   ` Jan Beulich
@ 2024-01-23 17:27     ` Oleksii
  2024-01-24  8:23       ` Jan Beulich
  2024-02-02 17:30     ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-23 17:27 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - update the commit message
> 
> ??? (yet again)
asm/mm.h was changed to mm.h
> 
> > --- a/xen/arch/riscv/include/asm/mm.h
> > +++ b/xen/arch/riscv/include/asm/mm.h
> > @@ -3,8 +3,251 @@
> >  #ifndef _ASM_RISCV_MM_H
> >  #define _ASM_RISCV_MM_H
> >  
> > +#include <public/xen.h>
> > +#include <xen/pdx.h>
> > +#include <xen/types.h>
> > +
> > +#include <asm/page.h>
> >  #include <asm/page-bits.h>
> >  
> > +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> > +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> > +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> > +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> > +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> > +#define vmap_to_mfn(va)    
> > maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> > +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
> 
> Everything you have above ...
> 
> > +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> > +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> > +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> > +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> > +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> > +#define vmap_to_mfn(va)    
> > maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> > +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
> 
> ... appears a 2nd time right afterwards.
Hmm, looks like rebase issue. I'll drop a copy. Thanks.
> 
> > +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK))
> > +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) |
> > DIRECTMAP_VIRT_START))
> > +
> > +/* Convert between Xen-heap virtual addresses and machine frame
> > numbers. */
> > +#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
> > +#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) <<
> > PAGE_SHIFT)
> 
> These would imo better use maddr_to_mfn() and mfn_to_maddr(), rather
> than
> kind of open-coding them. The former could also use PFN_DOWN() as an
> alternative.
Thanks. I'll take that into account.

> 
> > +/* Convert between Xen-heap virtual addresses and page-info
> > structures. */
> > +static inline struct page_info *virt_to_page(const void *v)
> > +{
> > +    BUG();
> > +    return NULL;
> > +}
> > +
> > +/*
> > + * We define non-underscored wrappers for above conversion
> > functions.
> > + * These are overriden in various source files while underscored
> > version
> > + * remain intact.
> > + */
> > +#define virt_to_mfn(va)     __virt_to_mfn(va)
> > +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
> 
> Is this really still needed? Would be pretty nice if in a new port we
> could get to start cleanly right away (i.e. by not needing per-file
> overrides, but using type-safe expansions here right away).
Yes, we can just rename __virt_to_mfn and __mfn_to_virt and updated it
accordingly to your previous comment.


> 
> > +struct page_info
> > +{
> > +    /* Each frame can be threaded onto a doubly-linked list. */
> > +    struct page_list_entry list;
> > +
> > +    /* Reference count and various PGC_xxx flags and fields. */
> > +    unsigned long count_info;
> > +
> > +    /* Context-dependent fields follow... */
> > +    union {
> > +        /* Page is in use: ((count_info & PGC_count_mask) != 0).
> > */
> > +        struct {
> > +            /* Type reference count and various PGT_xxx flags and
> > fields. */
> > +            unsigned long type_info;
> > +        } inuse;
> > +        /* Page is on a free list: ((count_info & PGC_count_mask)
> > == 0). */
> > +        union {
> > +            struct {
> > +                /*
> > +                 * Index of the first *possibly* unscrubbed page
> > in the buddy.
> > +                 * One more bit than maximum possible order to
> > accommodate
> > +                 * INVALID_DIRTY_IDX.
> > +                 */
> > +#define INVALID_DIRTY_IDX ((1UL << (MAX_ORDER + 1)) - 1)
> > +                unsigned long first_dirty:MAX_ORDER + 1;
> > +
> > +                /* Do TLBs need flushing for safety before next
> > page use? */
> > +                bool need_tlbflush:1;
> > +
> > +#define BUDDY_NOT_SCRUBBING    0
> > +#define BUDDY_SCRUBBING        1
> > +#define BUDDY_SCRUB_ABORT      2
> > +                unsigned long scrub_state:2;
> > +            };
> > +
> > +                unsigned long val;
> > +            } free;
> 
> Indentation is wrong (and thus misleading) for these two lines.
I'll correct it.

> 
> > +
> > +    } u;
> 
> Nit: I don't see the value of the trailing blank line inside the
> union.
Sure, there is no any sense.

> 
> > +    union {
> > +        /* Page is in use, but not as a shadow. */
> 
> I question the appicability of "shadow" here.
> 
> > +        struct {
> > +            /* Owner of this page (zero if page is anonymous). */
> > +            struct domain *domain;
> > +        } inuse;
> > +
> > +        /* Page is on a free list. */
> > +        struct {
> > +            /* Order-size of the free chunk this page is the head
> > of. */
> > +            unsigned int order;
> > +        } free;
> > +
> > +    } v;
> > +
> > +    union {
> > +        /*
> > +         * Timestamp from 'TLB clock', used to avoid extra safety
> > flushes.
> > +         * Only valid for: a) free pages, and b) pages with zero
> > type count
> > +         */
> > +        uint32_t tlbflush_timestamp;
> > +    };
> > +    uint64_t pad;
> > +};
> > +
> > +#define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
> > +
> > +/* PDX of the first page in the frame table. */
> > +extern unsigned long frametable_base_pdx;
> 
> From this I conclude memory on RISC-V systems may not start at (or
> near) 0?
I am not sure that it is impossible at all, but all platforms I saw it
was always not 0 and pretty big values. For example, on real platform,
there is =0000004000000000. In QEMU, it is 0x800...0

> 
> > +/* Convert between machine frame numbers and page-info structures.
> > */
> > +#define
> > mfn_to_page(mfn)                                            \
> > +    (frame_table + (mfn_to_pdx(mfn) - frametable_base_pdx))
> > +#define
> > page_to_mfn(pg)                                             \
> > +    pdx_to_mfn((unsigned long)((pg) - frame_table) +
> > frametable_base_pdx)
> > +
> > +static inline void *page_to_virt(const struct page_info *pg)
> > +{
> > +    return mfn_to_virt(mfn_x(page_to_mfn(pg)));
> > +}
> > +
> > +/*
> > + * Common code requires get_page_type and put_page_type.
> > + * We don't care about typecounts so we just do the minimum to
> > make it
> > + * happy.
> > + */
> > +static inline int get_page_type(struct page_info *page, unsigned
> > long type)
> > +{
> > +    return 1;
> > +}
> > +
> > +static inline void put_page_type(struct page_info *page)
> > +{
> > +}
> > +
> > +static inline void put_page_and_type(struct page_info *page)
> > +{
> > +    put_page_type(page);
> > +    put_page(page);
> > +}
> > +
> > +/*
> > + * RISC-V does not have an M2P, but common code expects a handful
> > of
> > + * M2P-related defines and functions. Provide dummy versions of
> > these.
> > + */
> > +#define INVALID_M2P_ENTRY        (~0UL)
> > +#define SHARED_M2P_ENTRY         (~0UL - 1UL)
> > +#define SHARED_M2P(_e)           ((_e) == SHARED_M2P_ENTRY)
> > +
> > +/* Xen always owns P2M on RISC-V */
> > +#define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn),
> > (void)(pfn); } while (0)
> 
> Nit: Stray blank again after cast.
I'll update this. Thanks.

> 
> > +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
> 
> What's the relation of the comment with these two #define-s?
I don't know, it was copied just from Arm. I think it would be better
to drop a comment and just define macros as BUG_ON("uimplemented") for
time being.

> 
> > +#define PDX_GROUP_SHIFT (16 + 5)
> > +
> > +static inline unsigned long domain_get_maximum_gpfn(struct domain
> > *d)
> > +{
> > +    BUG();
> > +    return 0;
> > +}
> > +
> > +static inline long arch_memory_op(int op,
> > XEN_GUEST_HANDLE_PARAM(void) arg)
> > +{
> > +    BUG();
> > +    return 0;
> > +}
> > +
> > +/*
> > + * On RISCV, all the RAM is currently direct mapped in Xen.
> > + * Hence return always true.
> > + */
> > +static inline bool arch_mfns_in_directmap(unsigned long mfn,
> > unsigned long nr)
> > +{
> > +    return true;
> > +}
> > +
> > +#define PG_shift(idx)   (BITS_PER_LONG - (idx))
> > +#define PG_mask(x, idx) (x ## UL << PG_shift(idx))
> > +
> > +#define PGT_none          PG_mask(0, 1)  /* no special uses of
> > this page   */
> > +#define PGT_writable_page PG_mask(1, 1)  /* has writable
> > mappings?         */
> > +#define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or
> > 63.                 */
> > +
> > + /* Count of uses of this frame as its current type. */
> > +#define PGT_count_width   PG_shift(2)
> > +#define PGT_count_mask    ((1UL<<PGT_count_width)-1)
> 
> Nit: Style (missing blanks around binary operators). Also a few more
> times further down.
Thanks. I'll update.
> 
> > +/*
> > + * Page needs to be scrubbed. Since this bit can only be set on a
> > page that is
> > + * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
> > + */
> > +#define _PGC_need_scrub   _PGC_allocated
> > +#define PGC_need_scrub    PGC_allocated
> > +
> > +//  /* Cleared when the owning guest 'frees' this page. */
> 
> Why a commented out comment?
Missed to remove, my IDE using this type of comment by default. and I
commented all the file when tried to find minimal of changes needed for
Xen build.

> 
> > +#define _PGC_allocated    PG_shift(1)
> > +#define PGC_allocated     PG_mask(1, 1)
> > +  /* Page is Xen heap? */
> > +#define _PGC_xen_heap     PG_shift(2)
> > +#define PGC_xen_heap      PG_mask(1, 2)
> > +/* Page is broken? */
> > +#define _PGC_broken       PG_shift(7)
> > +#define PGC_broken        PG_mask(1, 7)
> > + /* Mutually-exclusive page states: { inuse, offlining, offlined,
> > free }. */
> 
> Can similar comments in this block please all be similarly indented
> (or not)?
Sure. I'll update that.

> 
> > +#define PGC_state         PG_mask(3, 9)
> > +#define PGC_state_inuse   PG_mask(0, 9)
> > +#define PGC_state_offlining PG_mask(1, 9)
> > +#define PGC_state_offlined PG_mask(2, 9)
> > +#define PGC_state_free    PG_mask(3, 9)
> > +// #define page_state_is(pg, st) (((pg)->count_info&PGC_state) ==
> > PGC_state_##st)
> 
> ???
The same as above, just missed to remove that line.

> 
> > +/* Count of references to this frame. */
> > +#define PGC_count_width   PG_shift(9)
> > +#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
> > +
> > +#define page_state_is(pg, st) (((pg)->count_info&PGC_state) ==
> > PGC_state_##st)
> 
> And here it then "properly" appears?
> 
> > +#define _PGC_extra        PG_shift(10)
> > +#define PGC_extra         PG_mask(1, 10)
> > +
> > +#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
> > +#define is_xen_heap_mfn(mfn) \
> > +    (mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
> > +
> > +#define is_xen_fixed_mfn(mfn)                                   \
> > +    ((mfn_to_maddr(mfn) >= virt_to_maddr(&_start)) &&           \
> > +     (mfn_to_maddr(mfn) <= virt_to_maddr((vaddr_t)_end - 1)))
> 
> Why does _start need prefixing wuth & and _end prefixing with a cast?
> First and foremost both want to be consistent. And then preferably
> with as little extra clutter as possible.
This is how it was defined in Arm. I think it both can be casted.
I'll update that.
Thanks.
> 
> > +#define page_get_owner(_p)    (_p)->v.inuse.domain
> > +#define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d))
> > +
> > +/* TODO: implement */
> > +#define mfn_valid(mfn) ({ (void) (mfn); 0; })
> > +
> > +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
> 
> This appeared further up already.
> 
> > +#define domain_set_alloc_bitsize(d) ((void)0)
> 
> Better ((void)(d)) ? And then ...
> 
> > +#define domain_clamp_alloc_bitsize(d, b) (b)
> 
> ... ((void)(d), (b)) here?
I'll update properly. Thanks.

~ Oleksii


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

* Re: [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs to build full Xen
  2024-01-23 13:20   ` Jan Beulich
@ 2024-01-23 17:31     ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-23 17:31 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:20 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > --- a/xen/arch/riscv/early_printk.c
> > +++ b/xen/arch/riscv/early_printk.c
> > @@ -40,171 +40,3 @@ void early_printk(const char *str)
> >          str++;
> >      }
> >  }
> > -
> > -/*
> > - * The following #if 1 ... #endif should be removed after printk
> > - * and related stuff are ready.
> > - */
> > -#if 1
> > -
> > -#include <xen/stdarg.h>
> > -#include <xen/string.h>
> > -
> > -/**
> > - * strlen - Find the length of a string
> > - * @s: The string to be sized
> > - */
> > -size_t (strlen)(const char * s)
> > -{
> > -    const char *sc;
> > -
> > -    for (sc = s; *sc != '\0'; ++sc)
> > -        /* nothing */;
> > -    return sc - s;
> > -}
> > -
> > -/**
> > - * memcpy - Copy one area of memory to another
> > - * @dest: Where to copy to
> > - * @src: Where to copy from
> > - * @count: The size of the area.
> > - *
> > - * You should not use this function to access IO space, use
> > memcpy_toio()
> > - * or memcpy_fromio() instead.
> > - */
> > -void *(memcpy)(void *dest, const void *src, size_t count)
> > -{
> > -    char *tmp = (char *) dest, *s = (char *) src;
> > -
> > -    while (count--)
> > -        *tmp++ = *s++;
> > -
> > -    return dest;
> > -}
> > -
> > -int vsnprintf(char* str, size_t size, const char* format, va_list
> > args)
> > -{
> > -    size_t i = 0; /* Current position in the output string */
> > -    size_t written = 0; /* Total number of characters written */
> > -    char* dest = str;
> > -
> > -    while ( format[i] != '\0' && written < size - 1 )
> > -    {
> > -        if ( format[i] == '%' )
> > -        {
> > -            i++;
> > -
> > -            if ( format[i] == '\0' )
> > -                break;
> > -
> > -            if ( format[i] == '%' )
> > -            {
> > -                if ( written < size - 1 )
> > -                {
> > -                    dest[written] = '%';
> > -                    written++;
> > -                }
> > -                i++;
> > -                continue;
> > -            }
> > -
> > -            /*
> > -             * Handle format specifiers.
> > -             * For simplicity, only %s and %d are implemented
> > here.
> > -             */
> > -
> > -            if ( format[i] == 's' )
> > -            {
> > -                char* arg = va_arg(args, char*);
> > -                size_t arglen = strlen(arg);
> > -
> > -                size_t remaining = size - written - 1;
> > -
> > -                if ( arglen > remaining )
> > -                    arglen = remaining;
> > -
> > -                memcpy(dest + written, arg, arglen);
> > -
> > -                written += arglen;
> > -                i++;
> > -            }
> > -            else if ( format[i] == 'd' )
> > -            {
> > -                int arg = va_arg(args, int);
> > -
> > -                /* Convert the integer to string representation */
> > -                char numstr[32]; /* Assumes a maximum of 32 digits
> > */
> > -                int numlen = 0;
> > -                int num = arg;
> > -                size_t remaining;
> > -
> > -                if ( arg < 0 )
> > -                {
> > -                    if ( written < size - 1 )
> > -                    {
> > -                        dest[written] = '-';
> > -                        written++;
> > -                    }
> > -
> > -                    num = -arg;
> > -                }
> > -
> > -                do
> > -                {
> > -                    numstr[numlen] = '0' + num % 10;
> > -                    num = num / 10;
> > -                    numlen++;
> > -                } while ( num > 0 );
> > -
> > -                /* Reverse the string */
> > -                for (int j = 0; j < numlen / 2; j++)
> > -                {
> > -                    char tmp = numstr[j];
> > -                    numstr[j] = numstr[numlen - 1 - j];
> > -                    numstr[numlen - 1 - j] = tmp;
> > -                }
> > -
> > -                remaining = size - written - 1;
> > -
> > -                if ( numlen > remaining )
> > -                    numlen = remaining;
> > -
> > -                memcpy(dest + written, numstr, numlen);
> > -
> > -                written += numlen;
> > -                i++;
> > -            }
> > -        }
> > -        else
> > -        {
> > -            if ( written < size - 1 )
> > -            {
> > -                dest[written] = format[i];
> > -                written++;
> > -            }
> > -            i++;
> > -        }
> > -    }
> > -
> > -    if ( size > 0 )
> > -        dest[written] = '\0';
> > -
> > -    return written;
> > -}
> > -
> > -void printk(const char *format, ...)
> > -{
> > -    static char buf[1024];
> > -
> > -    va_list args;
> > -    va_start(args, format);
> > -
> > -    (void)vsnprintf(buf, sizeof(buf), format, args);
> > -
> > -    early_printk(buf);
> > -
> > -    va_end(args);
> > -}
> > -
> > -#endif
> > -
> 
> Aren't you transiently breaking the build by removing these here,
> rather
> than in the next patch?
It should break. I'll double check. If it will, then I'll move these
changes in the next patch.
> 
> > --- /dev/null
> > +++ b/xen/arch/riscv/stubs.c
> > @@ -0,0 +1,422 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#include <xen/cpumask.h>
> > +#include <xen/domain.h>
> > +#include <xen/irq.h>
> > +#include <xen/nodemask.h>
> > +#include <xen/time.h>
> > +#include <public/domctl.h>
> > +
> > +#include <asm/current.h>
> > +
> > +/* smpboot.c */
> > +
> > +cpumask_t cpu_online_map;
> > +cpumask_t cpu_present_map;
> > +cpumask_t cpu_possible_map;
> > +
> > +/* ID of the PCPU we're running on */
> > +DEFINE_PER_CPU(unsigned int, cpu_id);
> > +/* XXX these seem awfully x86ish... */
> > +/* representing HT siblings of each logical CPU */
> > +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask);
> > +/* representing HT and core siblings of each logical CPU */
> > +DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_mask);
> > +
> > +nodemask_t __read_mostly node_online_map = { { [0] = 1UL } };
> > +
> > +/* time.c */
> > +
> > +unsigned long __read_mostly cpu_khz;  /* CPU clock frequency in
> > kHz. */
> 
> __ro_after_init?
Yes, it should be __ro_after_init. Thanks.

> 
> > +s_time_t get_s_time(void)
> > +{
> > +    BUG();
> > +}
> > +
> > +int reprogram_timer(s_time_t timeout)
> > +{
> > +    BUG();
> > +}
> > +
> > +void send_timer_event(struct vcpu *v)
> > +{
> > +    BUG();
> > +}
> > +
> > +void domain_set_time_offset(struct domain *d, int64_t
> > time_offset_seconds)
> > +{
> > +    BUG();
> > +}
> > +
> > +/* shutdown.c */
> > +
> > +void machine_restart(unsigned int delay_millisecs)
> > +{
> > +    BUG();
> > +}
> > +
> > +void machine_halt(void)
> > +{
> > +    BUG();
> > +}
> > +
> > +/* vm_event.c */
> > +
> > +struct vm_event_st;
> > +
> > +void vm_event_fill_regs(struct vm_event_st *req)
> > +{
> > +    BUG();
> > +}
> > +
> > +void vm_event_set_registers(struct vcpu *v, struct vm_event_st
> > *rsp)
> > +{
> > +    BUG();
> > +}
> > +
> > +void vm_event_monitor_next_interrupt(struct vcpu *v)
> > +{
> > +    /* Not supported on RISCV. */
> > +}
> > +
> > +void vm_event_reset_vmtrace(struct vcpu *v)
> > +{
> > +    /* Not supported on RISCV. */
> > +}
> 
> Judging from the comments these last two are in their final shape.
> Wouldn't it make sense to put them in vm_event.c right away then? And
> then perhaps together with the two stubs?
Yes, it makes sense.

> 
> Yet then - Arm gets away without vm_event_reset_vmtrace()? Can you
> explain why the same isn't true for RISC-V?
It should true and for RISC-V. I'll look at when they gets away
vm_event_reset_vmtrace().

> 
> > @@ -11,3 +15,24 @@ void do_trap(struct cpu_user_regs *cpu_regs)
> >  {
> >      die();
> >  }
> > +
> > +void vcpu_show_execution_state(struct vcpu *v)
> > +{
> > +    assert_failed("need to be implented");
> 
> Just to mention it again - the expectation is that all instances will
> use the same "canonical" pattern for identifying yet-to-be-
> implemented
> functions.
Sure, I'll update using BUG_ON("unimplemented");

Thanks for review.

~ Oleksii

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

* Re: [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64
  2024-01-23 17:05       ` Jan Beulich
@ 2024-01-23 17:34         ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-23 17:34 UTC (permalink / raw
  To: Jan Beulich
  Cc: Andrew Cooper, George Dunlap, Julien Grall, Stefano Stabellini,
	Wei Liu, xen-devel

On Tue, 2024-01-23 at 18:05 +0100, Jan Beulich wrote:
> On 23.01.2024 15:49, Oleksii wrote:
> > On Tue, 2024-01-23 at 12:22 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > > ---
> > > >  Changes in V3:
> > > >   - new patch
> > > > ---
> > > >  README | 3 +++
> > > >  1 file changed, 3 insertions(+)
> > > > 
> > > > diff --git a/README b/README
> > > > index c8a108449e..1015a285c0 100644
> > > > --- a/README
> > > > +++ b/README
> > > > @@ -48,6 +48,9 @@ provided by your OS distributor:
> > > >        - For ARM 64-bit:
> > > >          - GCC 5.1 or later
> > > >          - GNU Binutils 2.24 or later
> > > > +      - For RISC-V 64-bit:
> > > > +        - GCC 13.2.1 or later
> > > > +        - GNU Binutils 2.40 or later
> > > 
> > > That's pretty new. For gcc that's even newer than the newest
> > > release.
> > > If older versions really won't do, I don't think you can leave
> > > this
> > > unjustified (by having an empty description). Till now gcc 13.2
> > > has
> > > served me well, and iirc 13.1, 12.3, and 12.2 were fine, too.
> > It can be 12.2.0 for GCC and 2.39 for GNU Binutils. ( it is
> > toolchain
> > which is used by contrainer for RISC-V in Xen ). I'll update
> > versions
> > then.
> > 
> > But could you please explain again why it can't be 13.2.1 ( it is a
> > version which I have in my distribution, so it is the reason why I
> > used
> > this version in README file ) ?
> 
> 13.2.1 is a pre-release of 13.3.0. Only versions ending in .0 are
> upstream
> released versions these days. And I think it would be helpful if the
> minimum version also was the first in a major-version series, i.e.
> I'd
> generally prefer naming <N>.1.0 (or <N>.1 for simplicity; see Arm's
> entry).
> Of course if no such suitable version exists (because of being
> buggy), then
> specifying another one is okay. As to x.y.1 - nobody will then really
> know
> which version it is, because every distro will ship its own variant.
> 
Thanks for explanation.
I'll drop the last number then.

~ Oleksii


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

* Re: [PATCH v3 27/34] xen/riscv: define an address of frame table
  2024-01-23 16:50     ` Oleksii
@ 2024-01-24  8:07       ` Jan Beulich
  2024-01-24 10:01         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-24  8:07 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 17:50, Oleksii wrote:
> On Tue, 2024-01-23 at 12:32 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> @@ -22,25 +30,56 @@
>>>   *
>>>   * It means that:
>>>   *   top VA bits are simply ignored for the purpose of translating
>>> to PA.
>>> +#endif
>>>   *
>>> - *
>>> ===================================================================
>>> =========
>>> - *    Start addr    |   End addr        |  Size  | Slot      
>>> |area description
>>> - *
>>> ===================================================================
>>> =========
>>> - * FFFFFFFFC0800000 |  FFFFFFFFFFFFFFFF |1016 MB | L2 511     |
>>> Unused
>>> - * FFFFFFFFC0600000 |  FFFFFFFFC0800000 |  2 MB  | L2 511     |
>>> Fixmap
>>> - * FFFFFFFFC0200000 |  FFFFFFFFC0600000 |  4 MB  | L2 511     |
>>> FDT
>>> - * FFFFFFFFC0000000 |  FFFFFFFFC0200000 |  2 MB  | L2 511     |
>>> Xen
>>> - *                 ...                  |  1 GB  | L2 510     |
>>> Unused
>>> - * 0000003200000000 |  0000007F80000000 | 309 GB | L2 200-509 |
>>> Direct map
>>> - *                 ...                  |  1 GB  | L2 199     |
>>> Unused
>>> - * 0000003100000000 |  00000031C0000000 |  3 GB  | L2 196-198 |
>>> Frametable
>>> - *                 ...                  |  1 GB  | L2 195     |
>>> Unused
>>> - * 0000003080000000 |  00000030C0000000 |  1 GB  | L2 194     |
>>> VMAP
>>> - *                 ...                  | 194 GB | L2 0 - 193 |
>>> Unused
>>> - *
>>> ===================================================================
>>> =========
>>> + *       SATP_MODE_SV32   | SATP_MODE_SV39   | SATP_MODE_SV48   |
>>> SATP_MODE_SV57
>>> + *     
>>> ==================|==================|==================|==========
>>> =======
>>> + * BA0 | FFFFFFFFFFE00000 | FFFFFFFFC0000000 | FFFFFF8000000000 |
>>> FFFF000000000000
>>> + * BA1 | 0000000019000000 | 0000003200000000 | 0000640000000000 |
>>> 00C8000000000000
>>> + * BA2 | 0000000018800000 | 0000003100000000 | 0000620000000000 |
>>> 00C4000000000000
>>> + * BA3 | 0000000018400000 | 0000003080000000 | 0000610000000000 |
>>> 00C2000000000000
>>>   *
>>> -#endif
>>> + *
>>> ===================================================================
>>> ============
>>> + * Start addr     |   End addr          |  Size  | Root PT slot |
>>> Area description
>>> + *
>>> ===================================================================
>>> ============
>>> + * BA0 + 0x800000 |  FFFFFFFFFFFFFFFF   |1016 MB |     511      |
>>> Unused
>>> + * BA0 + 0x400000 |  BA0 + 0x800000     |  2 MB  |     511      |
>>> Fixmap
>>> + * BA0 + 0x200000 |  BA0 + 0x400000     |  4 MB  |     511      |
>>> FDT
>>> + * BA0            |  BA0 + 0x200000     |  2 MB  |     511      |
>>> Xen
>>> + *                 ...                  |  1 GB  |     510      |
>>> Unused
>>> + * BA1 + 0x000000 |  BA1 + 0x4D80000000 | 309 GB |   200-509    |
>>> Direct map
>>
>> This definitely can't be right for SV32. Others may be problematic,
>> too, like ...
>>
>>> + *                 ...                  |  1 GB  |     199      |
>>> Unused
>>> + * BA2 + 0x000000 |  BA2 + 0xC0000000   |  3 GB  |   196-198    |
>>> Frametable
>>
>> ... this one. Otoh I'd expect both to potentially be much larger in
>> SV48 and SV57 modes.
> Regarding Sv32, it looks to me the only BA0 and End addr at the first
> line isn't correct as address size is 32.
> 
> Regarding other modes, yes, it should be changed Size column. Also, the
> size of frame table should be recalculated.
> 
> Do we really need size column?
> 
> Wouldn't it be enough only have PT slot number?

Perhaps.

> Would it be better to have separate table for each mode?

Don't know.

>>> +#define VPN_BITS    (9)
>>
>> This need to move ...
>>
>>> +#define HYP_PT_ROOT_LEVEL (CONFIG_PAGING_LEVELS - 1)
>>> +
>>> +#ifdef CONFIG_RISCV_64
>>
>> ... here, I think, for not being applicable to SV32?
> You are right, it is not applicable for Sv32. In case of Sv32, it
> should be 10.
> But I am not sure that it is correct only to move this definition as
> RISCV-64 can also use Sv32. So it looks like VPN_BITS should be "#ifdef
> RV_STAGE1_MODE == Sv32".

Can it? The spec talks of SXLEN=32 implying SV32, while SXLEN=64 permits
SV39, SV48, and SV57. No mention of SV32 there.

>>> +#define SLOTN_ENTRY_BITS        (HYP_PT_ROOT_LEVEL * VPN_BITS +
>>> PAGE_SHIFT)
>>> +#define SLOTN(slot)             (_AT(vaddr_t, slot) <<
>>> SLOTN_ENTRY_BITS)
>>> +#define SLOTN_ENTRY_SIZE        SLOTN(1)
>>
>> Do you have any example of how/where this going to be used?
> Yes, it will be used to define DIRECTMAP_SIZE:
> #define DIRECTMAP_SIZE          (SLOTN_ENTRY_SIZE * (509-200))

How about

#define DIRECTMAP_SIZE          (SLOTN(509) - SLOTN(200))

instead?

>>> +#define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1 -
>>> GB(1)) */
>>
>> Won't /* -GB(1) */ do, thus allowing the line to also be padded such
>> that
>> it matches neighboring ones in layout?
> Could you please clarify what do you mean by padded here? The intention
> was to show that 1 GB is used for Xen, FDT and fixmap.

I'm talking of blank padding in the source file. Note how preceding and
following #define-s blank-pad expansions so they all align. Just this
one in the middle does not.

Jan

>>> +#define FRAMETABLE_VIRT_START   SLOTN(196)
>>> +#define FRAMETABLE_SIZE         GB(3)
>>> +#define FRAMETABLE_NR           (FRAMETABLE_SIZE /
>>> sizeof(*frame_table))
>>> +#define FRAMETABLE_VIRT_END     (FRAMETABLE_VIRT_START +
>>> FRAMETABLE_SIZE - 1)
>>> +
>>> +#define VMAP_VIRT_START         SLOTN(194)
>>> +#define VMAP_VIRT_SIZE          GB(1)
>>> [...]
>>
> 



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

* Re: [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen
  2024-01-23 16:54     ` Oleksii
@ 2024-01-24  8:09       ` Jan Beulich
  2024-01-24 10:02         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-24  8:09 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 17:54, Oleksii wrote:
> On Tue, 2024-01-23 at 12:36 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> Acked-by: Jan Beulich <jbeulich@suse.com>
>>> ---
>>> Changes in V3:
>>>  - update the commit message
>>
>> Once again I find this puzzling, considering there's no commit
>> message
>> at all.
> By the I meant that asm/page.h was changed to page.h

Oh. Can you say "title" or "subject" when you mean that, and "commit
message" (or "description") only when you actually mean the description?

Jan


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2024-01-23 17:08     ` Oleksii
@ 2024-01-24  8:19       ` Jan Beulich
  2024-01-24 10:12         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-24  8:19 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 18:08, Oleksii wrote:
> On Tue, 2024-01-23 at 12:39 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
>>> ---
>>> Changes in V3:
>>>  - Update the commit message
>>
>> ??? (again)
> The same as with previous. asm/processor.h was changed to processor.h
> 
>>
>>> @@ -53,6 +56,18 @@ struct cpu_user_regs
>>>      unsigned long pregs;
>>>  };
>>>  
>>> +/* TODO: need to implement */
>>> +#define cpu_to_core(cpu)   (0)
>>> +#define cpu_to_socket(cpu) (0)
>>> +
>>> +static inline void cpu_relax(void)
>>> +{
>>> +    /* Encoding of the pause instruction */
>>> +    __asm__ __volatile__ ( ".insn 0x100000F" );
>>
>> binutils 2.40 knows "pause" - why use .insn then?
> I thought that for this instruction it is needed to have extension
> ZIHINTPAUSE ( according to Linux Kernel source code [1] ) and to cover
> older version.

Well, of course you'll need to enable the extension then for gas. But
as long as you use the insn unconditionally, that's all fine and
natural. Another thing would be if you meant to also run on systems
not supporting the extension: Then the above use of .insn would need
to become conditional anyway.

>>> +    barrier();
>>
>> Why?
> Just to be aligned with Linux kernel implemetation from where this
> function was taken.

Hmm, looking more closely we have an (open-coded) barrier even on x86.
So I suppose it's really wanted (to keep the compiler from moving
memory accesses around this construct), but then you may want to
consider using

    __asm__ __volatile__ ( "pause" ::: "memory" );

here. First and foremost because at least in the general case two
separate asm()s aren't the same as one combined one (volatile ones
are more restricted, but I'd always err on the safe side, even if
just to avoid giving bad examples which later on may be taken as a
basis for deriving other code).

Jan


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-01-23 17:27     ` Oleksii
@ 2024-01-24  8:23       ` Jan Beulich
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-24  8:23 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 23.01.2024 18:27, Oleksii wrote:
> On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> +#define _PGC_extra        PG_shift(10)
>>> +#define PGC_extra         PG_mask(1, 10)
>>> +
>>> +#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
>>> +#define is_xen_heap_mfn(mfn) \
>>> +    (mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
>>> +
>>> +#define is_xen_fixed_mfn(mfn)                                   \
>>> +    ((mfn_to_maddr(mfn) >= virt_to_maddr(&_start)) &&           \
>>> +     (mfn_to_maddr(mfn) <= virt_to_maddr((vaddr_t)_end - 1)))
>>
>> Why does _start need prefixing wuth & and _end prefixing with a cast?
>> First and foremost both want to be consistent. And then preferably
>> with as little extra clutter as possible.
> This is how it was defined in Arm. I think it both can be casted.
> I'll update that.

Judging from your present use of virt_to_maddr(&_start), I'd assume
you're fine without casts. And when casts aren't needed, they're
better avoided.

Jan


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-23 13:27           ` Jan Beulich
@ 2024-01-24  9:15             ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-24  9:15 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:27 +0100, Jan Beulich wrote:
> On 23.01.2024 13:18, Oleksii wrote:
> > On Tue, 2024-01-23 at 11:28 +0100, Jan Beulich wrote:
> > > On 23.01.2024 11:15, Oleksii wrote:
> > > > On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
> > > > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > > > +static inline unsigned long __xchg(volatile void *ptr,
> > > > > > unsigned
> > > > > > long x, int size)
> > > > > > +{
> > > > > > +    switch (size) {
> > > > > > +    case 1:
> > > > > > +        return __cmpxchg_case_1(ptr, (uint32_t)-1, x);
> > > > > > +    case 2:
> > > > > > +        return __cmpxchg_case_2(ptr, (uint32_t)-1, x);
> > > > > 
> > > > > How are these going to work? You'll compare against ~0, and
> > > > > if
> > > > > the
> > > > > value
> > > > > in memory isn't ~0, memory won't be updated; you will only
> > > > > (correctly)
> > > > > return the value found in memory.
> > > > > 
> > > > > Or wait - looking at __cmpxchg_case_{1,2}() far further down,
> > > > > you
> > > > > ignore
> > > > > "old" there. Which apparently means they'll work for the use
> > > > > here,
> > > > > but
> > > > > not for the use in __cmpxchg().
> > > > Yes, the trick is that old is ignored and is read in
> > > > __emulate_cmpxchg_case1_2() before __cmpxchg_case_4 is called:
> > > >     do
> > > > {                                                              
> > > >         read_val =
> > > > read_func(aligned_ptr);                            
> > > >         swapped_new = read_val &
> > > > ~mask;                               
> > > >         swapped_new |=
> > > > masked_new;                                    
> > > >         ret = cmpxchg_func(aligned_ptr, read_val,
> > > > swapped_new);       
> > > >     } while ( ret != read_val
> > > > );                                      
> > > > read_val it is 'old'.
> > > > 
> > > > But now I am not 100% sure that it is correct for __cmpxchg...
> > > 
> > > It just can't be correct - you can't ignore "old" there. I think
> > > you
> > > want simple cmpxchg primitives, which xchg then uses in a loop
> > > (while
> > > cmpxchg uses them plainly).
> > But xchg doesn't require 'old' value, so it should be ignored in
> > some
> > way by cmpxchg.
> 
> Well, no. If you have only cmpxchg, I think your only choice is - as
> said - to read the old value and then loop over cmpxchg until that
> succeeds. Not really different from other operations which need
> emulating using cmpxchg.
Then it looks like the main error in __emulate_cmpxchg_case1_2 is that
I read the value each time, so read_val = read_func(aligned_ptr); 
should be before the do {...} while(). Also, it would be better to
rename it to old_val or just old.

> 
> > > > > > +static always_inline unsigned short
> > > > > > __cmpxchg_case_2(volatile
> > > > > > uint32_t *ptr,
> > > > > > +                                                    
> > > > > > uint32_t
> > > > > > old,
> > > > > > +                                                    
> > > > > > uint32_t
> > > > > > new)
> > > > > > +{
> > > > > > +    (void) old;
> > > > > > +
> > > > > > +    if (((unsigned long)ptr & 3) == 3)
> > > > > > +    {
> > > > > > +#ifdef CONFIG_64BIT
> > > > > > +        return __emulate_cmpxchg_case1_2((uint64_t *)ptr,
> > > > > > new,
> > > > > > +                                         readq,
> > > > > > __cmpxchg_case_8,
> > > > > > 0xffffU);
> > > > > 
> > > > > What if ((unsigned long)ptr & 7) == 7 (which is a sub-case of
> > > > > what
> > > > > the
> > > > > if() above checks for? Isn't it more reasonable to require
> > > > > aligned
> > > > > 16-bit quantities here? Or if mis-aligned addresses are okay,
> > > > > you
> > > > > could
> > > > > as well emulate using __cmpxchg_case_4().
> > > > Yes, it will be more reasonable. I'll use IS_ALIGNED instead.
> > > 
> > > Not sure I get your use of "instead" here correctly. There's more
> > > to change here than just the if() condition.
> > I meant something like:
> > 
> > if ( IS_ALIGNED(ptr, 16) )
> >     __emulate_cmpxchg_case1_2(...);
> > else
> >     assert_failed("ptr isn't aligned\n");
> 
> Except that you'd better not use assert_failed() directly anywhere,
> and the above is easier as
> 
>     ASSERT(IS_ALIGNED(ptr, 16));
>     __emulate_cmpxchg_case1_2(...);
> 
> anyway (leaving aside that I guess you mean 2, not 16).
Yeah, it should be 2. Thanks.

~ Oleksii

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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-23 13:30           ` Jan Beulich
@ 2024-01-24  9:23             ` Oleksii
  2024-01-24 11:19               ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-24  9:23 UTC (permalink / raw
  To: Jan Beulich
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:30 +0100, Jan Beulich wrote:
> On 23.01.2024 13:24, Oleksii wrote:
> > On Tue, 2024-01-23 at 11:30 +0100, Jan Beulich wrote:
> > > On 23.01.2024 11:21, Oleksii wrote:
> > > > On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
> > > > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > > > --- /dev/null
> > > > > > +++ b/xen/arch/riscv/include/asm/fence.h
> > > > > > @@ -0,0 +1,13 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > > > > +#ifndef _ASM_RISCV_FENCE_H
> > > > > > +#define _ASM_RISCV_FENCE_H
> > > > > > +
> > > > > > +#ifdef CONFIG_SMP
> > > > > > +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
> > > > > > +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
> > > > > > +#else
> > > > > > +#define RISCV_ACQUIRE_BARRIER
> > > > > > +#define RISCV_RELEASE_BARRIER
> > > > > > +#endif
> > > > > 
> > > > > Do you really care about the !SMP case? On x86 at least we
> > > > > stopped
> > > > > special-
> > > > > casing that configuration many years ago (the few cases where
> > > > > for
> > > > > typically
> > > > > build reasons it matters, using CONFIG_NR_CPUS is
> > > > > sufficient). If
> > > > > you
> > > > > care
> > > > > about it, there needs to be somewhere you actually #define
> > > > > CONFIG_SMP.
> > > > Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS?
> > > 
> > > You can. Question is whether there's a point in doing so. Do you
> > > expect people to actually want to run Xen on single-CPU systems?
> > > They're generally not overly well suited for virtualization ...
> > Just to clarify.
> > 
> > Do you mean physically single based CPU?
> > Then I don't expect to run Xen on such systems and it is not
> > nesessary
> > to define *_BARRIER in this case. Should we have to add build error
> > notification that we don't support single-CPU systems in this
> > header?
> > 
> > If you are speaking about we have ,let it be, 4 CPUs and only 1 CPU
> > is
> > currently supported by Xen then it still makes sense.
> 
> No, that's still not what I mean. The question is: Is it useful for
> you
> to _special case_ the NR_CPUS=1 case? Or is it instead simpler to
> handle
> NR_CPUS=1 the same as NR_CPUS>1 (accepting less than ideal
> performance,
> on the basis that in reality nobody's expected to use such in
> production
> anyway)?
NR_CPUS=1 sometimes is useful for debugging. At least, at the start I
used that several times, but ITBO I don't remember when I used that
case after SMP support was added and context_switch() was fixed.

Probably, I misunderstand the real idea of NR_CPUS. Does NR_CPUS
represent a number of logical CPUs which can be different from physical
amount of CPU?
If yes, then what I wrote above it was about physical CPU and then in
context of logical CPUs I don't need a special case when NR_CPUS=1.

~ Oleksii



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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-23 13:37       ` Jan Beulich
@ 2024-01-24  9:34         ` Oleksii
  2024-01-24 11:24           ` Jan Beulich
  2024-01-26  9:44         ` Oleksii
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-24  9:34 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
> On 23.01.2024 13:34, Oleksii wrote:
> > On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > --- a/xen/common/Kconfig
> > > > +++ b/xen/common/Kconfig
> > > > @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
> > > >  config GENERIC_BUG_FRAME
> > > >  	bool
> > > >  
> > > > +config GENERIC_FIND_NEXT_BIT
> > > > +	bool
> > > 
> > > There's no need for this, as ...
> > > 
> > > > --- a/xen/lib/Makefile
> > > > +++ b/xen/lib/Makefile
> > > > @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
> > > >  lib-y += bsearch.o
> > > >  lib-y += ctors.o
> > > >  lib-y += ctype.o
> > > > +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
> > > 
> > > ... you're moving this to lib/. Or have you encountered any issue
> > > with building this uniformly, and you forgot to mention this in
> > > the description?
> > I didn't check. My intention was to provide opportunity to check if
> > an
> > architecture want to use generic version or not. Otherwise, I
> > expected
> > that we will have multiple definiotion of the funcion.
> > 
> > But considering that they are all defined under #ifdef...#endif we
> > can
> > remove the declaration of the config GENERIC_FIND_NEXT_BIT.
> 
> What #ifdef / #endif would matter here? Whats in lib/ is intended to
> be
> generic anyway. And what is in the resulting lib.a won't be used by
> an
> arch if it has an arch-specific implementation. 
If what is implemented in lib.a won't be used by an arch if it has an
arch-specific implementation then, for sure, I have to drop
CONFIG_GENERIC_FIND_NEXT_BIT.
But I am not really understand if lib.a is linked with Xen, then it
should be an issue then if some arch implement find-next-bit function
we will have to multiple definitions ( one in lib.a and one arch
specific ). Probably, I have to look at how it is done.

> Problems could arise if
> an arch had an inline function colliding with the out-of-line one.
> But
> that's about the old case where I could see a need to make the
> building
> of one of the objects conditional. And you'll note that withing this
> Makefile there are pretty few conditionals.
Could you please clarify What does it mean "out-of-line" ?
> 
> > > > --- /dev/null
> > > > +++ b/xen/lib/find-next-bit.c
> > > > [...]
> > > 
> > > I was going to ask that you convince git to actually present a
> > > proper
> > > diff, to make visible what changes. But other than the
> > > description
> > > says
> > > you don't really move the file, you copy it. Judging from further
> > > titles
> > > there's also nowhere you'd make Arm actually use this now generic
> > > code.
> > I wanted to do it separately, outside this patch series to simplify
> > review and not have Arm specific changes in RISC-V patch series.
> 
> Then do it the other way around: Make a separate _prereq_ change
> truly
> moving the file.
So this one patch should be separated by 2? One which moves find-next-
bit.c from Arm to xen/lib, and second where xen/lib/Makefile is
updated.

> 
> > Regarding a proper diff, you would like me to make git shows that
> > it
> > was copy from Arm and it is not newly created file. Am I understand
> > you
> > correctly?
> 
> Not quite, I think. Git has move detection (and we've seen that in
> action in other patches of yours). So when truly moving a file, what
> (if anything) is changed is easily visible.
I think I am still a little bit confused. But I think the answer on my
question above can clarify that.

~ Oleksii


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

* Re: [PATCH v3 27/34] xen/riscv: define an address of frame table
  2024-01-24  8:07       ` Jan Beulich
@ 2024-01-24 10:01         ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-24 10:01 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-24 at 09:07 +0100, Jan Beulich wrote:
> On 23.01.2024 17:50, Oleksii wrote:
> > On Tue, 2024-01-23 at 12:32 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > @@ -22,25 +30,56 @@
> > > >   *
> > > >   * It means that:
> > > >   *   top VA bits are simply ignored for the purpose of
> > > > translating
> > > > to PA.
> > > > +#endif
> > > >   *
> > > > - *
> > > > ===============================================================
> > > > ====
> > > > =========
> > > > - *    Start addr    |   End addr        |  Size  | Slot      
> > > > > area description
> > > > - *
> > > > ===============================================================
> > > > ====
> > > > =========
> > > > - * FFFFFFFFC0800000 |  FFFFFFFFFFFFFFFF |1016 MB | L2 511    
> > > > |
> > > > Unused
> > > > - * FFFFFFFFC0600000 |  FFFFFFFFC0800000 |  2 MB  | L2 511    
> > > > |
> > > > Fixmap
> > > > - * FFFFFFFFC0200000 |  FFFFFFFFC0600000 |  4 MB  | L2 511    
> > > > |
> > > > FDT
> > > > - * FFFFFFFFC0000000 |  FFFFFFFFC0200000 |  2 MB  | L2 511    
> > > > |
> > > > Xen
> > > > - *                 ...                  |  1 GB  | L2 510    
> > > > |
> > > > Unused
> > > > - * 0000003200000000 |  0000007F80000000 | 309 GB | L2 200-509
> > > > |
> > > > Direct map
> > > > - *                 ...                  |  1 GB  | L2 199    
> > > > |
> > > > Unused
> > > > - * 0000003100000000 |  00000031C0000000 |  3 GB  | L2 196-198
> > > > |
> > > > Frametable
> > > > - *                 ...                  |  1 GB  | L2 195    
> > > > |
> > > > Unused
> > > > - * 0000003080000000 |  00000030C0000000 |  1 GB  | L2 194    
> > > > |
> > > > VMAP
> > > > - *                 ...                  | 194 GB | L2 0 - 193
> > > > |
> > > > Unused
> > > > - *
> > > > ===============================================================
> > > > ====
> > > > =========
> > > > + *       SATP_MODE_SV32   | SATP_MODE_SV39   |
> > > > SATP_MODE_SV48   |
> > > > SATP_MODE_SV57
> > > > + *     
> > > > ==================|==================|==================|======
> > > > ====
> > > > =======
> > > > + * BA0 | FFFFFFFFFFE00000 | FFFFFFFFC0000000 |
> > > > FFFFFF8000000000 |
> > > > FFFF000000000000
> > > > + * BA1 | 0000000019000000 | 0000003200000000 |
> > > > 0000640000000000 |
> > > > 00C8000000000000
> > > > + * BA2 | 0000000018800000 | 0000003100000000 |
> > > > 0000620000000000 |
> > > > 00C4000000000000
> > > > + * BA3 | 0000000018400000 | 0000003080000000 |
> > > > 0000610000000000 |
> > > > 00C2000000000000
> > > >   *
> > > > -#endif
> > > > + *
> > > > ===============================================================
> > > > ====
> > > > ============
> > > > + * Start addr     |   End addr          |  Size  | Root PT
> > > > slot |
> > > > Area description
> > > > + *
> > > > ===============================================================
> > > > ====
> > > > ============
> > > > + * BA0 + 0x800000 |  FFFFFFFFFFFFFFFF   |1016 MB |    
> > > > 511      |
> > > > Unused
> > > > + * BA0 + 0x400000 |  BA0 + 0x800000     |  2 MB  |    
> > > > 511      |
> > > > Fixmap
> > > > + * BA0 + 0x200000 |  BA0 + 0x400000     |  4 MB  |    
> > > > 511      |
> > > > FDT
> > > > + * BA0            |  BA0 + 0x200000     |  2 MB  |    
> > > > 511      |
> > > > Xen
> > > > + *                 ...                  |  1 GB  |    
> > > > 510      |
> > > > Unused
> > > > + * BA1 + 0x000000 |  BA1 + 0x4D80000000 | 309 GB |   200-
> > > > 509    |
> > > > Direct map
> > > 
> > > This definitely can't be right for SV32. Others may be
> > > problematic,
> > > too, like ...
> > > 
> > > > + *                 ...                  |  1 GB  |    
> > > > 199      |
> > > > Unused
> > > > + * BA2 + 0x000000 |  BA2 + 0xC0000000   |  3 GB  |   196-
> > > > 198    |
> > > > Frametable
> > > 
> > > ... this one. Otoh I'd expect both to potentially be much larger
> > > in
> > > SV48 and SV57 modes.
> > Regarding Sv32, it looks to me the only BA0 and End addr at the
> > first
> > line isn't correct as address size is 32.
> > 
> > Regarding other modes, yes, it should be changed Size column. Also,
> > the
> > size of frame table should be recalculated.
> > 
> > Do we really need size column?
> > 
> > Wouldn't it be enough only have PT slot number?
> 
> Perhaps.
> 
> > Would it be better to have separate table for each mode?
> 
> Don't know.
Then I'll play around different ways to display memory layout.

> 
> > > > +#define VPN_BITS    (9)
> > > 
> > > This need to move ...
> > > 
> > > > +#define HYP_PT_ROOT_LEVEL (CONFIG_PAGING_LEVELS - 1)
> > > > +
> > > > +#ifdef CONFIG_RISCV_64
> > > 
> > > ... here, I think, for not being applicable to SV32?
> > You are right, it is not applicable for Sv32. In case of Sv32, it
> > should be 10.
> > But I am not sure that it is correct only to move this definition
> > as
> > RISCV-64 can also use Sv32. So it looks like VPN_BITS should be
> > "#ifdef
> > RV_STAGE1_MODE == Sv32".
> 
> Can it? The spec talks of SXLEN=32 implying SV32, while SXLEN=64
> permits
> SV39, SV48, and SV57. No mention of SV32 there.
According to spec it can't, but when I tried that in baremetal it
worked.

Let's stick to the spec, and then it would be better to move VPN_BITS
to #ifdef CONFIG_RISCV_64.

> 
> > > > +#define SLOTN_ENTRY_BITS        (HYP_PT_ROOT_LEVEL * VPN_BITS
> > > > +
> > > > PAGE_SHIFT)
> > > > +#define SLOTN(slot)             (_AT(vaddr_t, slot) <<
> > > > SLOTN_ENTRY_BITS)
> > > > +#define SLOTN_ENTRY_SIZE        SLOTN(1)
> > > 
> > > Do you have any example of how/where this going to be used?
> > Yes, it will be used to define DIRECTMAP_SIZE:
> > #define DIRECTMAP_SIZE          (SLOTN_ENTRY_SIZE * (509-200))
> 
> How about
> 
> #define DIRECTMAP_SIZE          (SLOTN(509) - SLOTN(200))
> 
> instead?
It would be better, I'll drop SLOTN_ENTRY_SIZE then. Thanks.

> 
> > > > +#define XEN_VIRT_START 0xFFFFFFFFC0000000 /* (_AC(-1, UL) + 1
> > > > -
> > > > GB(1)) */
> > > 
> > > Won't /* -GB(1) */ do, thus allowing the line to also be padded
> > > such
> > > that
> > > it matches neighboring ones in layout?
> > Could you please clarify what do you mean by padded here? The
> > intention
> > was to show that 1 GB is used for Xen, FDT and fixmap.
> 
> I'm talking of blank padding in the source file. Note how preceding
> and
> following #define-s blank-pad expansions so they all align. Just this
> one in the middle does not.
I see what you mean now. Thanks.

~ Oleksii
> 
> > > > +#define FRAMETABLE_VIRT_START   SLOTN(196)
> > > > +#define FRAMETABLE_SIZE         GB(3)
> > > > +#define FRAMETABLE_NR           (FRAMETABLE_SIZE /
> > > > sizeof(*frame_table))
> > > > +#define FRAMETABLE_VIRT_END     (FRAMETABLE_VIRT_START +
> > > > FRAMETABLE_SIZE - 1)
> > > > +
> > > > +#define VMAP_VIRT_START         SLOTN(194)
> > > > +#define VMAP_VIRT_SIZE          GB(1)
> > > > [...]
> > > 
> > 
> 



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

* Re: [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen
  2024-01-24  8:09       ` Jan Beulich
@ 2024-01-24 10:02         ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-24 10:02 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-24 at 09:09 +0100, Jan Beulich wrote:
> On 23.01.2024 17:54, Oleksii wrote:
> > On Tue, 2024-01-23 at 12:36 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > > Acked-by: Jan Beulich <jbeulich@suse.com>
> > > > ---
> > > > Changes in V3:
> > > >  - update the commit message
> > > 
> > > Once again I find this puzzling, considering there's no commit
> > > message
> > > at all.
> > By the I meant that asm/page.h was changed to page.h
> 
> Oh. Can you say "title" or "subject" when you mean that, and "commit
> message" (or "description") only when you actually mean the
> description?
Sure, I'll stick to proposed terminology next time.
Thanks.

~ Oleksii


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2024-01-24  8:19       ` Jan Beulich
@ 2024-01-24 10:12         ` Oleksii
  2024-01-24 11:27           ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-24 10:12 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-24 at 09:19 +0100, Jan Beulich wrote:
> On 23.01.2024 18:08, Oleksii wrote:
> > On Tue, 2024-01-23 at 12:39 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > > > ---
> > > > Changes in V3:
> > > >  - Update the commit message
> > > 
> > > ??? (again)
> > The same as with previous. asm/processor.h was changed to
> > processor.h
> > 
> > > 
> > > > @@ -53,6 +56,18 @@ struct cpu_user_regs
> > > >      unsigned long pregs;
> > > >  };
> > > >  
> > > > +/* TODO: need to implement */
> > > > +#define cpu_to_core(cpu)   (0)
> > > > +#define cpu_to_socket(cpu) (0)
> > > > +
> > > > +static inline void cpu_relax(void)
> > > > +{
> > > > +    /* Encoding of the pause instruction */
> > > > +    __asm__ __volatile__ ( ".insn 0x100000F" );
> > > 
> > > binutils 2.40 knows "pause" - why use .insn then?
> > I thought that for this instruction it is needed to have extension
> > ZIHINTPAUSE ( according to Linux Kernel source code [1] ) and to
> > cover
> > older version.
> 
> Well, of course you'll need to enable the extension then for gas. But
> as long as you use the insn unconditionally, that's all fine and
> natural. Another thing would be if you meant to also run on systems
> not supporting the extension: Then the above use of .insn would need
> to become conditional anyway.
Then it makes sense to use "pause". 
Let's assume that for now we are running only on systems which support
the extension until we won't face compilation issue for some system.

> 
> > > > +    barrier();
> > > 
> > > Why?
> > Just to be aligned with Linux kernel implemetation from where this
> > function was taken.
> 
> Hmm, looking more closely we have an (open-coded) barrier even on
> x86.
> So I suppose it's really wanted (to keep the compiler from moving
> memory accesses around this construct), but then you may want to
> consider using
> 
>     __asm__ __volatile__ ( "pause" ::: "memory" );
> 
> here. First and foremost because at least in the general case two
> separate asm()s aren't the same as one combined one (volatile ones
> are more restricted, but I'd always err on the safe side, even if
> just to avoid giving bad examples which later on may be taken as a
> basis for deriving other code).
It makes sense, I'll update inline assembler line code.

Thanks.

~ Oleksii



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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-24  9:23             ` Oleksii
@ 2024-01-24 11:19               ` Jan Beulich
  2024-01-24 14:56                 ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-24 11:19 UTC (permalink / raw
  To: Oleksii
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 24.01.2024 10:23, Oleksii wrote:
> On Tue, 2024-01-23 at 14:30 +0100, Jan Beulich wrote:
>> On 23.01.2024 13:24, Oleksii wrote:
>>> On Tue, 2024-01-23 at 11:30 +0100, Jan Beulich wrote:
>>>> On 23.01.2024 11:21, Oleksii wrote:
>>>>> On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
>>>>>> On 22.12.2023 16:12, Oleksii Kurochko wrote:
>>>>>>> --- /dev/null
>>>>>>> +++ b/xen/arch/riscv/include/asm/fence.h
>>>>>>> @@ -0,0 +1,13 @@
>>>>>>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>>>>>>> +#ifndef _ASM_RISCV_FENCE_H
>>>>>>> +#define _ASM_RISCV_FENCE_H
>>>>>>> +
>>>>>>> +#ifdef CONFIG_SMP
>>>>>>> +#define RISCV_ACQUIRE_BARRIER		"\tfence r , rw\n"
>>>>>>> +#define RISCV_RELEASE_BARRIER		"\tfence rw,  w\n"
>>>>>>> +#else
>>>>>>> +#define RISCV_ACQUIRE_BARRIER
>>>>>>> +#define RISCV_RELEASE_BARRIER
>>>>>>> +#endif
>>>>>>
>>>>>> Do you really care about the !SMP case? On x86 at least we
>>>>>> stopped
>>>>>> special-
>>>>>> casing that configuration many years ago (the few cases where
>>>>>> for
>>>>>> typically
>>>>>> build reasons it matters, using CONFIG_NR_CPUS is
>>>>>> sufficient). If
>>>>>> you
>>>>>> care
>>>>>> about it, there needs to be somewhere you actually #define
>>>>>> CONFIG_SMP.
>>>>> Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS?
>>>>
>>>> You can. Question is whether there's a point in doing so. Do you
>>>> expect people to actually want to run Xen on single-CPU systems?
>>>> They're generally not overly well suited for virtualization ...
>>> Just to clarify.
>>>
>>> Do you mean physically single based CPU?
>>> Then I don't expect to run Xen on such systems and it is not
>>> nesessary
>>> to define *_BARRIER in this case. Should we have to add build error
>>> notification that we don't support single-CPU systems in this
>>> header?
>>>
>>> If you are speaking about we have ,let it be, 4 CPUs and only 1 CPU
>>> is
>>> currently supported by Xen then it still makes sense.
>>
>> No, that's still not what I mean. The question is: Is it useful for
>> you
>> to _special case_ the NR_CPUS=1 case? Or is it instead simpler to
>> handle
>> NR_CPUS=1 the same as NR_CPUS>1 (accepting less than ideal
>> performance,
>> on the basis that in reality nobody's expected to use such in
>> production
>> anyway)?
> NR_CPUS=1 sometimes is useful for debugging. At least, at the start I
> used that several times, but ITBO I don't remember when I used that
> case after SMP support was added and context_switch() was fixed.

And "sometimes is useful for debugging" warrants introducing special
cases? I've not suggested disallowing that configuration. I'm merely
asking whether it isn't easier to have the barriers there at all
times. Just like on x86 we now leave the LOCK prefixes in place at
all times.

> Probably, I misunderstand the real idea of NR_CPUS. Does NR_CPUS
> represent a number of logical CPUs which can be different from physical
> amount of CPU?

No.

Jan


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-24  9:34         ` Oleksii
@ 2024-01-24 11:24           ` Jan Beulich
  2024-01-24 15:04             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-24 11:24 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 24.01.2024 10:34, Oleksii wrote:
> On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
>> On 23.01.2024 13:34, Oleksii wrote:
>>> On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>>>> --- a/xen/common/Kconfig
>>>>> +++ b/xen/common/Kconfig
>>>>> @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
>>>>>  config GENERIC_BUG_FRAME
>>>>>  	bool
>>>>>  
>>>>> +config GENERIC_FIND_NEXT_BIT
>>>>> +	bool
>>>>
>>>> There's no need for this, as ...
>>>>
>>>>> --- a/xen/lib/Makefile
>>>>> +++ b/xen/lib/Makefile
>>>>> @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
>>>>>  lib-y += bsearch.o
>>>>>  lib-y += ctors.o
>>>>>  lib-y += ctype.o
>>>>> +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
>>>>
>>>> ... you're moving this to lib/. Or have you encountered any issue
>>>> with building this uniformly, and you forgot to mention this in
>>>> the description?
>>> I didn't check. My intention was to provide opportunity to check if
>>> an
>>> architecture want to use generic version or not. Otherwise, I
>>> expected
>>> that we will have multiple definiotion of the funcion.
>>>
>>> But considering that they are all defined under #ifdef...#endif we
>>> can
>>> remove the declaration of the config GENERIC_FIND_NEXT_BIT.
>>
>> What #ifdef / #endif would matter here? Whats in lib/ is intended to
>> be
>> generic anyway. And what is in the resulting lib.a won't be used by
>> an
>> arch if it has an arch-specific implementation. 
> If what is implemented in lib.a won't be used by an arch if it has an
> arch-specific implementation then, for sure, I have to drop
> CONFIG_GENERIC_FIND_NEXT_BIT.
> But I am not really understand if lib.a is linked with Xen, then it
> should be an issue then if some arch implement find-next-bit function
> we will have to multiple definitions ( one in lib.a and one arch
> specific ). Probably, I have to look at how it is done.

You're aware how linking works? Objects are pulled out of archives only
if there's no other definition for a to-be-resolved symbol provided by
a particular object in the archive.

>> Problems could arise if
>> an arch had an inline function colliding with the out-of-line one.
>> But
>> that's about the old case where I could see a need to make the
>> building
>> of one of the objects conditional. And you'll note that withing this
>> Makefile there are pretty few conditionals.
> Could you please clarify What does it mean "out-of-line" ?

"not inline"

>>>>> --- /dev/null
>>>>> +++ b/xen/lib/find-next-bit.c
>>>>> [...]
>>>>
>>>> I was going to ask that you convince git to actually present a
>>>> proper
>>>> diff, to make visible what changes. But other than the
>>>> description
>>>> says
>>>> you don't really move the file, you copy it. Judging from further
>>>> titles
>>>> there's also nowhere you'd make Arm actually use this now generic
>>>> code.
>>> I wanted to do it separately, outside this patch series to simplify
>>> review and not have Arm specific changes in RISC-V patch series.
>>
>> Then do it the other way around: Make a separate _prereq_ change
>> truly
>> moving the file.
> So this one patch should be separated by 2? One which moves find-next-
> bit.c from Arm to xen/lib, and second where xen/lib/Makefile is
> updated.

No, that would break the Arm build. I suggested breaking out this
patch from the series, and then doing what the description says:
Actually move the file. I don't think I suggested splitting the
patch. Even the breaking out of the series was only because you
said "I wanted to do it separately, outside this patch series".

Jan


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2024-01-24 10:12         ` Oleksii
@ 2024-01-24 11:27           ` Jan Beulich
  2024-01-24 15:33             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-24 11:27 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 24.01.2024 11:12, Oleksii wrote:
> On Wed, 2024-01-24 at 09:19 +0100, Jan Beulich wrote:
>> On 23.01.2024 18:08, Oleksii wrote:
>>> On Tue, 2024-01-23 at 12:39 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>>>> @@ -53,6 +56,18 @@ struct cpu_user_regs
>>>>>      unsigned long pregs;
>>>>>  };
>>>>>  
>>>>> +/* TODO: need to implement */
>>>>> +#define cpu_to_core(cpu)   (0)
>>>>> +#define cpu_to_socket(cpu) (0)
>>>>> +
>>>>> +static inline void cpu_relax(void)
>>>>> +{
>>>>> +    /* Encoding of the pause instruction */
>>>>> +    __asm__ __volatile__ ( ".insn 0x100000F" );
>>>>
>>>> binutils 2.40 knows "pause" - why use .insn then?
>>> I thought that for this instruction it is needed to have extension
>>> ZIHINTPAUSE ( according to Linux Kernel source code [1] ) and to
>>> cover
>>> older version.
>>
>> Well, of course you'll need to enable the extension then for gas. But
>> as long as you use the insn unconditionally, that's all fine and
>> natural. Another thing would be if you meant to also run on systems
>> not supporting the extension: Then the above use of .insn would need
>> to become conditional anyway.
> Then it makes sense to use "pause". 
> Let's assume that for now we are running only on systems which support
> the extension until we won't face compilation issue for some system.

Gives me the impression that you still don't properly separate the two
aspects: One is what systems Xen is to run on, and other is what's
needed to make Xen build properly. The first needs documenting (and
ideally at some point actually enforcing), while the latter may require
e.g. compiler command line option adjustments.

Jan


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

* Re: [PATCH v3 15/34] xen/riscv: introduce atomic.h
  2024-01-24 11:19               ` Jan Beulich
@ 2024-01-24 14:56                 ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-24 14:56 UTC (permalink / raw
  To: Jan Beulich
  Cc: Bobby Eshleman, Alistair Francis, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-24 at 12:19 +0100, Jan Beulich wrote:
> On 24.01.2024 10:23, Oleksii wrote:
> > On Tue, 2024-01-23 at 14:30 +0100, Jan Beulich wrote:
> > > On 23.01.2024 13:24, Oleksii wrote:
> > > > On Tue, 2024-01-23 at 11:30 +0100, Jan Beulich wrote:
> > > > > On 23.01.2024 11:21, Oleksii wrote:
> > > > > > On Mon, 2024-01-22 at 17:56 +0100, Jan Beulich wrote:
> > > > > > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/xen/arch/riscv/include/asm/fence.h
> > > > > > > > @@ -0,0 +1,13 @@
> > > > > > > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > > > > > > +#ifndef _ASM_RISCV_FENCE_H
> > > > > > > > +#define _ASM_RISCV_FENCE_H
> > > > > > > > +
> > > > > > > > +#ifdef CONFIG_SMP
> > > > > > > > +#define RISCV_ACQUIRE_BARRIER		"\tfence r ,
> > > > > > > > rw\n"
> > > > > > > > +#define RISCV_RELEASE_BARRIER		"\tfence rw, 
> > > > > > > > w\n"
> > > > > > > > +#else
> > > > > > > > +#define RISCV_ACQUIRE_BARRIER
> > > > > > > > +#define RISCV_RELEASE_BARRIER
> > > > > > > > +#endif
> > > > > > > 
> > > > > > > Do you really care about the !SMP case? On x86 at least
> > > > > > > we
> > > > > > > stopped
> > > > > > > special-
> > > > > > > casing that configuration many years ago (the few cases
> > > > > > > where
> > > > > > > for
> > > > > > > typically
> > > > > > > build reasons it matters, using CONFIG_NR_CPUS is
> > > > > > > sufficient). If
> > > > > > > you
> > > > > > > care
> > > > > > > about it, there needs to be somewhere you actually
> > > > > > > #define
> > > > > > > CONFIG_SMP.
> > > > > > Can't we use instead of CONFIG_SMP - CONFIG_NR_CPUS?
> > > > > 
> > > > > You can. Question is whether there's a point in doing so. Do
> > > > > you
> > > > > expect people to actually want to run Xen on single-CPU
> > > > > systems?
> > > > > They're generally not overly well suited for virtualization
> > > > > ...
> > > > Just to clarify.
> > > > 
> > > > Do you mean physically single based CPU?
> > > > Then I don't expect to run Xen on such systems and it is not
> > > > nesessary
> > > > to define *_BARRIER in this case. Should we have to add build
> > > > error
> > > > notification that we don't support single-CPU systems in this
> > > > header?
> > > > 
> > > > If you are speaking about we have ,let it be, 4 CPUs and only 1
> > > > CPU
> > > > is
> > > > currently supported by Xen then it still makes sense.
> > > 
> > > No, that's still not what I mean. The question is: Is it useful
> > > for
> > > you
> > > to _special case_ the NR_CPUS=1 case? Or is it instead simpler to
> > > handle
> > > NR_CPUS=1 the same as NR_CPUS>1 (accepting less than ideal
> > > performance,
> > > on the basis that in reality nobody's expected to use such in
> > > production
> > > anyway)?
> > NR_CPUS=1 sometimes is useful for debugging. At least, at the start
> > I
> > used that several times, but ITBO I don't remember when I used that
> > case after SMP support was added and context_switch() was fixed.
> 
> And "sometimes is useful for debugging" warrants introducing special
> cases? I've not suggested disallowing that configuration. I'm merely
> asking whether it isn't easier to have the barriers there at all
> times. Just like on x86 we now leave the LOCK prefixes in place at
> all times.
I misunderstood your initial suggestion. In this case we can always
have the barriers. I'll drop then #ifdef CONFIG_SMP.

Thanks for clarification.

~ Oleksii
> 
> > Probably, I misunderstand the real idea of NR_CPUS. Does NR_CPUS
> > represent a number of logical CPUs which can be different from
> > physical
> > amount of CPU?
> 
> No.
> 
> Jan



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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-24 11:24           ` Jan Beulich
@ 2024-01-24 15:04             ` Oleksii
  2024-01-24 15:32               ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-24 15:04 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-24 at 12:24 +0100, Jan Beulich wrote:
> On 24.01.2024 10:34, Oleksii wrote:
> > On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
> > > On 23.01.2024 13:34, Oleksii wrote:
> > > > On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
> > > > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > > > --- a/xen/common/Kconfig
> > > > > > +++ b/xen/common/Kconfig
> > > > > > @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
> > > > > >  config GENERIC_BUG_FRAME
> > > > > >  	bool
> > > > > >  
> > > > > > +config GENERIC_FIND_NEXT_BIT
> > > > > > +	bool
> > > > > 
> > > > > There's no need for this, as ...
> > > > > 
> > > > > > --- a/xen/lib/Makefile
> > > > > > +++ b/xen/lib/Makefile
> > > > > > @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
> > > > > >  lib-y += bsearch.o
> > > > > >  lib-y += ctors.o
> > > > > >  lib-y += ctype.o
> > > > > > +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
> > > > > 
> > > > > ... you're moving this to lib/. Or have you encountered any
> > > > > issue
> > > > > with building this uniformly, and you forgot to mention this
> > > > > in
> > > > > the description?
> > > > I didn't check. My intention was to provide opportunity to
> > > > check if
> > > > an
> > > > architecture want to use generic version or not. Otherwise, I
> > > > expected
> > > > that we will have multiple definiotion of the funcion.
> > > > 
> > > > But considering that they are all defined under #ifdef...#endif
> > > > we
> > > > can
> > > > remove the declaration of the config GENERIC_FIND_NEXT_BIT.
> > > 
> > > What #ifdef / #endif would matter here? Whats in lib/ is intended
> > > to
> > > be
> > > generic anyway. And what is in the resulting lib.a won't be used
> > > by
> > > an
> > > arch if it has an arch-specific implementation. 
> > If what is implemented in lib.a won't be used by an arch if it has
> > an
> > arch-specific implementation then, for sure, I have to drop
> > CONFIG_GENERIC_FIND_NEXT_BIT.
> > But I am not really understand if lib.a is linked with Xen, then it
> > should be an issue then if some arch implement find-next-bit
> > function
> > we will have to multiple definitions ( one in lib.a and one arch
> > specific ). Probably, I have to look at how it is done.
> 
> You're aware how linking works? Objects are pulled out of archives
> only
> if there's no other definition for a to-be-resolved symbol provided
> by
> a particular object in the archive.
I wasn't aware about the case of the archive. Thanks for the
explanation.

> 
> > > Problems could arise if
> > > an arch had an inline function colliding with the out-of-line
> > > one.
> > > But
> > > that's about the old case where I could see a need to make the
> > > building
> > > of one of the objects conditional. And you'll note that withing
> > > this
> > > Makefile there are pretty few conditionals.
> > Could you please clarify What does it mean "out-of-line" ?
> 
> "not inline"
> 
> > > > > > --- /dev/null
> > > > > > +++ b/xen/lib/find-next-bit.c
> > > > > > [...]
> > > > > 
> > > > > I was going to ask that you convince git to actually present
> > > > > a
> > > > > proper
> > > > > diff, to make visible what changes. But other than the
> > > > > description
> > > > > says
> > > > > you don't really move the file, you copy it. Judging from
> > > > > further
> > > > > titles
> > > > > there's also nowhere you'd make Arm actually use this now
> > > > > generic
> > > > > code.
> > > > I wanted to do it separately, outside this patch series to
> > > > simplify
> > > > review and not have Arm specific changes in RISC-V patch
> > > > series.
> > > 
> > > Then do it the other way around: Make a separate _prereq_ change
> > > truly
> > > moving the file.
> > So this one patch should be separated by 2? One which moves find-
> > next-
> > bit.c from Arm to xen/lib, and second where xen/lib/Makefile is
> > updated.
> 
> No, that would break the Arm build. I suggested breaking out this
> patch from the series, and then doing what the description says:
> Actually move the file. I don't think I suggested splitting the
> patch. Even the breaking out of the series was only because you
> said "I wanted to do it separately, outside this patch series".
What I meant was that I would like to have a patch which introduces
generic version of find-next-bit in the current patch series and
provide a separate patch outside of the current patch series which
switches Arm to use generic version.

~ Oleksii


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-24 15:04             ` Oleksii
@ 2024-01-24 15:32               ` Jan Beulich
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-24 15:32 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 24.01.2024 16:04, Oleksii wrote:
> On Wed, 2024-01-24 at 12:24 +0100, Jan Beulich wrote:
>> On 24.01.2024 10:34, Oleksii wrote:
>>> On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
>>>> On 23.01.2024 13:34, Oleksii wrote:
>>>>> On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
>>>>>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>>>>>> --- /dev/null
>>>>>>> +++ b/xen/lib/find-next-bit.c
>>>>>>> [...]
>>>>>>
>>>>>> I was going to ask that you convince git to actually present
>>>>>> a
>>>>>> proper
>>>>>> diff, to make visible what changes. But other than the
>>>>>> description
>>>>>> says
>>>>>> you don't really move the file, you copy it. Judging from
>>>>>> further
>>>>>> titles
>>>>>> there's also nowhere you'd make Arm actually use this now
>>>>>> generic
>>>>>> code.
>>>>> I wanted to do it separately, outside this patch series to
>>>>> simplify
>>>>> review and not have Arm specific changes in RISC-V patch
>>>>> series.
>>>>
>>>> Then do it the other way around: Make a separate _prereq_ change
>>>> truly
>>>> moving the file.
>>> So this one patch should be separated by 2? One which moves find-
>>> next-
>>> bit.c from Arm to xen/lib, and second where xen/lib/Makefile is
>>> updated.
>>
>> No, that would break the Arm build. I suggested breaking out this
>> patch from the series, and then doing what the description says:
>> Actually move the file. I don't think I suggested splitting the
>> patch. Even the breaking out of the series was only because you
>> said "I wanted to do it separately, outside this patch series".
> What I meant was that I would like to have a patch which introduces
> generic version of find-next-bit in the current patch series and
> provide a separate patch outside of the current patch series which
> switches Arm to use generic version.

I understand that this is what you meant. Yet I don't like the
duplication of code, even if it's only temporary. The more that iirc
git can show proper history for moved files, while there'll be a
disconnect when you first add a 2nd copy and later purge the original.
If you want this change separate from the series - fine. But then, as
said, please as a prereq patch.

Jan


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2024-01-24 11:27           ` Jan Beulich
@ 2024-01-24 15:33             ` Oleksii
  2024-01-24 15:38               ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-24 15:33 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Wed, 2024-01-24 at 12:27 +0100, Jan Beulich wrote:
> On 24.01.2024 11:12, Oleksii wrote:
> > On Wed, 2024-01-24 at 09:19 +0100, Jan Beulich wrote:
> > > On 23.01.2024 18:08, Oleksii wrote:
> > > > On Tue, 2024-01-23 at 12:39 +0100, Jan Beulich wrote:
> > > > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > > > @@ -53,6 +56,18 @@ struct cpu_user_regs
> > > > > >      unsigned long pregs;
> > > > > >  };
> > > > > >  
> > > > > > +/* TODO: need to implement */
> > > > > > +#define cpu_to_core(cpu)   (0)
> > > > > > +#define cpu_to_socket(cpu) (0)
> > > > > > +
> > > > > > +static inline void cpu_relax(void)
> > > > > > +{
> > > > > > +    /* Encoding of the pause instruction */
> > > > > > +    __asm__ __volatile__ ( ".insn 0x100000F" );
> > > > > 
> > > > > binutils 2.40 knows "pause" - why use .insn then?
> > > > I thought that for this instruction it is needed to have
> > > > extension
> > > > ZIHINTPAUSE ( according to Linux Kernel source code [1] ) and
> > > > to
> > > > cover
> > > > older version.
> > > 
> > > Well, of course you'll need to enable the extension then for gas.
> > > But
> > > as long as you use the insn unconditionally, that's all fine and
> > > natural. Another thing would be if you meant to also run on
> > > systems
> > > not supporting the extension: Then the above use of .insn would
> > > need
> > > to become conditional anyway.
> > Then it makes sense to use "pause". 
> > Let's assume that for now we are running only on systems which
> > support
> > the extension until we won't face compilation issue for some
> > system.
> 
> Gives me the impression that you still don't properly separate the
> two
> aspects: One is what systems Xen is to run on, and other is what's
> needed to make Xen build properly. The first needs documenting (and
> ideally at some point actually enforcing), while the latter may
> require
> e.g. compiler command line option adjustments.
I understand that it will be required update "-march=..._zihintpause"
and it should be a check that this extension is supported by a
toolchain.

But I am not sure that I know how can I enforce that a system should
have this extension, and considering Linux kernel implementation which
uses always pause instruction, it looks like all available systems
support this extension.

But I agree what I wrote above isn't fully correct.

~ Oleksii


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

* Re: [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h to build full Xen
  2024-01-24 15:33             ` Oleksii
@ 2024-01-24 15:38               ` Jan Beulich
  0 siblings, 0 replies; 146+ messages in thread
From: Jan Beulich @ 2024-01-24 15:38 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 24.01.2024 16:33, Oleksii wrote:
> On Wed, 2024-01-24 at 12:27 +0100, Jan Beulich wrote:
>> On 24.01.2024 11:12, Oleksii wrote:
>>> On Wed, 2024-01-24 at 09:19 +0100, Jan Beulich wrote:
>>>> On 23.01.2024 18:08, Oleksii wrote:
>>>>> On Tue, 2024-01-23 at 12:39 +0100, Jan Beulich wrote:
>>>>>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>>>>>> @@ -53,6 +56,18 @@ struct cpu_user_regs
>>>>>>>      unsigned long pregs;
>>>>>>>  };
>>>>>>>  
>>>>>>> +/* TODO: need to implement */
>>>>>>> +#define cpu_to_core(cpu)   (0)
>>>>>>> +#define cpu_to_socket(cpu) (0)
>>>>>>> +
>>>>>>> +static inline void cpu_relax(void)
>>>>>>> +{
>>>>>>> +    /* Encoding of the pause instruction */
>>>>>>> +    __asm__ __volatile__ ( ".insn 0x100000F" );
>>>>>>
>>>>>> binutils 2.40 knows "pause" - why use .insn then?
>>>>> I thought that for this instruction it is needed to have
>>>>> extension
>>>>> ZIHINTPAUSE ( according to Linux Kernel source code [1] ) and
>>>>> to
>>>>> cover
>>>>> older version.
>>>>
>>>> Well, of course you'll need to enable the extension then for gas.
>>>> But
>>>> as long as you use the insn unconditionally, that's all fine and
>>>> natural. Another thing would be if you meant to also run on
>>>> systems
>>>> not supporting the extension: Then the above use of .insn would
>>>> need
>>>> to become conditional anyway.
>>> Then it makes sense to use "pause". 
>>> Let's assume that for now we are running only on systems which
>>> support
>>> the extension until we won't face compilation issue for some
>>> system.
>>
>> Gives me the impression that you still don't properly separate the
>> two
>> aspects: One is what systems Xen is to run on, and other is what's
>> needed to make Xen build properly. The first needs documenting (and
>> ideally at some point actually enforcing), while the latter may
>> require
>> e.g. compiler command line option adjustments.
> I understand that it will be required update "-march=..._zihintpause"
> and it should be a check that this extension is supported by a
> toolchain.
> 
> But I am not sure that I know how can I enforce that a system should
> have this extension, and considering Linux kernel implementation which
> uses always pause instruction, it looks like all available systems
> support this extension.

Which is why I said documenting will suffice, at least for now.

Jan


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-23 13:37       ` Jan Beulich
  2024-01-24  9:34         ` Oleksii
@ 2024-01-26  9:44         ` Oleksii
  2024-01-26  9:48           ` Jan Beulich
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-26  9:44 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
> On 23.01.2024 13:34, Oleksii wrote:
> > On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > --- a/xen/common/Kconfig
> > > > +++ b/xen/common/Kconfig
> > > > @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
> > > >  config GENERIC_BUG_FRAME
> > > >  	bool
> > > >  
> > > > +config GENERIC_FIND_NEXT_BIT
> > > > +	bool
> > > 
> > > There's no need for this, as ...
> > > 
> > > > --- a/xen/lib/Makefile
> > > > +++ b/xen/lib/Makefile
> > > > @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
> > > >  lib-y += bsearch.o
> > > >  lib-y += ctors.o
> > > >  lib-y += ctype.o
> > > > +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
> > > 
> > > ... you're moving this to lib/. Or have you encountered any issue
> > > with building this uniformly, and you forgot to mention this in
> > > the description?
> > I didn't check. My intention was to provide opportunity to check if
> > an
> > architecture want to use generic version or not. Otherwise, I
> > expected
> > that we will have multiple definiotion of the funcion.
> > 
> > But considering that they are all defined under #ifdef...#endif we
> > can
> > remove the declaration of the config GENERIC_FIND_NEXT_BIT.
> 
> What #ifdef / #endif would matter here? Whats in lib/ is intended to
> be
> generic anyway. And what is in the resulting lib.a won't be used by
> an
> arch if it has an arch-specific implementation. Problems could arise
> if
> an arch had an inline function colliding with the out-of-line one.
> But
> that's about the old case where I could see a need to make the
> building
> of one of the objects conditional. And you'll note that withing this
> Makefile there are pretty few conditionals.
We will have such issue with PPC:
...
static inline unsigned long find_next_bit(const unsigned long *addr,
                                          unsigned long size,
                                          unsigned long offset)
...

It looks like an introduction of new config for find_next_bit is
needed.

Does a better option exist? Would making find_next_bit non inline non
inline for PPC better?

~ Oleksii


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-26  9:44         ` Oleksii
@ 2024-01-26  9:48           ` Jan Beulich
  2024-01-26  9:56             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-26  9:48 UTC (permalink / raw
  To: Oleksii, Shawn Anastasio
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 26.01.2024 10:44, Oleksii wrote:
> On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
>> On 23.01.2024 13:34, Oleksii wrote:
>>> On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>>>> --- a/xen/common/Kconfig
>>>>> +++ b/xen/common/Kconfig
>>>>> @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
>>>>>  config GENERIC_BUG_FRAME
>>>>>  	bool
>>>>>  
>>>>> +config GENERIC_FIND_NEXT_BIT
>>>>> +	bool
>>>>
>>>> There's no need for this, as ...
>>>>
>>>>> --- a/xen/lib/Makefile
>>>>> +++ b/xen/lib/Makefile
>>>>> @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
>>>>>  lib-y += bsearch.o
>>>>>  lib-y += ctors.o
>>>>>  lib-y += ctype.o
>>>>> +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
>>>>
>>>> ... you're moving this to lib/. Or have you encountered any issue
>>>> with building this uniformly, and you forgot to mention this in
>>>> the description?
>>> I didn't check. My intention was to provide opportunity to check if
>>> an
>>> architecture want to use generic version or not. Otherwise, I
>>> expected
>>> that we will have multiple definiotion of the funcion.
>>>
>>> But considering that they are all defined under #ifdef...#endif we
>>> can
>>> remove the declaration of the config GENERIC_FIND_NEXT_BIT.
>>
>> What #ifdef / #endif would matter here? Whats in lib/ is intended to
>> be
>> generic anyway. And what is in the resulting lib.a won't be used by
>> an
>> arch if it has an arch-specific implementation. Problems could arise
>> if
>> an arch had an inline function colliding with the out-of-line one.
>> But
>> that's about the old case where I could see a need to make the
>> building
>> of one of the objects conditional. And you'll note that withing this
>> Makefile there are pretty few conditionals.
> We will have such issue with PPC:
> ...
> static inline unsigned long find_next_bit(const unsigned long *addr,
>                                           unsigned long size,
>                                           unsigned long offset)
> ...
> 
> It looks like an introduction of new config for find_next_bit is
> needed.
> 
> Does a better option exist? Would making find_next_bit non inline non
> inline for PPC better?

Isn't that generic code anyway? If so, that also wants replacing by
the generic library function(s). Shawn - I have to admit I have a
hard time seeing why this was introduced as inline functions in the
first place.

Jan


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

* Re: [PATCH v3 16/34] xen/lib: introduce generic find next bit operations
  2024-01-26  9:48           ` Jan Beulich
@ 2024-01-26  9:56             ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-26  9:56 UTC (permalink / raw
  To: Jan Beulich, Shawn Anastasio
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Fri, 2024-01-26 at 10:48 +0100, Jan Beulich wrote:
> On 26.01.2024 10:44, Oleksii wrote:
> > On Tue, 2024-01-23 at 14:37 +0100, Jan Beulich wrote:
> > > On 23.01.2024 13:34, Oleksii wrote:
> > > > On Tue, 2024-01-23 at 12:14 +0100, Jan Beulich wrote:
> > > > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > > > --- a/xen/common/Kconfig
> > > > > > +++ b/xen/common/Kconfig
> > > > > > @@ -47,6 +47,9 @@ config ARCH_MAP_DOMAIN_PAGE
> > > > > >  config GENERIC_BUG_FRAME
> > > > > >  	bool
> > > > > >  
> > > > > > +config GENERIC_FIND_NEXT_BIT
> > > > > > +	bool
> > > > > 
> > > > > There's no need for this, as ...
> > > > > 
> > > > > > --- a/xen/lib/Makefile
> > > > > > +++ b/xen/lib/Makefile
> > > > > > @@ -3,6 +3,7 @@ obj-$(CONFIG_X86) += x86/
> > > > > >  lib-y += bsearch.o
> > > > > >  lib-y += ctors.o
> > > > > >  lib-y += ctype.o
> > > > > > +lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find-next-bit.o
> > > > > 
> > > > > ... you're moving this to lib/. Or have you encountered any
> > > > > issue
> > > > > with building this uniformly, and you forgot to mention this
> > > > > in
> > > > > the description?
> > > > I didn't check. My intention was to provide opportunity to
> > > > check if
> > > > an
> > > > architecture want to use generic version or not. Otherwise, I
> > > > expected
> > > > that we will have multiple definiotion of the funcion.
> > > > 
> > > > But considering that they are all defined under #ifdef...#endif
> > > > we
> > > > can
> > > > remove the declaration of the config GENERIC_FIND_NEXT_BIT.
> > > 
> > > What #ifdef / #endif would matter here? Whats in lib/ is intended
> > > to
> > > be
> > > generic anyway. And what is in the resulting lib.a won't be used
> > > by
> > > an
> > > arch if it has an arch-specific implementation. Problems could
> > > arise
> > > if
> > > an arch had an inline function colliding with the out-of-line
> > > one.
> > > But
> > > that's about the old case where I could see a need to make the
> > > building
> > > of one of the objects conditional. And you'll note that withing
> > > this
> > > Makefile there are pretty few conditionals.
> > We will have such issue with PPC:
> > ...
> > static inline unsigned long find_next_bit(const unsigned long
> > *addr,
> >                                           unsigned long size,
> >                                           unsigned long offset)
> > ...
> > 
> > It looks like an introduction of new config for find_next_bit is
> > needed.
> > 
> > Does a better option exist? Would making find_next_bit non inline
> > non
> > inline for PPC better?
> 
> Isn't that generic code anyway? If so, that also wants replacing by
> the generic library function(s). Shawn - I have to admit I have a
> hard time seeing why this was introduced as inline functions in the
> first place.
You are right, it is generic one too. I'll replace it too.

~ Oleksii


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-22 16:27   ` Jan Beulich
  2024-01-23 10:15     ` Oleksii
@ 2024-01-30 14:57     ` Oleksii
  2024-01-30 15:05       ` Jan Beulich
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-01-30 14:57 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
> > +#define __xchg_acquire(ptr, new, size) \
> > +({ \
> > +    __typeof__(ptr) ptr__ = (ptr); \
> > +    __typeof__(new) new__ = (new); \
> > +    __typeof__(*(ptr)) ret__; \
> > +    switch (size) \
> > +	{ \
> > +    case 4: \
> > +        asm volatile( \
> > +            "	amoswap.w %0, %2, %1\n" \
> > +            RISCV_ACQUIRE_BARRIER \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory" ); \
> > +        break; \
> > +    case 8: \
> > +        asm volatile( \
> > +            "	amoswap.d %0, %2, %1\n" \
> > +            RISCV_ACQUIRE_BARRIER \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory" ); \
> > +        break; \
> > +    default: \
> > +        ASSERT_UNREACHABLE(); \
> > +    } \
> > +    ret__; \
> > +})
> 
> If I'm not mistaken this differs from __xchg_relaxed() only in the
> use
> of RISCV_ACQUIRE_BARRIER, and ...
> 
> > +#define xchg_acquire(ptr, x) \
> > +({ \
> > +    __typeof__(*(ptr)) x_ = (x); \
> > +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
> > sizeof(*(ptr))); \
> > +})
> > +
> > +#define __xchg_release(ptr, new, size) \
> > +({ \
> > +    __typeof__(ptr) ptr__ = (ptr); \
> > +    __typeof__(new) new__ = (new); \
> > +    __typeof__(*(ptr)) ret__; \
> > +    switch (size) \
> > +	{ \
> > +    case 4: \
> > +        asm volatile ( \
> > +            RISCV_RELEASE_BARRIER \
> > +            "	amoswap.w %0, %2, %1\n" \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory"); \
> > +        break; \
> > +    case 8: \
> > +        asm volatile ( \
> > +            RISCV_RELEASE_BARRIER \
> > +            "	amoswap.d %0, %2, %1\n" \
> > +            : "=r" (ret__), "+A" (*ptr__) \
> > +            : "r" (new__) \
> > +            : "memory"); \
> > +        break; \
> > +    default: \
> > +        ASSERT_UNREACHABLE(); \
> > +    } \
> > +    ret__; \
> > +})
> 
> this only in the use of RISCV_RELEASE_BARRIER. If so they likely want
> folding, to limit redundancy and make eventual updating easier. (Same
> for the cmpxchg helper further down, as it seems.)
Also the difference is in where to place barrier before or after atomic
instruction. I am not sure that we can easily folded this macros.

~ Oleksii

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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-30 14:57     ` Oleksii
@ 2024-01-30 15:05       ` Jan Beulich
  2024-01-30 15:16         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-01-30 15:05 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 30.01.2024 15:57, Oleksii wrote:
> On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
>>> +#define __xchg_acquire(ptr, new, size) \
>>> +({ \
>>> +    __typeof__(ptr) ptr__ = (ptr); \
>>> +    __typeof__(new) new__ = (new); \
>>> +    __typeof__(*(ptr)) ret__; \
>>> +    switch (size) \
>>> +	{ \
>>> +    case 4: \
>>> +        asm volatile( \
>>> +            "	amoswap.w %0, %2, %1\n" \
>>> +            RISCV_ACQUIRE_BARRIER \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory" ); \
>>> +        break; \
>>> +    case 8: \
>>> +        asm volatile( \
>>> +            "	amoswap.d %0, %2, %1\n" \
>>> +            RISCV_ACQUIRE_BARRIER \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory" ); \
>>> +        break; \
>>> +    default: \
>>> +        ASSERT_UNREACHABLE(); \
>>> +    } \
>>> +    ret__; \
>>> +})
>>
>> If I'm not mistaken this differs from __xchg_relaxed() only in the
>> use
>> of RISCV_ACQUIRE_BARRIER, and ...
>>
>>> +#define xchg_acquire(ptr, x) \
>>> +({ \
>>> +    __typeof__(*(ptr)) x_ = (x); \
>>> +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
>>> sizeof(*(ptr))); \
>>> +})
>>> +
>>> +#define __xchg_release(ptr, new, size) \
>>> +({ \
>>> +    __typeof__(ptr) ptr__ = (ptr); \
>>> +    __typeof__(new) new__ = (new); \
>>> +    __typeof__(*(ptr)) ret__; \
>>> +    switch (size) \
>>> +	{ \
>>> +    case 4: \
>>> +        asm volatile ( \
>>> +            RISCV_RELEASE_BARRIER \
>>> +            "	amoswap.w %0, %2, %1\n" \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory"); \
>>> +        break; \
>>> +    case 8: \
>>> +        asm volatile ( \
>>> +            RISCV_RELEASE_BARRIER \
>>> +            "	amoswap.d %0, %2, %1\n" \
>>> +            : "=r" (ret__), "+A" (*ptr__) \
>>> +            : "r" (new__) \
>>> +            : "memory"); \
>>> +        break; \
>>> +    default: \
>>> +        ASSERT_UNREACHABLE(); \
>>> +    } \
>>> +    ret__; \
>>> +})
>>
>> this only in the use of RISCV_RELEASE_BARRIER. If so they likely want
>> folding, to limit redundancy and make eventual updating easier. (Same
>> for the cmpxchg helper further down, as it seems.)
> Also the difference is in where to place barrier before or after atomic
> instruction. I am not sure that we can easily folded this macros.

The folded macro would have two barrier parameters - on for acquire, one
for release.

Jan


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

* Re: [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h
  2024-01-30 15:05       ` Jan Beulich
@ 2024-01-30 15:16         ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-30 15:16 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-30 at 16:05 +0100, Jan Beulich wrote:
> On 30.01.2024 15:57, Oleksii wrote:
> > On Mon, 2024-01-22 at 17:27 +0100, Jan Beulich wrote:
> > > > +#define __xchg_acquire(ptr, new, size) \
> > > > +({ \
> > > > +    __typeof__(ptr) ptr__ = (ptr); \
> > > > +    __typeof__(new) new__ = (new); \
> > > > +    __typeof__(*(ptr)) ret__; \
> > > > +    switch (size) \
> > > > +	{ \
> > > > +    case 4: \
> > > > +        asm volatile( \
> > > > +            "	amoswap.w %0, %2, %1\n" \
> > > > +            RISCV_ACQUIRE_BARRIER \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory" ); \
> > > > +        break; \
> > > > +    case 8: \
> > > > +        asm volatile( \
> > > > +            "	amoswap.d %0, %2, %1\n" \
> > > > +            RISCV_ACQUIRE_BARRIER \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory" ); \
> > > > +        break; \
> > > > +    default: \
> > > > +        ASSERT_UNREACHABLE(); \
> > > > +    } \
> > > > +    ret__; \
> > > > +})
> > > 
> > > If I'm not mistaken this differs from __xchg_relaxed() only in
> > > the
> > > use
> > > of RISCV_ACQUIRE_BARRIER, and ...
> > > 
> > > > +#define xchg_acquire(ptr, x) \
> > > > +({ \
> > > > +    __typeof__(*(ptr)) x_ = (x); \
> > > > +    (__typeof__(*(ptr))) __xchg_acquire((ptr), x_,
> > > > sizeof(*(ptr))); \
> > > > +})
> > > > +
> > > > +#define __xchg_release(ptr, new, size) \
> > > > +({ \
> > > > +    __typeof__(ptr) ptr__ = (ptr); \
> > > > +    __typeof__(new) new__ = (new); \
> > > > +    __typeof__(*(ptr)) ret__; \
> > > > +    switch (size) \
> > > > +	{ \
> > > > +    case 4: \
> > > > +        asm volatile ( \
> > > > +            RISCV_RELEASE_BARRIER \
> > > > +            "	amoswap.w %0, %2, %1\n" \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory"); \
> > > > +        break; \
> > > > +    case 8: \
> > > > +        asm volatile ( \
> > > > +            RISCV_RELEASE_BARRIER \
> > > > +            "	amoswap.d %0, %2, %1\n" \
> > > > +            : "=r" (ret__), "+A" (*ptr__) \
> > > > +            : "r" (new__) \
> > > > +            : "memory"); \
> > > > +        break; \
> > > > +    default: \
> > > > +        ASSERT_UNREACHABLE(); \
> > > > +    } \
> > > > +    ret__; \
> > > > +})
> > > 
> > > this only in the use of RISCV_RELEASE_BARRIER. If so they likely
> > > want
> > > folding, to limit redundancy and make eventual updating easier.
> > > (Same
> > > for the cmpxchg helper further down, as it seems.)
> > Also the difference is in where to place barrier before or after
> > atomic
> > instruction. I am not sure that we can easily folded this macros.
> 
> The folded macro would have two barrier parameters - on for acquire,
> one
> for release.
Yes, in such case it will work.

Thanks.

~ Oleksii

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

* Re: [PATCH v3 14/34] xen/riscv: introduce io.h
  2024-01-16 16:09       ` Jan Beulich
@ 2024-01-31 17:30         ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-01-31 17:30 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-16 at 17:09 +0100, Jan Beulich wrote:
> On 16.01.2024 16:20, Oleksii wrote:
> > On Mon, 2024-01-15 at 17:57 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:12, Oleksii Kurochko wrote:
> > > > +/*
> > > > + * Unordered I/O memory access primitives.  These are even
> > > > more
> > > > relaxed than
> > > > + * the relaxed versions, as they don't even order accesses
> > > > between
> > > > successive
> > > > + * operations to the I/O regions.
> > > > + */
> > > > +#define readb_cpu(c)		({ u8  __r = __raw_readb(c);
> > > > __r;
> > > > })
> > > > +#define readw_cpu(c)		({ u16 __r =
> > > > le16_to_cpu((__force
> > > > __le16)__raw_readw(c)); __r; })
> > > > +#define readl_cpu(c)		({ u32 __r =
> > > > le32_to_cpu((__force
> > > > __le32)__raw_readl(c)); __r; })
> > > > +
> > > > +#define
> > > > writeb_cpu(v,c)		((void)__raw_writeb((v),(c)))
> > > > +#define
> > > > writew_cpu(v,c)		((void)__raw_writew((__force
> > > > u16)cpu_to_le16(v),(c)))
> > > > +#define
> > > > writel_cpu(v,c)		((void)__raw_writel((__force
> > > > u32)cpu_to_le32(v),(c)))
> > > > +
> > > > +#ifdef CONFIG_64BIT
> > > > +#define readq_cpu(c)		({ u64 __r =
> > > > le64_to_cpu((__force
> > > > __le64)__raw_readq(c)); __r; })
> > > > +#define
> > > > writeq_cpu(v,c)		((void)__raw_writeq((__force
> > > > u64)cpu_to_le64(v),(c)))
> > > > +#endif
> > > 
> > > How come there are endianness assumptions here on the MMIO
> > > accessed?
> > It is a hard story.
> > 
> > As you might expect it was copy from Linux Kernel where it was
> > decided
> > to follow only LE way:
> > https://patchwork.kernel.org/project/linux-riscv/patch/20190411115623.5749-3-hch@lst.de/
> > One of the answers of the author of the commit:
> >     And we don't know if Linux will be around if that ever changes.
> >     The point is:
> >      a) the current RISC-V spec is LE only
> >      b) the current linux port is LE only except for this little
> > bit
> >     There is no point in leaving just this bitrotting code around. 
> > It
> >     just confuses developers, (very very slightly) slows down
> > compiles
> >     and will bitrot.  It also won't be any significant help to a
> > future
> >     developer down the road doing a hypothetical BE RISC-V Linux
> > port.
> 
> Reads to me like a justification to _omit_ the cpu_to_le<N>().
Looks like we can omit cpu_to_le<N>(). Even docs say that memory system
is little-endian except:
   However, certain application areas, such as IP networking, operate
   on big-endian data structures, and certain legacy code bases have
   been built assuming big-endian
   processors, so we expect that future specifications will describe
   big-endian or bi-endian variants
   of RISC-V.
   
~ Oleksii


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-01-23 13:03   ` Jan Beulich
  2024-01-23 17:27     ` Oleksii
@ 2024-02-02 17:30     ` Oleksii
  2024-02-05  7:46       ` Jan Beulich
  1 sibling, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-02-02 17:30 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
> On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> > ---
> > Changes in V3:
> >  - update the commit message
> 
> ??? (yet again)
> 
> > --- a/xen/arch/riscv/include/asm/mm.h
> > +++ b/xen/arch/riscv/include/asm/mm.h
> > @@ -3,8 +3,251 @@
> >  #ifndef _ASM_RISCV_MM_H
> >  #define _ASM_RISCV_MM_H
> >  
> > +#include <public/xen.h>
> > +#include <xen/pdx.h>
> > +#include <xen/types.h>
> > +
> > +#include <asm/page.h>
> >  #include <asm/page-bits.h>
> >  
> > +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> > +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> > +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> > +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> > +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> > +#define vmap_to_mfn(va)    
> > maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> > +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
> 
> Everything you have above ...
> 
> > +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
> > +#define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
> > +#define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
> > +#define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> > +#define maddr_to_mfn(ma)    _mfn(paddr_to_pfn(ma))
> > +#define vmap_to_mfn(va)    
> > maddr_to_mfn(virt_to_maddr((vaddr_t)va))
> > +#define vmap_to_page(va)    mfn_to_page(vmap_to_mfn(va))
> 
> ... appears a 2nd time right afterwards.
> 
> > +#define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK))
> > +#define maddr_to_virt(pa) ((void *)((paddr_t)(pa) |
> > DIRECTMAP_VIRT_START))
> > +
> > +/* Convert between Xen-heap virtual addresses and machine frame
> > numbers. */
> > +#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
> > +#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) <<
> > PAGE_SHIFT)
> 
> These would imo better use maddr_to_mfn() and mfn_to_maddr(), rather
> than
> kind of open-coding them. The former could also use PFN_DOWN() as an
> alternative.
We can't to as __virt_to_mfn() when is used it is usually wrapped by
_mfn() which expect to have unsigned long as an argument.

> 
> > +/* Convert between Xen-heap virtual addresses and page-info
> > structures. */
> > +static inline struct page_info *virt_to_page(const void *v)
> > +{
> > +    BUG();
> > +    return NULL;
> > +}
> > +
> > +/*
> > + * We define non-underscored wrappers for above conversion
> > functions.
> > + * These are overriden in various source files while underscored
> > version
> > + * remain intact.
> > + */
> > +#define virt_to_mfn(va)     __virt_to_mfn(va)
> > +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
> 
> Is this really still needed? Would be pretty nice if in a new port we
> could get to start cleanly right away (i.e. by not needing per-file
> overrides, but using type-safe expansions here right away).
We still need __virt_to_mfn and __mfn_to_virt as common code use them:
 * xen/common/xenoprof.c:24:#define virt_to_mfn(va)
mfn(__virt_to_mfn(va))
 * xen/include/xen/domain_page.h:59:#define domain_page_map_to_mfn(ptr)
_mfn(__virt_to_mfn((unsigned long)(ptr)))

~ Oleksii
> 
> > +struct page_info
> > +{
> > +    /* Each frame can be threaded onto a doubly-linked list. */
> > +    struct page_list_entry list;
> > +
> > +    /* Reference count and various PGC_xxx flags and fields. */
> > +    unsigned long count_info;
> > +
> > +    /* Context-dependent fields follow... */
> > +    union {
> > +        /* Page is in use: ((count_info & PGC_count_mask) != 0).
> > */
> > +        struct {
> > +            /* Type reference count and various PGT_xxx flags and
> > fields. */
> > +            unsigned long type_info;
> > +        } inuse;
> > +        /* Page is on a free list: ((count_info & PGC_count_mask)
> > == 0). */
> > +        union {
> > +            struct {
> > +                /*
> > +                 * Index of the first *possibly* unscrubbed page
> > in the buddy.
> > +                 * One more bit than maximum possible order to
> > accommodate
> > +                 * INVALID_DIRTY_IDX.
> > +                 */
> > +#define INVALID_DIRTY_IDX ((1UL << (MAX_ORDER + 1)) - 1)
> > +                unsigned long first_dirty:MAX_ORDER + 1;
> > +
> > +                /* Do TLBs need flushing for safety before next
> > page use? */
> > +                bool need_tlbflush:1;
> > +
> > +#define BUDDY_NOT_SCRUBBING    0
> > +#define BUDDY_SCRUBBING        1
> > +#define BUDDY_SCRUB_ABORT      2
> > +                unsigned long scrub_state:2;
> > +            };
> > +
> > +                unsigned long val;
> > +            } free;
> 
> Indentation is wrong (and thus misleading) for these two lines.
> 
> > +
> > +    } u;
> 
> Nit: I don't see the value of the trailing blank line inside the
> union.
> 
> > +    union {
> > +        /* Page is in use, but not as a shadow. */
> 
> I question the appicability of "shadow" here.
> 
> > +        struct {
> > +            /* Owner of this page (zero if page is anonymous). */
> > +            struct domain *domain;
> > +        } inuse;
> > +
> > +        /* Page is on a free list. */
> > +        struct {
> > +            /* Order-size of the free chunk this page is the head
> > of. */
> > +            unsigned int order;
> > +        } free;
> > +
> > +    } v;
> > +
> > +    union {
> > +        /*
> > +         * Timestamp from 'TLB clock', used to avoid extra safety
> > flushes.
> > +         * Only valid for: a) free pages, and b) pages with zero
> > type count
> > +         */
> > +        uint32_t tlbflush_timestamp;
> > +    };
> > +    uint64_t pad;
> > +};
> > +
> > +#define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
> > +
> > +/* PDX of the first page in the frame table. */
> > +extern unsigned long frametable_base_pdx;
> 
> From this I conclude memory on RISC-V systems may not start at (or
> near) 0?
> 
> > +/* Convert between machine frame numbers and page-info structures.
> > */
> > +#define
> > mfn_to_page(mfn)                                            \
> > +    (frame_table + (mfn_to_pdx(mfn) - frametable_base_pdx))
> > +#define
> > page_to_mfn(pg)                                             \
> > +    pdx_to_mfn((unsigned long)((pg) - frame_table) +
> > frametable_base_pdx)
> > +
> > +static inline void *page_to_virt(const struct page_info *pg)
> > +{
> > +    return mfn_to_virt(mfn_x(page_to_mfn(pg)));
> > +}
> > +
> > +/*
> > + * Common code requires get_page_type and put_page_type.
> > + * We don't care about typecounts so we just do the minimum to
> > make it
> > + * happy.
> > + */
> > +static inline int get_page_type(struct page_info *page, unsigned
> > long type)
> > +{
> > +    return 1;
> > +}
> > +
> > +static inline void put_page_type(struct page_info *page)
> > +{
> > +}
> > +
> > +static inline void put_page_and_type(struct page_info *page)
> > +{
> > +    put_page_type(page);
> > +    put_page(page);
> > +}
> > +
> > +/*
> > + * RISC-V does not have an M2P, but common code expects a handful
> > of
> > + * M2P-related defines and functions. Provide dummy versions of
> > these.
> > + */
> > +#define INVALID_M2P_ENTRY        (~0UL)
> > +#define SHARED_M2P_ENTRY         (~0UL - 1UL)
> > +#define SHARED_M2P(_e)           ((_e) == SHARED_M2P_ENTRY)
> > +
> > +/* Xen always owns P2M on RISC-V */
> > +#define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn),
> > (void)(pfn); } while (0)
> 
> Nit: Stray blank again after cast.
> 
> > +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
> 
> What's the relation of the comment with these two #define-s?
> 
> > +#define PDX_GROUP_SHIFT (16 + 5)
> > +
> > +static inline unsigned long domain_get_maximum_gpfn(struct domain
> > *d)
> > +{
> > +    BUG();
> > +    return 0;
> > +}
> > +
> > +static inline long arch_memory_op(int op,
> > XEN_GUEST_HANDLE_PARAM(void) arg)
> > +{
> > +    BUG();
> > +    return 0;
> > +}
> > +
> > +/*
> > + * On RISCV, all the RAM is currently direct mapped in Xen.
> > + * Hence return always true.
> > + */
> > +static inline bool arch_mfns_in_directmap(unsigned long mfn,
> > unsigned long nr)
> > +{
> > +    return true;
> > +}
> > +
> > +#define PG_shift(idx)   (BITS_PER_LONG - (idx))
> > +#define PG_mask(x, idx) (x ## UL << PG_shift(idx))
> > +
> > +#define PGT_none          PG_mask(0, 1)  /* no special uses of
> > this page   */
> > +#define PGT_writable_page PG_mask(1, 1)  /* has writable
> > mappings?         */
> > +#define PGT_type_mask     PG_mask(1, 1)  /* Bits 31 or
> > 63.                 */
> > +
> > + /* Count of uses of this frame as its current type. */
> > +#define PGT_count_width   PG_shift(2)
> > +#define PGT_count_mask    ((1UL<<PGT_count_width)-1)
> 
> Nit: Style (missing blanks around binary operators). Also a few more
> times further down.
> 
> > +/*
> > + * Page needs to be scrubbed. Since this bit can only be set on a
> > page that is
> > + * free (i.e. in PGC_state_free) we can reuse PGC_allocated bit.
> > + */
> > +#define _PGC_need_scrub   _PGC_allocated
> > +#define PGC_need_scrub    PGC_allocated
> > +
> > +//  /* Cleared when the owning guest 'frees' this page. */
> 
> Why a commented out comment?
> 
> > +#define _PGC_allocated    PG_shift(1)
> > +#define PGC_allocated     PG_mask(1, 1)
> > +  /* Page is Xen heap? */
> > +#define _PGC_xen_heap     PG_shift(2)
> > +#define PGC_xen_heap      PG_mask(1, 2)
> > +/* Page is broken? */
> > +#define _PGC_broken       PG_shift(7)
> > +#define PGC_broken        PG_mask(1, 7)
> > + /* Mutually-exclusive page states: { inuse, offlining, offlined,
> > free }. */
> 
> Can similar comments in this block please all be similarly indented
> (or not)?
> 
> > +#define PGC_state         PG_mask(3, 9)
> > +#define PGC_state_inuse   PG_mask(0, 9)
> > +#define PGC_state_offlining PG_mask(1, 9)
> > +#define PGC_state_offlined PG_mask(2, 9)
> > +#define PGC_state_free    PG_mask(3, 9)
> > +// #define page_state_is(pg, st) (((pg)->count_info&PGC_state) ==
> > PGC_state_##st)
> 
> ???
> 
> > +/* Count of references to this frame. */
> > +#define PGC_count_width   PG_shift(9)
> > +#define PGC_count_mask    ((1UL<<PGC_count_width)-1)
> > +
> > +#define page_state_is(pg, st) (((pg)->count_info&PGC_state) ==
> > PGC_state_##st)
> 
> And here it then "properly" appears?
> 
> > +#define _PGC_extra        PG_shift(10)
> > +#define PGC_extra         PG_mask(1, 10)
> > +
> > +#define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
> > +#define is_xen_heap_mfn(mfn) \
> > +    (mfn_valid(mfn) && is_xen_heap_page(mfn_to_page(mfn)))
> > +
> > +#define is_xen_fixed_mfn(mfn)                                   \
> > +    ((mfn_to_maddr(mfn) >= virt_to_maddr(&_start)) &&           \
> > +     (mfn_to_maddr(mfn) <= virt_to_maddr((vaddr_t)_end - 1)))
> 
> Why does _start need prefixing wuth & and _end prefixing with a cast?
> First and foremost both want to be consistent. And then preferably
> with as little extra clutter as possible.
> 
> > +#define page_get_owner(_p)    (_p)->v.inuse.domain
> > +#define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d))
> > +
> > +/* TODO: implement */
> > +#define mfn_valid(mfn) ({ (void) (mfn); 0; })
> > +
> > +#define mfn_to_gfn(d, mfn) ((void)(d), _gfn(mfn_x(mfn)))
> 
> This appeared further up already.
> 
> > +#define domain_set_alloc_bitsize(d) ((void)0)
> 
> Better ((void)(d)) ? And then ...
> 
> > +#define domain_clamp_alloc_bitsize(d, b) (b)
> 
> ... ((void)(d), (b)) here?
> 
> Jan



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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-02-02 17:30     ` Oleksii
@ 2024-02-05  7:46       ` Jan Beulich
  2024-02-05 12:49         ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-02-05  7:46 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 02.02.2024 18:30, Oleksii wrote:
> On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>> +/* Convert between Xen-heap virtual addresses and machine frame
>>> numbers. */
>>> +#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
>>> +#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) <<
>>> PAGE_SHIFT)
>>
>> These would imo better use maddr_to_mfn() and mfn_to_maddr(), rather
>> than
>> kind of open-coding them. The former could also use PFN_DOWN() as an
>> alternative.
> We can't to as __virt_to_mfn() when is used it is usually wrapped by
> _mfn() which expect to have unsigned long as an argument.

#define __virt_to_mfn(va)  mfn_x(maddr_to_mfn(virt_to_maddr(va))
#define __mfn_to_virt(mfn) maddr_to_virt(mfn_to_maddr(_mfn(mfn)))

?

>>> +/* Convert between Xen-heap virtual addresses and page-info
>>> structures. */
>>> +static inline struct page_info *virt_to_page(const void *v)
>>> +{
>>> +    BUG();
>>> +    return NULL;
>>> +}
>>> +
>>> +/*
>>> + * We define non-underscored wrappers for above conversion
>>> functions.
>>> + * These are overriden in various source files while underscored
>>> version
>>> + * remain intact.
>>> + */
>>> +#define virt_to_mfn(va)     __virt_to_mfn(va)
>>> +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
>>
>> Is this really still needed? Would be pretty nice if in a new port we
>> could get to start cleanly right away (i.e. by not needing per-file
>> overrides, but using type-safe expansions here right away).
> We still need __virt_to_mfn and __mfn_to_virt as common code use them:
>  * xen/common/xenoprof.c:24:#define virt_to_mfn(va)
> mfn(__virt_to_mfn(va))

Are you meaning to enable this code on RISC-V.

>  * xen/include/xen/domain_page.h:59:#define domain_page_map_to_mfn(ptr)
> _mfn(__virt_to_mfn((unsigned long)(ptr)))

Hmm, yes, we should finally get this sorted. But yeah, not something I want
to ask you to do.

Jan


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-02-05  7:46       ` Jan Beulich
@ 2024-02-05 12:49         ` Oleksii
  2024-02-05 14:05           ` Jan Beulich
  0 siblings, 1 reply; 146+ messages in thread
From: Oleksii @ 2024-02-05 12:49 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-02-05 at 08:46 +0100, Jan Beulich wrote:
> On 02.02.2024 18:30, Oleksii wrote:
> > On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
> > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > +/* Convert between Xen-heap virtual addresses and machine
> > > > frame
> > > > numbers. */
> > > > +#define __virt_to_mfn(va) (virt_to_maddr(va) >> PAGE_SHIFT)
> > > > +#define __mfn_to_virt(mfn) maddr_to_virt((paddr_t)(mfn) <<
> > > > PAGE_SHIFT)
> > > 
> > > These would imo better use maddr_to_mfn() and mfn_to_maddr(),
> > > rather
> > > than
> > > kind of open-coding them. The former could also use PFN_DOWN() as
> > > an
> > > alternative.
> > We can't to as __virt_to_mfn() when is used it is usually wrapped
> > by
> > _mfn() which expect to have unsigned long as an argument.
> 
> #define __virt_to_mfn(va)  mfn_x(maddr_to_mfn(virt_to_maddr(va))
> #define __mfn_to_virt(mfn) maddr_to_virt(mfn_to_maddr(_mfn(mfn)))
> 
> ?
I had an issue with the compilation when I tried to define them in
similar way.

I'll double check again.

> 
> > > > +/* Convert between Xen-heap virtual addresses and page-info
> > > > structures. */
> > > > +static inline struct page_info *virt_to_page(const void *v)
> > > > +{
> > > > +    BUG();
> > > > +    return NULL;
> > > > +}
> > > > +
> > > > +/*
> > > > + * We define non-underscored wrappers for above conversion
> > > > functions.
> > > > + * These are overriden in various source files while
> > > > underscored
> > > > version
> > > > + * remain intact.
> > > > + */
> > > > +#define virt_to_mfn(va)     __virt_to_mfn(va)
> > > > +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
> > > 
> > > Is this really still needed? Would be pretty nice if in a new
> > > port we
> > > could get to start cleanly right away (i.e. by not needing per-
> > > file
> > > overrides, but using type-safe expansions here right away).
> > We still need __virt_to_mfn and __mfn_to_virt as common code use
> > them:
> >  * xen/common/xenoprof.c:24:#define virt_to_mfn(va)
> > mfn(__virt_to_mfn(va))
> 
> Are you meaning to enable this code on RISC-V.
Yes, that is what I meant.

~ Oleksii

> 
> >  * xen/include/xen/domain_page.h:59:#define
> > domain_page_map_to_mfn(ptr)
> > _mfn(__virt_to_mfn((unsigned long)(ptr)))
> 
> Hmm, yes, we should finally get this sorted. But yeah, not something
> I want
> to ask you to do.
> 
> Jan




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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-02-05 12:49         ` Oleksii
@ 2024-02-05 14:05           ` Jan Beulich
  2024-02-05 14:40             ` Oleksii
  0 siblings, 1 reply; 146+ messages in thread
From: Jan Beulich @ 2024-02-05 14:05 UTC (permalink / raw
  To: Oleksii
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On 05.02.2024 13:49, Oleksii wrote:
> On Mon, 2024-02-05 at 08:46 +0100, Jan Beulich wrote:
>> On 02.02.2024 18:30, Oleksii wrote:
>>> On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
>>>> On 22.12.2023 16:13, Oleksii Kurochko wrote:
>>>>> +/* Convert between Xen-heap virtual addresses and page-info
>>>>> structures. */
>>>>> +static inline struct page_info *virt_to_page(const void *v)
>>>>> +{
>>>>> +    BUG();
>>>>> +    return NULL;
>>>>> +}
>>>>> +
>>>>> +/*
>>>>> + * We define non-underscored wrappers for above conversion
>>>>> functions.
>>>>> + * These are overriden in various source files while
>>>>> underscored
>>>>> version
>>>>> + * remain intact.
>>>>> + */
>>>>> +#define virt_to_mfn(va)     __virt_to_mfn(va)
>>>>> +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
>>>>
>>>> Is this really still needed? Would be pretty nice if in a new
>>>> port we
>>>> could get to start cleanly right away (i.e. by not needing per-
>>>> file
>>>> overrides, but using type-safe expansions here right away).
>>> We still need __virt_to_mfn and __mfn_to_virt as common code use
>>> them:
>>>  * xen/common/xenoprof.c:24:#define virt_to_mfn(va)
>>> mfn(__virt_to_mfn(va))
>>
>> Are you meaning to enable this code on RISC-V.
> Yes, that is what I meant.

And why would you do that? Even Arm doesn't use it, and I'd expect no
newer port would care about this very old interface.

Jan


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

* Re: [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h to build full Xen
  2024-02-05 14:05           ` Jan Beulich
@ 2024-02-05 14:40             ` Oleksii
  0 siblings, 0 replies; 146+ messages in thread
From: Oleksii @ 2024-02-05 14:40 UTC (permalink / raw
  To: Jan Beulich
  Cc: Alistair Francis, Bob Eshleman, Connor Davis, Andrew Cooper,
	George Dunlap, Julien Grall, Stefano Stabellini, Wei Liu,
	xen-devel

On Mon, 2024-02-05 at 15:05 +0100, Jan Beulich wrote:
> On 05.02.2024 13:49, Oleksii wrote:
> > On Mon, 2024-02-05 at 08:46 +0100, Jan Beulich wrote:
> > > On 02.02.2024 18:30, Oleksii wrote:
> > > > On Tue, 2024-01-23 at 14:03 +0100, Jan Beulich wrote:
> > > > > On 22.12.2023 16:13, Oleksii Kurochko wrote:
> > > > > > +/* Convert between Xen-heap virtual addresses and page-
> > > > > > info
> > > > > > structures. */
> > > > > > +static inline struct page_info *virt_to_page(const void
> > > > > > *v)
> > > > > > +{
> > > > > > +    BUG();
> > > > > > +    return NULL;
> > > > > > +}
> > > > > > +
> > > > > > +/*
> > > > > > + * We define non-underscored wrappers for above conversion
> > > > > > functions.
> > > > > > + * These are overriden in various source files while
> > > > > > underscored
> > > > > > version
> > > > > > + * remain intact.
> > > > > > + */
> > > > > > +#define virt_to_mfn(va)     __virt_to_mfn(va)
> > > > > > +#define mfn_to_virt(mfn)    __mfn_to_virt(mfn)
> > > > > 
> > > > > Is this really still needed? Would be pretty nice if in a new
> > > > > port we
> > > > > could get to start cleanly right away (i.e. by not needing
> > > > > per-
> > > > > file
> > > > > overrides, but using type-safe expansions here right away).
> > > > We still need __virt_to_mfn and __mfn_to_virt as common code
> > > > use
> > > > them:
> > > >  * xen/common/xenoprof.c:24:#define virt_to_mfn(va)
> > > > mfn(__virt_to_mfn(va))
> > > 
> > > Are you meaning to enable this code on RISC-V.
> > Yes, that is what I meant.
> 
> And why would you do that? Even Arm doesn't use it, and I'd expect no
> newer port would care about this very old interface.
Oh, sorry, I read your question wrongly. I am not going to enable that
config.

~ Oleksii


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

end of thread, other threads:[~2024-02-05 14:40 UTC | newest]

Thread overview: 146+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-22 15:12 [PATCH v3 00/34] Enable build of full Xen for RISC-V Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 01/34] xen/riscv: disable unnecessary configs Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 02/34] xen/riscv: use some asm-generic headers Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 03/34] xen: add support in public/hvm/save.h for PPC and RISC-V Oleksii Kurochko
2024-01-04 11:01   ` Jan Beulich
2024-01-08 14:46     ` Oleksii
2023-12-22 15:12 ` [PATCH v3 04/34] xen/riscv: introduce cpufeature.h Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 05/34] xen/riscv: introduce guest_atomics.h Oleksii Kurochko
2024-01-11 15:57   ` Jan Beulich
2024-01-15  9:26     ` Oleksii
2023-12-22 15:12 ` [PATCH v3 06/34] xen: avoid generation of empty asm/iommu.h Oleksii Kurochko
2024-01-04 11:04   ` Jan Beulich
2024-01-08 14:47     ` Oleksii
2023-12-22 15:12 ` [PATCH v3 07/34] xen/asm-generic: introdure nospec.h Oleksii Kurochko
2024-01-04 11:06   ` Jan Beulich
2024-01-04 11:13     ` Andrew Cooper
2024-01-04 12:03       ` Jan Beulich
2024-01-08 14:58     ` Oleksii
2024-01-05 19:02   ` Shawn Anastasio
2023-12-22 15:12 ` [PATCH v3 08/34] xen/riscv: introduce setup.h Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 09/34] xen/riscv: introduce system.h Oleksii Kurochko
2024-01-11 16:00   ` Jan Beulich
2024-01-15  9:28     ` Oleksii
2023-12-22 15:12 ` [PATCH v3 10/34] xen/riscv: introduce bitops.h Oleksii Kurochko
2024-01-15 16:44   ` Jan Beulich
2024-01-16 13:06     ` Oleksii
2024-01-16 13:24       ` Jan Beulich
2024-01-17 11:13         ` Oleksii
2024-01-17 11:17           ` Jan Beulich
2024-01-17 11:37             ` Oleksii
2024-01-17 13:42               ` Jan Beulich
2024-01-18  9:43                 ` Oleksii
2024-01-18 11:01                   ` Jan Beulich
2024-01-19  9:16                     ` Oleksii
2024-01-19  9:20                       ` Jan Beulich
2024-01-18 11:03   ` Jan Beulich
2024-01-19  9:09     ` Oleksii
2024-01-19  9:14       ` Jan Beulich
2024-01-19  9:30         ` Oleksii
2023-12-22 15:12 ` [PATCH v3 11/34] xen/riscv: introduce flushtlb.h Oleksii Kurochko
2023-12-22 15:12 ` [PATCH v3 12/34] xen/riscv: introduce smp.h Oleksii Kurochko
2024-01-11 16:36   ` Jan Beulich
2024-01-15  9:35     ` Oleksii
2023-12-22 15:12 ` [PATCH v3 13/34] xen/riscv: introduce cmpxchg.h Oleksii Kurochko
2024-01-22 16:27   ` Jan Beulich
2024-01-23 10:15     ` Oleksii
2024-01-23 10:28       ` Jan Beulich
2024-01-23 12:18         ` Oleksii
2024-01-23 13:27           ` Jan Beulich
2024-01-24  9:15             ` Oleksii
2024-01-30 14:57     ` Oleksii
2024-01-30 15:05       ` Jan Beulich
2024-01-30 15:16         ` Oleksii
2023-12-22 15:12 ` [PATCH v3 14/34] xen/riscv: introduce io.h Oleksii Kurochko
2024-01-15 16:57   ` Jan Beulich
2024-01-16 15:20     ` Oleksii
2024-01-16 16:09       ` Jan Beulich
2024-01-31 17:30         ` Oleksii
2023-12-22 15:12 ` [PATCH v3 15/34] xen/riscv: introduce atomic.h Oleksii Kurochko
2024-01-22 16:56   ` Jan Beulich
2024-01-23 10:21     ` Oleksii
2024-01-23 10:30       ` Jan Beulich
2024-01-23 12:24         ` Oleksii
2024-01-23 13:30           ` Jan Beulich
2024-01-24  9:23             ` Oleksii
2024-01-24 11:19               ` Jan Beulich
2024-01-24 14:56                 ` Oleksii
2023-12-22 15:13 ` [PATCH v3 16/34] xen/lib: introduce generic find next bit operations Oleksii Kurochko
2024-01-23 11:14   ` Jan Beulich
2024-01-23 12:34     ` Oleksii
2024-01-23 13:37       ` Jan Beulich
2024-01-24  9:34         ` Oleksii
2024-01-24 11:24           ` Jan Beulich
2024-01-24 15:04             ` Oleksii
2024-01-24 15:32               ` Jan Beulich
2024-01-26  9:44         ` Oleksii
2024-01-26  9:48           ` Jan Beulich
2024-01-26  9:56             ` Oleksii
2023-12-22 15:13 ` [PATCH v3 17/34] xen/riscv: add compilation of generic find-next-bit.c Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 18/34] xen/riscv: introduce domain.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 19/34] xen/riscv: introduce guest_access.h Oleksii Kurochko
2024-01-23 11:16   ` Jan Beulich
2023-12-22 15:13 ` [PATCH v3 20/34] xen/riscv: introduce irq.h Oleksii Kurochko
2024-01-23 11:18   ` Jan Beulich
2024-01-23 12:25     ` Oleksii
2023-12-22 15:13 ` [PATCH v3 21/34] xen/riscv: introduce p2m.h Oleksii Kurochko
2024-01-11 23:11   ` Shawn Anastasio
2024-01-15  9:37     ` Oleksii
2024-01-12 10:39   ` Julien Grall
2024-01-12 11:06     ` Jan Beulich
2024-01-12 11:09       ` Julien Grall
2024-01-15 10:35     ` Oleksii
2024-01-15 11:01       ` Jan Beulich
2024-01-16  9:44         ` Oleksii
2024-01-16 17:12           ` Julien Grall
2024-01-17  9:32             ` Oleksii
2023-12-22 15:13 ` [PATCH v3 22/34] xen/riscv: introduce regs.h Oleksii Kurochko
2024-01-15 17:00   ` Jan Beulich
2024-01-16  9:46     ` Oleksii
2023-12-22 15:13 ` [PATCH v3 23/34] xen/riscv: introduce time.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 24/34] xen/riscv: introduce event.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 25/34] xen/riscv: introduce monitor.h Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 26/34] xen/riscv: add definition of __read_mostly Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 27/34] xen/riscv: define an address of frame table Oleksii Kurochko
2024-01-23 11:32   ` Jan Beulich
2024-01-23 16:50     ` Oleksii
2024-01-24  8:07       ` Jan Beulich
2024-01-24 10:01         ` Oleksii
2023-12-22 15:13 ` [PATCH v3 28/34] xen/riscv: add required things to current.h Oleksii Kurochko
2024-01-23 11:35   ` Jan Beulich
2024-01-23 16:52     ` Oleksii
2023-12-22 15:13 ` [PATCH v3 29/34] xen/riscv: add minimal stuff to page.h to build full Xen Oleksii Kurochko
2024-01-23 11:36   ` Jan Beulich
2024-01-23 16:54     ` Oleksii
2024-01-24  8:09       ` Jan Beulich
2024-01-24 10:02         ` Oleksii
2023-12-22 15:13 ` [PATCH v3 30/34] xen/riscv: add minimal stuff to processor.h " Oleksii Kurochko
2024-01-23 11:39   ` Jan Beulich
2024-01-23 17:08     ` Oleksii
2024-01-24  8:19       ` Jan Beulich
2024-01-24 10:12         ` Oleksii
2024-01-24 11:27           ` Jan Beulich
2024-01-24 15:33             ` Oleksii
2024-01-24 15:38               ` Jan Beulich
2023-12-22 15:13 ` [PATCH v3 31/34] xen/riscv: add minimal stuff to mm.h " Oleksii Kurochko
2023-12-22 16:32   ` Oleksii
2023-12-22 18:16     ` Oleksii
2024-01-11 16:43     ` Jan Beulich
2024-01-15 10:36       ` Oleksii
2024-01-23 13:03   ` Jan Beulich
2024-01-23 17:27     ` Oleksii
2024-01-24  8:23       ` Jan Beulich
2024-02-02 17:30     ` Oleksii
2024-02-05  7:46       ` Jan Beulich
2024-02-05 12:49         ` Oleksii
2024-02-05 14:05           ` Jan Beulich
2024-02-05 14:40             ` Oleksii
2023-12-22 15:13 ` [PATCH v3 32/34] xen/rirscv: add minimal amount of stubs " Oleksii Kurochko
2024-01-23 13:20   ` Jan Beulich
2024-01-23 17:31     ` Oleksii
2023-12-22 15:13 ` [PATCH v3 33/34] xen/riscv: enable full Xen build Oleksii Kurochko
2023-12-22 15:13 ` [PATCH v3 34/34] xen/README: add compiler and binutils versions for RISC-V64 Oleksii Kurochko
2024-01-23 11:22   ` Jan Beulich
2024-01-23 14:49     ` Oleksii
2024-01-23 17:05       ` Jan Beulich
2024-01-23 17:34         ` Oleksii

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