[PATCH v3 00/15] Introduce /dev/mshv drivers

2023-09-22 Thread Nuno Das Neves
This series introduces support for creating and running guest machines
while running on the Microsoft Hypervisor. [0]
This is done via an IOCTL interface accessed through /dev/mshv, similar to
/dev/kvm. Another series introducing this support was previously posted.
[1]

These interfaces support VMMs running in:
1. The root patition - provided in the mshv_root module, and
2. VTL 2 - provided in the mshv_vtl module [2]

Patches breakdown
-
The first 7 patches are refactoring and adding some helper functions.
They provide some benefit on their own and could be applied independently
as cleanup patches.

Patches 8-12 just set things up for the driver code to come. These are very
small. They come first so that the remaining patches are more self-contained.

The final 3 patches are the meat of the series:
- Patch 13 contains new header files used by the driver.
  These are designed to mirror the ABI headers exported by Hyper-V. This is
  done to avoid polluting hyperv-tlfs.h and help track changes to the ABIs
  that are still unstable. (See FAQ below).
- Patch 14 conditionally includes these new header files into mshyperv.h
  and linux/hyperv.h, in order to be able to use these files in the new
  drivers while remaining independent from hyperv-tlfs.h.
- Patch 15 contains the new driver code located in drivers/hv. This is a
  large amount of code and new files, but it is mostly self-contained and
  all within drivers/hv - apart from the IOCTL interface itself in uapi.

Patch 15 is rather big and has bounced back from some mailing lists. If you
did not get a copy in your inbox, you can view it here instead:
https://github.com/NunoDasNeves/linux/commit/2ae1cabd82257cb303296ab6af707d1bac867e42

FAQ on include/uapi/hyperv/*.h
--
Q:
Why not just add these definitions to hyperv-tlfs.h?
A:
The intention of hyperv-tlfs.h is to contain stable definitions documented
in the public TLFS document. These new definitions don't fit that criteria,
so they should be separate.

Q:
The new headers redefine many things that are already in hyperv-tlfs.h - why?
A:
Some definitions are extended compared to what is documented in the TLFS.
In order to avoid adding undocumented or unstable definitions to hyperv-tlfs.h,
the new headers must compile independently.
Therefore, the new headers must redefine many things in hyperv-tlfs.h in order
to compile.

Q:
Why are these files named hvgdk.h, hvgdk_mini.h, hvhdk.h and hvhdk_mini.h?
A:
The precise meaning of the names reflects conventions used internally at
Microsoft.
Naming them this way makes it easy to find where particular Hyper-V
definitions come from, and check their correctness.
It also facilitates the future work of automatically generating these files.

Q:
Why are they in uapi?
A:
In short, to keep things simple. There are many definitions needed in both
the kernel and the VMM in userspace. Separating them doesn't serve much
purpose, and makes it more laborious to import definitions from Hyper-V
code.

--
[0] "Hyper-V" is more well-known, but it really refers to the whole stack
including the hypervisor and other components that run in Windows
kernel and userspace.
[1] Previous /dev/mshv patch series and discussion:

https://lore.kernel.org/linux-hyperv/1632853875-20261-1-git-send-email-nunodasne...@linux.microsoft.com/
[2] Virtual Secure Mode (VSM) and Virtual Trust Levels (VTL):
https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/vsm
--

Changes since v2:
* Fix some commit message wrapping
* Fix many checkpatch.pl --strict style issues
* Replace uapi ints with __s32
* Replace uapi enums with __u32
* Replace uapi pointers with __u64
* Add explicit padding to uapi structures
* Initialize status in get/set registers hypercall helpers
* Add missing return on error in get_vp_signaled_count
* Remove select TRANSPARENT_HUGEPAGES for mshv_vtl
* Use __func__ prefix consistently in printks
* Use single generic cpuid() to get all 4 registers instead of 4 calls
* Change hv_proximity_domain_info from union to struct for clarity
Changes since v1:
* Clean up formatting, capitalization in commit messages
* Add detail to commit message for patch 15
* Remove errant lines in Makefile and Kconfig in patch 15
* Move a reference to CONFIG_MSHV_VTL from patch 9 to 15

Nuno Das Neves (15):
  hyperv-tlfs: Change shared HV_REGISTER_* defines to HV_MSR_*
  mshyperv: Introduce hv_get_hypervisor_version function
  mshyperv: Introduce numa_node_to_proximity_domain_info
  asm-generic/mshyperv: Introduce hv_recommend_using_aeoi()
  hyperv: Move hv_connection_id to hyperv-tlfs
  hyperv-tlfs: Introduce hv_status_to_string and hv_status_to_errno
  Drivers: hv: Move hv_call_deposit_pages and hv_call_create_vp to
common code
  Drivers: hv: Introduce per-cpu event ring tail
  Drivers: hv: Introduce hv_

[PATCH v3 02/15] mshyperv: Introduce hv_get_hypervisor_version function

2023-09-22 Thread Nuno Das Neves
x86_64 and arm64 implementations to get the hypervisor version
information. Store these in hv_hypervisor_version_info structure to
simplify parsing the fields.

Replace the existing parsing when printing the version numbers at boot.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/mshyperv.c  | 23 +---
 arch/x86/kernel/cpu/mshyperv.c| 36 +++
 include/asm-generic/hyperv-tlfs.h | 23 
 include/asm-generic/mshyperv.h|  2 ++
 4 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index f1b8a04ee9f2..53bdd3bc81ac 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,10 +19,19 @@
 
 static bool hyperv_initialized;
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
+(struct hv_get_vp_registers_output *)info);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
+
 static int __init hyperv_init(void)
 {
-   struct hv_get_vp_registers_output   result;
-   u32 a, b, c, d;
+   struct hv_get_vp_registers_output result;
+   union hv_hypervisor_version_info version;
u64 guest_id;
int ret;
 
@@ -55,13 +64,11 @@ static int __init hyperv_init(void)
ms_hyperv.misc_features);
 
/* Get information about the Hyper-V host version */
-   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
-   a = result.as32.a;
-   b = result.as32.b;
-   c = result.as32.c;
-   d = result.as32.d;
+   hv_get_hypervisor_version(&version);
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   b >> 16, b & 0x, a, d & 0xFF, c, d >> 24);
+   version.major_version, version.minor_version,
+   version.build_number, version.service_number,
+   version.service_pack, version.service_branch);
 
ret = hv_common_init();
if (ret)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 7c82b96da11f..73fbcc003d68 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -347,13 +347,26 @@ static void __init reduced_hw_init(void)
x86_init.irqs.pre_vector_init   = x86_init_noop;
 }
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   unsigned int hv_max_functions;
+
+   hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
+   if (hv_max_functions < HYPERV_CPUID_VERSION) {
+   pr_err("%s: Could not detect Hyper-V version\n", __func__);
+   return -ENODEV;
+   }
+
+   cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, 
&info->edx);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
+
 static void __init ms_hyperv_init_platform(void)
 {
int hv_max_functions_eax;
-   int hv_host_info_eax;
-   int hv_host_info_ebx;
-   int hv_host_info_ecx;
-   int hv_host_info_edx;
+   union hv_hypervisor_version_info version;
 
 #ifdef CONFIG_PARAVIRT
pv_info.name = "Hyper-V";
@@ -407,16 +420,11 @@ static void __init ms_hyperv_init_platform(void)
/*
 * Extract host information.
 */
-   if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
-   hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
-   hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
-   hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
-   hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
-
-   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   hv_host_info_ebx >> 16, hv_host_info_ebx & 0x,
-   hv_host_info_eax, hv_host_info_edx & 0xFF,
-   hv_host_info_ecx, hv_host_info_edx >> 24);
+   if (hv_get_hypervisor_version(&version) == 0) {
+   pr_info("Hyper-V Host Build:%d-%d.%d-%d-%d.%d\n",
+   version.build_number, version.major_version,
+   version.minor_version, version.service_pack,
+   version.service_branch, version.service_number);
}
 
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index fdac4a1714ec..f63b3704d89e 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -787,6 +787,29 @@ struct hv_input_unmap_device_interrupt {
 #define HV_SOURCE_SHADOW_NONE   0x0
 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE   0x1
 
+/*
+ * Version info reported by hypervisor
+ */
+union hv_hyperviso

[PATCH v3 04/15] asm-generic/mshyperv: Introduce hv_recommend_using_aeoi()

2023-09-22 Thread Nuno Das Neves
Factor out logic for determining if we should set the auto eoi flag in SINT
register.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 drivers/hv/hv.c| 12 +---
 include/asm-generic/mshyperv.h | 13 +
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 5ea104c61fa7..d7869205dcbe 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -315,17 +315,7 @@ void hv_synic_enable_regs(unsigned int cpu)
 
shared_sint.vector = vmbus_interrupt;
shared_sint.masked = false;
-
-   /*
-* On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
-* it doesn't provide a recommendation flag and AEOI must be disabled.
-*/
-#ifdef HV_DEPRECATING_AEOI_RECOMMENDED
-   shared_sint.auto_eoi =
-   !(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED);
-#else
-   shared_sint.auto_eoi = 0;
-#endif
+   shared_sint.auto_eoi = hv_recommend_using_aeoi();
hv_set_register(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT,
shared_sint.as_uint64);
 
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index e16557523b6e..c9e166d73fca 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -82,6 +82,19 @@ extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
 bool hv_isolation_type_snp(void);
 bool hv_isolation_type_tdx(void);
 
+/*
+ * On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
+ * it doesn't provide a recommendation flag and AEOI must be disabled.
+ */
+static inline bool hv_recommend_using_aeoi(void)
+{
+#ifdef HV_DEPRECATING_AEOI_RECOMMENDED
+   return !(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED);
+#else
+   return false;
+#endif
+}
+
 /* Helper functions that provide a consistent pattern for checking Hyper-V 
hypercall status. */
 static inline int hv_result(u64 status)
 {
-- 
2.25.1




[PATCH v3 01/15] hyperv-tlfs: Change shared HV_REGISTER_* defines to HV_MSR_*

2023-09-22 Thread Nuno Das Neves
In x86 hyperv-tlfs, HV_REGISTER_ prefix is used to indicate MSRs
accessed via rdmsrl/wrmsrl. But in ARM64, HV_REGISTER_ instead indicates
VP registers accessed via get/set vp registers hypercall.

This is due to HV_REGISTER_* names being used by hv_set/get_register,
with the arch-specific version delegating to the appropriate mechanism.

The problem is, using prefix HV_REGISTER_ for MSRs will conflict with
VP registers when they are introduced for x86 in future.

This patch solves the issue by:

1. Defining all the x86 MSRs with a consistent prefix: HV_X64_MSR_.
   This is so HV_REGISTER_ can be reserved for VP registers.

2. Change the non-arch-specific alias used by hv_set/get_register to
   HV_MSR_. This is also happens to be the same name HyperV uses for this
   purpose.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/include/asm/hyperv-tlfs.h |  25 +
 arch/x86/include/asm/hyperv-tlfs.h   | 137 +--
 arch/x86/include/asm/mshyperv.h  |   8 +-
 arch/x86/kernel/cpu/mshyperv.c   |  22 ++---
 drivers/clocksource/hyperv_timer.c   |  24 ++---
 drivers/hv/hv.c  |  36 +++
 drivers/hv/hv_common.c   |  18 ++--
 include/asm-generic/mshyperv.h   |   2 +-
 8 files changed, 148 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
index bc6c7ac934a1..a6e852c2fc3a 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -64,6 +64,31 @@
 #define HV_REGISTER_STIMER0_CONFIG 0x000B
 #define HV_REGISTER_STIMER0_COUNT  0x000B0001
 
+/*
+ * To support non-arch-specific code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
+ */
+#define HV_MSR_VP_INDEX(HV_REGISTER_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT  (HV_REGISTER_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TS(HV_REGISTER_REFERENCE_TSC)
+
+#define HV_MSR_STIMER0_CONFIG  (HV_REGISTER_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT   (HV_REGISTER_STIMER0_COUNT)
+
+#define HV_MSR_SCONTROL(HV_REGISTER_SCONTROL)
+#define HV_MSR_SIEFP   (HV_REGISTER_SIEFP)
+#define HV_MSR_SIMP(HV_REGISTER_SIMP)
+#define HV_MSR_EOM (HV_REGISTER_EOM)
+#define HV_MSR_SINT0   (HV_REGISTER_SINT0)
+
+#define HV_MSR_CRASH_P0(HV_REGISTER_CRASH_P0)
+#define HV_MSR_CRASH_P1(HV_REGISTER_CRASH_P1)
+#define HV_MSR_CRASH_P2(HV_REGISTER_CRASH_P2)
+#define HV_MSR_CRASH_P3(HV_REGISTER_CRASH_P3)
+#define HV_MSR_CRASH_P4(HV_REGISTER_CRASH_P4)
+#define HV_MSR_CRASH_CTL   (HV_REGISTER_CRASH_CTL)
+
 union hv_msi_entry {
u64 as_uint64[2];
struct {
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 2ff26f53cd62..058c5c8dc382 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -182,7 +182,7 @@ enum hv_isolation_type {
 #define HV_X64_MSR_HYPERCALL   0x4001
 
 /* MSR used to provide vcpu index */
-#define HV_REGISTER_VP_INDEX   0x4002
+#define HV_X64_MSR_VP_INDEX0x4002
 
 /* MSR used to reset the guest OS. */
 #define HV_X64_MSR_RESET   0x4003
@@ -191,10 +191,10 @@ enum hv_isolation_type {
 #define HV_X64_MSR_VP_RUNTIME  0x4010
 
 /* MSR used to read the per-partition time reference counter */
-#define HV_REGISTER_TIME_REF_COUNT 0x4020
+#define HV_X64_MSR_TIME_REF_COUNT  0x4020
 
 /* A partition's reference time stamp counter (TSC) page */
-#define HV_REGISTER_REFERENCE_TSC  0x4021
+#define HV_X64_MSR_REFERENCE_TSC   0x4021
 
 /* MSR used to retrieve the TSC frequency */
 #define HV_X64_MSR_TSC_FREQUENCY   0x4022
@@ -209,61 +209,61 @@ enum hv_isolation_type {
 #define HV_X64_MSR_VP_ASSIST_PAGE  0x4073
 
 /* Define synthetic interrupt controller model specific registers. */
-#define HV_REGISTER_SCONTROL   0x4080
-#define HV_REGISTER_SVERSION   0x4081
-#define HV_REGISTER_SIEFP  0x4082
-#define HV_REGISTER_SIMP   0x4083
-#define HV_REGISTER_EOM0x4084
-#define HV_REGISTER_SINT0  0x4090
-#define HV_REGISTER_SINT1  0x4091
-#define HV_REGISTER_SINT2  0x4092
-#define HV_REGISTER_SINT3  0x4093
-#define HV_REGISTER_SINT4  0x4094
-#define HV_REGISTER_SINT5  0x4095
-#define HV_REGISTER_SINT6  0x4096
-#define HV_REGISTER_SINT7  0x4097
-#define HV_REGISTER_

[PATCH v3 14/15] asm-generic: hyperv: Use new Hyper-V headers conditionally.

2023-09-22 Thread Nuno Das Neves
Add asm-generic/hyperv-defs.h. It includes hyperv-tlfs.h or hvhdk.h
depending on compile-time constant HV_HYPERV_DEFS which will be defined in
the mshv driver.

This is needed to keep unstable Hyper-V interfaces independent of
hyperv-tlfs.h. This ensures hvhdk.h replaces hyperv-tlfs.h in the mshv
driver, even via indirect includes.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/arm64/include/asm/mshyperv.h |  2 +-
 arch/x86/include/asm/mshyperv.h   |  3 +--
 drivers/hv/hyperv_vmbus.h |  1 -
 include/asm-generic/hyperv-defs.h | 26 ++
 include/asm-generic/mshyperv.h|  2 +-
 include/linux/hyperv.h|  2 +-
 6 files changed, 30 insertions(+), 6 deletions(-)
 create mode 100644 include/asm-generic/hyperv-defs.h

diff --git a/arch/arm64/include/asm/mshyperv.h 
b/arch/arm64/include/asm/mshyperv.h
index 20070a847304..8ec14caf3d4f 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -20,7 +20,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Declare calls to get and set Hyper-V VP register values on ARM64, which
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 6e96d3420a9d..e19fc6140a31 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -6,10 +6,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 09792eb4ffed..0e4bc18a13fa 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/include/asm-generic/hyperv-defs.h 
b/include/asm-generic/hyperv-defs.h
new file mode 100644
index ..ac6fcba35c8c
--- /dev/null
+++ b/include/asm-generic/hyperv-defs.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_HYPERV_DEFS_H
+#define _ASM_GENERIC_HYPERV_DEFS_H
+
+/*
+ * There are cases where Microsoft Hypervisor ABIs are needed which may not be
+ * stable or present in the Hyper-V TLFS document. E.g. the mshv_root driver.
+ *
+ * As these interfaces are unstable and may differ from hyperv-tlfs.h, they
+ * must be kept separate and independent.
+ *
+ * However, code from files that depend on hyperv-tlfs.h (such as mshyperv.h)
+ * is still needed, so work around the issue by conditionally including the
+ * correct definitions.
+ *
+ * Note: Since they are independent of each other, there are many definitions
+ * duplicated in both hyperv-tlfs.h and uapi/hyperv/hv*.h files.
+ */
+#ifdef HV_HYPERV_DEFS
+#include 
+#else
+#include 
+#endif
+
+#endif /* _ASM_GENERIC_HYPERV_DEFS_H */
+
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 0a9e8ff31b73..d3864ba64e47 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -25,7 +25,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define VTPM_BASE_ADDRESS 0xfed4
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 2d8568708d90..d0bc3d34241c 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -24,7 +24,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define MAX_PAGE_BUFFER_COUNT  32
 #define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */
-- 
2.25.1




[PATCH v3 06/15] hyperv-tlfs: Introduce hv_status_to_string and hv_status_to_errno

2023-09-22 Thread Nuno Das Neves
hv_status_to_errno translates hyperv statuses to linux error codes.
This is useful for returning something linux-friendly from a hypercall
helper function.

hv_status_to_string improves clarity of error messages.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/x86/hyperv/hv_init.c |  2 +-
 arch/x86/hyperv/hv_proc.c |  6 ++--
 include/asm-generic/hyperv-tlfs.h | 47 ++-
 include/asm-generic/mshyperv.h| 33 ++
 4 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 2b0124394e24..5b679bfbc7f7 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -386,7 +386,7 @@ static void __init hv_get_partition_id(void)
status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
if (!hv_result_success(status)) {
/* No point in proceeding if this failed */
-   pr_err("Failed to get partition ID: %lld\n", status);
+   pr_err("Failed to get partition ID: %s\n", 
hv_status_to_string(status));
BUG();
}
hv_current_partition_id = output_page->partition_id;
diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 5ba5ca1b2089..ed80da64649e 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -144,9 +144,9 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
 
if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
if (!hv_result_success(status)) {
-   pr_err("%s: cpu %u apic ID %u, %lld\n", 
__func__,
-  lp_index, apic_id, status);
-   ret = hv_result(status);
+   pr_err("%s: cpu %u apic ID %u, %s\n", __func__,
+  lp_index, apic_id, 
hv_status_to_string(status));
+   ret = hv_status_to_errno(status);
}
break;
}
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 1316584983c1..8d76661a8c9f 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -212,19 +212,40 @@ enum HV_GENERIC_SET_FORMAT {
 HV_HYPERCALL_RSVD2_MASK)
 
 /* hypercall status code */
-#define HV_STATUS_SUCCESS  0
-#define HV_STATUS_INVALID_HYPERCALL_CODE   2
-#define HV_STATUS_INVALID_HYPERCALL_INPUT  3
-#define HV_STATUS_INVALID_ALIGNMENT4
-#define HV_STATUS_INVALID_PARAMETER5
-#define HV_STATUS_ACCESS_DENIED6
-#define HV_STATUS_OPERATION_DENIED 8
-#define HV_STATUS_INSUFFICIENT_MEMORY  11
-#define HV_STATUS_INVALID_PORT_ID  17
-#define HV_STATUS_INVALID_CONNECTION_ID18
-#define HV_STATUS_INSUFFICIENT_BUFFERS 19
-#define HV_STATUS_TIME_OUT  120
-#define HV_STATUS_VTL_ALREADY_ENABLED  134
+#define __HV_STATUS_DEF(OP) \
+   OP(HV_STATUS_SUCCESS,   0x0) \
+   OP(HV_STATUS_INVALID_HYPERCALL_CODE,0x2) \
+   OP(HV_STATUS_INVALID_HYPERCALL_INPUT,   0x3) \
+   OP(HV_STATUS_INVALID_ALIGNMENT, 0x4) \
+   OP(HV_STATUS_INVALID_PARAMETER, 0x5) \
+   OP(HV_STATUS_ACCESS_DENIED, 0x6) \
+   OP(HV_STATUS_INVALID_PARTITION_STATE,   0x7) \
+   OP(HV_STATUS_OPERATION_DENIED,  0x8) \
+   OP(HV_STATUS_UNKNOWN_PROPERTY,  0x9) \
+   OP(HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE,   0xA) \
+   OP(HV_STATUS_INSUFFICIENT_MEMORY,   0xB) \
+   OP(HV_STATUS_INVALID_PARTITION_ID,  0xD) \
+   OP(HV_STATUS_INVALID_VP_INDEX,  0xE) \
+   OP(HV_STATUS_NOT_FOUND, 0x10) \
+   OP(HV_STATUS_INVALID_PORT_ID,   0x11) \
+   OP(HV_STATUS_INVALID_CONNECTION_ID, 0x12) \
+   OP(HV_STATUS_INSUFFICIENT_BUFFERS,  0x13) \
+   OP(HV_STATUS_NOT_ACKNOWLEDGED,  0x14) \
+   OP(HV_STATUS_INVALID_VP_STATE,  0x15) \
+   OP(HV_STATUS_NO_RESOURCES,  0x1D) \
+   OP(HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED,   0x20) \
+   OP(HV_STATUS_INVALID_LP_INDEX,  0x41) \
+   OP(HV_STATUS_INVALID_REGISTER_VALUE,0x50) \
+   OP(HV_STATUS_TIME_OUT,  0x78) \
+   OP(HV_STATUS_CALL_PENDING,  0x79) \
+   OP(HV_STATUS_VTL_ALREADY_ENABLED,   0x86)
+
+#define __HV_MAKE_HV_STATUS_ENUM(NAME, VAL) NAME = (VAL),
+#define __HV_MAKE_HV_STATUS_CASE(NAME, VAL) cas

[PATCH v3 10/15] x86: hyperv: Add mshv_handler irq handler and setup function

2023-09-22 Thread Nuno Das Neves
This will handle SYNIC interrupts such as intercepts, doorbells, and
scheduling messages intended for the mshv driver.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
Reviewed-by: Tianyu Lan 
---
 arch/x86/kernel/cpu/mshyperv.c | 9 +
 drivers/hv/hv_common.c | 5 +
 include/asm-generic/mshyperv.h | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 73fbcc003d68..b8c3177d6389 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -110,6 +110,7 @@ void hv_set_register(unsigned int reg, u64 value)
 }
 EXPORT_SYMBOL_GPL(hv_set_register);
 
+static void (*mshv_handler)(void);
 static void (*vmbus_handler)(void);
 static void (*hv_stimer0_handler)(void);
 static void (*hv_kexec_handler)(void);
@@ -120,6 +121,9 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
struct pt_regs *old_regs = set_irq_regs(regs);
 
inc_irq_stat(irq_hv_callback_count);
+   if (mshv_handler)
+   mshv_handler();
+
if (vmbus_handler)
vmbus_handler();
 
@@ -129,6 +133,11 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
set_irq_regs(old_regs);
 }
 
+void hv_setup_mshv_irq(void (*handler)(void))
+{
+   mshv_handler = handler;
+}
+
 void hv_setup_vmbus_handler(void (*handler)(void))
 {
vmbus_handler = handler;
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 89f5c1fb2a35..092b0c727db9 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -585,6 +585,11 @@ void __weak hv_remove_vmbus_handler(void)
 }
 EXPORT_SYMBOL_GPL(hv_remove_vmbus_handler);
 
+void __weak hv_setup_mshv_irq(void (*handler)(void))
+{
+}
+EXPORT_SYMBOL_GPL(hv_setup_mshv_irq);
+
 void __weak hv_setup_kexec_handler(void (*handler)(void))
 {
 }
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 5a12e5754e97..0a9e8ff31b73 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -198,6 +198,8 @@ void hv_remove_vmbus_handler(void);
 void hv_setup_stimer0_handler(void (*handler)(void));
 void hv_remove_stimer0_handler(void);
 
+void hv_setup_mshv_irq(void (*handler)(void));
+
 void hv_setup_kexec_handler(void (*handler)(void));
 void hv_remove_kexec_handler(void);
 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
-- 
2.25.1




[PATCH v3 08/15] Drivers: hv: Introduce per-cpu event ring tail

2023-09-22 Thread Nuno Das Neves
Add a pointer hv_synic_eventring_tail to track the tail pointer for the
SynIC event ring buffer for each SINT.

This will be used by the mshv driver, but must be tracked independently
since the driver module could be removed and re-inserted.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 drivers/hv/hv_common.c | 28 ++--
 include/asm-generic/mshyperv.h |  2 ++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 8c6ab60d5387..d346ce6adf00 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -62,6 +62,16 @@ static void hv_kmsg_dump_unregister(void);
 
 static struct ctl_table_header *hv_ctl_table_hdr;
 
+/*
+ * Per-cpu array holding the tail pointer for the SynIC event ring buffer
+ * for each SINT.
+ *
+ * We cannot maintain this in mshv driver because the tail pointer should
+ * persist even if the mshv driver is unloaded.
+ */
+u8 __percpu **hv_synic_eventring_tail;
+EXPORT_SYMBOL_GPL(hv_synic_eventring_tail);
+
 /*
  * Hyper-V specific initialization and shutdown code that is
  * common across all architectures.  Called from architecture
@@ -84,6 +94,9 @@ void __init hv_common_free(void)
 
free_percpu(hyperv_pcpu_input_arg);
hyperv_pcpu_input_arg = NULL;
+
+   free_percpu(hv_synic_eventring_tail);
+   hv_synic_eventring_tail = NULL;
 }
 
 /*
@@ -333,6 +346,8 @@ int __init hv_common_init(void)
if (hv_root_partition) {
hyperv_pcpu_output_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_output_arg);
+   hv_synic_eventring_tail = alloc_percpu(u8 *);
+   BUG_ON(hv_synic_eventring_tail == NULL);
}
 
hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
@@ -357,6 +372,7 @@ int __init hv_common_init(void)
 int hv_common_cpu_init(unsigned int cpu)
 {
void **inputarg, **outputarg;
+   u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
int pgcount = hv_root_partition ? 2 : 1;
@@ -369,8 +385,8 @@ int hv_common_cpu_init(unsigned int cpu)
inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
 
/*
-* hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory is already
-* allocated if this CPU was previously online and then taken offline
+* The per-cpu memory is already allocated if this CPU was previously
+* online and then taken offline
 */
if (!*inputarg) {
mem = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
@@ -380,6 +396,14 @@ int hv_common_cpu_init(unsigned int cpu)
if (hv_root_partition) {
outputarg = (void 
**)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
+   synic_eventring_tail = (u8 
**)this_cpu_ptr(hv_synic_eventring_tail);
+   *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, 
sizeof(u8),
+   flags);
+
+   if (unlikely(!*synic_eventring_tail)) {
+   kfree(mem);
+   return -ENOMEM;
+   }
}
 
if (!ms_hyperv.paravisor_present &&
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 5be3e3402e37..5a12e5754e97 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -77,6 +77,8 @@ extern bool hv_nested;
 extern void * __percpu *hyperv_pcpu_input_arg;
 extern void * __percpu *hyperv_pcpu_output_arg;
 
+extern u8 __percpu **hv_synic_eventring_tail;
+
 extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
 extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
 bool hv_isolation_type_snp(void);
-- 
2.25.1




[PATCH v3 11/15] Drivers: hv: export vmbus_isr, hv_context and hv_post_message

2023-09-22 Thread Nuno Das Neves
These will be used by the mshv_vtl driver.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 drivers/hv/hv.c   | 2 ++
 drivers/hv/hyperv_vmbus.h | 1 +
 drivers/hv/vmbus_drv.c| 3 ++-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index d7869205dcbe..c60a4fb55f3c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -25,6 +25,7 @@
 
 /* The one and only */
 struct hv_context hv_context;
+EXPORT_SYMBOL_GPL(hv_context);
 
 /*
  * hv_init - Main initialization routine.
@@ -93,6 +94,7 @@ int hv_post_message(union hv_connection_id connection_id,
 
return hv_result(status);
 }
+EXPORT_SYMBOL_GPL(hv_post_message);
 
 int hv_synic_alloc(void)
 {
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f6b1e710f805..09792eb4ffed 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -32,6 +32,7 @@
  */
 #define HV_UTIL_NEGO_TIMEOUT 55
 
+void vmbus_isr(void);
 
 /* Definitions for the monitored notification facility */
 union hv_monitor_trigger_group {
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index edbb38f6956b..6d27597af8bf 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1286,7 +1286,7 @@ static void vmbus_chan_sched(struct hv_per_cpu_context 
*hv_cpu)
}
 }
 
-static void vmbus_isr(void)
+void vmbus_isr(void)
 {
struct hv_per_cpu_context *hv_cpu
= this_cpu_ptr(hv_context.cpu_context);
@@ -1309,6 +1309,7 @@ static void vmbus_isr(void)
 
add_interrupt_randomness(vmbus_interrupt);
 }
+EXPORT_SYMBOL_GPL(vmbus_isr);
 
 static irqreturn_t vmbus_percpu_isr(int irq, void *dev_id)
 {
-- 
2.25.1




[PATCH v3 07/15] Drivers: hv: Move hv_call_deposit_pages and hv_call_create_vp to common code

2023-09-22 Thread Nuno Das Neves
These hypercalls are not arch-specific. Move them to common code.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/x86/hyperv/hv_proc.c   | 152 
 arch/x86/include/asm/mshyperv.h |   1 -
 drivers/hv/hv_common.c  | 147 ++
 include/asm-generic/mshyperv.h  |   2 +
 4 files changed, 149 insertions(+), 153 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index ed80da64649e..0a35cb865427 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -14,106 +13,6 @@
 
 #include 
 
-/*
- * See struct hv_deposit_memory. The first u64 is partition ID, the rest
- * are GPAs.
- */
-#define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1)
-
-/* Deposits exact number of pages. Must be called with interrupts enabled.  */
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
-{
-   struct page **pages, *page;
-   int *counts;
-   int num_allocations;
-   int i, j, page_count;
-   int order;
-   u64 status;
-   int ret;
-   u64 base_pfn;
-   struct hv_deposit_memory *input_page;
-   unsigned long flags;
-
-   if (num_pages > HV_DEPOSIT_MAX)
-   return -E2BIG;
-   if (!num_pages)
-   return 0;
-
-   /* One buffer for page pointers and counts */
-   page = alloc_page(GFP_KERNEL);
-   if (!page)
-   return -ENOMEM;
-   pages = page_address(page);
-
-   counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
-   if (!counts) {
-   free_page((unsigned long)pages);
-   return -ENOMEM;
-   }
-
-   /* Allocate all the pages before disabling interrupts */
-   i = 0;
-
-   while (num_pages) {
-   /* Find highest order we can actually allocate */
-   order = 31 - __builtin_clz(num_pages);
-
-   while (1) {
-   pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
-   if (pages[i])
-   break;
-   if (!order) {
-   ret = -ENOMEM;
-   num_allocations = i;
-   goto err_free_allocations;
-   }
-   --order;
-   }
-
-   split_page(pages[i], order);
-   counts[i] = 1 << order;
-   num_pages -= counts[i];
-   i++;
-   }
-   num_allocations = i;
-
-   local_irq_save(flags);
-
-   input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-   input_page->partition_id = partition_id;
-
-   /* Populate gpa_page_list - these will fit on the input page */
-   for (i = 0, page_count = 0; i < num_allocations; ++i) {
-   base_pfn = page_to_pfn(pages[i]);
-   for (j = 0; j < counts[i]; ++j, ++page_count)
-   input_page->gpa_page_list[page_count] = base_pfn + j;
-   }
-   status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
-page_count, 0, input_page, NULL);
-   local_irq_restore(flags);
-   if (!hv_result_success(status)) {
-   pr_err("Failed to deposit pages: %lld\n", status);
-   ret = hv_result(status);
-   goto err_free_allocations;
-   }
-
-   ret = 0;
-   goto free_buf;
-
-err_free_allocations:
-   for (i = 0; i < num_allocations; ++i) {
-   base_pfn = page_to_pfn(pages[i]);
-   for (j = 0; j < counts[i]; ++j)
-   __free_page(pfn_to_page(base_pfn + j));
-   }
-
-free_buf:
-   free_page((unsigned long)pages);
-   kfree(counts);
-   return ret;
-}
-
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 {
struct hv_add_logical_processor_in *input;
@@ -156,54 +55,3 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
return ret;
 }
 
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
-{
-   struct hv_create_vp *input;
-   u64 status;
-   unsigned long irq_flags;
-   int ret = HV_STATUS_SUCCESS;
-   int pxm = node_to_pxm(node);
-
-   /* Root VPs don't seem to need pages deposited */
-   if (partition_id != hv_current_partition_id) {
-   /* The value 90 is empirically determined. It may change. */
-   ret = hv_call_deposit_pages(node, partition_id, 90);
-   if (ret)
-   return ret;
-   }
-
-   do {
-   local_irq_save(irq_flags);
-
-   input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-   input->partition_id = partition_id;
-   input->vp_index = vp_index;
-   input->

[PATCH v3 09/15] Drivers: hv: Introduce hv_output_arg_exists in hv_common.c

2023-09-22 Thread Nuno Das Neves
This is a more flexible approach for determining whether to allocate the
output page.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 drivers/hv/hv_common.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index d346ce6adf00..89f5c1fb2a35 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -58,6 +58,14 @@ EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
 void * __percpu *hyperv_pcpu_output_arg;
 EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
 
+/*
+ * Determine whether output arg is needed
+ */
+static inline bool hv_output_arg_exists(void)
+{
+   return hv_root_partition ? true : false;
+}
+
 static void hv_kmsg_dump_unregister(void);
 
 static struct ctl_table_header *hv_ctl_table_hdr;
@@ -342,10 +350,12 @@ int __init hv_common_init(void)
hyperv_pcpu_input_arg = alloc_percpu(void  *);
BUG_ON(!hyperv_pcpu_input_arg);
 
-   /* Allocate the per-CPU state for output arg for root */
-   if (hv_root_partition) {
+   if (hv_output_arg_exists()) {
hyperv_pcpu_output_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_output_arg);
+   }
+
+   if (hv_root_partition) {
hv_synic_eventring_tail = alloc_percpu(u8 *);
BUG_ON(hv_synic_eventring_tail == NULL);
}
@@ -375,7 +385,7 @@ int hv_common_cpu_init(unsigned int cpu)
u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
-   int pgcount = hv_root_partition ? 2 : 1;
+   int pgcount = hv_output_arg_exists() ? 2 : 1;
void *mem;
int ret;
 
@@ -393,9 +403,12 @@ int hv_common_cpu_init(unsigned int cpu)
if (!mem)
return -ENOMEM;
 
-   if (hv_root_partition) {
+   if (hv_output_arg_exists()) {
outputarg = (void 
**)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
+   }
+
+   if (hv_root_partition) {
synic_eventring_tail = (u8 
**)this_cpu_ptr(hv_synic_eventring_tail);
*synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, 
sizeof(u8),
flags);
-- 
2.25.1




[PATCH v3 12/15] Documentation: Reserve ioctl number for mshv driver

2023-09-22 Thread Nuno Das Neves
Signed-off-by: Nuno Das Neves 
Acked-by: Jonathan Corbet 
---
 Documentation/userspace-api/ioctl/ioctl-number.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst 
b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 4ea5b837399a..71e6d23070ca 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -355,6 +355,8 @@ Code  Seq#Include File  
 Comments
 0xB6  alllinux/fpga-dfl.h
 0xB7  alluapi/linux/remoteproc_cdev.h
<mailto:linux-remotep...@vger.kernel.org>
 0xB7  alluapi/linux/nsfs.h   
<mailto:Andrei Vagin >
+0xB8  alluapi/linux/mshv.h   Microsoft 
Hypervisor VM management APIs
+ 
<mailto:linux-hyperv@vger.kernel.org>
 0xC0  00-0F  linux/usb/iowarrior.h
 0xCA  00-0F  uapi/misc/cxl.h
 0xCA  10-2F  uapi/misc/ocxl.h
-- 
2.25.1




[PATCH v3 05/15] hyperv: Move hv_connection_id to hyperv-tlfs

2023-09-22 Thread Nuno Das Neves
The definition conflicts with one added in hvgdk.h as part of the mshv
driver so must be moved to hyperv-tlfs.h.

This structure should be in hyperv-tlfs.h anyway, since it is part of
the TLFS document.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 include/asm-generic/hyperv-tlfs.h | 9 +
 include/linux/hyperv.h| 9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index a6dffb346bf2..1316584983c1 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -842,4 +842,13 @@ struct hv_mmio_write_input {
u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
 } __packed;
 
+/* Define connection identifier type. */
+union hv_connection_id {
+   u32 asu32;
+   struct {
+   u32 id:24;
+   u32 reserved:8;
+   } u;
+};
+
 #endif
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index a922d4526de4..2d8568708d90 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -748,15 +748,6 @@ struct vmbus_close_msg {
struct vmbus_channel_close_channel msg;
 };
 
-/* Define connection identifier type. */
-union hv_connection_id {
-   u32 asu32;
-   struct {
-   u32 id:24;
-   u32 reserved:8;
-   } u;
-};
-
 enum vmbus_device_type {
HV_IDE = 0,
HV_SCSI,
-- 
2.25.1




[PATCH v3 03/15] mshyperv: Introduce numa_node_to_proximity_domain_info

2023-09-22 Thread Nuno Das Neves
Factor out logic for converting numa node to proximity domain info into
a helper function, and export it.

Change hv_proximity_domain_info to a struct to simplify the code.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 arch/x86/hyperv/hv_proc.c |  8 ++--
 drivers/acpi/numa/srat.c  |  1 +
 include/asm-generic/hyperv-tlfs.h | 14 +-
 include/asm-generic/mshyperv.h| 15 +++
 4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 68a0843d4750..5ba5ca1b2089 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -121,7 +121,6 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
u64 status;
unsigned long flags;
int ret = HV_STATUS_SUCCESS;
-   int pxm = node_to_pxm(node);
 
/*
 * When adding a logical processor, the hypervisor may return
@@ -137,11 +136,8 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
 
input->lp_index = lp_index;
input->apic_id = apic_id;
-   input->flags = 0;
-   input->proximity_domain_info.domain_id = pxm;
-   input->proximity_domain_info.flags.reserved = 0;
-   input->proximity_domain_info.flags.proximity_info_valid = 1;
-   input->proximity_domain_info.flags.proximity_preferred = 1;
+   input->proximity_domain_info =
+   numa_node_to_proximity_domain_info(node);
status = hv_do_hypercall(HVCALL_ADD_LOGICAL_PROCESSOR,
 input, output);
local_irq_restore(flags);
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 1f4fc5f8a819..0cf9f0574495 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -48,6 +48,7 @@ int node_to_pxm(int node)
return PXM_INVAL;
return node_to_pxm_map[node];
 }
+EXPORT_SYMBOL(node_to_pxm);
 
 static void __acpi_map_pxm_to_node(int pxm, int node)
 {
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index f63b3704d89e..a6dffb346bf2 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -512,13 +512,9 @@ struct hv_proximity_domain_flags {
u32 proximity_info_valid : 1;
 } __packed;
 
-/* Not a union in windows but useful for zeroing */
-union hv_proximity_domain_info {
-   struct {
-   u32 domain_id;
-   struct hv_proximity_domain_flags flags;
-   };
-   u64 as_uint64;
+struct hv_proximity_domain_info {
+   u32 domain_id;
+   struct hv_proximity_domain_flags flags;
 } __packed;
 
 struct hv_lp_startup_status {
@@ -535,7 +531,7 @@ struct hv_lp_startup_status {
 struct hv_add_logical_processor_in {
u32 lp_index;
u32 apic_id;
-   union hv_proximity_domain_info proximity_domain_info;
+   struct hv_proximity_domain_info proximity_domain_info;
u64 flags;
 } __packed;
 
@@ -560,7 +556,7 @@ struct hv_create_vp {
u8 padding[3];
u8 subnode_type;
u64 subnode_id;
-   union hv_proximity_domain_info proximity_domain_info;
+   struct hv_proximity_domain_info proximity_domain_info;
u64 flags;
 } __packed;
 
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 5b3512e5a72e..e16557523b6e 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,20 @@
 
 #define VTPM_BASE_ADDRESS 0xfed4
 
+static inline struct hv_proximity_domain_info
+numa_node_to_proximity_domain_info(int node)
+{
+   struct hv_proximity_domain_info proximity_domain_info = {};
+
+   if (node != NUMA_NO_NODE) {
+   proximity_domain_info.domain_id = node_to_pxm(node);
+   proximity_domain_info.flags.proximity_info_valid = 1;
+   proximity_domain_info.flags.proximity_preferred = 1;
+   }
+
+   return proximity_domain_info;
+}
+
 struct ms_hyperv_info {
u32 features;
u32 priv_high;
-- 
2.25.1




[PATCH v3 13/15] uapi: hyperv: Add mshv driver headers defining hypervisor ABIs

2023-09-22 Thread Nuno Das Neves
These must be in uapi because they will be used in the mshv ioctl API.

Version numbers for each file:
hvhdk.h 25212
hvhdk_mini.h25294
hvgdk.h 25125
hvgdk_mini.h25294

These are unstable interfaces and as such must be compiled independently
from published interfaces found in hyperv-tlfs.h.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 include/uapi/hyperv/hvgdk.h  |   41 +
 include/uapi/hyperv/hvgdk_mini.h | 1076 
 include/uapi/hyperv/hvhdk.h  | 1342 ++
 include/uapi/hyperv/hvhdk_mini.h |  160 
 4 files changed, 2619 insertions(+)
 create mode 100644 include/uapi/hyperv/hvgdk.h
 create mode 100644 include/uapi/hyperv/hvgdk_mini.h
 create mode 100644 include/uapi/hyperv/hvhdk.h
 create mode 100644 include/uapi/hyperv/hvhdk_mini.h

diff --git a/include/uapi/hyperv/hvgdk.h b/include/uapi/hyperv/hvgdk.h
new file mode 100644
index ..9bcbb7d902b2
--- /dev/null
+++ b/include/uapi/hyperv/hvgdk.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2023, Microsoft Corporation.
+ *
+ * These files (hvhdk.h, hvhdk_mini.h, hvgdk.h, hvgdk_mini.h) define APIs for
+ * communicating with the Microsoft Hypervisor.
+ *
+ * These definitions are subject to change across hypervisor versions, and as
+ * such are separate and independent from hyperv-tlfs.h.
+ *
+ * The naming of these headers reflects conventions used in the Microsoft
+ * Hypervisor.
+ */
+#ifndef _UAPI_HV_HVGDK_H
+#define _UAPI_HV_HVGDK_H
+
+#include "hvgdk_mini.h"
+
+enum hv_unimplemented_msr_action {
+   HV_UNIMPLEMENTED_MSR_ACTION_FAULT = 0,
+   HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO = 1,
+   HV_UNIMPLEMENTED_MSR_ACTION_COUNT = 2,
+};
+
+/* Define connection identifier type. */
+union hv_connection_id {
+   __u32 asu32;
+   struct {
+   __u32 id:24;
+   __u32 reserved:8;
+   } __packed u;
+};
+
+struct hv_input_unmap_gpa_pages {
+   __u64 target_partition_id;
+   __u64 target_gpa_base;
+   __u32 unmap_flags;
+   __u32 padding;
+} __packed;
+
+#endif /* #ifndef _UAPI_HV_HVGDK_H */
diff --git a/include/uapi/hyperv/hvgdk_mini.h b/include/uapi/hyperv/hvgdk_mini.h
new file mode 100644
index ..f894327206c8
--- /dev/null
+++ b/include/uapi/hyperv/hvgdk_mini.h
@@ -0,0 +1,1076 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2023, Microsoft Corporation.
+ *
+ * These files (hvhdk.h, hvhdk_mini.h, hvgdk.h, hvgdk_mini.h) define APIs for
+ * communicating with the Microsoft Hypervisor.
+ *
+ * These definitions are subject to change across hypervisor versions, and as
+ * such are separate and independent from hyperv-tlfs.h.
+ *
+ * The naming of these headers reflects conventions used in the Microsoft
+ * Hypervisor.
+ */
+#ifndef _UAPI_HV_HVGDK_MINI_H
+#define _UAPI_HV_HVGDK_MINI_H
+
+struct hv_u128 {
+   __u64 low_part;
+   __u64 high_part;
+} __packed;
+
+/* hypercall status code */
+#define __HV_STATUS_DEF(OP) \
+   OP(HV_STATUS_SUCCESS,   0x0) \
+   OP(HV_STATUS_INVALID_HYPERCALL_CODE,0x2) \
+   OP(HV_STATUS_INVALID_HYPERCALL_INPUT,   0x3) \
+   OP(HV_STATUS_INVALID_ALIGNMENT, 0x4) \
+   OP(HV_STATUS_INVALID_PARAMETER, 0x5) \
+   OP(HV_STATUS_ACCESS_DENIED, 0x6) \
+   OP(HV_STATUS_INVALID_PARTITION_STATE,   0x7) \
+   OP(HV_STATUS_OPERATION_DENIED,  0x8) \
+   OP(HV_STATUS_UNKNOWN_PROPERTY,  0x9) \
+   OP(HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE,   0xA) \
+   OP(HV_STATUS_INSUFFICIENT_MEMORY,   0xB) \
+   OP(HV_STATUS_INVALID_PARTITION_ID,  0xD) \
+   OP(HV_STATUS_INVALID_VP_INDEX,  0xE) \
+   OP(HV_STATUS_NOT_FOUND, 0x10) \
+   OP(HV_STATUS_INVALID_PORT_ID,   0x11) \
+   OP(HV_STATUS_INVALID_CONNECTION_ID, 0x12) \
+   OP(HV_STATUS_INSUFFICIENT_BUFFERS,  0x13) \
+   OP(HV_STATUS_NOT_ACKNOWLEDGED,  0x14) \
+   OP(HV_STATUS_INVALID_VP_STATE,  0x15) \
+   OP(HV_STATUS_NO_RESOURCES,  0x1D) \
+   OP(HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED,   0x20) \
+   OP(HV_STATUS_INVALID_LP_INDEX,  0x41) \
+   OP(HV_STATUS_INVALID_REGISTER_VALUE,0x50) \
+   OP(HV_STATUS_CALL_PENDING,  0x79)
+
+#define __HV_MAKE_HV_STATUS_ENUM(NAME, VAL) NAME = (VAL),
+#define __HV_MAKE_HV_STATUS_CASE(NAME, VAL) case (NAME): return (#NAME);
+
+enum hv_status {
+   __HV_STATUS_DEF(__HV_MAKE_HV_STATUS_ENUM)
+};
+
+/* TODO not in hv headers */
+#define HV_LINUX_VENDOR_ID  0x8100
+#define HV_HYP_PAGE_SHIFT  12
+#define HV_HYP_PAGE_SIZE   BIT(HV_HYP_PAGE_SHIFT)
+#define HV_HYP

Re: [PATCH v3 15/15] Drivers: hv: Add modules to expose /dev/mshv to VMMs running on Hyper-V

2023-09-25 Thread Nuno Das Neves

Resend in plain text instead of HTML - oops!

On 9/23/2023 12:58 AM, Greg KH wrote:

On Fri, Sep 22, 2023 at 11:38:35AM -0700, Nuno Das Neves wrote:

+static int mshv_vtl_get_vsm_regs(void)
+{
+   struct hv_register_assoc registers[2];
+   union hv_input_vtl input_vtl;
+   int ret, count = 2;
+
+   input_vtl.as_uint8 = 0;
+   registers[0].name = HV_REGISTER_VSM_CODE_PAGE_OFFSETS;
+   registers[1].name = HV_REGISTER_VSM_CAPABILITIES;
+
+   ret = hv_call_get_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
+  count, input_vtl, registers);
+   if (ret)
+   return ret;
+
+   mshv_vsm_page_offsets.as_uint64 = registers[0].value.reg64;
+   mshv_vsm_capabilities.as_uint64 = registers[1].value.reg64;
+
+   pr_debug("%s: VSM code page offsets: %#016llx\n", __func__,
+mshv_vsm_page_offsets.as_uint64);
+   pr_info("%s: VSM capabilities: %#016llx\n", __func__,
+   mshv_vsm_capabilities.as_uint64);


When drivers are working properly, they are quiet.  This is very noisy
and probably is leaking memory addresses to userspace?



I will remove these, thanks.


Also, there is NEVER a need for __func__ in a pr_debug() line, it has
that for you automatically.



Thank you, I didn't know this.


Also, drivers should never call pr_*() calls, always use the proper
dev_*() calls instead.



We only use struct device in one place in this driver, I think that is 
the only place it makes sense to use dev_*() over pr_*() calls.




+
+   return ret;
+}
+
+static int mshv_vtl_configure_vsm_partition(void)
+{
+   union hv_register_vsm_partition_config config;
+   struct hv_register_assoc reg_assoc;
+   union hv_input_vtl input_vtl;
+
+   config.as_u64 = 0;
+   config.default_vtl_protection_mask = HV_MAP_GPA_PERMISSIONS_MASK;
+   config.enable_vtl_protection = 1;
+   config.zero_memory_on_reset = 1;
+   config.intercept_vp_startup = 1;
+   config.intercept_cpuid_unimplemented = 1;
+
+   if (mshv_vsm_capabilities.intercept_page_available) {
+   pr_debug("%s: using intercept page", __func__);


Again, __func__ is not needed, you are providing it twice here for no
real reason except to waste storage space :)



Thanks, I will review all the uses of pr_debug().


+   config.intercept_page = 1;
+   }
+
+   reg_assoc.name = HV_REGISTER_VSM_PARTITION_CONFIG;
+   reg_assoc.value.reg64 = config.as_u64;
+   input_vtl.as_uint8 = 0;
+
+   return hv_call_set_vp_registers(HV_VP_INDEX_SELF, HV_PARTITION_ID_SELF,
+  1, input_vtl, ®_assoc);



None of this needs to be unwound if initialization fails later on?



I think unwinding this is not needed, not 100% sure.
Saurabh, can you comment?

Thanks,
Nuno


thanks,

greg k-h





Re: [PATCH v3 15/15] Drivers: hv: Add modules to expose /dev/mshv to VMMs running on Hyper-V

2023-09-26 Thread Nuno Das Neves

On 9/26/2023 1:03 AM, Greg KH wrote:

On Tue, Sep 26, 2023 at 07:00:51AM +, Wei Liu wrote:

On Tue, Sep 26, 2023 at 08:31:03AM +0200, Greg KH wrote:

On Tue, Sep 26, 2023 at 05:54:34AM +, Wei Liu wrote:

On Tue, Sep 26, 2023 at 06:52:46AM +0200, Greg KH wrote:

On Mon, Sep 25, 2023 at 05:07:24PM -0700, Nuno Das Neves wrote:

On 9/23/2023 12:58 AM, Greg KH wrote:

Also, drivers should never call pr_*() calls, always use the proper
dev_*() calls instead.



We only use struct device in one place in this driver, I think that is the
only place it makes sense to use dev_*() over pr_*() calls.


Then the driver needs to be fixed to use struct device properly so that
you do have access to it when you want to print messages.  That's a
valid reason to pass around your device structure when needed.




What is the tangible benefit of using dev_*() over pr_*()? As I said,
our use of struct device is very limited compared to all the places we
may need to log errors.

pr_*() is used by many, many drivers; it seems to be the norm. We can
certainly add a pr_fmt to improve the logging.


Greg, ACRN and Nitro drivers do not pass around the device structure.
Instead, they rely on a global struct device. We can follow the same.


A single global struct device is wrong, please don't do that.

Don't copy bad design patterns from other drivers, be better :)



What makes it a bad pattern? It seems to be well-established, and is
also used by KVM which this driver is loosely modeled after:
https://elixir.bootlin.com/linux/v6.5.5/source/virt/kvm/kvm_main.c#L5128



If we're working with real devices like network cards or graphics cards
I would agree -- it is easy to imagine that we have several cards of the
same model in the system -- but in real world there won't be two
hypervisor instances running on the same hardware.

We can stash the struct device inside some private data fields, but that
doesn't change the fact that we're still having one instance of the
structure. Is this what you want? Or do you have something else in mind?


You have a real device, it's how userspace interacts with your
subsystem.  Please use that, it is dynamically created and handled and
is the correct representation here.



Are you referring to the struct device we get from calling
misc_register? If not, please be more specific.

How would you suggest we get a reference to that device via e.g. open()
or ioctl() without keeping a global reference to it?


Thanks,
Nuno



Re: [PATCH v3 15/15] Drivers: hv: Add modules to expose /dev/mshv to VMMs running on Hyper-V

2023-09-27 Thread Nuno Das Neves

On 9/27/2023 1:33 AM, Greg KH wrote:

On Wed, Sep 27, 2023 at 08:04:42AM +, Wei Liu wrote:

So, the driver is supposed to stash a pointer to struct device in
private_data. That's what I alluded to in my previous reply. The core
driver framework or the VFS doesn't give us a reference to struct
device. We have to do it ourselves.


Please read Linux Device Drivers, 3rd edition, chapter 3, for how to do
this properly.  The book is free online.



Thanks, the issue that confused us was how to get the miscdevice.
I eventually found the answer in the misc_register() documentation:

"By default, an open() syscall to the device sets file->private_data to
point to the structure."

That's good - when we create a guest, we will have the miscdevice
in private_data already. Then we can just put it in our per-guest data
structure. That will let us retrieve the device in the other ioctls so 
we can call dev_*().


Thanks,
Nuno



[PATCH v4 00/15] Introduce /dev/mshv drivers

2023-09-29 Thread Nuno Das Neves
 cpuid() to get all 4 registers instead of 4 calls
* Change hv_proximity_domain_info from union to struct for clarity
Changes since v1:
* Clean up formatting, capitalization in commit messages
* Add detail to commit message for patch 15
* Remove errant lines in Makefile and Kconfig in patch 15
* Move a reference to CONFIG_MSHV_VTL from patch 9 to 15

Nuno Das Neves (15):
  hyperv-tlfs: Change shared HV_REGISTER_* defines to HV_MSR_*
  mshyperv: Introduce hv_get_hypervisor_version function
  mshyperv: Introduce numa_node_to_proximity_domain_info
  asm-generic/mshyperv: Introduce hv_recommend_using_aeoi()
  hyperv: Move hv_connection_id to hyperv-tlfs
  hyperv-tlfs: Introduce hv_status_to_string and hv_status_to_errno
  Drivers: hv: Move hv_call_deposit_pages and hv_call_create_vp to
common code
  Drivers: hv: Introduce per-cpu event ring tail
  Drivers: hv: Introduce hv_output_arg_exists in hv_common.c
  x86: hyperv: Add mshv_handler irq handler and setup function
  Drivers: hv: export vmbus_isr, hv_context and hv_post_message
  Documentation: Reserve ioctl number for mshv driver
  uapi: hyperv: Add mshv driver headers defining hypervisor ABIs
  asm-generic: hyperv: Use new Hyper-V headers conditionally.
  Drivers: hv: Add modules to expose /dev/mshv to VMMs running on
Hyper-V

 .../userspace-api/ioctl/ioctl-number.rst  |2 +
 arch/arm64/hyperv/mshyperv.c  |   23 +-
 arch/arm64/include/asm/hyperv-tlfs.h  |   25 +
 arch/arm64/include/asm/mshyperv.h |2 +-
 arch/x86/hyperv/hv_init.c |2 +-
 arch/x86/hyperv/hv_proc.c |  166 +-
 arch/x86/include/asm/hyperv-tlfs.h|  137 +-
 arch/x86/include/asm/mshyperv.h   |   12 +-
 arch/x86/kernel/cpu/mshyperv.c|   67 +-
 drivers/acpi/numa/srat.c  |1 +
 drivers/clocksource/hyperv_timer.c|   24 +-
 drivers/hv/Kconfig|   49 +
 drivers/hv/Makefile   |   20 +
 drivers/hv/hv.c   |   50 +-
 drivers/hv/hv_call.c  |  103 +
 drivers/hv/hv_common.c|  223 +-
 drivers/hv/hyperv_vmbus.h |2 +-
 drivers/hv/mshv.h |  125 ++
 drivers/hv/mshv_eventfd.c |  761 +++
 drivers/hv/mshv_eventfd.h |   80 +
 drivers/hv/mshv_main.c|  196 ++
 drivers/hv/mshv_msi.c |  129 ++
 drivers/hv/mshv_portid_table.c|   84 +
 drivers/hv/mshv_root.h|  232 ++
 drivers/hv/mshv_root_hv_call.c|  911 
 drivers/hv/mshv_root_main.c   | 1911 +
 drivers/hv/mshv_synic.c   |  688 ++
 drivers/hv/mshv_vtl.h |   52 +
 drivers/hv/mshv_vtl_main.c| 1522 +
 drivers/hv/vmbus_drv.c|3 +-
 drivers/hv/xfer_to_guest.c|   28 +
 include/asm-generic/hyperv-defs.h |   26 +
 include/asm-generic/hyperv-tlfs.h |   93 +-
 include/asm-generic/mshyperv.h|   73 +-
 include/linux/hyperv.h|   11 +-
 include/uapi/hyperv/hvgdk.h   |   41 +
 include/uapi/hyperv/hvgdk_mini.h  | 1076 ++
 include/uapi/hyperv/hvhdk.h   | 1342 
 include/uapi/hyperv/hvhdk_mini.h  |  160 ++
 include/uapi/linux/mshv.h |  306 +++
 40 files changed, 10394 insertions(+), 364 deletions(-)
 create mode 100644 drivers/hv/hv_call.c
 create mode 100644 drivers/hv/mshv.h
 create mode 100644 drivers/hv/mshv_eventfd.c
 create mode 100644 drivers/hv/mshv_eventfd.h
 create mode 100644 drivers/hv/mshv_main.c
 create mode 100644 drivers/hv/mshv_msi.c
 create mode 100644 drivers/hv/mshv_portid_table.c
 create mode 100644 drivers/hv/mshv_root.h
 create mode 100644 drivers/hv/mshv_root_hv_call.c
 create mode 100644 drivers/hv/mshv_root_main.c
 create mode 100644 drivers/hv/mshv_synic.c
 create mode 100644 drivers/hv/mshv_vtl.h
 create mode 100644 drivers/hv/mshv_vtl_main.c
 create mode 100644 drivers/hv/xfer_to_guest.c
 create mode 100644 include/asm-generic/hyperv-defs.h
 create mode 100644 include/uapi/hyperv/hvgdk.h
 create mode 100644 include/uapi/hyperv/hvgdk_mini.h
 create mode 100644 include/uapi/hyperv/hvhdk.h
 create mode 100644 include/uapi/hyperv/hvhdk_mini.h
 create mode 100644 include/uapi/linux/mshv.h

-- 
2.25.1




[PATCH v4 05/15] hyperv: Move hv_connection_id to hyperv-tlfs

2023-09-29 Thread Nuno Das Neves
The definition conflicts with one added in hvgdk.h as part of the mshv
driver so must be moved to hyperv-tlfs.h.

This structure should be in hyperv-tlfs.h anyway, since it is part of
the TLFS document.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 include/asm-generic/hyperv-tlfs.h | 9 +
 include/linux/hyperv.h| 9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index a6dffb346bf2..1316584983c1 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -842,4 +842,13 @@ struct hv_mmio_write_input {
u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
 } __packed;
 
+/* Define connection identifier type. */
+union hv_connection_id {
+   u32 asu32;
+   struct {
+   u32 id:24;
+   u32 reserved:8;
+   } u;
+};
+
 #endif
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 2b00faf98017..4d5a5e39d76c 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -748,15 +748,6 @@ struct vmbus_close_msg {
struct vmbus_channel_close_channel msg;
 };
 
-/* Define connection identifier type. */
-union hv_connection_id {
-   u32 asu32;
-   struct {
-   u32 id:24;
-   u32 reserved:8;
-   } u;
-};
-
 enum vmbus_device_type {
HV_IDE = 0,
HV_SCSI,
-- 
2.25.1




[PATCH v4 03/15] mshyperv: Introduce numa_node_to_proximity_domain_info

2023-09-29 Thread Nuno Das Neves
Factor out logic for converting numa node to proximity domain info into
a helper function, and export it.

Change hv_proximity_domain_info to a struct to simplify the code.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 arch/x86/hyperv/hv_proc.c |  8 ++--
 drivers/acpi/numa/srat.c  |  1 +
 include/asm-generic/hyperv-tlfs.h | 14 +-
 include/asm-generic/mshyperv.h| 15 +++
 4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 68a0843d4750..5ba5ca1b2089 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -121,7 +121,6 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
u64 status;
unsigned long flags;
int ret = HV_STATUS_SUCCESS;
-   int pxm = node_to_pxm(node);
 
/*
 * When adding a logical processor, the hypervisor may return
@@ -137,11 +136,8 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
 
input->lp_index = lp_index;
input->apic_id = apic_id;
-   input->flags = 0;
-   input->proximity_domain_info.domain_id = pxm;
-   input->proximity_domain_info.flags.reserved = 0;
-   input->proximity_domain_info.flags.proximity_info_valid = 1;
-   input->proximity_domain_info.flags.proximity_preferred = 1;
+   input->proximity_domain_info =
+   numa_node_to_proximity_domain_info(node);
status = hv_do_hypercall(HVCALL_ADD_LOGICAL_PROCESSOR,
 input, output);
local_irq_restore(flags);
diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
index 1f4fc5f8a819..0cf9f0574495 100644
--- a/drivers/acpi/numa/srat.c
+++ b/drivers/acpi/numa/srat.c
@@ -48,6 +48,7 @@ int node_to_pxm(int node)
return PXM_INVAL;
return node_to_pxm_map[node];
 }
+EXPORT_SYMBOL(node_to_pxm);
 
 static void __acpi_map_pxm_to_node(int pxm, int node)
 {
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index f63b3704d89e..a6dffb346bf2 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -512,13 +512,9 @@ struct hv_proximity_domain_flags {
u32 proximity_info_valid : 1;
 } __packed;
 
-/* Not a union in windows but useful for zeroing */
-union hv_proximity_domain_info {
-   struct {
-   u32 domain_id;
-   struct hv_proximity_domain_flags flags;
-   };
-   u64 as_uint64;
+struct hv_proximity_domain_info {
+   u32 domain_id;
+   struct hv_proximity_domain_flags flags;
 } __packed;
 
 struct hv_lp_startup_status {
@@ -535,7 +531,7 @@ struct hv_lp_startup_status {
 struct hv_add_logical_processor_in {
u32 lp_index;
u32 apic_id;
-   union hv_proximity_domain_info proximity_domain_info;
+   struct hv_proximity_domain_info proximity_domain_info;
u64 flags;
 } __packed;
 
@@ -560,7 +556,7 @@ struct hv_create_vp {
u8 padding[3];
u8 subnode_type;
u64 subnode_id;
-   union hv_proximity_domain_info proximity_domain_info;
+   struct hv_proximity_domain_info proximity_domain_info;
u64 flags;
 } __packed;
 
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 9f2c06c9d5d1..8cc7b0e316d7 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,20 @@
 
 #define VTPM_BASE_ADDRESS 0xfed4
 
+static inline struct hv_proximity_domain_info
+numa_node_to_proximity_domain_info(int node)
+{
+   struct hv_proximity_domain_info proximity_domain_info = {};
+
+   if (node != NUMA_NO_NODE) {
+   proximity_domain_info.domain_id = node_to_pxm(node);
+   proximity_domain_info.flags.proximity_info_valid = 1;
+   proximity_domain_info.flags.proximity_preferred = 1;
+   }
+
+   return proximity_domain_info;
+}
+
 struct ms_hyperv_info {
u32 features;
u32 priv_high;
-- 
2.25.1




[PATCH v4 08/15] Drivers: hv: Introduce per-cpu event ring tail

2023-09-29 Thread Nuno Das Neves
Add a pointer hv_synic_eventring_tail to track the tail pointer for the
SynIC event ring buffer for each SINT.

This will be used by the mshv driver, but must be tracked independently
since the driver module could be removed and re-inserted.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 drivers/hv/hv_common.c | 28 ++--
 include/asm-generic/mshyperv.h |  2 ++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 9d9f6f90f99e..39077841d518 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -62,6 +62,16 @@ static void hv_kmsg_dump_unregister(void);
 
 static struct ctl_table_header *hv_ctl_table_hdr;
 
+/*
+ * Per-cpu array holding the tail pointer for the SynIC event ring buffer
+ * for each SINT.
+ *
+ * We cannot maintain this in mshv driver because the tail pointer should
+ * persist even if the mshv driver is unloaded.
+ */
+u8 __percpu **hv_synic_eventring_tail;
+EXPORT_SYMBOL_GPL(hv_synic_eventring_tail);
+
 /*
  * Hyper-V specific initialization and shutdown code that is
  * common across all architectures.  Called from architecture
@@ -84,6 +94,9 @@ void __init hv_common_free(void)
 
free_percpu(hyperv_pcpu_input_arg);
hyperv_pcpu_input_arg = NULL;
+
+   free_percpu(hv_synic_eventring_tail);
+   hv_synic_eventring_tail = NULL;
 }
 
 /*
@@ -333,6 +346,8 @@ int __init hv_common_init(void)
if (hv_root_partition) {
hyperv_pcpu_output_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_output_arg);
+   hv_synic_eventring_tail = alloc_percpu(u8 *);
+   BUG_ON(hv_synic_eventring_tail == NULL);
}
 
hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index),
@@ -357,6 +372,7 @@ int __init hv_common_init(void)
 int hv_common_cpu_init(unsigned int cpu)
 {
void **inputarg, **outputarg;
+   u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
int pgcount = hv_root_partition ? 2 : 1;
@@ -369,8 +385,8 @@ int hv_common_cpu_init(unsigned int cpu)
inputarg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
 
/*
-* hyperv_pcpu_input_arg and hyperv_pcpu_output_arg memory is already
-* allocated if this CPU was previously online and then taken offline
+* The per-cpu memory is already allocated if this CPU was previously
+* online and then taken offline
 */
if (!*inputarg) {
mem = kmalloc(pgcount * HV_HYP_PAGE_SIZE, flags);
@@ -380,6 +396,14 @@ int hv_common_cpu_init(unsigned int cpu)
if (hv_root_partition) {
outputarg = (void 
**)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
+   synic_eventring_tail = (u8 
**)this_cpu_ptr(hv_synic_eventring_tail);
+   *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, 
sizeof(u8),
+   flags);
+
+   if (unlikely(!*synic_eventring_tail)) {
+   kfree(mem);
+   return -ENOMEM;
+   }
}
 
if (!ms_hyperv.paravisor_present &&
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 4f2bb6099063..4e49fd662b2b 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -77,6 +77,8 @@ extern bool hv_nested;
 extern void * __percpu *hyperv_pcpu_input_arg;
 extern void * __percpu *hyperv_pcpu_output_arg;
 
+extern u8 __percpu **hv_synic_eventring_tail;
+
 extern u64 hv_do_hypercall(u64 control, void *inputaddr, void *outputaddr);
 extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
 bool hv_isolation_type_snp(void);
-- 
2.25.1




[PATCH v4 11/15] Drivers: hv: export vmbus_isr, hv_context and hv_post_message

2023-09-29 Thread Nuno Das Neves
These will be used by the mshv_vtl driver.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 drivers/hv/hv.c   | 2 ++
 drivers/hv/hyperv_vmbus.h | 1 +
 drivers/hv/vmbus_drv.c| 3 ++-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index d7869205dcbe..c60a4fb55f3c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -25,6 +25,7 @@
 
 /* The one and only */
 struct hv_context hv_context;
+EXPORT_SYMBOL_GPL(hv_context);
 
 /*
  * hv_init - Main initialization routine.
@@ -93,6 +94,7 @@ int hv_post_message(union hv_connection_id connection_id,
 
return hv_result(status);
 }
+EXPORT_SYMBOL_GPL(hv_post_message);
 
 int hv_synic_alloc(void)
 {
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index f6b1e710f805..09792eb4ffed 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -32,6 +32,7 @@
  */
 #define HV_UTIL_NEGO_TIMEOUT 55
 
+void vmbus_isr(void);
 
 /* Definitions for the monitored notification facility */
 union hv_monitor_trigger_group {
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index edbb38f6956b..6d27597af8bf 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1286,7 +1286,7 @@ static void vmbus_chan_sched(struct hv_per_cpu_context 
*hv_cpu)
}
 }
 
-static void vmbus_isr(void)
+void vmbus_isr(void)
 {
struct hv_per_cpu_context *hv_cpu
= this_cpu_ptr(hv_context.cpu_context);
@@ -1309,6 +1309,7 @@ static void vmbus_isr(void)
 
add_interrupt_randomness(vmbus_interrupt);
 }
+EXPORT_SYMBOL_GPL(vmbus_isr);
 
 static irqreturn_t vmbus_percpu_isr(int irq, void *dev_id)
 {
-- 
2.25.1




[PATCH v4 04/15] asm-generic/mshyperv: Introduce hv_recommend_using_aeoi()

2023-09-29 Thread Nuno Das Neves
Factor out logic for determining if we should set the auto eoi flag in SINT
register.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 drivers/hv/hv.c| 12 +---
 include/asm-generic/mshyperv.h | 13 +
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 5ea104c61fa7..d7869205dcbe 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -315,17 +315,7 @@ void hv_synic_enable_regs(unsigned int cpu)
 
shared_sint.vector = vmbus_interrupt;
shared_sint.masked = false;
-
-   /*
-* On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
-* it doesn't provide a recommendation flag and AEOI must be disabled.
-*/
-#ifdef HV_DEPRECATING_AEOI_RECOMMENDED
-   shared_sint.auto_eoi =
-   !(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED);
-#else
-   shared_sint.auto_eoi = 0;
-#endif
+   shared_sint.auto_eoi = hv_recommend_using_aeoi();
hv_set_register(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT,
shared_sint.as_uint64);
 
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8cc7b0e316d7..3e715aa114da 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -82,6 +82,19 @@ extern u64 hv_do_fast_hypercall8(u16 control, u64 input8);
 bool hv_isolation_type_snp(void);
 bool hv_isolation_type_tdx(void);
 
+/*
+ * On architectures where Hyper-V doesn't support AEOI (e.g., ARM64),
+ * it doesn't provide a recommendation flag and AEOI must be disabled.
+ */
+static inline bool hv_recommend_using_aeoi(void)
+{
+#ifdef HV_DEPRECATING_AEOI_RECOMMENDED
+   return !(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED);
+#else
+   return false;
+#endif
+}
+
 /* Helper functions that provide a consistent pattern for checking Hyper-V 
hypercall status. */
 static inline int hv_result(u64 status)
 {
-- 
2.25.1




[PATCH v4 07/15] Drivers: hv: Move hv_call_deposit_pages and hv_call_create_vp to common code

2023-09-29 Thread Nuno Das Neves
These hypercalls are not arch-specific. Move them to common code.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/x86/hyperv/hv_proc.c   | 152 
 arch/x86/include/asm/mshyperv.h |   1 -
 drivers/hv/hv_common.c  | 147 ++
 include/asm-generic/mshyperv.h  |   2 +
 4 files changed, 149 insertions(+), 153 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index ed80da64649e..0a35cb865427 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -14,106 +13,6 @@
 
 #include 
 
-/*
- * See struct hv_deposit_memory. The first u64 is partition ID, the rest
- * are GPAs.
- */
-#define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1)
-
-/* Deposits exact number of pages. Must be called with interrupts enabled.  */
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
-{
-   struct page **pages, *page;
-   int *counts;
-   int num_allocations;
-   int i, j, page_count;
-   int order;
-   u64 status;
-   int ret;
-   u64 base_pfn;
-   struct hv_deposit_memory *input_page;
-   unsigned long flags;
-
-   if (num_pages > HV_DEPOSIT_MAX)
-   return -E2BIG;
-   if (!num_pages)
-   return 0;
-
-   /* One buffer for page pointers and counts */
-   page = alloc_page(GFP_KERNEL);
-   if (!page)
-   return -ENOMEM;
-   pages = page_address(page);
-
-   counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
-   if (!counts) {
-   free_page((unsigned long)pages);
-   return -ENOMEM;
-   }
-
-   /* Allocate all the pages before disabling interrupts */
-   i = 0;
-
-   while (num_pages) {
-   /* Find highest order we can actually allocate */
-   order = 31 - __builtin_clz(num_pages);
-
-   while (1) {
-   pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
-   if (pages[i])
-   break;
-   if (!order) {
-   ret = -ENOMEM;
-   num_allocations = i;
-   goto err_free_allocations;
-   }
-   --order;
-   }
-
-   split_page(pages[i], order);
-   counts[i] = 1 << order;
-   num_pages -= counts[i];
-   i++;
-   }
-   num_allocations = i;
-
-   local_irq_save(flags);
-
-   input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-   input_page->partition_id = partition_id;
-
-   /* Populate gpa_page_list - these will fit on the input page */
-   for (i = 0, page_count = 0; i < num_allocations; ++i) {
-   base_pfn = page_to_pfn(pages[i]);
-   for (j = 0; j < counts[i]; ++j, ++page_count)
-   input_page->gpa_page_list[page_count] = base_pfn + j;
-   }
-   status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
-page_count, 0, input_page, NULL);
-   local_irq_restore(flags);
-   if (!hv_result_success(status)) {
-   pr_err("Failed to deposit pages: %lld\n", status);
-   ret = hv_result(status);
-   goto err_free_allocations;
-   }
-
-   ret = 0;
-   goto free_buf;
-
-err_free_allocations:
-   for (i = 0; i < num_allocations; ++i) {
-   base_pfn = page_to_pfn(pages[i]);
-   for (j = 0; j < counts[i]; ++j)
-   __free_page(pfn_to_page(base_pfn + j));
-   }
-
-free_buf:
-   free_page((unsigned long)pages);
-   kfree(counts);
-   return ret;
-}
-
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 {
struct hv_add_logical_processor_in *input;
@@ -156,54 +55,3 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
return ret;
 }
 
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
-{
-   struct hv_create_vp *input;
-   u64 status;
-   unsigned long irq_flags;
-   int ret = HV_STATUS_SUCCESS;
-   int pxm = node_to_pxm(node);
-
-   /* Root VPs don't seem to need pages deposited */
-   if (partition_id != hv_current_partition_id) {
-   /* The value 90 is empirically determined. It may change. */
-   ret = hv_call_deposit_pages(node, partition_id, 90);
-   if (ret)
-   return ret;
-   }
-
-   do {
-   local_irq_save(irq_flags);
-
-   input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-   input->partition_id = partition_id;
-   input->vp_index = vp_index;
-   input->

[PATCH v4 01/15] hyperv-tlfs: Change shared HV_REGISTER_* defines to HV_MSR_*

2023-09-29 Thread Nuno Das Neves
In x86 hyperv-tlfs, HV_REGISTER_ prefix is used to indicate MSRs
accessed via rdmsrl/wrmsrl. But in ARM64, HV_REGISTER_ instead indicates
VP registers accessed via get/set vp registers hypercall.

This is due to HV_REGISTER_* names being used by hv_set/get_register,
with the arch-specific version delegating to the appropriate mechanism.

The problem is, using prefix HV_REGISTER_ for MSRs will conflict with
VP registers when they are introduced for x86 in future.

This patch solves the issue by:

1. Defining all the x86 MSRs with a consistent prefix: HV_X64_MSR_.
   This is so HV_REGISTER_ can be reserved for VP registers.

2. Change the non-arch-specific alias used by hv_set/get_register to
   HV_MSR_. This is also happens to be the same name Hyper-V uses for this
   purpose.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 arch/arm64/include/asm/hyperv-tlfs.h |  25 +
 arch/x86/include/asm/hyperv-tlfs.h   | 137 +--
 arch/x86/include/asm/mshyperv.h  |   8 +-
 arch/x86/kernel/cpu/mshyperv.c   |  22 ++---
 drivers/clocksource/hyperv_timer.c   |  24 ++---
 drivers/hv/hv.c  |  36 +++
 drivers/hv/hv_common.c   |  18 ++--
 include/asm-generic/mshyperv.h   |   2 +-
 8 files changed, 148 insertions(+), 124 deletions(-)

diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
index bc6c7ac934a1..a6e852c2fc3a 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -64,6 +64,31 @@
 #define HV_REGISTER_STIMER0_CONFIG 0x000B
 #define HV_REGISTER_STIMER0_COUNT  0x000B0001
 
+/*
+ * To support non-arch-specific code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
+ */
+#define HV_MSR_VP_INDEX(HV_REGISTER_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT  (HV_REGISTER_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TS(HV_REGISTER_REFERENCE_TSC)
+
+#define HV_MSR_STIMER0_CONFIG  (HV_REGISTER_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT   (HV_REGISTER_STIMER0_COUNT)
+
+#define HV_MSR_SCONTROL(HV_REGISTER_SCONTROL)
+#define HV_MSR_SIEFP   (HV_REGISTER_SIEFP)
+#define HV_MSR_SIMP(HV_REGISTER_SIMP)
+#define HV_MSR_EOM (HV_REGISTER_EOM)
+#define HV_MSR_SINT0   (HV_REGISTER_SINT0)
+
+#define HV_MSR_CRASH_P0(HV_REGISTER_CRASH_P0)
+#define HV_MSR_CRASH_P1(HV_REGISTER_CRASH_P1)
+#define HV_MSR_CRASH_P2(HV_REGISTER_CRASH_P2)
+#define HV_MSR_CRASH_P3(HV_REGISTER_CRASH_P3)
+#define HV_MSR_CRASH_P4(HV_REGISTER_CRASH_P4)
+#define HV_MSR_CRASH_CTL   (HV_REGISTER_CRASH_CTL)
+
 union hv_msi_entry {
u64 as_uint64[2];
struct {
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 2ff26f53cd62..058c5c8dc382 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -182,7 +182,7 @@ enum hv_isolation_type {
 #define HV_X64_MSR_HYPERCALL   0x4001
 
 /* MSR used to provide vcpu index */
-#define HV_REGISTER_VP_INDEX   0x4002
+#define HV_X64_MSR_VP_INDEX0x4002
 
 /* MSR used to reset the guest OS. */
 #define HV_X64_MSR_RESET   0x4003
@@ -191,10 +191,10 @@ enum hv_isolation_type {
 #define HV_X64_MSR_VP_RUNTIME  0x4010
 
 /* MSR used to read the per-partition time reference counter */
-#define HV_REGISTER_TIME_REF_COUNT 0x4020
+#define HV_X64_MSR_TIME_REF_COUNT  0x4020
 
 /* A partition's reference time stamp counter (TSC) page */
-#define HV_REGISTER_REFERENCE_TSC  0x4021
+#define HV_X64_MSR_REFERENCE_TSC   0x4021
 
 /* MSR used to retrieve the TSC frequency */
 #define HV_X64_MSR_TSC_FREQUENCY   0x4022
@@ -209,61 +209,61 @@ enum hv_isolation_type {
 #define HV_X64_MSR_VP_ASSIST_PAGE  0x4073
 
 /* Define synthetic interrupt controller model specific registers. */
-#define HV_REGISTER_SCONTROL   0x4080
-#define HV_REGISTER_SVERSION   0x4081
-#define HV_REGISTER_SIEFP  0x4082
-#define HV_REGISTER_SIMP   0x4083
-#define HV_REGISTER_EOM0x4084
-#define HV_REGISTER_SINT0  0x4090
-#define HV_REGISTER_SINT1  0x4091
-#define HV_REGISTER_SINT2  0x4092
-#define HV_REGISTER_SINT3  0x4093
-#define HV_REGISTER_SINT4  0x4094
-#define HV_REGISTER_SINT5  0x4095
-#define HV_REGISTER_SINT6  0x4096
-#define HV_REGISTER_SINT7  0x4097
-#d

[PATCH v4 10/15] x86: hyperv: Add mshv_handler irq handler and setup function

2023-09-29 Thread Nuno Das Neves
This will handle SYNIC interrupts such as intercepts, doorbells, and
scheduling messages intended for the mshv driver.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
Reviewed-by: Tianyu Lan 
---
 arch/x86/kernel/cpu/mshyperv.c | 9 +
 drivers/hv/hv_common.c | 5 +
 include/asm-generic/mshyperv.h | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 9b898b65a013..06f79963add5 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -110,6 +110,7 @@ void hv_set_register(unsigned int reg, u64 value)
 }
 EXPORT_SYMBOL_GPL(hv_set_register);
 
+static void (*mshv_handler)(void);
 static void (*vmbus_handler)(void);
 static void (*hv_stimer0_handler)(void);
 static void (*hv_kexec_handler)(void);
@@ -120,6 +121,9 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
struct pt_regs *old_regs = set_irq_regs(regs);
 
inc_irq_stat(irq_hv_callback_count);
+   if (mshv_handler)
+   mshv_handler();
+
if (vmbus_handler)
vmbus_handler();
 
@@ -129,6 +133,11 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
set_irq_regs(old_regs);
 }
 
+void hv_setup_mshv_irq(void (*handler)(void))
+{
+   mshv_handler = handler;
+}
+
 void hv_setup_vmbus_handler(void (*handler)(void))
 {
vmbus_handler = handler;
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 3f6f23e4c579..6ec63502d83d 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -585,6 +585,11 @@ void __weak hv_remove_vmbus_handler(void)
 }
 EXPORT_SYMBOL_GPL(hv_remove_vmbus_handler);
 
+void __weak hv_setup_mshv_irq(void (*handler)(void))
+{
+}
+EXPORT_SYMBOL_GPL(hv_setup_mshv_irq);
+
 void __weak hv_setup_kexec_handler(void (*handler)(void))
 {
 }
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 4e49fd662b2b..d832852d0ee7 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -198,6 +198,8 @@ void hv_remove_vmbus_handler(void);
 void hv_setup_stimer0_handler(void (*handler)(void));
 void hv_remove_stimer0_handler(void);
 
+void hv_setup_mshv_irq(void (*handler)(void));
+
 void hv_setup_kexec_handler(void (*handler)(void));
 void hv_remove_kexec_handler(void);
 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
-- 
2.25.1




[PATCH v4 14/15] asm-generic: hyperv: Use new Hyper-V headers conditionally.

2023-09-29 Thread Nuno Das Neves
Add asm-generic/hyperv-defs.h. It includes hyperv-tlfs.h or hvhdk.h
depending on compile-time constant HV_HYPERV_DEFS which will be defined in
the mshv driver.

This is needed to keep unstable Hyper-V interfaces independent of
hyperv-tlfs.h. This ensures hvhdk.h replaces hyperv-tlfs.h in the mshv
driver, even via indirect includes.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/arm64/include/asm/mshyperv.h |  2 +-
 arch/x86/include/asm/mshyperv.h   |  3 +--
 drivers/hv/hyperv_vmbus.h |  1 -
 include/asm-generic/hyperv-defs.h | 26 ++
 include/asm-generic/mshyperv.h|  2 +-
 include/linux/hyperv.h|  2 +-
 6 files changed, 30 insertions(+), 6 deletions(-)
 create mode 100644 include/asm-generic/hyperv-defs.h

diff --git a/arch/arm64/include/asm/mshyperv.h 
b/arch/arm64/include/asm/mshyperv.h
index 20070a847304..8ec14caf3d4f 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -20,7 +20,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Declare calls to get and set Hyper-V VP register values on ARM64, which
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index e3768d787065..bb1b97106cd3 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -6,10 +6,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 09792eb4ffed..0e4bc18a13fa 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/include/asm-generic/hyperv-defs.h 
b/include/asm-generic/hyperv-defs.h
new file mode 100644
index ..ac6fcba35c8c
--- /dev/null
+++ b/include/asm-generic/hyperv-defs.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_HYPERV_DEFS_H
+#define _ASM_GENERIC_HYPERV_DEFS_H
+
+/*
+ * There are cases where Microsoft Hypervisor ABIs are needed which may not be
+ * stable or present in the Hyper-V TLFS document. E.g. the mshv_root driver.
+ *
+ * As these interfaces are unstable and may differ from hyperv-tlfs.h, they
+ * must be kept separate and independent.
+ *
+ * However, code from files that depend on hyperv-tlfs.h (such as mshyperv.h)
+ * is still needed, so work around the issue by conditionally including the
+ * correct definitions.
+ *
+ * Note: Since they are independent of each other, there are many definitions
+ * duplicated in both hyperv-tlfs.h and uapi/hyperv/hv*.h files.
+ */
+#ifdef HV_HYPERV_DEFS
+#include 
+#else
+#include 
+#endif
+
+#endif /* _ASM_GENERIC_HYPERV_DEFS_H */
+
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index d832852d0ee7..6bef0d59d1b7 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -25,7 +25,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define VTPM_BASE_ADDRESS 0xfed4
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 4d5a5e39d76c..722a8cf23d87 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -24,7 +24,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define MAX_PAGE_BUFFER_COUNT  32
 #define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */
-- 
2.25.1




[PATCH v4 02/15] mshyperv: Introduce hv_get_hypervisor_version function

2023-09-29 Thread Nuno Das Neves
x86_64 and arm64 implementations to get the hypervisor version
information. Store these in hv_hypervisor_version_info structure to
simplify parsing the fields.

Replace the existing parsing when printing the version numbers at boot.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/arm64/hyperv/mshyperv.c  | 23 +---
 arch/x86/kernel/cpu/mshyperv.c| 36 +++
 include/asm-generic/hyperv-tlfs.h | 23 
 include/asm-generic/mshyperv.h|  2 ++
 4 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index f1b8a04ee9f2..53bdd3bc81ac 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,10 +19,19 @@
 
 static bool hyperv_initialized;
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
+(struct hv_get_vp_registers_output *)info);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
+
 static int __init hyperv_init(void)
 {
-   struct hv_get_vp_registers_output   result;
-   u32 a, b, c, d;
+   struct hv_get_vp_registers_output result;
+   union hv_hypervisor_version_info version;
u64 guest_id;
int ret;
 
@@ -55,13 +64,11 @@ static int __init hyperv_init(void)
ms_hyperv.misc_features);
 
/* Get information about the Hyper-V host version */
-   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
-   a = result.as32.a;
-   b = result.as32.b;
-   c = result.as32.c;
-   d = result.as32.d;
+   hv_get_hypervisor_version(&version);
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   b >> 16, b & 0x, a, d & 0xFF, c, d >> 24);
+   version.major_version, version.minor_version,
+   version.build_number, version.service_number,
+   version.service_pack, version.service_branch);
 
ret = hv_common_init();
if (ret)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index d85a8e2a10c9..9b898b65a013 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -347,13 +347,26 @@ static void __init reduced_hw_init(void)
x86_init.irqs.pre_vector_init   = x86_init_noop;
 }
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   unsigned int hv_max_functions;
+
+   hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
+   if (hv_max_functions < HYPERV_CPUID_VERSION) {
+   pr_err("%s: Could not detect Hyper-V version\n", __func__);
+   return -ENODEV;
+   }
+
+   cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, 
&info->edx);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
+
 static void __init ms_hyperv_init_platform(void)
 {
int hv_max_functions_eax;
-   int hv_host_info_eax;
-   int hv_host_info_ebx;
-   int hv_host_info_ecx;
-   int hv_host_info_edx;
+   union hv_hypervisor_version_info version;
 
 #ifdef CONFIG_PARAVIRT
pv_info.name = "Hyper-V";
@@ -407,16 +420,11 @@ static void __init ms_hyperv_init_platform(void)
/*
 * Extract host information.
 */
-   if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
-   hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
-   hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
-   hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
-   hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
-
-   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   hv_host_info_ebx >> 16, hv_host_info_ebx & 0x,
-   hv_host_info_eax, hv_host_info_edx & 0xFF,
-   hv_host_info_ecx, hv_host_info_edx >> 24);
+   if (hv_get_hypervisor_version(&version) == 0) {
+   pr_info("Hyper-V Host Build:%d-%d.%d-%d-%d.%d\n",
+   version.build_number, version.major_version,
+   version.minor_version, version.service_pack,
+   version.service_branch, version.service_number);
}
 
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index fdac4a1714ec..f63b3704d89e 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -787,6 +787,29 @@ struct hv_input_unmap_device_interrupt {
 #define HV_SOURCE_SHADOW_NONE   0x0
 #define HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE   0x1
 
+/*
+ * Version info reported by hypervisor
+ */
+union hv_hype

[PATCH v4 12/15] Documentation: Reserve ioctl number for mshv driver

2023-09-29 Thread Nuno Das Neves
Signed-off-by: Nuno Das Neves 
Acked-by: Jonathan Corbet 
Acked-by: Wei Liu 
---
 Documentation/userspace-api/ioctl/ioctl-number.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst 
b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 4ea5b837399a..71e6d23070ca 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -355,6 +355,8 @@ Code  Seq#Include File  
 Comments
 0xB6  alllinux/fpga-dfl.h
 0xB7  alluapi/linux/remoteproc_cdev.h
<mailto:linux-remotep...@vger.kernel.org>
 0xB7  alluapi/linux/nsfs.h   
<mailto:Andrei Vagin >
+0xB8  alluapi/linux/mshv.h   Microsoft 
Hypervisor VM management APIs
+ 
<mailto:linux-hyperv@vger.kernel.org>
 0xC0  00-0F  linux/usb/iowarrior.h
 0xCA  00-0F  uapi/misc/cxl.h
 0xCA  10-2F  uapi/misc/ocxl.h
-- 
2.25.1




[PATCH v4 09/15] Drivers: hv: Introduce hv_output_arg_exists in hv_common.c

2023-09-29 Thread Nuno Das Neves
This is a more flexible approach for determining whether to allocate the
output page.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 drivers/hv/hv_common.c | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 39077841d518..3f6f23e4c579 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -58,6 +58,14 @@ EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
 void * __percpu *hyperv_pcpu_output_arg;
 EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);
 
+/*
+ * Determine whether output arg is needed
+ */
+static inline bool hv_output_arg_exists(void)
+{
+   return hv_root_partition ? true : false;
+}
+
 static void hv_kmsg_dump_unregister(void);
 
 static struct ctl_table_header *hv_ctl_table_hdr;
@@ -342,10 +350,12 @@ int __init hv_common_init(void)
hyperv_pcpu_input_arg = alloc_percpu(void  *);
BUG_ON(!hyperv_pcpu_input_arg);
 
-   /* Allocate the per-CPU state for output arg for root */
-   if (hv_root_partition) {
+   if (hv_output_arg_exists()) {
hyperv_pcpu_output_arg = alloc_percpu(void *);
BUG_ON(!hyperv_pcpu_output_arg);
+   }
+
+   if (hv_root_partition) {
hv_synic_eventring_tail = alloc_percpu(u8 *);
BUG_ON(hv_synic_eventring_tail == NULL);
}
@@ -375,7 +385,7 @@ int hv_common_cpu_init(unsigned int cpu)
u8 **synic_eventring_tail;
u64 msr_vp_index;
gfp_t flags;
-   int pgcount = hv_root_partition ? 2 : 1;
+   int pgcount = hv_output_arg_exists() ? 2 : 1;
void *mem;
int ret;
 
@@ -393,9 +403,12 @@ int hv_common_cpu_init(unsigned int cpu)
if (!mem)
return -ENOMEM;
 
-   if (hv_root_partition) {
+   if (hv_output_arg_exists()) {
outputarg = (void 
**)this_cpu_ptr(hyperv_pcpu_output_arg);
*outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
+   }
+
+   if (hv_root_partition) {
synic_eventring_tail = (u8 
**)this_cpu_ptr(hv_synic_eventring_tail);
*synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, 
sizeof(u8),
flags);
-- 
2.25.1




[PATCH v4 06/15] hyperv-tlfs: Introduce hv_status_to_string and hv_status_to_errno

2023-09-29 Thread Nuno Das Neves
hv_status_to_errno translates hyperv statuses to linux error codes.
This is useful for returning something linux-friendly from a hypercall
helper function.

hv_status_to_string improves clarity of error messages.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/x86/hyperv/hv_init.c |  2 +-
 arch/x86/hyperv/hv_proc.c |  6 ++--
 include/asm-generic/hyperv-tlfs.h | 47 ++-
 include/asm-generic/mshyperv.h| 33 ++
 4 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 783ed339f341..515ca168748d 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -387,7 +387,7 @@ static void __init hv_get_partition_id(void)
status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
if (!hv_result_success(status)) {
/* No point in proceeding if this failed */
-   pr_err("Failed to get partition ID: %lld\n", status);
+   pr_err("Failed to get partition ID: %s\n", 
hv_status_to_string(status));
BUG();
}
hv_current_partition_id = output_page->partition_id;
diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 5ba5ca1b2089..ed80da64649e 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -144,9 +144,9 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
 
if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) {
if (!hv_result_success(status)) {
-   pr_err("%s: cpu %u apic ID %u, %lld\n", 
__func__,
-  lp_index, apic_id, status);
-   ret = hv_result(status);
+   pr_err("%s: cpu %u apic ID %u, %s\n", __func__,
+  lp_index, apic_id, 
hv_status_to_string(status));
+   ret = hv_status_to_errno(status);
}
break;
}
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 1316584983c1..8d76661a8c9f 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -212,19 +212,40 @@ enum HV_GENERIC_SET_FORMAT {
 HV_HYPERCALL_RSVD2_MASK)
 
 /* hypercall status code */
-#define HV_STATUS_SUCCESS  0
-#define HV_STATUS_INVALID_HYPERCALL_CODE   2
-#define HV_STATUS_INVALID_HYPERCALL_INPUT  3
-#define HV_STATUS_INVALID_ALIGNMENT4
-#define HV_STATUS_INVALID_PARAMETER5
-#define HV_STATUS_ACCESS_DENIED6
-#define HV_STATUS_OPERATION_DENIED 8
-#define HV_STATUS_INSUFFICIENT_MEMORY  11
-#define HV_STATUS_INVALID_PORT_ID  17
-#define HV_STATUS_INVALID_CONNECTION_ID18
-#define HV_STATUS_INSUFFICIENT_BUFFERS 19
-#define HV_STATUS_TIME_OUT  120
-#define HV_STATUS_VTL_ALREADY_ENABLED  134
+#define __HV_STATUS_DEF(OP) \
+   OP(HV_STATUS_SUCCESS,   0x0) \
+   OP(HV_STATUS_INVALID_HYPERCALL_CODE,0x2) \
+   OP(HV_STATUS_INVALID_HYPERCALL_INPUT,   0x3) \
+   OP(HV_STATUS_INVALID_ALIGNMENT, 0x4) \
+   OP(HV_STATUS_INVALID_PARAMETER, 0x5) \
+   OP(HV_STATUS_ACCESS_DENIED, 0x6) \
+   OP(HV_STATUS_INVALID_PARTITION_STATE,   0x7) \
+   OP(HV_STATUS_OPERATION_DENIED,  0x8) \
+   OP(HV_STATUS_UNKNOWN_PROPERTY,  0x9) \
+   OP(HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE,   0xA) \
+   OP(HV_STATUS_INSUFFICIENT_MEMORY,   0xB) \
+   OP(HV_STATUS_INVALID_PARTITION_ID,  0xD) \
+   OP(HV_STATUS_INVALID_VP_INDEX,  0xE) \
+   OP(HV_STATUS_NOT_FOUND, 0x10) \
+   OP(HV_STATUS_INVALID_PORT_ID,   0x11) \
+   OP(HV_STATUS_INVALID_CONNECTION_ID, 0x12) \
+   OP(HV_STATUS_INSUFFICIENT_BUFFERS,  0x13) \
+   OP(HV_STATUS_NOT_ACKNOWLEDGED,  0x14) \
+   OP(HV_STATUS_INVALID_VP_STATE,  0x15) \
+   OP(HV_STATUS_NO_RESOURCES,  0x1D) \
+   OP(HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED,   0x20) \
+   OP(HV_STATUS_INVALID_LP_INDEX,  0x41) \
+   OP(HV_STATUS_INVALID_REGISTER_VALUE,0x50) \
+   OP(HV_STATUS_TIME_OUT,  0x78) \
+   OP(HV_STATUS_CALL_PENDING,  0x79) \
+   OP(HV_STATUS_VTL_ALREADY_ENABLED,   0x86)
+
+#define __HV_MAKE_HV_STATUS_ENUM(NAME, VAL) NAME = (VAL),
+#define __HV_MAKE_HV_STATUS_CASE(NAME, VAL) cas

[PATCH v4 13/15] uapi: hyperv: Add mshv driver headers defining hypervisor ABIs

2023-09-29 Thread Nuno Das Neves
These must be in uapi because they will be used in the mshv ioctl API.

Version numbers for each file:
hvhdk.h 25212
hvhdk_mini.h25294
hvgdk.h 25125
hvgdk_mini.h25294

These are unstable interfaces and as such must be compiled independently
from published interfaces found in hyperv-tlfs.h.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 include/uapi/hyperv/hvgdk.h  |   41 +
 include/uapi/hyperv/hvgdk_mini.h | 1076 
 include/uapi/hyperv/hvhdk.h  | 1342 ++
 include/uapi/hyperv/hvhdk_mini.h |  160 
 4 files changed, 2619 insertions(+)
 create mode 100644 include/uapi/hyperv/hvgdk.h
 create mode 100644 include/uapi/hyperv/hvgdk_mini.h
 create mode 100644 include/uapi/hyperv/hvhdk.h
 create mode 100644 include/uapi/hyperv/hvhdk_mini.h

diff --git a/include/uapi/hyperv/hvgdk.h b/include/uapi/hyperv/hvgdk.h
new file mode 100644
index ..9bcbb7d902b2
--- /dev/null
+++ b/include/uapi/hyperv/hvgdk.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2023, Microsoft Corporation.
+ *
+ * These files (hvhdk.h, hvhdk_mini.h, hvgdk.h, hvgdk_mini.h) define APIs for
+ * communicating with the Microsoft Hypervisor.
+ *
+ * These definitions are subject to change across hypervisor versions, and as
+ * such are separate and independent from hyperv-tlfs.h.
+ *
+ * The naming of these headers reflects conventions used in the Microsoft
+ * Hypervisor.
+ */
+#ifndef _UAPI_HV_HVGDK_H
+#define _UAPI_HV_HVGDK_H
+
+#include "hvgdk_mini.h"
+
+enum hv_unimplemented_msr_action {
+   HV_UNIMPLEMENTED_MSR_ACTION_FAULT = 0,
+   HV_UNIMPLEMENTED_MSR_ACTION_IGNORE_WRITE_READ_ZERO = 1,
+   HV_UNIMPLEMENTED_MSR_ACTION_COUNT = 2,
+};
+
+/* Define connection identifier type. */
+union hv_connection_id {
+   __u32 asu32;
+   struct {
+   __u32 id:24;
+   __u32 reserved:8;
+   } __packed u;
+};
+
+struct hv_input_unmap_gpa_pages {
+   __u64 target_partition_id;
+   __u64 target_gpa_base;
+   __u32 unmap_flags;
+   __u32 padding;
+} __packed;
+
+#endif /* #ifndef _UAPI_HV_HVGDK_H */
diff --git a/include/uapi/hyperv/hvgdk_mini.h b/include/uapi/hyperv/hvgdk_mini.h
new file mode 100644
index ..f894327206c8
--- /dev/null
+++ b/include/uapi/hyperv/hvgdk_mini.h
@@ -0,0 +1,1076 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2023, Microsoft Corporation.
+ *
+ * These files (hvhdk.h, hvhdk_mini.h, hvgdk.h, hvgdk_mini.h) define APIs for
+ * communicating with the Microsoft Hypervisor.
+ *
+ * These definitions are subject to change across hypervisor versions, and as
+ * such are separate and independent from hyperv-tlfs.h.
+ *
+ * The naming of these headers reflects conventions used in the Microsoft
+ * Hypervisor.
+ */
+#ifndef _UAPI_HV_HVGDK_MINI_H
+#define _UAPI_HV_HVGDK_MINI_H
+
+struct hv_u128 {
+   __u64 low_part;
+   __u64 high_part;
+} __packed;
+
+/* hypercall status code */
+#define __HV_STATUS_DEF(OP) \
+   OP(HV_STATUS_SUCCESS,   0x0) \
+   OP(HV_STATUS_INVALID_HYPERCALL_CODE,0x2) \
+   OP(HV_STATUS_INVALID_HYPERCALL_INPUT,   0x3) \
+   OP(HV_STATUS_INVALID_ALIGNMENT, 0x4) \
+   OP(HV_STATUS_INVALID_PARAMETER, 0x5) \
+   OP(HV_STATUS_ACCESS_DENIED, 0x6) \
+   OP(HV_STATUS_INVALID_PARTITION_STATE,   0x7) \
+   OP(HV_STATUS_OPERATION_DENIED,  0x8) \
+   OP(HV_STATUS_UNKNOWN_PROPERTY,  0x9) \
+   OP(HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE,   0xA) \
+   OP(HV_STATUS_INSUFFICIENT_MEMORY,   0xB) \
+   OP(HV_STATUS_INVALID_PARTITION_ID,  0xD) \
+   OP(HV_STATUS_INVALID_VP_INDEX,  0xE) \
+   OP(HV_STATUS_NOT_FOUND, 0x10) \
+   OP(HV_STATUS_INVALID_PORT_ID,   0x11) \
+   OP(HV_STATUS_INVALID_CONNECTION_ID, 0x12) \
+   OP(HV_STATUS_INSUFFICIENT_BUFFERS,  0x13) \
+   OP(HV_STATUS_NOT_ACKNOWLEDGED,  0x14) \
+   OP(HV_STATUS_INVALID_VP_STATE,  0x15) \
+   OP(HV_STATUS_NO_RESOURCES,  0x1D) \
+   OP(HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED,   0x20) \
+   OP(HV_STATUS_INVALID_LP_INDEX,  0x41) \
+   OP(HV_STATUS_INVALID_REGISTER_VALUE,0x50) \
+   OP(HV_STATUS_CALL_PENDING,  0x79)
+
+#define __HV_MAKE_HV_STATUS_ENUM(NAME, VAL) NAME = (VAL),
+#define __HV_MAKE_HV_STATUS_CASE(NAME, VAL) case (NAME): return (#NAME);
+
+enum hv_status {
+   __HV_STATUS_DEF(__HV_MAKE_HV_STATUS_ENUM)
+};
+
+/* TODO not in hv headers */
+#define HV_LINUX_VENDOR_ID  0x8100
+#define HV_HYP_PAGE_SHIFT  12
+#define HV_HYP_PAGE_SIZE   BIT(HV_HYP_PAGE_SHIFT)
+#define HV_HYP

Re: [PATCH v4 14/15] asm-generic: hyperv: Use new Hyper-V headers conditionally.

2023-10-02 Thread Nuno Das Neves

Hi Alex,

On 10/2/2023 12:35 PM, Alex Ionescu wrote:

Hi Nuno,

I understand the requirement to have
undocumented/non-standard/non-TLFS-published information in the HDK
headers, however, the current state of this patch is that for any
other code that's not in the kernel today, or in this upcoming driver,
the hyperv-tlfs definitions are incomplete, because some *documented*
TLFS fields are only in HDK headers. Similarly, it is also impossible


If I understand correctly, you are saying there are documented
definitions (in the TLFS document), which are NOT in hyperv-tlfs.h, but
ARE in these new HDK headers, correct?

If these are needed elsewhere in the kernel, they can just be added to
hyperv-tlfs.h.


to only use the HDK headers for other use cases, because some basic
documented, standard defines only exist in hyperv-tlfs. So there is no
"logical" relationship between the two -- HDK headers are not _just_
undocumented information, but also documented information, but also
not complete documented information.


That is correct - they are meant to be independently compileable.
The new HDK headers only serve as a replacement *in our driver* when we
need some definitions like do_hypercall() etc in mshyperv.h.



Would you consider:

1) Updating hyperv-tlfs with all newly documented TLFS fields that are
in the HDK headers?


I think this can be done on an as-needed basis, as I outlined above.


OR
2) Updating the new HDK headers you're adding here to also include
previously-documented information from hyperv-tlfs? This way, someone
can include the HDK headers and get everything they need


The new HDK headers are only intended for the new mshv driver.


OR
3) Truly making hypertv-tlfs the "documented" header, and then > removing any 
duplication from HDK so that it remains the
"undocumented" header file. In this manner, one would include
hyperv-tlfs to use the stable ABI, and they would include HDK (which
would include hyperv-tlfs) to use the unstable+stable ABI.


hyperv-tlfs.h is remaining the "documented" header.

But, we can't make the HDK header depend on hyperv-tlfs.h, for 2 primary
reasons:
1. We need to put the new HDK headers in uapi so that we can use them in 
our IOCTL interface. As a result, we can't include hyperv-tlfs.h (unless 
we put it in uapi as well).
2. The HDK headers not only duplicate, but also MODIFY some structures 
in hyperv-tlfs.h. e.g., The struct is in hyperv-tlfs.h, but a particular

field or bitfield is not.

Thanks,
Nuno



Thank you for your consideration.

Best regards,
Alex Ionescu

On Fri, Sep 29, 2023 at 2:02 PM Nuno Das Neves
 wrote:


Add asm-generic/hyperv-defs.h. It includes hyperv-tlfs.h or hvhdk.h
depending on compile-time constant HV_HYPERV_DEFS which will be defined in
the mshv driver.

This is needed to keep unstable Hyper-V interfaces independent of
hyperv-tlfs.h. This ensures hvhdk.h replaces hyperv-tlfs.h in the mshv
driver, even via indirect includes.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
  arch/arm64/include/asm/mshyperv.h |  2 +-
  arch/x86/include/asm/mshyperv.h   |  3 +--
  drivers/hv/hyperv_vmbus.h |  1 -
  include/asm-generic/hyperv-defs.h | 26 ++
  include/asm-generic/mshyperv.h|  2 +-
  include/linux/hyperv.h|  2 +-
  6 files changed, 30 insertions(+), 6 deletions(-)
  create mode 100644 include/asm-generic/hyperv-defs.h

diff --git a/arch/arm64/include/asm/mshyperv.h 
b/arch/arm64/include/asm/mshyperv.h
index 20070a847304..8ec14caf3d4f 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -20,7 +20,7 @@

  #include 
  #include 
-#include 
+#include 

  /*
   * Declare calls to get and set Hyper-V VP register values on ARM64, which
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index e3768d787065..bb1b97106cd3 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -6,10 +6,9 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
-#include 
+#include 

  /*
   * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 09792eb4ffed..0e4bc18a13fa 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -15,7 +15,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 
diff --git a/include/asm-generic/hyperv-defs.h 
b/include/asm-generic/hyperv-defs.h
new file mode 100644
index ..ac6fcba35c8c
--- /dev/null
+++ b/include/asm-generic/hyperv-defs.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_HYPERV_DEFS_H
+#define _ASM_GENERIC_HYPERV_DEFS_H
+
+/*
+ * There are cases where Microsoft Hypervisor ABIs are needed which may not be
+ * stable or present in the Hyper-V TLFS document. E.g. the mshv_root driver.
+ *
+ * As these interfaces are unstable an

Re: [PATCH v4 13/15] uapi: hyperv: Add mshv driver headers defining hypervisor ABIs

2023-10-03 Thread Nuno Das Neves

On 9/30/2023 11:19 PM, Greg KH wrote:

On Sat, Sep 30, 2023 at 10:01:58PM +, Wei Liu wrote:

On Sat, Sep 30, 2023 at 08:09:19AM +0200, Greg KH wrote:

On Fri, Sep 29, 2023 at 11:01:39AM -0700, Nuno Das Neves wrote:

+/* Define connection identifier type. */
+union hv_connection_id {
+   __u32 asu32;
+   struct {
+   __u32 id:24;
+   __u32 reserved:8;
+   } __packed u;


bitfields will not work properly in uapi .h files, please never do that.


Can you clarify a bit more why it wouldn't work? Endianess? Alignment?


Yes to both.

Did you all read the documentation for how to write a kernel api?  If
not, please do so.  I think it mentions bitfields, but it not, it really
should as of course, this will not work properly with different endian
systems or many compilers.


Yes, in https://docs.kernel.org/driver-api/ioctl.html it says that it is
"better to avoid" bitfields.

Unfortunately bitfields are used in the definition of the hypervisor
ABI. We import these definitions directly from the hypervisor code.

In practice the hypervisor, linux, and VMM compilers all produce the
same layout for bitfields on the architectures we support.

Thanks,
Nuno



thanks,

greg k-h





Re: [PATCH v4 13/15] uapi: hyperv: Add mshv driver headers defining hypervisor ABIs

2023-10-04 Thread Nuno Das Neves

On 10/4/2023 10:50 AM, Greg KH wrote:

On Wed, Oct 04, 2023 at 05:36:32PM +, Dexuan Cui wrote:

From: Greg KH 
Sent: Tuesday, October 3, 2023 11:10 PM
[...]
On Tue, Oct 03, 2023 at 04:37:01PM -0700, Nuno Das Neves wrote:

On 9/30/2023 11:19 PM, Greg KH wrote:

On Sat, Sep 30, 2023 at 10:01:58PM +, Wei Liu wrote:

On Sat, Sep 30, 2023 at 08:09:19AM +0200, Greg KH wrote:

On Fri, Sep 29, 2023 at 11:01:39AM -0700, Nuno Das Neves wrote:

+/* Define connection identifier type. */
+union hv_connection_id {
+   __u32 asu32;
+   struct {
+   __u32 id:24;
+   __u32 reserved:8;
+   } __packed u;


IMO the "__packed" is unnecessary.


bitfields will not work properly in uapi .h files, please never do that.


Can you clarify a bit more why it wouldn't work? Endianess? Alignment?


Yes to both.

Did you all read the documentation for how to write a kernel api?  If
not, please do so.  I think it mentions bitfields, but it not, it really
should as of course, this will not work properly with different endian
systems or many compilers.


Yes, in

https://docs.k/
ernel.org%2Fdriver-
api%2Fioctl.html&data=05%7C01%7Cdecui%40microsoft.com%7Ce404769e0f
85493f0aa108dbc4a08a27%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C
0%7C638319966071263290%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLj
AwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%
7C%7C&sdata=RiLNA5DRviWBQK6XXhxC4m77raSDBb%2F0BB6BDpFPUJY%3D
&reserved=0 it says that it is

"better to avoid" bitfields.

Unfortunately bitfields are used in the definition of the hypervisor
ABI. We import these definitions directly from the hypervisor code.


So why do you feel you have to use this specific format for your
user/kernel api?  That is not what is going to the hypervisor.



These *are* going to the hypervisor - we use these same definitions in
our driver for the kernel/hypervisor API. This is so we don't have to
maintain two separate definitions for user/kernel and kernel/hypervisor
APIs.


If it's hard to avoid bitfield here, maybe we can refer to the definition of
struct iphdr in include/uapi/linux/ip.h


It is not hard to avoid using bitfields, just use the proper definitions
to make this portable for all compilers.  And ick, ip.h is not a good
thing to follow :)


Greg, there is nothing making us use bitfields. It just makes the work
of porting the hypervisor definitions to Linux easier - aided by the
fact that in practice, all the compilers in our stack produce the same
code for these.

If that stops being true, or we need to support some other scenario,
then I can see the value in changing it. Right now it just feels like
pointless work.

Just a reminder - we are the only consumers of this code right now; no
one else can meaningfully use this interface yet.

That all said, if you really insist on changing it, then please say so.
And please point to an example of how it should be done so there is no
confusion on the best path forward.

Thanks,
Nuno


thanks,

greg k-h





Re: [PATCH v4 09/15] Drivers: hv: Introduce hv_output_arg_exists in hv_common.c

2023-10-04 Thread Nuno Das Neves

On 10/2/2023 12:29 PM, Alex Ionescu wrote:

Hi Nuno,

Is it possible to simply change to always allocating the output page?
For example, the output page could be needed in scenarios where Linux
is not running as the root partition, since certain hypercalls that a
guest can make will still require one (I realize that's not the case
_today_, but I don't believe this optimization buys much).


I agree - it would indeed simplify the code, and guests will probably
make use of it sooner or later.

Happy to make that change if Hyper-V guest maintainers agree.
Long, Dexuan, Michael, what do you think?

Thanks,
Nuno


Best regards,
Alex Ionescu


On Fri, Sep 29, 2023 at 2:02 PM Nuno Das Neves
 wrote:


This is a more flexible approach for determining whether to allocate the
output page.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
  drivers/hv/hv_common.c | 21 +
  1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 39077841d518..3f6f23e4c579 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -58,6 +58,14 @@ EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
  void * __percpu *hyperv_pcpu_output_arg;
  EXPORT_SYMBOL_GPL(hyperv_pcpu_output_arg);

+/*
+ * Determine whether output arg is needed
+ */
+static inline bool hv_output_arg_exists(void)
+{
+   return hv_root_partition ? true : false;
+}
+
  static void hv_kmsg_dump_unregister(void);

  static struct ctl_table_header *hv_ctl_table_hdr;
@@ -342,10 +350,12 @@ int __init hv_common_init(void)
 hyperv_pcpu_input_arg = alloc_percpu(void  *);
 BUG_ON(!hyperv_pcpu_input_arg);

-   /* Allocate the per-CPU state for output arg for root */
-   if (hv_root_partition) {
+   if (hv_output_arg_exists()) {
 hyperv_pcpu_output_arg = alloc_percpu(void *);
 BUG_ON(!hyperv_pcpu_output_arg);
+   }
+
+   if (hv_root_partition) {
 hv_synic_eventring_tail = alloc_percpu(u8 *);
 BUG_ON(hv_synic_eventring_tail == NULL);
 }
@@ -375,7 +385,7 @@ int hv_common_cpu_init(unsigned int cpu)
 u8 **synic_eventring_tail;
 u64 msr_vp_index;
 gfp_t flags;
-   int pgcount = hv_root_partition ? 2 : 1;
+   int pgcount = hv_output_arg_exists() ? 2 : 1;
 void *mem;
 int ret;

@@ -393,9 +403,12 @@ int hv_common_cpu_init(unsigned int cpu)
 if (!mem)
 return -ENOMEM;

-   if (hv_root_partition) {
+   if (hv_output_arg_exists()) {
 outputarg = (void 
**)this_cpu_ptr(hyperv_pcpu_output_arg);
 *outputarg = (char *)mem + HV_HYP_PAGE_SIZE;
+   }
+
+   if (hv_root_partition) {
 synic_eventring_tail = (u8 
**)this_cpu_ptr(hv_synic_eventring_tail);
 *synic_eventring_tail = kcalloc(HV_SYNIC_SINT_COUNT, 
sizeof(u8),
 flags);
--
2.25.1







Re: [PATCH v2 13/15] uapi: hyperv: Add mshv driver headers hvhdk.h, hvhdk_mini.h, hvgdk.h, hvgdk_mini.h

2023-10-10 Thread Nuno Das Neves

On 8/25/2023 11:24 AM, Nuno Das Neves wrote:

On 8/19/2023 3:26 AM, Greg KH wrote:


My "strong" opinion is the one kernel development rule that we have,
"you can not break userspace".  So, if you change these
values/structures/whatever in the future, and userspace tools break,
that's not ok and the changes have to be reverted.

If you can control both sides of the API here (with open tools that you
can guarantee everyone will always update to), then yes, you can change
the api in the future.



This is true for us - we contribute and maintain support for this driver
in Cloud Hypervisor[1], an open source VMM.



Hi Greg,

Bringing up this discussion again so we can clear up any confusion on the
uapi headers in this patch set.

The headers consist of the ioctls in mshv.h, and the hypervisor ABIs in
the *hdk.h files. The ioctls depend on the hypervisor ABIs.

We will add (to the next version), an ioctl like KVM_GET_API_VERSION [1].
This will return a version number for the ioctl interface that increments
any time there is a breaking change. Userspace would be required to check
this before calling any other ioctl, and it can exit gracefully if there
is a mismatch.

That's how KVM evolved its userspace ABI. We want to use the same approach.

I also wanted to reiterate that we are the only maintainers and users of
the userspace code for this driver via Cloud Hypervisor [2]. We generate
rust bindings from these headers using bindgen [3].

Taking this into account, is the above a viable path for this patch set?

Thanks,
Nuno

[1] https://docs.kernel.org/virt/kvm/api.html#kvm-get-api-version
[2] https://github.com/cloud-hypervisor/cloud-hypervisor
[3] https://github.com/rust-lang/rust-bindgen




Re: [PATCH v4 14/15] asm-generic: hyperv: Use new Hyper-V headers conditionally.

2023-10-11 Thread Nuno Das Neves

On 10/5/2023 12:52 PM, Alex Ionescu wrote:

3) Truly making hypertv-tlfs the "documented" header, and then > removing any 
duplication from HDK so that it remains the
"undocumented" header file. In this manner, one would include
hyperv-tlfs to use the stable ABI, and they would include HDK (which
would include hyperv-tlfs) to use the unstable+stable ABI.


hyperv-tlfs.h is remaining the "documented" header.

But, we can't make the HDK header depend on hyperv-tlfs.h, for 2 primary
reasons:
1. We need to put the new HDK headers in uapi so that we can use them in
our IOCTL interface. As a result, we can't include hyperv-tlfs.h (unless
we put it in uapi as well).
2. The HDK headers not only duplicate, but also MODIFY some structures
in hyperv-tlfs.h. e.g., The struct is in hyperv-tlfs.h, but a particular
field or bitfield is not.


#2 was something I was worried about. Do you know if the
standards/docs team is planning on updating the TLFS at some point
with updates on their end? At which point I'd assume you'd be OK with
patches to add them to hyperv-tlfs.h



I don't know the current plans for updating the TLFS. But yes, assuming
a new TLFS doc has something that is needed in the kernel, hyperv-tlfs.h
would be updated to support that.

Thanks,
Nuno



Re: [PATCH v2 13/15] uapi: hyperv: Add mshv driver headers hvhdk.h, hvhdk_mini.h, hvgdk.h, hvgdk_mini.h

2023-10-11 Thread Nuno Das Neves

On 10/10/2023 11:42 PM, Greg KH wrote:

On Tue, Oct 10, 2023 at 03:49:48PM -0700, Nuno Das Neves wrote:

On 8/25/2023 11:24 AM, Nuno Das Neves wrote:

On 8/19/2023 3:26 AM, Greg KH wrote:


My "strong" opinion is the one kernel development rule that we have,
"you can not break userspace".  So, if you change these
values/structures/whatever in the future, and userspace tools break,
that's not ok and the changes have to be reverted.

If you can control both sides of the API here (with open tools that you
can guarantee everyone will always update to), then yes, you can change
the api in the future.



We control both sides of the API. The code is open. No one else can use it
today, therefore we can guarantee all the users will stay updated.


Just submit your fixed up patch series based on the previous review
comments and it will be reviewed again, just like all kernel patches
are.


I will do that.


Perhaps you all should take the time to do some kernel patch reviews of
other stuff sent to the mailing lists to get an idea of how this whole
process works, and to get better integrated into the kernel development
community,


That is a good suggestion, I will do that.


before dumping a huge patchset on us with lots of process
questions like this?  Why are you asking the community to do a lot of
work and hand-holding when you aren't helping others out as well?


I take your point, sorry my questions came off that way. I will work to
improve on that :)

Thanks,
Nuno



Re: Incorrect definition of hv_enable_vp_vtl in hyperv-tlfs.h

2023-10-19 Thread Nuno Das Neves

On 10/16/2023 4:49 AM, Alex Ionescu wrote:

Hi,

In arch/x86/include/asm/hyperv-tlfs.h, the following definition at
line 786 (in Linus' tree), I believe to be incorrect.

struct hv_enable_vp_vtl {
 u64partition_id;
 u32vp_index;
 union hv_input_vtltarget_vtl; < Here

For this hypercall, the TLFS and MSDN documentation states this field
is HV_VTL (u8) and not HV_INPUT_VTL (the bit-field used for targeting
hypercalls to specific target VTLs, which is not the case here).

I realize this is essentially a no-op in code at the moment, but for
correctness should be addressed? I'm happy to make a patch, but wanted
to make sure this isn't a mistake in TLFS/MSDN to begin with
(although, my copy of GDK headers would corroborate it's indeed HV_VTL
as well).

Best regards,
Alex Ionescu


Hi Alex,

I checked the code to make sure - seems like the TLFS doc is correct. It
should indeed be HV_VTL (u8).

Feel free to submit a patch.

Thanks
Nuno



[PATCH] hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_*

2024-02-08 Thread Nuno Das Neves
The HV_REGISTER_ are used as arguments to hv_set/get_register(), which
delegate to arch-specific mechanisms for getting/setting synthetic
Hyper-V MSRs.

On arm64, HV_REGISTER_ defines are synthetic VP registers accessed via
the get/set vp registers hypercalls. The naming matches the TLFS
document, although these register names are not specific to arm64.

However, on x86 the prefix HV_REGISTER_ indicates Hyper-V MSRs accessed
via rdmsrl()/wrmsrl(). This is not consistent with the TLFS doc, where
HV_REGISTER_ is *only* used for used for VP register names used by
the get/set register hypercalls.

To fix this inconsistency and prevent future confusion, change the
arch-generic aliases used by callers of hv_set/get_register() to have
the prefix HV_MSR_ instead of HV_REGISTER_.

Use the prefix HV_X64_MSR_ for the x86-only Hyper-V MSRs. On x86, the
generic HV_MSR_'s point to the corresponding HV_X64_MSR_.

Move the arm64 HV_REGISTER_* defines to the asm-generic hyperv-tlfs.h,
since these are not specific to arm64. On arm64, the generic HV_MSR_'s
point to the corresponding HV_REGISTER_.

While at it, rename hv_get/set_registers() and related functions to
hv_get/set_msr(), hv_get/set_nested_msr(), etc. These are only used for
Hyper-V MSRs and this naming makes that clear.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
---
 arch/arm64/include/asm/hyperv-tlfs.h |  45 -
 arch/arm64/include/asm/mshyperv.h|   4 +-
 arch/x86/hyperv/hv_init.c|   8 +-
 arch/x86/include/asm/hyperv-tlfs.h   | 145 ++-
 arch/x86/include/asm/mshyperv.h  |  30 +++---
 arch/x86/kernel/cpu/mshyperv.c   |  56 +--
 drivers/clocksource/hyperv_timer.c   |  26 ++---
 drivers/hv/hv.c  |  36 +++
 drivers/hv/hv_common.c   |  22 ++--
 include/asm-generic/hyperv-tlfs.h|  32 +-
 include/asm-generic/mshyperv.h   |   2 +-
 11 files changed, 216 insertions(+), 190 deletions(-)

diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
index bc6c7ac934a1..54846d1d29c3 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -21,14 +21,6 @@
  * byte ordering of Linux running on ARM64, so no special handling is required.
  */
 
-/*
- * These Hyper-V registers provide information equivalent to the CPUID
- * instruction on x86/x64.
- */
-#define HV_REGISTER_HYPERVISOR_VERSION 0x0100 /*CPUID 0x4002 */
-#define HV_REGISTER_FEATURES   0x0200 /*CPUID 0x4003 */
-#define HV_REGISTER_ENLIGHTENMENTS 0x0201 /*CPUID 0x4004 */
-
 /*
  * Group C Features. See the asm-generic version of hyperv-tlfs.h
  * for a description of Feature Groups.
@@ -41,28 +33,29 @@
 #define HV_STIMER_DIRECT_MODE_AVAILABLEBIT(13)
 
 /*
- * Synthetic register definitions equivalent to MSRs on x86/x64
+ * To support arch-generic code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
  */
-#define HV_REGISTER_CRASH_P0   0x0210
-#define HV_REGISTER_CRASH_P1   0x0211
-#define HV_REGISTER_CRASH_P2   0x0212
-#define HV_REGISTER_CRASH_P3   0x0213
-#define HV_REGISTER_CRASH_P4   0x0214
-#define HV_REGISTER_CRASH_CTL  0x0215
+#define HV_MSR_CRASH_P0(HV_REGISTER_CRASH_P0)
+#define HV_MSR_CRASH_P1(HV_REGISTER_CRASH_P1)
+#define HV_MSR_CRASH_P2(HV_REGISTER_CRASH_P2)
+#define HV_MSR_CRASH_P3(HV_REGISTER_CRASH_P3)
+#define HV_MSR_CRASH_P4(HV_REGISTER_CRASH_P4)
+#define HV_MSR_CRASH_CTL   (HV_REGISTER_CRASH_CTL)
 
-#define HV_REGISTER_GUEST_OSID 0x00090002
-#define HV_REGISTER_VP_INDEX   0x00090003
-#define HV_REGISTER_TIME_REF_COUNT 0x00090004
-#define HV_REGISTER_REFERENCE_TSC  0x00090017
+#define HV_MSR_VP_INDEX(HV_REGISTER_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT  (HV_REGISTER_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TSC   (HV_REGISTER_REFERENCE_TSC)
 
-#define HV_REGISTER_SINT0  0x000A
-#define HV_REGISTER_SCONTROL   0x000A0010
-#define HV_REGISTER_SIEFP  0x000A0012
-#define HV_REGISTER_SIMP   0x000A0013
-#define HV_REGISTER_EOM0x000A0014
+#define HV_MSR_SINT0   (HV_REGISTER_SINT0)
+#define HV_MSR_SCONTROL(HV_REGISTER_SCONTROL)
+#define HV_MSR_SIEFP   (HV_REGISTER_SIEFP)
+#define HV_MSR_SIMP(HV_REGISTER_SIMP)
+#define HV_MSR_EOM (HV_REGISTER_EOM)
 
-#define HV_REGISTER_STIMER0_CONFIG 0x000B
-#define HV_REGISTER_STIMER0_COUNT  0x000B0001
+#define HV_MSR_STIMER0_CONFIG  (HV_REGISTER_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT   (HV_REGISTER_STIMER0_COUNT)
 
 union hv_msi_entry {
u64 as_uint6

Re: [PATCH] hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_*

2024-02-18 Thread Nuno Das Neves
On 2/10/2024 2:37 AM, Michael Kelley wrote:
> 
> Overall, this looks good to me.  It cleans up the mess I made five
> years ago when first separating x86 from ARM64. :-(
> 
> See one comment below, but otherwise,
> 
> Reviewed-by: Michael Kelley 
> 

Thanks! Responded to your comment below.

>>  #if IS_ENABLED(CONFIG_HYPERV)
>> -static inline unsigned int hv_get_nested_reg(unsigned int reg)
>> +static inline unsigned int hv_get_nested_msr(unsigned int reg)
>>  {
>> -if (hv_is_sint_reg(reg))
>> -return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0;
>> +if (hv_is_sint_msr(reg))
>> +return reg - HV_MSR_SINT0 + HV_MSR_NESTED_SINT0;
>>
>>  switch (reg) {
>> -case HV_REGISTER_SIMP:
>> -return HV_REGISTER_NESTED_SIMP;
>> -case HV_REGISTER_SIEFP:
>> -return HV_REGISTER_NESTED_SIEFP;
>> -case HV_REGISTER_SVERSION:
>> -return HV_REGISTER_NESTED_SVERSION;
>> -case HV_REGISTER_SCONTROL:
>> -return HV_REGISTER_NESTED_SCONTROL;
>> -case HV_REGISTER_EOM:
>> -return HV_REGISTER_NESTED_EOM;
>> +case HV_MSR_SIMP:
>> +return HV_MSR_NESTED_SIMP;
>> +case HV_MSR_SIEFP:
>> +return HV_MSR_NESTED_SIEFP;
>> +case HV_MSR_SVERSION:
>> +return HV_MSR_NESTED_SVERSION;
>> +case HV_MSR_SCONTROL:
>> +return HV_MSR_NESTED_SCONTROL;
>> +case HV_MSR_EOM:
>> +return HV_MSR_NESTED_EOM;
>>  default:
>>  return reg;
>>  }
>>  }
> 
> This function is x86 specific, but you are using the generic HV_MSR_* flavor
> instead of the x86 specific HV_X64_MSR_* flavor like in other x86 specific 
> code.
> Both flavors work, but I wondered if there is any reason for using the 
> generic flavor.
>> I remember debating myself the merits of one approach vs. the other, but I
> don't think there was a solid argument either way.   Given that you are
> doing the work to get this all fixed like it should have been originally, I 
> would
> argue for being consistently one way or the other.  ARM64 specific code is
> *not* using the generic HV_MSR_* flavor, so I suspect x86 code should not
> either.
> 
> Michael
> 

I see your point about keeping it consistent within the file.

My thinking was that hv_get_nested_msr is not inherently x86-specific, even 
though it
lives in arch/x86 today. However, I realize that even if this function *is* 
moved to
generic code in the future, at that time it could be changed to the generic 
prefix.
Doing so in this patch could be confusing since it introduces an inconsistency.

So, I will take your advice and keep it HV_X64_MSR_* for everything in this 
file.

Thanks again!
Nuno




[PATCH v2] hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_*

2024-02-20 Thread Nuno Das Neves
The HV_REGISTER_ are used as arguments to hv_set/get_register(), which
delegate to arch-specific mechanisms for getting/setting synthetic
Hyper-V MSRs.

On arm64, HV_REGISTER_ defines are synthetic VP registers accessed via
the get/set vp registers hypercalls. The naming matches the TLFS
document, although these register names are not specific to arm64.

However, on x86 the prefix HV_REGISTER_ indicates Hyper-V MSRs accessed
via rdmsrl()/wrmsrl(). This is not consistent with the TLFS doc, where
HV_REGISTER_ is *only* used for used for VP register names used by
the get/set register hypercalls.

To fix this inconsistency and prevent future confusion, change the
arch-generic aliases used by callers of hv_set/get_register() to have
the prefix HV_MSR_ instead of HV_REGISTER_.

Use the prefix HV_X64_MSR_ for the x86-only Hyper-V MSRs. On x86, the
generic HV_MSR_'s point to the corresponding HV_X64_MSR_.

Move the arm64 HV_REGISTER_* defines to the asm-generic hyperv-tlfs.h,
since these are not specific to arm64. On arm64, the generic HV_MSR_'s
point to the corresponding HV_REGISTER_.

While at it, rename hv_get/set_registers() and related functions to
hv_get/set_msr(), hv_get/set_nested_msr(), etc. These are only used for
Hyper-V MSRs and this naming makes that clear.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 
Reviewed-by: Michael Kelley 
---
Changes in v2:
* Use HV_X64_MSR_ instead of HV_MSR_ in arch/x86/kernel/cpu/mshyperv.c
---
 arch/arm64/include/asm/hyperv-tlfs.h |  45 -
 arch/arm64/include/asm/mshyperv.h|   4 +-
 arch/x86/hyperv/hv_init.c|   8 +-
 arch/x86/include/asm/hyperv-tlfs.h   | 145 ++-
 arch/x86/include/asm/mshyperv.h  |  30 +++---
 arch/x86/kernel/cpu/mshyperv.c   |  56 +--
 drivers/clocksource/hyperv_timer.c   |  26 ++---
 drivers/hv/hv.c  |  36 +++
 drivers/hv/hv_common.c   |  22 ++--
 include/asm-generic/hyperv-tlfs.h|  32 +-
 include/asm-generic/mshyperv.h   |   2 +-
 11 files changed, 216 insertions(+), 190 deletions(-)

diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
index bc6c7ac934a1..54846d1d29c3 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -21,14 +21,6 @@
  * byte ordering of Linux running on ARM64, so no special handling is required.
  */
 
-/*
- * These Hyper-V registers provide information equivalent to the CPUID
- * instruction on x86/x64.
- */
-#define HV_REGISTER_HYPERVISOR_VERSION 0x0100 /*CPUID 0x4002 */
-#define HV_REGISTER_FEATURES   0x0200 /*CPUID 0x4003 */
-#define HV_REGISTER_ENLIGHTENMENTS 0x0201 /*CPUID 0x4004 */
-
 /*
  * Group C Features. See the asm-generic version of hyperv-tlfs.h
  * for a description of Feature Groups.
@@ -41,28 +33,29 @@
 #define HV_STIMER_DIRECT_MODE_AVAILABLEBIT(13)
 
 /*
- * Synthetic register definitions equivalent to MSRs on x86/x64
+ * To support arch-generic code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
  */
-#define HV_REGISTER_CRASH_P0   0x0210
-#define HV_REGISTER_CRASH_P1   0x0211
-#define HV_REGISTER_CRASH_P2   0x0212
-#define HV_REGISTER_CRASH_P3   0x0213
-#define HV_REGISTER_CRASH_P4   0x0214
-#define HV_REGISTER_CRASH_CTL  0x0215
+#define HV_MSR_CRASH_P0(HV_REGISTER_CRASH_P0)
+#define HV_MSR_CRASH_P1(HV_REGISTER_CRASH_P1)
+#define HV_MSR_CRASH_P2(HV_REGISTER_CRASH_P2)
+#define HV_MSR_CRASH_P3(HV_REGISTER_CRASH_P3)
+#define HV_MSR_CRASH_P4(HV_REGISTER_CRASH_P4)
+#define HV_MSR_CRASH_CTL   (HV_REGISTER_CRASH_CTL)
 
-#define HV_REGISTER_GUEST_OSID 0x00090002
-#define HV_REGISTER_VP_INDEX   0x00090003
-#define HV_REGISTER_TIME_REF_COUNT 0x00090004
-#define HV_REGISTER_REFERENCE_TSC  0x00090017
+#define HV_MSR_VP_INDEX(HV_REGISTER_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT  (HV_REGISTER_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TSC   (HV_REGISTER_REFERENCE_TSC)
 
-#define HV_REGISTER_SINT0  0x000A
-#define HV_REGISTER_SCONTROL   0x000A0010
-#define HV_REGISTER_SIEFP  0x000A0012
-#define HV_REGISTER_SIMP   0x000A0013
-#define HV_REGISTER_EOM0x000A0014
+#define HV_MSR_SINT0   (HV_REGISTER_SINT0)
+#define HV_MSR_SCONTROL(HV_REGISTER_SCONTROL)
+#define HV_MSR_SIEFP   (HV_REGISTER_SIEFP)
+#define HV_MSR_SIMP(HV_REGISTER_SIMP)
+#define HV_MSR_EOM (HV_REGISTER_EOM)
 
-#define HV_REGISTER_STIMER0_CONFIG 0x000B
-#define HV_REGISTER_STIMER0_COUNT  0x000B0001
+#define HV_MSR_STIM

[PATCH] mshyperv: Introduce hv_get_hypervisor_version function

2024-03-06 Thread Nuno Das Neves
Introduce x86_64 and arm64 functions for getting the hypervisor version
information and storing it in a structure for simpler parsing.

Use the new function to get and parse the version at boot time. While at
it, print the version in the same format for each architecture, and move
the printing code to hv_common_init() so it is not duplicated.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
 arch/arm64/hyperv/mshyperv.c  | 19 -
 arch/x86/kernel/cpu/mshyperv.c| 35 ++-
 drivers/hv/hv_common.c|  9 
 include/asm-generic/hyperv-tlfs.h | 23 
 include/asm-generic/mshyperv.h|  2 ++
 5 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index f1b8a04ee9f2..55dc224d466d 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,10 +19,18 @@
 
 static bool hyperv_initialized;
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
+(struct hv_get_vp_registers_output *)info);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
+
 static int __init hyperv_init(void)
 {
struct hv_get_vp_registers_output   result;
-   u32 a, b, c, d;
u64 guest_id;
int ret;
 
@@ -54,15 +62,6 @@ static int __init hyperv_init(void)
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
ms_hyperv.misc_features);
 
-   /* Get information about the Hyper-V host version */
-   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
-   a = result.as32.a;
-   b = result.as32.b;
-   c = result.as32.c;
-   d = result.as32.d;
-   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   b >> 16, b & 0x, a, d & 0xFF, c, d >> 24);
-
ret = hv_common_init();
if (ret)
return ret;
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index d306f6184cee..03a3445faf7a 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -350,13 +350,25 @@ static void __init reduced_hw_init(void)
x86_init.irqs.pre_vector_init   = x86_init_noop;
 }
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   unsigned int hv_max_functions;
+
+   hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
+   if (hv_max_functions < HYPERV_CPUID_VERSION) {
+   pr_err("%s: Could not detect Hyper-V version\n", __func__);
+   return -ENODEV;
+   }
+
+   cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, 
&info->edx);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
+
 static void __init ms_hyperv_init_platform(void)
 {
int hv_max_functions_eax;
-   int hv_host_info_eax;
-   int hv_host_info_ebx;
-   int hv_host_info_ecx;
-   int hv_host_info_edx;
 
 #ifdef CONFIG_PARAVIRT
pv_info.name = "Hyper-V";
@@ -407,21 +419,6 @@ static void __init ms_hyperv_init_platform(void)
pr_info("Hyper-V: running on a nested hypervisor\n");
}
 
-   /*
-* Extract host information.
-*/
-   if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
-   hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
-   hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
-   hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
-   hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
-
-   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   hv_host_info_ebx >> 16, hv_host_info_ebx & 0x,
-   hv_host_info_eax, hv_host_info_edx & 0xFF,
-   hv_host_info_ecx, hv_host_info_edx >> 24);
-   }
-
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
x86_platform.calibrate_tsc = hv_get_tsc_khz;
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 2f1dd4b07f9a..4d72c528af68 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -278,6 +278,15 @@ static void hv_kmsg_dump_register(void)
 int __init hv_common_init(void)
 {
int i;
+   union hv_hypervisor_version_info version;
+
+   /* Get information about the Hyper-V host version */
+   if (hv_get_hypervisor_version(&version) == 0) {
+   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
+   version.major_version, version.minor_version,
+   version.build_number, version.service_number,
+

Re: [PATCH] mshyperv: Introduce hv_get_hypervisor_version function

2024-03-07 Thread Nuno Das Neves
On 3/7/2024 11:22 AM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Wednesday, 
> March 6, 2024 4:48 PM
>>
>> Introduce x86_64 and arm64 functions for getting the hypervisor version
>> information and storing it in a structure for simpler parsing.
>>
>> Use the new function to get and parse the version at boot time. While at
>> it, print the version in the same format for each architecture, and move
>> the printing code to hv_common_init() so it is not duplicated.
> 
> Isn't the format already the same for x86 and ARM64?   A couple of
> years ago they didn't match.  But that was fixed in commit eeda29db98f4.
> 

You're correct - I will amend the commit message. Thanks!

>>
>> Signed-off-by: Nuno Das Neves 
>> Acked-by: Wei Liu 
>> ---
>>  arch/arm64/hyperv/mshyperv.c  | 19 -
>>  arch/x86/kernel/cpu/mshyperv.c| 35 ++-
>>  drivers/hv/hv_common.c|  9 
>>  include/asm-generic/hyperv-tlfs.h | 23 
>>  include/asm-generic/mshyperv.h|  2 ++
>>  5 files changed, 59 insertions(+), 29 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c
>> b/arch/arm64/hyperv/mshyperv.c
>> index f1b8a04ee9f2..55dc224d466d 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -19,10 +19,18 @@
>>
>>  static bool hyperv_initialized;
>>
>> +int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>> +{
>> +hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
>> + (struct hv_get_vp_registers_output *)info);
>> +
>> +return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
> 
> I don't think this need to be exported, at least not for the usage in
> this patch.  The caller in hv_common.c is never part of a module -- it's
> always built-in. But maybe you are anticipating future use cases
> from a module?
> 

Yes, it will be used in a module eventually. Do you think I should remove
this and the below export until they are actually needed?

>> +
>>  static int __init hyperv_init(void)
>>  {
>>  struct hv_get_vp_registers_output   result;
>> -u32 a, b, c, d;
>>  u64 guest_id;
>>  int ret;
>>
>> @@ -54,15 +62,6 @@ static int __init hyperv_init(void)
>>  ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
>>  ms_hyperv.misc_features);
>>
>> -/* Get information about the Hyper-V host version */
>> -hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
>> -a = result.as32.a;
>> -b = result.as32.b;
>> -c = result.as32.c;
>> -d = result.as32.d;
>> -pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
>> -b >> 16, b & 0x, a, d & 0xFF, c, d >> 24);
>> -
>>  ret = hv_common_init();
>>  if (ret)
>>  return ret;
>> diff --git a/arch/x86/kernel/cpu/mshyperv.c
>> b/arch/x86/kernel/cpu/mshyperv.c
>> index d306f6184cee..03a3445faf7a 100644
>> --- a/arch/x86/kernel/cpu/mshyperv.c
>> +++ b/arch/x86/kernel/cpu/mshyperv.c
>> @@ -350,13 +350,25 @@ static void __init reduced_hw_init(void)
>>  x86_init.irqs.pre_vector_init   = x86_init_noop;
>>  }
>>
>> +int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>> +{
>> +unsigned int hv_max_functions;
>> +
>> +hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
>> +if (hv_max_functions < HYPERV_CPUID_VERSION) {
>> +pr_err("%s: Could not detect Hyper-V version\n", __func__);
>> +return -ENODEV;
>> +}
>> +
>> +cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, 
>> &info->edx);
>> +
>> +return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(hv_get_hypervisor_version);
> 
> Same for this EXPORT.
>>> +
>>  static void __init ms_hyperv_init_platform(void)
>>  {
>>  int hv_max_functions_eax;
>> -int hv_host_info_eax;
>> -int hv_host_info_ebx;
>> -int hv_host_info_ecx;
>> -int hv_host_info_edx;
>>
>>  #ifdef CONFIG_PARAVIRT
>>  pv_info.name = "Hyper-V";
>> @@ -407,21 +419,6 @@ static void __init ms_hyperv_init_platform(void)
>>  pr_info("Hyper-V: running on a nested hypervisor\n");
>>  }
>>
>> -/*
>> -  

[PATCH v2] mshyperv: Introduce hv_get_hypervisor_version function

2024-03-07 Thread Nuno Das Neves
Introduce x86_64 and arm64 functions to get the hypervisor version
information and store it in a structure for simpler parsing.

Use the new function to get and parse the version at boot time. While at
it, move the printing code to hv_common_init() so it is not duplicated.

Signed-off-by: Nuno Das Neves 
Acked-by: Wei Liu 
---
Changes since v1:
- Amend commit message
- Address minor style issues
- Remove unneeded EXPORT_SYMBOL_GPL(hv_get_hypervisor_version)
---
 arch/arm64/hyperv/mshyperv.c  | 18 
 arch/x86/kernel/cpu/mshyperv.c| 34 ++-
 drivers/hv/hv_common.c|  8 
 include/asm-generic/hyperv-tlfs.h | 23 +
 include/asm-generic/mshyperv.h|  1 +
 5 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index f1b8a04ee9f2..99362716ac87 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,10 +19,17 @@
 
 static bool hyperv_initialized;
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
+(struct hv_get_vp_registers_output *)info);
+
+   return 0;
+}
+
 static int __init hyperv_init(void)
 {
struct hv_get_vp_registers_output   result;
-   u32 a, b, c, d;
u64 guest_id;
int ret;
 
@@ -54,15 +61,6 @@ static int __init hyperv_init(void)
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
ms_hyperv.misc_features);
 
-   /* Get information about the Hyper-V host version */
-   hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
-   a = result.as32.a;
-   b = result.as32.b;
-   c = result.as32.c;
-   d = result.as32.d;
-   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   b >> 16, b & 0x, a, d & 0xFF, c, d >> 24);
-
ret = hv_common_init();
if (ret)
return ret;
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index d306f6184cee..56e731d8f513 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -350,13 +350,24 @@ static void __init reduced_hw_init(void)
x86_init.irqs.pre_vector_init   = x86_init_noop;
 }
 
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+   unsigned int hv_max_functions;
+
+   hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
+   if (hv_max_functions < HYPERV_CPUID_VERSION) {
+   pr_err("%s: Could not detect Hyper-V version\n", __func__);
+   return -ENODEV;
+   }
+
+   cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, 
&info->edx);
+
+   return 0;
+}
+
 static void __init ms_hyperv_init_platform(void)
 {
int hv_max_functions_eax;
-   int hv_host_info_eax;
-   int hv_host_info_ebx;
-   int hv_host_info_ecx;
-   int hv_host_info_edx;
 
 #ifdef CONFIG_PARAVIRT
pv_info.name = "Hyper-V";
@@ -407,21 +418,6 @@ static void __init ms_hyperv_init_platform(void)
pr_info("Hyper-V: running on a nested hypervisor\n");
}
 
-   /*
-* Extract host information.
-*/
-   if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
-   hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
-   hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
-   hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
-   hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
-
-   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
-   hv_host_info_ebx >> 16, hv_host_info_ebx & 0x,
-   hv_host_info_eax, hv_host_info_edx & 0xFF,
-   hv_host_info_ecx, hv_host_info_edx >> 24);
-   }
-
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
x86_platform.calibrate_tsc = hv_get_tsc_khz;
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 2f1dd4b07f9a..5d64cb0a709d 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -278,6 +278,14 @@ static void hv_kmsg_dump_register(void)
 int __init hv_common_init(void)
 {
int i;
+   union hv_hypervisor_version_info version;
+
+   /* Get information about the Hyper-V host version */
+   if (!hv_get_hypervisor_version(&version))
+   pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
+   version.major_version, version.minor_version,
+   version.build_number, version.service_number,
+   version.service_pack, v

Re: [PATCH v2] mshyperv: Introduce hv_get_hypervisor_version function

2024-03-11 Thread Nuno Das Neves
On 3/7/2024 3:03 PM, Nuno Das Neves wrote:
> Introduce x86_64 and arm64 functions to get the hypervisor version
> information and store it in a structure for simpler parsing.
> 
> Use the new function to get and parse the version at boot time. While at
> it, move the printing code to hv_common_init() so it is not duplicated.
> 
> Signed-off-by: Nuno Das Neves 
> Acked-by: Wei Liu 
> ---
> Changes since v1:
> - Amend commit message
> - Address minor style issues
> - Remove unneeded EXPORT_SYMBOL_GPL(hv_get_hypervisor_version)
> ---
>  arch/arm64/hyperv/mshyperv.c  | 18 
>  arch/x86/kernel/cpu/mshyperv.c| 34 ++-
>  drivers/hv/hv_common.c|  8 
>  include/asm-generic/hyperv-tlfs.h | 23 +
>  include/asm-generic/mshyperv.h|  1 +
>  5 files changed, 55 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index f1b8a04ee9f2..99362716ac87 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -19,10 +19,17 @@
>  
>  static bool hyperv_initialized;
>  
> +int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
> +{
> + hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
> +  (struct hv_get_vp_registers_output *)info);
> +
> + return 0;
> +}
> +
>  static int __init hyperv_init(void)
>  {
>   struct hv_get_vp_registers_output   result;
> - u32 a, b, c, d;
>   u64 guest_id;
>   int ret;
>  
> @@ -54,15 +61,6 @@ static int __init hyperv_init(void)
>   ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
>   ms_hyperv.misc_features);
>  
> - /* Get information about the Hyper-V host version */
> - hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
> - a = result.as32.a;
> - b = result.as32.b;
> - c = result.as32.c;
> - d = result.as32.d;
> - pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
> - b >> 16, b & 0x, a, d & 0xFF, c, d >> 24);
> -
>   ret = hv_common_init();
>   if (ret)
>   return ret;
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index d306f6184cee..56e731d8f513 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -350,13 +350,24 @@ static void __init reduced_hw_init(void)
>   x86_init.irqs.pre_vector_init   = x86_init_noop;
>  }
>  
> +int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
> +{
> + unsigned int hv_max_functions;
> +
> + hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
> + if (hv_max_functions < HYPERV_CPUID_VERSION) {
> + pr_err("%s: Could not detect Hyper-V version\n", __func__);
> + return -ENODEV;
> + }
> +
> + cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, 
> &info->edx);
> +
> + return 0;
> +}
> +
>  static void __init ms_hyperv_init_platform(void)
>  {
>   int hv_max_functions_eax;
> - int hv_host_info_eax;
> - int hv_host_info_ebx;
> - int hv_host_info_ecx;
> - int hv_host_info_edx;
>  
>  #ifdef CONFIG_PARAVIRT
>   pv_info.name = "Hyper-V";
> @@ -407,21 +418,6 @@ static void __init ms_hyperv_init_platform(void)
>   pr_info("Hyper-V: running on a nested hypervisor\n");
>   }
>  
> - /*
> -  * Extract host information.
> -  */
> - if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
> - hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
> - hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
> - hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
> - hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
> -
> - pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
> - hv_host_info_ebx >> 16, hv_host_info_ebx & 0x,
> - hv_host_info_eax, hv_host_info_edx & 0xFF,
> - hv_host_info_ecx, hv_host_info_edx >> 24);
> - }
> -
>   if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
>   ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
>   x86_platform.calibrate_tsc = hv_get_tsc_khz;
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 2f1dd4b07f9a..5d64cb0a709d 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers

[PATCH] hyperv-tlfs: Rename some HV_REGISTER_* defines for consistency

2024-03-12 Thread Nuno Das Neves
Rename HV_REGISTER_GUEST_OSID to HV_REGISTER_GUEST_OS_ID. This matches
the existing HV_X64_MSR_GUEST_OS_ID.

Rename HV_REGISTER_CRASH_* to HV_REGISTER_GUEST_CRASH_*. Including
GUEST_ is consistent with other #defines such as
HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE. The new names also match the TLFS
document more accurately, i.e. HvRegisterGuestCrash*.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c  | 14 +++---
 arch/arm64/hyperv/mshyperv.c |  2 +-
 arch/arm64/include/asm/hyperv-tlfs.h | 12 ++--
 arch/x86/kernel/cpu/mshyperv.c   |  2 +-
 include/asm-generic/hyperv-tlfs.h| 16 
 5 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index b54c34793701..f1ebc025e1df 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -160,22 +160,22 @@ void hyperv_report_panic(struct pt_regs *regs, long err, 
bool in_die)
return;
panic_reported = true;
 
-   guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);
+   guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OS_ID);
 
/*
 * Hyper-V provides the ability to store only 5 values.
 * Pick the passed in error value, the guest_id, the PC,
 * and the SP.
 */
-   hv_set_vpreg(HV_REGISTER_CRASH_P0, err);
-   hv_set_vpreg(HV_REGISTER_CRASH_P1, guest_id);
-   hv_set_vpreg(HV_REGISTER_CRASH_P2, regs->pc);
-   hv_set_vpreg(HV_REGISTER_CRASH_P3, regs->sp);
-   hv_set_vpreg(HV_REGISTER_CRASH_P4, 0);
+   hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P0, err);
+   hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P1, guest_id);
+   hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P2, regs->pc);
+   hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P3, regs->sp);
+   hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P4, 0);
 
/*
 * Let Hyper-V know there is crash data available
 */
-   hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
+   hv_set_vpreg(HV_REGISTER_GUEST_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
 }
 EXPORT_SYMBOL_GPL(hyperv_report_panic);
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 99362716ac87..03ac88bb9d10 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -46,7 +46,7 @@ static int __init hyperv_init(void)
 
/* Setup the guest ID */
guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
-   hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
+   hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
 
/* Get the features and hints from Hyper-V */
hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
index 54846d1d29c3..bc30aadedfe9 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -37,12 +37,12 @@
  * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
  * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
  */
-#define HV_MSR_CRASH_P0(HV_REGISTER_CRASH_P0)
-#define HV_MSR_CRASH_P1(HV_REGISTER_CRASH_P1)
-#define HV_MSR_CRASH_P2(HV_REGISTER_CRASH_P2)
-#define HV_MSR_CRASH_P3(HV_REGISTER_CRASH_P3)
-#define HV_MSR_CRASH_P4(HV_REGISTER_CRASH_P4)
-#define HV_MSR_CRASH_CTL   (HV_REGISTER_CRASH_CTL)
+#define HV_MSR_CRASH_P0(HV_REGISTER_GUEST_CRASH_P0)
+#define HV_MSR_CRASH_P1(HV_REGISTER_GUEST_CRASH_P1)
+#define HV_MSR_CRASH_P2(HV_REGISTER_GUEST_CRASH_P2)
+#define HV_MSR_CRASH_P3(HV_REGISTER_GUEST_CRASH_P3)
+#define HV_MSR_CRASH_P4(HV_REGISTER_GUEST_CRASH_P4)
+#define HV_MSR_CRASH_CTL   (HV_REGISTER_GUEST_CRASH_CTL)
 
 #define HV_MSR_VP_INDEX(HV_REGISTER_VP_INDEX)
 #define HV_MSR_TIME_REF_COUNT  (HV_REGISTER_TIME_REF_COUNT)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 56e731d8f513..909a6236a4c0 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -450,7 +450,7 @@ static void __init ms_hyperv_init_platform(void)
/* To be supported: more work is required.  */
ms_hyperv.features &= 
~HV_MSR_REFERENCE_TSC_AVAILABLE;
 
-   /* HV_REGISTER_CRASH_CTL is unsupported. */
+   /* HV_MSR_CRASH_CTL is unsupported. */
ms_hyperv.misc_features &= 
~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
 
/* Don't trust Hyper-V's TLB-flushing 
hypercalls. */
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 32514a870b98..87e3d49a4e29 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-t

Re: [PATCH v3 1/1] x86/hyperv: Use Hyper-V entropy to seed guest random number generator

2024-03-18 Thread Nuno Das Neves
On 3/18/2024 8:54 AM, mhkelle...@gmail.com wrote:
> From: Michael Kelley 
> 
> A Hyper-V host provides its guest VMs with entropy in a custom ACPI
> table named "OEM0".  The entropy bits are updated each time Hyper-V
> boots the VM, and are suitable for seeding the Linux guest random
> number generator (rng). See a brief description of OEM0 in [1].
> 
> Generation 2 VMs on Hyper-V use UEFI to boot. Existing EFI code in
> Linux seeds the rng with entropy bits from the EFI_RNG_PROTOCOL.
> Via this path, the rng is seeded very early during boot with good
> entropy. The ACPI OEM0 table provided in such VMs is an additional
> source of entropy.
> 
> Generation 1 VMs on Hyper-V boot from BIOS. For these VMs, Linux
> doesn't currently get any entropy from the Hyper-V host. While this
> is not fundamentally broken because Linux can generate its own entropy,
> using the Hyper-V host provided entropy would get the rng off to a
> better start and would do so earlier in the boot process.
> 
> Improve the rng seeding for Generation 1 VMs by having Hyper-V specific
> code in Linux take advantage of the OEM0 table to seed the rng. For
> Generation 2 VMs, use the OEM0 table to provide additional entropy
> beyond the EFI_RNG_PROTOCOL. Because the OEM0 table is custom to
> Hyper-V, parse it directly in the Hyper-V code in the Linux kernel
> and use add_bootloader_randomness() to add it to the rng. Once the
> entropy bits are read from OEM0, zero them out in the table so
> they don't appear in /sys/firmware/acpi/tables/OEM0 in the running
> VM. The zero'ing is done out of an abundance of caution to avoid
> potential security risks to the rng. Also set the OEM0 data length
> to zero so a kexec or other subsequent use of the table won't try
> to use the zero'ed bits.
> 
> [1] 
> https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf
> 
> Signed-off-by: Michael Kelley 
> ---
> Changes in v3:
> * Removed restriction to just Generation 1 VMs. Generation 2 VMs
>   now also use the additional entropy even though they also get
>   initial entropy via EFI_RNG_PROTOCOL [Jason Donenfeld]
> * Process the OEM0 table on ARM64 systems in addition to x86/x64,
>   as a result of no longer excluding Generation 2 VM.
> * Enlarge the range of entropy byte counts that are considered valid
>   in the OEM0 table. New range is 8 to 4K; previously the range was
>   32 to 256. [Jason Donenfeld]
> * After processing the entropy bits in OEM0, also set the OEM0
>   table length to indicate that the entropy byte count is zero,
>   to prevent a subsequent kexec or other use of the table from
>   trying to use the zero'ed bits. [Jason Donenfeld]
> 
> Changes in v2:
> * Tweaked commit message [Wei Liu]
> * Removed message when OEM0 table isn't found. Added debug-level
>   message when OEM0 is successfully used to add randomness. [Wei Liu]
> 
>  arch/arm64/hyperv/mshyperv.c   |  2 +
>  arch/x86/kernel/cpu/mshyperv.c |  1 +
>  drivers/hv/hv_common.c | 69 ++
>  include/asm-generic/mshyperv.h |  2 +
>  4 files changed, 74 insertions(+)
> 
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> index f1b8a04ee9f2..c8193cec1b90 100644
> --- a/arch/arm64/hyperv/mshyperv.c
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -74,6 +74,8 @@ static int __init hyperv_init(void)
>   return ret;
>   }
>  
> + ms_hyperv_late_init();
> +
>   hyperv_initialized = true;
>   return 0;
>  }
> diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> index 303fef824167..65c9cbdd2282 100644
> --- a/arch/x86/kernel/cpu/mshyperv.c
> +++ b/arch/x86/kernel/cpu/mshyperv.c
> @@ -648,6 +648,7 @@ const __initconst struct hypervisor_x86 
> x86_hyper_ms_hyperv = {
>   .init.x2apic_available  = ms_hyperv_x2apic_available,
>   .init.msi_ext_dest_id   = ms_hyperv_msi_ext_dest_id,
>   .init.init_platform = ms_hyperv_init_platform,
> + .init.guest_late_init   = ms_hyperv_late_init,
>  #ifdef CONFIG_AMD_MEM_ENCRYPT
>   .runtime.sev_es_hcall_prepare = hv_sev_es_hcall_prepare,
>   .runtime.sev_es_hcall_finish = hv_sev_es_hcall_finish,
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 0285a74363b3..724de94d885f 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -20,8 +20,11 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -347,6 +350,72 @@ int __init hv_common_init(void)
>   return 0;
>  }
>  
> +void __init ms_hyperv_late_init(void)
> +{
> + struct acpi_table_header *header;
> + acpi_status status;
> + u8 *randomdata;
> + u32 length, i;
> +
> + /*
> +  * Seed the Linux random number generator with entropy provided by
> +  * the Hyper-V host in ACPI table OEM0.
> +  */
> + if

[PATCH v3] mshyperv: Introduce hv_numa_node_to_pxm_info()

2024-03-22 Thread Nuno Das Neves
Factor out logic for converting numa node to hv_proximity_domain_info
into a helper function.

Change hv_proximity_domain_info to a struct to improve readability.

While at it, rename hv_add_logical_processor_* structs to the correct
hv_input_/hv_output_ prefix, and remove the flags field which is not
present in the ABI.

Signed-off-by: Nuno Das Neves 
Reviewed-by: Wei Liu 

---

Changes in v3:
* Shorten function name to hv_numa_node_to_pxm_info()
* Correct hv_add_logical_processor_* naming, and remove flags

Changes in v2:
* Change hv_proximity_domain_info from union to struct to improve
  readability [Dave Hanson]

---
 arch/x86/hyperv/hv_proc.c | 22 --
 include/asm-generic/hyperv-tlfs.h | 19 +++
 include/asm-generic/mshyperv.h| 14 ++
 3 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 68a0843d4750..3fa1f2ee7b0d 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -116,12 +115,11 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 
num_pages)
 
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 {
-   struct hv_add_logical_processor_in *input;
-   struct hv_add_logical_processor_out *output;
+   struct hv_input_add_logical_processor *input;
+   struct hv_output_add_logical_processor *output;
u64 status;
unsigned long flags;
int ret = HV_STATUS_SUCCESS;
-   int pxm = node_to_pxm(node);
 
/*
 * When adding a logical processor, the hypervisor may return
@@ -137,11 +135,7 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
 
input->lp_index = lp_index;
input->apic_id = apic_id;
-   input->flags = 0;
-   input->proximity_domain_info.domain_id = pxm;
-   input->proximity_domain_info.flags.reserved = 0;
-   input->proximity_domain_info.flags.proximity_info_valid = 1;
-   input->proximity_domain_info.flags.proximity_preferred = 1;
+   input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
status = hv_do_hypercall(HVCALL_ADD_LOGICAL_PROCESSOR,
 input, output);
local_irq_restore(flags);
@@ -166,7 +160,6 @@ int hv_call_create_vp(int node, u64 partition_id, u32 
vp_index, u32 flags)
u64 status;
unsigned long irq_flags;
int ret = HV_STATUS_SUCCESS;
-   int pxm = node_to_pxm(node);
 
/* Root VPs don't seem to need pages deposited */
if (partition_id != hv_current_partition_id) {
@@ -185,14 +178,7 @@ int hv_call_create_vp(int node, u64 partition_id, u32 
vp_index, u32 flags)
input->vp_index = vp_index;
input->flags = flags;
input->subnode_type = HvSubnodeAny;
-   if (node != NUMA_NO_NODE) {
-   input->proximity_domain_info.domain_id = pxm;
-   input->proximity_domain_info.flags.reserved = 0;
-   input->proximity_domain_info.flags.proximity_info_valid 
= 1;
-   input->proximity_domain_info.flags.proximity_preferred 
= 1;
-   } else {
-   input->proximity_domain_info.as_uint64 = 0;
-   }
+   input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
local_irq_restore(irq_flags);
 
diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 87e3d49a4e29..814207e7c37f 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -512,13 +512,9 @@ struct hv_proximity_domain_flags {
u32 proximity_info_valid : 1;
 } __packed;
 
-/* Not a union in windows but useful for zeroing */
-union hv_proximity_domain_info {
-   struct {
-   u32 domain_id;
-   struct hv_proximity_domain_flags flags;
-   };
-   u64 as_uint64;
+struct hv_proximity_domain_info {
+   u32 domain_id;
+   struct hv_proximity_domain_flags flags;
 } __packed;
 
 struct hv_lp_startup_status {
@@ -532,14 +528,13 @@ struct hv_lp_startup_status {
 } __packed;
 
 /* HvAddLogicalProcessor hypercall */
-struct hv_add_logical_processor_in {
+struct hv_input_add_logical_processor {
u32 lp_index;
u32 apic_id;
-   union hv_proximity_domain_info proximity_domain_info;
-   u64 flags;
+   struct hv_proximity_domain_info proximity_domain_info;
 } __packed;
 
-struct hv_add_logical_processor_out {
+struct hv_output_add_logical_processor {
struct hv_lp_startup_status startup_status;
 } __packed;
 
@@ -560,7 +555,7 @@ struct hv_cr

Re: [PATCH] Drivers: hv: vmbus: Deferring per cpu tasks

2024-07-25 Thread Nuno Das Neves
On 7/24/2024 10:26 PM, Saurabh Sengar wrote:
> Currently on a very large system with 1780 CPUs, hv_acpi_init takes
> around 3 seconds to complete for all the CPUs. This is because of
> sequential synic initialization for each CPU.
> 
> Defer these tasks so that each CPU executes hv_acpi_init in parallel
> to take full advantage of multiple CPUs.

I think you mean hv_synic_init() here, not hv_acpi_init()?

> 
> This solution saves around 2 seconds of boot time on a 1780 CPU system,
> that around 66% improvement in the existing logic.
> 
> Signed-off-by: Saurabh Sengar 
> ---
>  drivers/hv/vmbus_drv.c | 33 ++---
>  1 file changed, 30 insertions(+), 3 deletions(-)
> 

LGTM otherwise.

Reviewed-by: Nuno Das Neves 




Re: [PATCH 5/5] hyperv: Use hvhdk.h instead of hyperv-tlfs.h in Hyper-V code

2024-10-04 Thread Nuno Das Neves
On 10/4/2024 8:58 AM, Stanislav Kinsburskii wrote:
> Hi Nuno,
> 
> On Thu, Oct 03, 2024 at 12:51:04PM -0700, Nuno Das Neves wrote:
>> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
>> index 9d1969b875e9..bb7f28f74bf4 100644
>> --- a/arch/arm64/hyperv/hv_core.c
>> +++ b/arch/arm64/hyperv/hv_core.c
>> @@ -14,6 +14,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#define HYPERV_NONTLFS_HEADERS
>>  #include 
>>  
> 
> Perhaps it would be cleaner to introduce a new header file to be
> included, containing the new define and including  instead.
> 
> Stas

If I understand correctly, you're suggesting adding another stub named e.g.
"hv_mshyperv.h", containing:

#define HYPERV_NONTLFS_HEADERS
#include

Then in the roughly 24 places in this patch where we have:

+#define HYPERV_NONTLFS_HEADERS

Instead, we'd have:

-#include 
+#include 

I suppose the current version is a bit opaque - it's not immediately clear
why HYPERV_NONTLFs_HEADERS is defined, and that it must be defined before
including asm/mshyperv.h - someone reading the code would have to go find
hv_defs.h to puzzle that out.

This improves the situation slightly by associating the #define with
asm/mshyperv.h. I'll consider it for v2, thanks!

Nuno



Re: [PATCH 5/5] hyperv: Use hvhdk.h instead of hyperv-tlfs.h in Hyper-V code

2024-10-04 Thread Nuno Das Neves
On 10/4/2024 12:11 PM, Simon Horman wrote:
> Hi,
> 
> With this change in place I see allmodconfig x86_64 builds reporting that
> HV_REGISTER_FEATURES is undeclared.
> 
> arch/arm64/hyperv/mshyperv.c: In function 'hyperv_init':
> arch/arm64/hyperv/mshyperv.c:53:26: error: 'HV_REGISTER_FEATURES' undeclared 
> (first use in this function); did you mean 'HV_REGISTER_FEATURES_INFO'?
>53 | hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
>   |  ^~~~
>   |  HV_REGISTER_FEATURES_INFO
> arch/arm64/hyperv/mshyperv.c:53:26: note: each undeclared identifier is 
> reported only once for each function it appears in
> arch/arm64/hyperv/mshyperv.c:58:26: error: 'HV_REGISTER_ENLIGHTENMENTS' 
> undeclared (first use in this function); did you mean 
> 'HV_ACCESS_REENLIGHTENMENT'?
>58 | hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
>   |  ^~
>   |  HV_ACCESS_REENLIGHTENMENT
> 

Ah, I did forgot to check arm64. Thanks for the catch, I'll be sure to
fix it for v2.

> 
> And here too, with x86_64 allmodconfig.
> 
> In file included from ./include/linux/string.h:390,
>  from ./include/linux/efi.h:16,
>  from arch/x86/hyperv/hv_init.c:12:
> arch/x86/hyperv/hv_init.c: In function 'get_vtl':
> ./include/linux/overflow.h:372:23: error: invalid application of 'sizeof' to 
> incomplete type 'struct hv_get_vp_registers_input'
>   372 | sizeof(*(p)) + flex_array_size(p, member, count), 
>   \
>   |   ^
> ./include/linux/fortify-string.h:502:42: note: in definition of macro 
> '__fortify_memset_chk'
>   502 | size_t __fortify_size = (size_t)(size);   
>   \
>   |  ^~~~
> arch/x86/hyperv/hv_init.c:427:9: note: in expansion of macro 'memset'
>   427 | memset(input, 0, struct_size(input, element, 1));
>   | ^~
> arch/x86/hyperv/hv_init.c:427:26: note: in expansion of macro 'struct_size'
>   427 | memset(input, 0, struct_size(input, element, 1));
>   |  ^~~
> 
> [errors trimmed for the sake of brevity]
> 
> ...
> 

Thanks

> 
> And, likewise, with this patch applied I see a number of errors when
> compiling this file. This is with allmodconfig on x86_64 with:
> 
> Modified: CONFIG_HYPERV=y (instead of m)
> Added: CONFIG_HYPERV_VTL_MODE=y
> 

Thanks again,
Ah, I wish there was a way to check these different combinations of y/m
more easily.

> arch/x86/hyperv/hv_vtl.c: In function 'hv_vtl_bringup_vcpu':
> arch/x86/hyperv/hv_vtl.c:154:34: error: 'HVCALL_ENABLE_VP_VTL' undeclared 
> (first use in this function)
>   154 | status = hv_do_hypercall(HVCALL_ENABLE_VP_VTL, input, NULL);
>   |  ^~~~
> arch/x86/hyperv/hv_vtl.c:154:34: note: each undeclared identifier is reported 
> only once for each function it appears in
> In file included from ./include/linux/string.h:390,
>  from ./include/linux/bitmap.h:13,
>  from ./include/linux/cpumask.h:12,
>  from ./arch/x86/include/asm/apic.h:5,
>  from arch/x86/hyperv/hv_vtl.c:9:
> arch/x86/hyperv/hv_vtl.c: In function 'hv_vtl_apicid_to_vp_id':
> arch/x86/hyperv/hv_vtl.c:189:32: error: invalid application of 'sizeof' to 
> incomplete type 'struct hv_get_vp_from_apic_id_in'
>   189 | memset(input, 0, sizeof(*input));
>   |^
> ./include/linux/fortify-string.h:502:42: note: in definition of macro 
> '__fortify_memset_chk'
>   502 | size_t __fortify_size = (size_t)(size);   
>   \
>   |  ^~~~
> arch/x86/hyperv/hv_vtl.c:189:9: note: in expansion of macro 'memset'
>   189 | memset(input, 0, sizeof(*input));
>   | ^~
> arch/x86/hyperv/hv_vtl.c:190:14: error: invalid use of undefined type 'struct 
> hv_get_vp_from_apic_id_in'
>   190 | input->partition_id = HV_PARTITION_ID_SELF;
>   |  ^~
> arch/x86/hyperv/hv_vtl.c:191:14: error: invalid use of undefined type 'struct 
> hv_get_vp_from_apic_id_in'
>   191 | input->apic_ids[0] = apic_id;
>   |  ^~
> arch/x86/hyperv/hv_vtl.c:195:45: error: 'HVCALL_GET_VP_ID_FROM_APIC_ID' 
> undeclared (first use in this function)
>   195 | control = HV_HYPERCALL_REP_COMP_1 | 
> HVCALL_GET_VP_ID_FROM_APIC_ID;
>   | 
> ^
> 
> ...

Looks like I'm missing a one or two definitions in the new headers, and the
names have changed slightly in couple of cases. I'll do some more thorough
checking and have it all fixed for v2.

I didn't know about this allmodconfig target, that will make it a bit easier!

Nuno



[PATCH 4/5] hyperv: Add hv_defs.h to conditionally include hyperv-tlfs.h or hvhdk.h

2024-10-03 Thread Nuno Das Neves
Include one or the other depending on whether HYPERV_NONTLFS_HEADERS is
defined.

This will allow Hyper-V code to use the new headers while other code can
continue using hyperv-tlfs.h which is only for Hyper-V guests.

Replace hyperv-tlfs.h in shared headers with hv_defs.h These headers are
shared between Hyper-V code and non-Hyper-V code (KVM for example). This
will allow switching to the new headers in Hyper-V code only.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/include/asm/mshyperv.h  |  2 +-
 arch/x86/include/asm/mshyperv.h|  2 +-
 arch/x86/include/asm/svm.h |  2 +-
 include/asm-generic/mshyperv.h |  2 +-
 include/clocksource/hyperv_timer.h |  2 +-
 include/hyperv/hv_defs.h   | 29 +
 6 files changed, 34 insertions(+), 5 deletions(-)
 create mode 100644 include/hyperv/hv_defs.h

diff --git a/arch/arm64/include/asm/mshyperv.h 
b/arch/arm64/include/asm/mshyperv.h
index a975e1a689dd..13b2b2218d85 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -20,7 +20,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Declare calls to get and set Hyper-V VP register values on ARM64, which
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 47ca48062547..dc8587f02850 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -6,9 +6,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
+#include 
 
 /*
  * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index f0dea3750ca9..c682fc080310 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -5,7 +5,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 /*
  * 32-bit intercept words in the VMCB Control Area, starting
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8fe7aaab2599..8bd308ae1056 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -25,7 +25,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define VTPM_BASE_ADDRESS 0xfed4
 
diff --git a/include/clocksource/hyperv_timer.h 
b/include/clocksource/hyperv_timer.h
index 6cdc873ac907..068ca1934c23 100644
--- a/include/clocksource/hyperv_timer.h
+++ b/include/clocksource/hyperv_timer.h
@@ -15,7 +15,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 #define HV_MAX_MAX_DELTA_TICKS 0x
 #define HV_MIN_DELTA_TICKS 1
diff --git a/include/hyperv/hv_defs.h b/include/hyperv/hv_defs.h
new file mode 100644
index ..eed500288499
--- /dev/null
+++ b/include/hyperv/hv_defs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This file includes Microsoft Hypervisor definitions from hyperv-tlfs.h, or
+ * hvhdk.h when HYPERV_NONTLFS_HEADERS is defined.
+ */
+/*
+ * NOTE:
+ * The typical #ifdef guard to prevent redefinition errors is intentionally
+ * omitted. This makes compiler error (either via #error or redefinition) in
+ * the case where hyperv-tlfs.h is accidentally included, followed by
+ * definition of HYPERV_NON_TLFS_HEADERS and inclusion of this file.
+ * If this file could only be included once, the compiler would ignore the
+ * attempt to use HYPERV_NONTLFS_HEADERS to include hvhdk.h.
+ */
+
+#ifdef HYPERV_NONTLFS_HEADERS
+
+#ifdef HYPERV_TLFS_HEADERS_INCLUDED
+#error "hyperv-tlfs.h was already included before HYPERV_NONTLFS_HEADERS was 
defined"
+#else
+#include 
+#endif
+
+#else /* HYPERV_NONTLFS_HEADERS */
+
+#include 
+#define HYPERV_TLFS_HEADERS_INCLUDED
+
+#endif /* !HYPERV_NONTLFS_HEADERS */
-- 
2.34.1




[PATCH 1/5] hyperv: Move hv_connection_id to hyperv-tlfs.h

2024-10-03 Thread Nuno Das Neves
This definition is in the wrong file; it is part of the TLFS doc.

Signed-off-by: Nuno Das Neves 
---
 include/asm-generic/hyperv-tlfs.h | 9 +
 include/linux/hyperv.h| 9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 814207e7c37f..52274c9aefef 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -871,4 +871,13 @@ struct hv_mmio_write_input {
u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
 } __packed;
 
+/* Define connection identifier type. */
+union hv_connection_id {
+   u32 asu32;
+   struct {
+   u32 id:24;
+   u32 reserved:8;
+   } u;
+};
+
 #endif
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 22c22fb91042..d0893ec488ae 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -768,15 +768,6 @@ struct vmbus_close_msg {
struct vmbus_channel_close_channel msg;
 };
 
-/* Define connection identifier type. */
-union hv_connection_id {
-   u32 asu32;
-   struct {
-   u32 id:24;
-   u32 reserved:8;
-   } u;
-};
-
 enum vmbus_device_type {
HV_IDE = 0,
HV_SCSI,
-- 
2.34.1




[PATCH 0/5] Add new headers for Hyper-V Dom0

2024-10-03 Thread Nuno Das Neves
To support Hyper-V Dom0 (aka Linux as root partition), many new
definitions are required.

The plan going forward is to directly import headers from
Hyper-V. This is a more maintainable way to import definitions
rather than via the TLFS doc. This patch series introduces
new headers (hvhdk.h, hvgdk.h, etc, see patch #3) directly
derived from Hyper-V code.

This patch series replaces hyperv-tlfs.h with hvhdk.h, but only
in Microsoft-maintained Hyper-V code where they are needed. This
leaves the existing hyperv-tlfs.h in use elsewhere - notably for
Hyper-V enlightenments on KVM guests.

An intermediary header "hv_defs.h" is introduced to conditionally
include either hyperv-tlfs.h or hvhdk.h. This is required because
several headers which today include hyperv-tlfs.h, are shared
between Hyper-V and KVM code (e.g. mshyperv.h).

Summary:
Patch 1-2: Cleanup patches
Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
Patch 4: Add hv_defs.h and use it in mshyperv.h, svm.h,
 hyperv_timer.h
Patch 5: Switch to the new headers, only in Hyper-V code

Nuno Das Neves (5):
  hyperv: Move hv_connection_id to hyperv-tlfs.h
  hyperv: Remove unnecessary #includes
  hyperv: Add new Hyper-V headers
  hyperv: Add hv_defs.h to conditionally include hyperv-tlfs.h or
hvhdk.h
  hyperv: Use hvhdk.h instead of hyperv-tlfs.h in Hyper-V code

 arch/arm64/hyperv/hv_core.c  |3 +-
 arch/arm64/hyperv/mshyperv.c |1 +
 arch/arm64/include/asm/mshyperv.h|2 +-
 arch/x86/entry/vdso/vma.c|1 +
 arch/x86/hyperv/hv_apic.c|2 +-
 arch/x86/hyperv/hv_init.c|3 +-
 arch/x86/hyperv/hv_proc.c|4 +-
 arch/x86/hyperv/hv_spinlock.c|1 +
 arch/x86/hyperv/hv_vtl.c |1 +
 arch/x86/hyperv/irqdomain.c  |1 +
 arch/x86/hyperv/ivm.c|2 +-
 arch/x86/hyperv/mmu.c|2 +-
 arch/x86/hyperv/nested.c |2 +-
 arch/x86/include/asm/kvm_host.h  |1 -
 arch/x86/include/asm/mshyperv.h  |3 +-
 arch/x86/include/asm/svm.h   |2 +-
 arch/x86/include/asm/vdso/gettimeofday.h |1 +
 arch/x86/kernel/cpu/mshyperv.c   |2 +-
 arch/x86/kernel/cpu/mtrr/generic.c   |1 +
 arch/x86/kvm/vmx/vmx_onhyperv.h  |1 -
 arch/x86/mm/pat/set_memory.c |2 -
 drivers/clocksource/hyperv_timer.c   |2 +-
 drivers/hv/channel.c |1 +
 drivers/hv/channel_mgmt.c|1 +
 drivers/hv/connection.c  |1 +
 drivers/hv/hv.c  |1 +
 drivers/hv/hv_balloon.c  |5 +-
 drivers/hv/hv_common.c   |2 +-
 drivers/hv/hv_kvp.c  |1 -
 drivers/hv/hv_snapshot.c |1 -
 drivers/hv/hv_util.c |1 +
 drivers/hv/hyperv_vmbus.h|1 -
 drivers/hv/ring_buffer.c |1 +
 drivers/hv/vmbus_drv.c   |1 +
 drivers/iommu/hyperv-iommu.c |1 +
 drivers/net/hyperv/netvsc.c  |1 +
 drivers/pci/controller/pci-hyperv.c  |1 +
 include/asm-generic/hyperv-tlfs.h|9 +
 include/asm-generic/mshyperv.h   |2 +-
 include/clocksource/hyperv_timer.h   |2 +-
 include/hyperv/hv_defs.h |   29 +
 include/hyperv/hvgdk.h   |   66 ++
 include/hyperv/hvgdk_ext.h   |   46 +
 include/hyperv/hvgdk_mini.h  | 1212 ++
 include/hyperv/hvhdk.h   |  733 +
 include/hyperv/hvhdk_mini.h  |  310 ++
 include/linux/hyperv.h   |   12 +-
 net/vmw_vsock/hyperv_transport.c |1 -
 48 files changed, 2442 insertions(+), 40 deletions(-)
 create mode 100644 include/hyperv/hv_defs.h
 create mode 100644 include/hyperv/hvgdk.h
 create mode 100644 include/hyperv/hvgdk_ext.h
 create mode 100644 include/hyperv/hvgdk_mini.h
 create mode 100644 include/hyperv/hvhdk.h
 create mode 100644 include/hyperv/hvhdk_mini.h

-- 
2.34.1




[PATCH 2/5] hyperv: Remove unnecessary #includes

2024-10-03 Thread Nuno Das Neves
asm/hyperv-tlfs.h is already included implicitly wherever mshyperv.h
or linux/hyperv.h is included. Remove those redundancies.

Remove includes of linux/hyperv.h and mshyperv.h where they are not
needed.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c| 2 --
 arch/x86/hyperv/hv_apic.c  | 1 -
 arch/x86/hyperv/hv_init.c  | 2 --
 arch/x86/hyperv/hv_proc.c  | 1 -
 arch/x86/hyperv/ivm.c  | 1 -
 arch/x86/hyperv/mmu.c  | 1 -
 arch/x86/hyperv/nested.c   | 1 -
 arch/x86/include/asm/kvm_host.h| 1 -
 arch/x86/include/asm/mshyperv.h| 1 -
 arch/x86/kernel/cpu/mshyperv.c | 1 -
 arch/x86/kvm/vmx/vmx_onhyperv.h| 1 -
 arch/x86/mm/pat/set_memory.c   | 2 --
 drivers/clocksource/hyperv_timer.c | 1 -
 drivers/hv/hv_balloon.c| 2 --
 drivers/hv/hv_common.c | 1 -
 drivers/hv/hv_kvp.c| 1 -
 drivers/hv/hv_snapshot.c   | 1 -
 drivers/hv/hyperv_vmbus.h  | 1 -
 net/vmw_vsock/hyperv_transport.c   | 1 -
 19 files changed, 23 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index f1ebc025e1df..9d1969b875e9 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -11,11 +11,9 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
-#include 
 #include 
 
 /*
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 0569f579338b..f022d5f64fb6 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 17a71e92a343..fc3c3d76c181 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -27,7 +26,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 3fa1f2ee7b0d..b74c06c04ff1 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 60fc3ed72830..b56d70612734 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -7,7 +7,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 1cc113200ff5..cc8c3bd0e7c2 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -1,6 +1,5 @@
 #define pr_fmt(fmt)  "Hyper-V: " fmt
 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/nested.c b/arch/x86/hyperv/nested.c
index 9dc259fa322e..ee06d0315c24 100644
--- a/arch/x86/hyperv/nested.c
+++ b/arch/x86/hyperv/nested.c
@@ -11,7 +11,6 @@
 
 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4a68cb3eba78..3627eab994a3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 390c4d13956d..47ca48062547 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -9,7 +9,6 @@
 #include 
 #include 
 #include 
-#include 
 
 /*
  * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index e0fd57a8ba84..8e8fd23b1439 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -20,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/kvm/vmx/vmx_onhyperv.h b/arch/x86/kvm/vmx/vmx_onhyperv.h
index eb48153bfd73..f4b081eb6521 100644
--- a/arch/x86/kvm/vmx/vmx_onhyperv.h
+++ b/arch/x86/kvm/vmx/vmx_onhyperv.h
@@ -3,7 +3,6 @@
 #ifndef __ARCH_X86_KVM_VMX_ONHYPERV_H__
 #define __ARCH_X86_KVM_VMX_ONHYPERV_H__
 
-#include 
 #include 
 
 #include 
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 44f7b2ea6a07..85fa0d4509f0 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -32,8 +32,6 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #include "../mm_internal.h"
 
diff --git a/drivers/clocksource/hyperv_timer.c 
b/drivers/clocksource/hyperv_timer.c
index b2a080647e41..1b7de45a7185 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 static struct clock_event_device __percpu *hv_clock_event;
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index c38dcdfcb914..a120e9b80ded 100644
--- a/drivers/hv/hv_bal

[PATCH 3/5] hyperv: Add new Hyper-V headers

2024-10-03 Thread Nuno Das Neves
Add definitions needed for privileged Hyper-V partitions.

These files are derived from headers exported from the hypervisor code.
This is a step toward importing headers directly, similar to Xen public
files in include/xen/interface/.

Signed-off-by: Nuno Das Neves 
---
 include/hyperv/hvgdk.h  |   66 ++
 include/hyperv/hvgdk_ext.h  |   46 ++
 include/hyperv/hvgdk_mini.h | 1212 +++
 include/hyperv/hvhdk.h  |  733 +
 include/hyperv/hvhdk_mini.h |  310 +
 5 files changed, 2367 insertions(+)
 create mode 100644 include/hyperv/hvgdk.h
 create mode 100644 include/hyperv/hvgdk_ext.h
 create mode 100644 include/hyperv/hvgdk_mini.h
 create mode 100644 include/hyperv/hvhdk.h
 create mode 100644 include/hyperv/hvhdk_mini.h

diff --git a/include/hyperv/hvgdk.h b/include/hyperv/hvgdk.h
new file mode 100644
index ..af44e8034090
--- /dev/null
+++ b/include/hyperv/hvgdk.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Type definitions for the Microsoft Hypervisor.
+ */
+#ifndef _HV_HVGDK_H
+#define _HV_HVGDK_H
+
+#include "hvgdk_mini.h"
+#include "hvgdk_ext.h"
+
+/*
+ * The guest OS needs to register the guest ID with the hypervisor.
+ * The guest ID is a 64 bit entity and the structure of this ID is
+ * specified in the Hyper-V TLFS specification.
+ *
+ * While the current guideline does not specify how Linux guest ID(s)
+ * need to be generated, our plan is to publish the guidelines for
+ * Linux and other guest operating systems that currently are hosted
+ * on Hyper-V. The implementation here conforms to this yet
+ * unpublished guidelines.
+ *
+ * Bit(s)
+ * 63 - Indicates if the OS is Open Source or not; 1 is Open Source
+ * 62:56 - Os Type; Linux is 0x100
+ * 55:48 - Distro specific identification
+ * 47:16 - Linux kernel version number
+ * 15:0  - Distro specific identification
+ */
+
+#define HV_LINUX_VENDOR_ID  0x8100
+
+/*
+ * Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
+ * SVM enlightenments to guests. This is documented in the TLFS doc.
+ * HV_VMX_ENLIGHTENED_VMCS or SVM_NESTED_ENLIGHTENED_VMCB_FIELDS
+ */
+struct hv_vmcb_enlightenments {
+   struct __packed hv_enlightenments_control {
+   u32 nested_flush_hypercall : 1;
+   u32 msr_bitmap : 1;
+   u32 enlightened_npt_tlb: 1;
+   u32 reserved : 29;
+   } __packed hv_enlightenments_control;
+   u32 hv_vp_id;
+   u64 hv_vm_id;
+   u64 partition_assist_page;
+   u64 reserved;
+} __packed;
+
+/* Define connection identifier type. */
+union hv_connection_id {
+   u32 asu32;
+   struct {
+   u32 id : 24;
+   u32 reserved : 8;
+   } __packed u;
+};
+
+struct hv_input_unmap_gpa_pages {
+   u64 target_partition_id;
+   u64 target_gpa_base;
+   u32 unmap_flags;
+   u32 padding;
+} __packed;
+
+#endif /* #ifndef _HV_HVGDK_H */
diff --git a/include/hyperv/hvgdk_ext.h b/include/hyperv/hvgdk_ext.h
new file mode 100644
index ..641b591ee61f
--- /dev/null
+++ b/include/hyperv/hvgdk_ext.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Type definitions for the Microsoft Hypervisor.
+ */
+#ifndef _HV_HVGDK_EXT_H
+#define _HV_HVGDK_EXT_H
+
+#include "hvgdk_mini.h"
+
+/* Extended hypercalls */
+#define HV_EXT_CALL_QUERY_CAPABILITIES 0x8001
+#define HV_EXT_CALL_MEMORY_HEAT_HINT   0x8003
+
+/* Extended hypercalls */
+enum { /* HV_EXT_CALL */
+   HV_EXTCALL_QUERY_CAPABILITIES = 0x8001,
+   HV_EXTCALL_MEMORY_HEAT_HINT   = 0x8003,
+};
+
+/* HV_EXT_OUTPUT_QUERY_CAPABILITIES */
+#define HV_EXT_CAPABILITY_MEMORY_COLD_DISCARD_HINT BIT(8)
+
+enum { /* HV_EXT_MEMORY_HEAT_HINT_TYPE */
+   HV_EXTMEM_HEAT_HINT_COLD = 0,
+   HV_EXTMEM_HEAT_HINT_HOT = 1,
+   HV_EXTMEM_HEAT_HINT_COLD_DISCARD = 2,
+   HV_EXTMEM_HEAT_HINT_MAX
+};
+
+/*
+ * The whole argument should fit in a page to be able to pass to the hypervisor
+ * in one hypercall.
+ */
+#define HV_MEMORY_HINT_MAX_GPA_PAGE_RANGES  \
+   ((HV_HYP_PAGE_SIZE - sizeof(struct hv_memory_hint)) / \
+   sizeof(union hv_gpa_page_range))
+
+/* HvExtCallMemoryHeatHint hypercall */
+#define HV_EXT_MEMORY_HEAT_HINT_TYPE_COLD_DISCARD  2
+struct hv_memory_hint {/* HV_EXT_INPUT_MEMORY_HEAT_HINT */
+   u64 heat_type : 2;  /* HV_EXTMEM_HEAT_HINT_* */
+   u64 reserved : 62;
+   union hv_gpa_page_range ranges[];
+} __packed;
+
+#endif /* _HV_HVGDK_EXT_H */
diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
new file mode 100644
index ..b7dd22784c96
--- /dev/null
+++ b/include/hyperv/hvgdk_mini.h
@@ -0,0 +1,1212 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Type definitions for the Microsoft hypervisor.
+ */
+#ifndef _HV_HVGDK_MINI_H
+#define _HV_HVGDK_MINI_H
+
+#include 
+#include 
+
+struct 

[PATCH 5/5] hyperv: Use hvhdk.h instead of hyperv-tlfs.h in Hyper-V code

2024-10-03 Thread Nuno Das Neves
To move toward importing headers from Hyper-V directly, switch to
using hvhdk.h in all Hyper-V code. KVM code that uses Hyper-V
definitions from hyperv-tlfs.h remains untouched.

Add HYPERV_NONTLFS_HEADERS everywhere mshyperv.h, asm/svm.h,
clocksource/hyperv_timer.h is included in Hyper-V code.

Replace hyperv-tlfs.h with hvhdk.h directly in linux/hyperv.h, and
define HYPERV_NONTLFS_HEADERS there, since it is only used in
Hyper-V device code.

Update a couple of definitions to updated names found in the new
headers: HV_EXT_MEM_HEAT_HINT, HV_SUBNODE_TYPE_ANY.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c  | 1 +
 arch/arm64/hyperv/mshyperv.c | 1 +
 arch/x86/entry/vdso/vma.c| 1 +
 arch/x86/hyperv/hv_apic.c| 1 +
 arch/x86/hyperv/hv_init.c| 1 +
 arch/x86/hyperv/hv_proc.c| 3 ++-
 arch/x86/hyperv/hv_spinlock.c| 1 +
 arch/x86/hyperv/hv_vtl.c | 1 +
 arch/x86/hyperv/irqdomain.c  | 1 +
 arch/x86/hyperv/ivm.c| 1 +
 arch/x86/hyperv/mmu.c| 1 +
 arch/x86/hyperv/nested.c | 1 +
 arch/x86/include/asm/vdso/gettimeofday.h | 1 +
 arch/x86/kernel/cpu/mshyperv.c   | 1 +
 arch/x86/kernel/cpu/mtrr/generic.c   | 1 +
 drivers/clocksource/hyperv_timer.c   | 1 +
 drivers/hv/channel.c | 1 +
 drivers/hv/channel_mgmt.c| 1 +
 drivers/hv/connection.c  | 1 +
 drivers/hv/hv.c  | 1 +
 drivers/hv/hv_balloon.c  | 3 ++-
 drivers/hv/hv_common.c   | 1 +
 drivers/hv/hv_util.c | 1 +
 drivers/hv/ring_buffer.c | 1 +
 drivers/hv/vmbus_drv.c   | 1 +
 drivers/iommu/hyperv-iommu.c | 1 +
 drivers/net/hyperv/netvsc.c  | 1 +
 drivers/pci/controller/pci-hyperv.c  | 1 +
 include/linux/hyperv.h   | 3 ++-
 29 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index 9d1969b875e9..bb7f28f74bf4 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 
 /*
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index b1a4de4eee29..62b2a270ae65 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 
 static bool hyperv_initialized;
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 6d83ceb7f1ba..5f4053c49658 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 
 #undef _ASM_X86_VVAR_H
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f022d5f64fb6..4fe3b3b13256 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 #include 
 
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index fc3c3d76c181..680c4abc456e 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index b74c06c04ff1..428542134b84 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 #include 
 
@@ -176,7 +177,7 @@ int hv_call_create_vp(int node, u64 partition_id, u32 
vp_index, u32 flags)
input->partition_id = partition_id;
input->vp_index = vp_index;
input->flags = flags;
-   input->subnode_type = HvSubnodeAny;
+   input->subnode_type = HV_SUBNODE_ANY;
input->proximity_domain_info = hv_numa_node_to_pxm_info(node);
status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL);
local_irq_restore(irq_flags);
diff --git a/arch/x86/hyperv/hv_spinlock.c b/arch/x86/hyperv/hv_spinlock.c
index 151e851bef09..7e8e2c03f669 100644
--- a/arch/x86/hyperv/hv_spinlock.c
+++ b/arch/x86/hyperv/hv_spinlock.c
@@ -12,6 +12,7 @@
 
 #include 
 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
index 04775346369c..a8bb6ad7efb6 100644
--- a/arch/x86/hyperv/hv_vtl.c
+++ b/arch/x86/hyperv/hv_vtl.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#define HYPERV_NONTLFS_HEADERS
 #include 
 #include 
 #include <../kernel/smpboot.h>
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdom

Re: [EXTERNAL] RE: [PATCH 0/5] Add new headers for Hyper-V Dom0

2024-10-22 Thread Nuno Das Neves
Michael - sorry for the delay, I just got back from vacation.

On 10/10/2024 6:34 PM, MUKESH RATHOR wrote:
> 
> 
> On 10/10/24 11:21, Michael Kelley wrote:
>  > From: Nuno Das Neves  Sent: 
> Thursday, October 3, 2024 12:51 PM
>  >>
>  >> To support Hyper-V Dom0 (aka Linux as root partition), many new
>  >> definitions are required.
>  >>
>  >> The plan going forward is to directly import headers from
>  >> Hyper-V. This is a more maintainable way to import definitions
>  >> rather than via the TLFS doc. This patch series introduces
>  >> new headers (hvhdk.h, hvgdk.h, etc, see patch #3) directly
>  >> derived from Hyper-V code.
>  >>
>  >> This patch series replaces hyperv-tlfs.h with hvhdk.h, but only
>  >> in Microsoft-maintained Hyper-V code where they are needed. This
>  >> leaves the existing hyperv-tlfs.h in use elsewhere - notably for
>  >> Hyper-V enlightenments on KVM guests.
>  >
>  > Could you elaborate on why the bifurcation is necessary? Is it an
>  > interim step until the KVM code can use the new scheme as well?

It's not strictly necessary. We chose this approach in order to
minimize any potential impact on KVM and other non-Microsoft-
maintained code that uses hyperv-tlfs.h. As Mukesh mentioned below,
eventually it will be better if everyone uses the new headers.

>  > Also, does "Hyper-V enlightenments on KVM guests" refer to
>  > nested KVM running at L1 on an L0 Hyper-V, and supporting L2 guests?
>  > Or is it the more general KVM support for mimicking Hyper-V for
>  > the purposes of running Windows guests? From these patches, it
>  > looks like your intention is for all KVM support for Hyper-V
>  > functionality to continue to use the existing hyperv-tlfs.h file.

You're correct - "all KVM support for Hyper-V" is really what I meant.
> 
> Like it says above, we are creating new dom0 (root/host) support
> that requires many new defs only available to dom0 and not any
> guest. Hypervisor makes them publicly available via hv*dk files.
> 
> Ideally, someday everybody will use those, I hope we can move in
> that direction, but I guess one step at a time. For now, KVM can
> continue to use the tlfs file, and if there is no resistance, we
> can move them to hv*dk files also as next step and obsolete the
> single tlfs file.
> 
> Since headers are the ultimate source of truth, this will allow
> better maintenance, better debug/support experience, and a more
> stable stack. It also enforces non-leaking of data structs from
> private header files (unfortunately has happened).
> 
> Thanks
> -Mukesh
> 

Thanks for providing the additional context, Mukesh.

Nuno




Re: [PATCH 0/5] Add new headers for Hyper-V Dom0

2024-10-22 Thread Nuno Das Neves
On 10/10/2024 11:21 AM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Thursday, 
> October 3, 2024 12:51 PM
>>>> An intermediary header "hv_defs.h" is introduced to conditionally
>> include either hyperv-tlfs.h or hvhdk.h. This is required because
>> several headers which today include hyperv-tlfs.h, are shared
>> between Hyper-V and KVM code (e.g. mshyperv.h).
> 
> Have you considered user space code that uses
> include/linux/hyperv.h? Which of the two schemes will it use? That code
> needs to compile correctly on x86 and ARM64 after your changes.
> User space code includes the separate DPDK project, and some of the
> tools in the kernel tree under tools/hv. Anything that uses the
> uio_hv_generic.c driver falls into this category.
> 
Unless I misunderstand something, the uapi code isn't affected at all
by this patch set. e.g. the code in tools/hv uses include/uapi/linux/hyperv.h,
which doesn't include any other Hyper-V headers.

I'm not aware of how the DPDK project uses the Hyper-V definitions, but if it
is getting headers from uapi it should also be unaffected.

> I think there's also user space code that is built for vDSO that might pull
> in the .h files you are modifying. There are in-progress patches dealing
> with vDSO include files, such as [1]. My general comment on vDSO
> is to be careful in making #include file changes that it uses, but I'm
> not knowledgeable enough on how vDSO is built to give specific
> guidance. :-(
> 
Hmm, interesting, looks like it does get used by userspace. The tsc page
is mapped into userspace in vdso.vma.c, and read in vdso/gettimeofday.h.

That is unexpected for me, since these things aren't in uapi. However I don't
anticipate a problem. The definitions used haven't changed, just the headers
they are included from.

Thanks
Nuno

> Michael
> 
> [1] 
> https://lore.kernel.org/lkml/20241010135146.181175-1-vincenzo.frasc...@arm.com/
> 
>>
>> Summary:
>> Patch 1-2: Cleanup patches
>> Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
>> Patch 4: Add hv_defs.h and use it in mshyperv.h, svm.h,
>>  hyperv_timer.h
>> Patch 5: Switch to the new headers, only in Hyper-V code
>>
>> Nuno Das Neves (5):
>>   hyperv: Move hv_connection_id to hyperv-tlfs.h
>>   hyperv: Remove unnecessary #includes
>>   hyperv: Add new Hyper-V headers
>>   hyperv: Add hv_defs.h to conditionally include hyperv-tlfs.h or
>> hvhdk.h
>>   hyperv: Use hvhdk.h instead of hyperv-tlfs.h in Hyper-V code
>>
>>  arch/arm64/hyperv/hv_core.c  |3 +-
>>  arch/arm64/hyperv/mshyperv.c |1 +
>>  arch/arm64/include/asm/mshyperv.h|2 +-
>>  arch/x86/entry/vdso/vma.c|1 +
>>  arch/x86/hyperv/hv_apic.c|2 +-
>>  arch/x86/hyperv/hv_init.c|3 +-
>>  arch/x86/hyperv/hv_proc.c|4 +-
>>  arch/x86/hyperv/hv_spinlock.c|1 +
>>  arch/x86/hyperv/hv_vtl.c |1 +
>>  arch/x86/hyperv/irqdomain.c  |1 +
>>  arch/x86/hyperv/ivm.c|2 +-
>>  arch/x86/hyperv/mmu.c|2 +-
>>  arch/x86/hyperv/nested.c |2 +-
>>  arch/x86/include/asm/kvm_host.h  |1 -
>>  arch/x86/include/asm/mshyperv.h  |3 +-
>>  arch/x86/include/asm/svm.h   |2 +-
>>  arch/x86/include/asm/vdso/gettimeofday.h |1 +
>>  arch/x86/kernel/cpu/mshyperv.c   |2 +-
>>  arch/x86/kernel/cpu/mtrr/generic.c   |1 +
>>  arch/x86/kvm/vmx/vmx_onhyperv.h  |1 -
>>  arch/x86/mm/pat/set_memory.c |2 -
>>  drivers/clocksource/hyperv_timer.c   |2 +-
>>  drivers/hv/channel.c |1 +
>>  drivers/hv/channel_mgmt.c|1 +
>>  drivers/hv/connection.c  |1 +
>>  drivers/hv/hv.c  |1 +
>>  drivers/hv/hv_balloon.c  |5 +-
>>  drivers/hv/hv_common.c   |2 +-
>>  drivers/hv/hv_kvp.c  |1 -
>>  drivers/hv/hv_snapshot.c |1 -
>>  drivers/hv/hv_util.c |1 +
>>  drivers/hv/hyperv_vmbus.h|1 -
>>  drivers/hv/ring_buffer.c |1 +
>>  drivers/hv/vmbus_drv.c   |1 +
>>  drivers/iommu/hyperv-iommu.c |1 +
>>  drivers/net/hyperv/netvsc.c  |1 +
>>  drivers/pci/controller/pci-hyperv.c  |1 +
>>  include/asm-generic/hyper

Re: [PATCH 2/5] hyperv: Remove unnecessary #includes

2024-10-31 Thread Nuno Das Neves
On 10/10/2024 11:21 AM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Thursday, 
> October 3, 2024 12:51 PM
>>
>> asm/hyperv-tlfs.h is already included implicitly wherever mshyperv.h
>> or linux/hyperv.h is included. Remove those redundancies.
> 
> I've been under the impression that it is preferable to directly include
> .h files for all definitions that a source code file uses, even if the
> needed .h file is indirectly included by some other .h file. I looked through

I've also heard this idea, and generally try to stick to it. I myself
haven't yet encountered a situation where doing this or not has greatly
impacted the readability of the code.

> the coding style documentation, and didn't find anything addressing
> this topic, so maybe I'm wrong. But I know I've seen patches to other
> parts of the kernel that were changes to follow the direct inclusion
> approach.  Direct inclusion is less fragile if the #include file nesting
> structure changes (and perhaps removes the indirect inclusion).
> 
> The mshyperv.h and linux/hyperv.h dependency on hyperv-tlfs.h is
> highly unlikely to change, so the chance of breakage is minimal. But

You probably already understood this after seeing the later patches, but
it's worth pointing out that the goal of this series is to change that
dependency (situationally), which is exactly why I created this precursor
patch.

> I wonder if your approach is going the wrong direction vs. preferred
> kernel practices.
> 

I could replace  with  in most of these
cases (in v2), to preserve the explicit include of the definitions before
mshyperv.h or linux/hyperv.h. I will give it a try in v2.

Thanks,
Nuno

> Michael
> 
>>
>> Remove includes of linux/hyperv.h and mshyperv.h where they are not
>> needed.
>>
>> Signed-off-by: Nuno Das Neves 
>> ---
>>  arch/arm64/hyperv/hv_core.c| 2 --
>>  arch/x86/hyperv/hv_apic.c  | 1 -
>>  arch/x86/hyperv/hv_init.c  | 2 --
>>  arch/x86/hyperv/hv_proc.c  | 1 -
>>  arch/x86/hyperv/ivm.c  | 1 -
>>  arch/x86/hyperv/mmu.c  | 1 -
>>  arch/x86/hyperv/nested.c   | 1 -
>>  arch/x86/include/asm/kvm_host.h| 1 -
>>  arch/x86/include/asm/mshyperv.h| 1 -
>>  arch/x86/kernel/cpu/mshyperv.c | 1 -
>>  arch/x86/kvm/vmx/vmx_onhyperv.h| 1 -
>>  arch/x86/mm/pat/set_memory.c   | 2 --
>>  drivers/clocksource/hyperv_timer.c | 1 -
>>  drivers/hv/hv_balloon.c| 2 --
>>  drivers/hv/hv_common.c | 1 -
>>  drivers/hv/hv_kvp.c| 1 -
>>  drivers/hv/hv_snapshot.c   | 1 -
>>  drivers/hv/hyperv_vmbus.h  | 1 -
>>  net/vmw_vsock/hyperv_transport.c   | 1 -
>>  19 files changed, 23 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
>> index f1ebc025e1df..9d1969b875e9 100644
>> --- a/arch/arm64/hyperv/hv_core.c
>> +++ b/arch/arm64/hyperv/hv_core.c
>> @@ -11,11 +11,9 @@
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>>  #include 
>>
>>  /*
>> diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
>> index 0569f579338b..f022d5f64fb6 100644
>> --- a/arch/x86/hyperv/hv_apic.c
>> +++ b/arch/x86/hyperv/hv_apic.c
>> @@ -23,7 +23,6 @@
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>>  #include 
>>  #include 
>>  #include 
>> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
>> index 17a71e92a343..fc3c3d76c181 100644
>> --- a/arch/x86/hyperv/hv_init.c
>> +++ b/arch/x86/hyperv/hv_init.c
>> @@ -19,7 +19,6 @@
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -27,7 +26,6 @@
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>>  #include 
>>  #include 
>>  #include 
>> diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
>> index 3fa1f2ee7b0d..b74c06c04ff1 100644
>> --- a/arch/x86/hyperv/hv_proc.c
>> +++ b/arch/x86/hyperv/hv_proc.c
>> @@ -3,7 +3,6 @@
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>>  #include 
>>  #include 
>>  #include 
>> diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
>> index 60fc3ed72830..b56d70612734 100644
>> --- a/arch/x86/hyperv/ivm.c
>> +++ b/arch/x86/hyperv/ivm.c
>> @@ -7,7 +7,6 @@
>>   */
>>
>>  #include 
>> -#include 
&

Re: [PATCH v2 3/4] hyperv: Add new Hyper-V headers in include/hyperv

2024-11-11 Thread Nuno Das Neves
On 11/10/2024 8:13 PM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Thursday, 
> November 7, 2024 2:32 PM
>>
>> These headers contain definitions for regular Hyper-V guests (as in
>> hyperv-tlfs.h), as well as interfaces for more privileged guests like
>> Dom0.
> 
> See my comment on Patch 0/4 about use of "dom0" terminology.
> 

Thanks, noted.

>>
>> These files are derived from headers exported from Hyper-V, rather than
>> being derived from the TLFS document. (Although, to preserve
>> compatibility with existing Linux code, some definitions are copied
>> directly from hyperv-tlfs.h too).
>>
>> The new files follow a naming convention according to their original
>> use:
>> - hdk "host development kit"
>> - gdk "guest development kit"
>> With postfix "_mini" implying userspace-only headers, and "_ext" for
>> extended hypercalls.
>>
>> These names should be considered a rough guide only - since there are
>> many places already where both host and guest code are in the same
>> place, hvhdk.h (which includes everything) can be used most of the time.
> 
> Just curious -- are there really cases where hvhdk.h can't be used?
> If so, could you summarize why?
> 

No, there aren't cases where it "can't" be used. I suppose if someone
doesn't want to include everything, perhaps they could just include
hvgdk.h, for example. It doesn't really matter though.

> I ask because it would be nice to expand slightly on your paragraph
> below, as follows:  (if indeed what I've added is correct)
> 
> The use of multiple files and their original names is primarily to
> keep the provenance of exactly where they came from in Hyper-V
> code, which is helpful for manual maintenance and extension
> of these definitions. Microsoft maintainers importing new definitions
> should take care to put them in the right file. However, Linux kernel code
> that uses any of the definitions need not be aware of the multiple files
> or assign any meaning to the new names. Linux kernel uses should
> always just include hvhdk.h
> 

Thanks, I think that additional sentence helps clarify things. I'll
include it in the next version, and I think I can probably omit the prior
paragraph: "These names should be considered a rough guide only...".

>>
>> The original names are kept intact primarily to keep the provenance of
>> exactly where they came from in Hyper-V code, which is helpful for
>> manual maintenance and extension of these definitions. Microsoft
>> maintainers importing new definitions should take care to put them in
>> the right file.
>>
>> Note also that the files contain both arm64 and x86_64 code guarded by
>> \#ifdefs, which is how the definitions originally appear in Hyper-V.
> 
> Spurious backslash?
> 

Indeed, thanks.

> I would suggest some additional clarification:  The #ifdef guards are
> employed minimally where necessary to prevent conflicts due to
> different definitions for the same thing on x86_64 and arm64. Where
> there are no conflicts, the union of x86_64 definitions and arm64
> definitions is visible when building for either architecture. In other
> words, not all definitions specific to x86_64 are protected by #ifdef
> x86_64. Such unprotected definitions may be visible when building
> for arm64. And vice versa.
> 

Is there a reason you specifically want to point out that "Such
unprotected definitions may be visible when building for arm64. And vice
versa."? I think, in all the cases where #ifdefs are not used, an
arch-specific prefix is used - hv_x64_ or hv_arm64_.

The main thing I wanted to call out here was the reasoning for not
splitting arch-specific definitions into separate files in arch/x86/
and arch/arm64/ as is typical in Linux.

Maybe this is a bit clearer:
"
Note the new headers contain both arm64 and x86_64 definitions. Some are
guarded by #ifdefs, and some are instead prefixed with the architecture,
e.g. hv_x64_*. These conventions are kept from Hyper-V code as another
tactic to simplify the process of importing and maintaining the
definitions, rather than splitting them up into their own files in
arch/x86/ and arch/arm64/.
"

I hope it's reasonably clear that it's a good tradeoff to go against
Linux convention in this case, to make it easy to import and maintain
Hyper-V definitions.

Thanks
Nuno

> Michael
> 
>> Keeping this convention from Hyper-V code is another tactic for
>> simplying the process of importing new definitions.
>>
>> These headers are a step toward importing headers directly from Hyper-V
>> in the future, similar to Xen public files in includ

Re: [PATCH v2 3/4] hyperv: Add new Hyper-V headers in include/hyperv

2024-11-11 Thread Nuno Das Neves
On 11/7/2024 9:59 PM, Naman Jain wrote:
> 
> 
> On 11/8/2024 4:02 AM, Nuno Das Neves wrote:
>> These headers contain definitions for regular Hyper-V guests (as in
>> hyperv-tlfs.h), as well as interfaces for more privileged guests like
>> Dom0.
>>
>> These files are derived from headers exported from Hyper-V, rather than
>> being derived from the TLFS document. (Although, to preserve
>> compatibility with existing Linux code, some definitions are copied
>> directly from hyperv-tlfs.h too).
>>
>> The new files follow a naming convention according to their original
>> use:
>> - hdk "host development kit"
>> - gdk "guest development kit"
>> With postfix "_mini" implying userspace-only headers, and "_ext" for
>> extended hypercalls.
> 
> Naming convention for mini (which may have come from HyperV code) is a bit 
> odd TBH. May be it has more to it than what is mentioned here or what I know. 
> If more information helps, or this can be changed, please see.
> 

The naming is originally from the Hyper-V code. See below: "The original
names are kept intact primarily to keep the provenance of exactly where
they came from in Hyper-V code, which is helpful for manual maintenance
and extension of these definitions."

>>
>> These names should be considered a rough guide only - since there are
>> many places already where both host and guest code are in the same
>> place, hvhdk.h (which includes everything) can be used most of the time.
>>
>> The original names are kept intact primarily to keep the provenance of
>> exactly where they came from in Hyper-V code, which is helpful for
>> manual maintenance and extension of these definitions. Microsoft
>> maintainers importing new definitions should take care to put them in
>> the right file.
>>
>> Note also that the files contain both arm64 and x86_64 code guarded by
>> \#ifdefs, which is how the definitions originally appear in Hyper-V.
>> Keeping this convention from Hyper-V code is another tactic for
>> simplying the process of importing new definitions.
>>
>> These headers are a step toward importing headers directly from Hyper-V
>> in the future, similar to Xen public files in include/xen/interface/.
>>
>> Signed-off-by: Nuno Das Neves 
> 
> While I understand the motivation behind this series that this is going to 
> ease out the process of updating the header files with respect to HyperV, I 
> think, we will need to pay attention to what we are bringing in with these 
> headers, whether there are any users of it or not, and make sure that TLFS 
> document is updated regularly, to avoid having bunch of code with no 
> information of it.
> The code comments in these files are one step forward towards that.
> And from your cover letter it seems that some changes which actually make use 
> of these additional interfaces are underway, so things will make more sense 
> later. For now, this looks good to me.
> 

Yes, we do need to be careful about what interfaces we add here. Not just
anything can be copied from Hyper-V code into these files. The exact
process is a matter we can discuss internally. But, as you say, there are
upcoming patches (previous versions can be found in the mailing list) which
use the new root partition interfaces.

Updating the TLFS and documenting the interfaces is a different matter.
I can't speak to the best way forward for documenting these, but in many
cases the use of the new interfaces will be self-evident from the code
that uses them, and/or comments as you mentioned.

Over the years many Hyper-V definitions have already been added and used
in Linux which have not been documented in the TLFS or elsewhere. This
patch series makes that fact more obvious and sets us on a path towards a
more maintainable method (i.e., publishing headers directly from the Hyper-V
code, hopefully).

Thanks
Nuno

> > Regards,
> Naman
> 
> 




Re: [PATCH v2 0/4] Add new headers for Hyper-V Dom0

2024-11-11 Thread Nuno Das Neves
On 11/10/2024 8:12 PM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Thursday, 
> November 7, 2024 2:32 PM
>>
>> To support Hyper-V Dom0 (aka Linux as root partition), many new
>> definitions are required.
> 
> Using "dom0" terminology here and in the Subject: line is likely to
> be confusing to folks who aren't intimately involved in Hyper-V work.
> Previous Linux kernel commit messages and code for running in the
> Hyper-V root partition use "root partition" terminology, and I couldn't
> find "dom0" having been used before. "root partition" would be more
> consistent, and it also matches the public documentation for Hyper-V.
> "dom0" is Xen specific terminology, and having it show up in Hyper-V
> patches would be confusing for the casual reader. I know "dom0" has
> been used internally at Microsoft as shorthand for "Hyper-V root
> partition", but it's probably best to completely avoid such shorthand
> in public Linux kernel patches and code.
> 
> Just my $.02 
> 

Noted - I will update the terminology in v3 and generally avoid "Dom0",
except possibly by way of explanation (i.e. to compare it to Xen Dom0).

Thanks
Nuno

>>
>> The plan going forward is to directly import definitions from
>> Hyper-V code without waiting for them to land in the TLFS document.
>> This is a quicker and more maintainable way to import definitions,
>> and is a step toward the eventual goal of exporting headers directly
>> from Hyper-V for use in Linux.
>>
>> This patch series introduces new headers (hvhdk.h, hvgdk.h, etc,
>> see patch #3) derived directly from Hyper-V code. hyperv-tlfs.h is
>> replaced with hvhdk.h (which includes the other new headers)
>> everywhere.
>>
>> No functional change is expected.
>>
>> Summary:
>> Patch 1-2: Minor cleanup patches
>> Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
>> Patch 4: Switch to the new headers
>>
>> Signed-off-by: Nuno Das Neves 
>> ---
>> Changelog:
>> v2:
>> - Rework the series to simply use the new headers everywhere
>>   instead of fiddling around to keep hyperv-tlfs.h used in some
>>   places, suggested by Michael Kelley and Easwar Hariharan
> 
> Thanks! That should be simpler all around.
> 
> Michael
> 
>> - Fix compilation errors with some configs by adding missing
>>   definitions and changing some names, thanks to Simon Horman for
>>   catching those
>> - Add additional definitions to the new headers to support them now
>>   replacing hyperv-tlfs.h everywhere
>> - Add additional context in the commit messages for patches #3 and #4
>> - In patch #2, don't remove indirect includes. Only remove includes
>>   which truly aren't used, suggested by Michael Kelley
>>
>> ---
>> Nuno Das Neves (4):
>>   hyperv: Move hv_connection_id to hyperv-tlfs.h
>>   hyperv: Clean up unnecessary #includes
>>   hyperv: Add new Hyper-V headers in include/hyperv
>>   hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h
>>
>>  arch/arm64/hyperv/hv_core.c|3 +-
>>  arch/arm64/hyperv/mshyperv.c   |4 +-
>>  arch/arm64/include/asm/mshyperv.h  |2 +-
>>  arch/x86/hyperv/hv_apic.c  |1 -
>>  arch/x86/hyperv/hv_init.c  |   21 +-
>>  arch/x86/hyperv/hv_proc.c  |3 +-
>>  arch/x86/hyperv/ivm.c  |1 -
>>  arch/x86/hyperv/mmu.c  |1 -
>>  arch/x86/hyperv/nested.c   |2 +-
>>  arch/x86/include/asm/kvm_host.h|3 +-
>>  arch/x86/include/asm/mshyperv.h|3 +-
>>  arch/x86/include/asm/svm.h |2 +-
>>  arch/x86/kernel/cpu/mshyperv.c |2 +-
>>  arch/x86/kvm/vmx/hyperv_evmcs.h|2 +-
>>  arch/x86/kvm/vmx/vmx_onhyperv.h|2 +-
>>  arch/x86/mm/pat/set_memory.c   |2 -
>>  drivers/clocksource/hyperv_timer.c |2 +-
>>  drivers/hv/hv_balloon.c|4 +-
>>  drivers/hv/hv_common.c |2 +-
>>  drivers/hv/hv_kvp.c|2 +-
>>  drivers/hv/hv_snapshot.c   |2 +-
>>  drivers/hv/hyperv_vmbus.h  |2 +-
>>  include/asm-generic/hyperv-tlfs.h  |9 +
>>  include/asm-generic/mshyperv.h |2 +-
>>  include/clocksource/hyperv_timer.h |2 +-
>>  include/hyperv/hvgdk.h |  303 +++
>>  include/hyperv/hvgdk_ext.h |   46 +
>>  include/hyperv/hvgdk_mini.h| 1295 
>>  include/hyperv/hvhdk.h |  733 
>>  include/hyperv/hvhdk_mini.h|  310 +++
>>  include/linux/hyperv.h |   11 +-
>>  net/vmw_vsock/hyperv_transport.c   |2 +-
>>  32 files changed, 2729 insertions(+), 52 deletions(-)
>>  create mode 100644 include/hyperv/hvgdk.h
>>  create mode 100644 include/hyperv/hvgdk_ext.h
>>  create mode 100644 include/hyperv/hvgdk_mini.h
>>  create mode 100644 include/hyperv/hvhdk.h
>>  create mode 100644 include/hyperv/hvhdk_mini.h
>>
>> --
>> 2.34.1




Re: [PATCH 0/5] Add new headers for Hyper-V Dom0

2024-10-31 Thread Nuno Das Neves
On 10/31/2024 12:05 PM, Easwar Hariharan wrote:
> On 10/3/2024 12:50 PM, Nuno Das Neves wrote:
>> To support Hyper-V Dom0 (aka Linux as root partition), many new
>> definitions are required.
>>
>> The plan going forward is to directly import headers from
>> Hyper-V. This is a more maintainable way to import definitions
>> rather than via the TLFS doc. This patch series introduces
>> new headers (hvhdk.h, hvgdk.h, etc, see patch #3) directly
>> derived from Hyper-V code.
>>
>> This patch series replaces hyperv-tlfs.h with hvhdk.h, but only
>> in Microsoft-maintained Hyper-V code where they are needed. This
>> leaves the existing hyperv-tlfs.h in use elsewhere - notably for
>> Hyper-V enlightenments on KVM guests.
>>
>> An intermediary header "hv_defs.h" is introduced to conditionally
>> include either hyperv-tlfs.h or hvhdk.h. This is required because
>> several headers which today include hyperv-tlfs.h, are shared
>> between Hyper-V and KVM code (e.g. mshyperv.h).
>>
>> Summary:
>> Patch 1-2: Cleanup patches
>> Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
>> Patch 4: Add hv_defs.h and use it in mshyperv.h, svm.h,
>>  hyperv_timer.h
>> Patch 5: Switch to the new headers, only in Hyper-V code
>>
>> Nuno Das Neves (5):
>>   hyperv: Move hv_connection_id to hyperv-tlfs.h
>>   hyperv: Remove unnecessary #includes
>>   hyperv: Add new Hyper-V headers
>>   hyperv: Add hv_defs.h to conditionally include hyperv-tlfs.h or
>> hvhdk.h
>>   hyperv: Use hvhdk.h instead of hyperv-tlfs.h in Hyper-V code
>>

Hi Easwar, thanks for the questions. I will attempt to clarify.
> 
> What is the model for Hyper-V code that has both guest and host roles
> where the corresponding hypercalls are available for both? As I
> understand it, those are supposed to be in hvgdk*.h.
>

It's true that the naming of the files implies hvgdk*.h is for guests,
and hvhdk*.h (which includes hvgdk*.h), is for hosts/dom0. But I would
only take that as a rough guide.

The real reason for keeping these names is to make it a easier to copy
and maintain the definitions from the Windows code into Linux, by
keeping the provenance of exactly where they came from.

> For a specific example, IOMMU hypercalls can operate on stage 2 or stage
> 1 translations depending on the role of the (hyper) caller and the input
> values provided. Should a driver using these hypercalls import both
> hvhdk* and hvgdk*? What about hyperv-tlfs?
>

I'd recommend importing hvhdk.h since it contains everything you need
(including hvgdk*.h).

The goal of this patchset is to move away from hyperv-tlfs.h, because by
definition it should only contain definitions from the TLFS document.

> Patches 4 and 5 seem to draw a bright line between host and guest roles
> while the reality is more gray. Please do correct me if I'm wrong here,
> perhaps the picture would be clearer if Stas' suggestion of a new header
> file is implemented.
> 

Patches 4 and 5 introduce the new headers in a way that avoids any
potential impact on KVM and other non-Microsoft-maintained code.

The 'line' is not between guest and host, but between Microsoft-maintained
and non-Microsoft-maintained code.

Thanks,
Nuno

> Thanks,
> Easwar




[PATCH v2 3/4] hyperv: Add new Hyper-V headers in include/hyperv

2024-11-07 Thread Nuno Das Neves
These headers contain definitions for regular Hyper-V guests (as in
hyperv-tlfs.h), as well as interfaces for more privileged guests like
Dom0.

These files are derived from headers exported from Hyper-V, rather than
being derived from the TLFS document. (Although, to preserve
compatibility with existing Linux code, some definitions are copied
directly from hyperv-tlfs.h too).

The new files follow a naming convention according to their original
use:
- hdk "host development kit"
- gdk "guest development kit"
With postfix "_mini" implying userspace-only headers, and "_ext" for
extended hypercalls.

These names should be considered a rough guide only - since there are
many places already where both host and guest code are in the same
place, hvhdk.h (which includes everything) can be used most of the time.

The original names are kept intact primarily to keep the provenance of
exactly where they came from in Hyper-V code, which is helpful for
manual maintenance and extension of these definitions. Microsoft
maintainers importing new definitions should take care to put them in
the right file.

Note also that the files contain both arm64 and x86_64 code guarded by
\#ifdefs, which is how the definitions originally appear in Hyper-V.
Keeping this convention from Hyper-V code is another tactic for
simplying the process of importing new definitions.

These headers are a step toward importing headers directly from Hyper-V
in the future, similar to Xen public files in include/xen/interface/.

Signed-off-by: Nuno Das Neves 
---
 include/hyperv/hvgdk.h  |  303 
 include/hyperv/hvgdk_ext.h  |   46 ++
 include/hyperv/hvgdk_mini.h | 1295 +++
 include/hyperv/hvhdk.h  |  733 
 include/hyperv/hvhdk_mini.h |  310 +
 5 files changed, 2687 insertions(+)
 create mode 100644 include/hyperv/hvgdk.h
 create mode 100644 include/hyperv/hvgdk_ext.h
 create mode 100644 include/hyperv/hvgdk_mini.h
 create mode 100644 include/hyperv/hvhdk.h
 create mode 100644 include/hyperv/hvhdk_mini.h

diff --git a/include/hyperv/hvgdk.h b/include/hyperv/hvgdk.h
new file mode 100644
index ..9687c6570dfb
--- /dev/null
+++ b/include/hyperv/hvgdk.h
@@ -0,0 +1,303 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Type definitions for the Microsoft Hypervisor.
+ */
+#ifndef _HV_HVGDK_H
+#define _HV_HVGDK_H
+
+#include "hvgdk_mini.h"
+#include "hvgdk_ext.h"
+
+/*
+ * The guest OS needs to register the guest ID with the hypervisor.
+ * The guest ID is a 64 bit entity and the structure of this ID is
+ * specified in the Hyper-V TLFS specification.
+ *
+ * While the current guideline does not specify how Linux guest ID(s)
+ * need to be generated, our plan is to publish the guidelines for
+ * Linux and other guest operating systems that currently are hosted
+ * on Hyper-V. The implementation here conforms to this yet
+ * unpublished guidelines.
+ *
+ * Bit(s)
+ * 63 - Indicates if the OS is Open Source or not; 1 is Open Source
+ * 62:56 - Os Type; Linux is 0x100
+ * 55:48 - Distro specific identification
+ * 47:16 - Linux kernel version number
+ * 15:0  - Distro specific identification
+ */
+
+#define HV_LINUX_VENDOR_ID  0x8100
+
+/* HV_VMX_ENLIGHTENED_VMCS */
+struct hv_enlightened_vmcs {
+   u32 revision_id;
+   u32 abort;
+
+   u16 host_es_selector;
+   u16 host_cs_selector;
+   u16 host_ss_selector;
+   u16 host_ds_selector;
+   u16 host_fs_selector;
+   u16 host_gs_selector;
+   u16 host_tr_selector;
+
+   u16 padding16_1;
+
+   u64 host_ia32_pat;
+   u64 host_ia32_efer;
+
+   u64 host_cr0;
+   u64 host_cr3;
+   u64 host_cr4;
+
+   u64 host_ia32_sysenter_esp;
+   u64 host_ia32_sysenter_eip;
+   u64 host_rip;
+   u32 host_ia32_sysenter_cs;
+
+   u32 pin_based_vm_exec_control;
+   u32 vm_exit_controls;
+   u32 secondary_vm_exec_control;
+
+   u64 io_bitmap_a;
+   u64 io_bitmap_b;
+   u64 msr_bitmap;
+
+   u16 guest_es_selector;
+   u16 guest_cs_selector;
+   u16 guest_ss_selector;
+   u16 guest_ds_selector;
+   u16 guest_fs_selector;
+   u16 guest_gs_selector;
+   u16 guest_ldtr_selector;
+   u16 guest_tr_selector;
+
+   u32 guest_es_limit;
+   u32 guest_cs_limit;
+   u32 guest_ss_limit;
+   u32 guest_ds_limit;
+   u32 guest_fs_limit;
+   u32 guest_gs_limit;
+   u32 guest_ldtr_limit;
+   u32 guest_tr_limit;
+   u32 guest_gdtr_limit;
+   u32 guest_idtr_limit;
+
+   u32 guest_es_ar_bytes;
+   u32 guest_cs_ar_bytes;
+   u32 guest_ss_ar_bytes;
+   u32 guest_ds_ar_bytes;
+   u32 guest_fs_ar_bytes;
+   u32 guest_gs_ar_bytes;
+   u32 guest_ldtr_ar_bytes;
+   u32 guest_tr_ar_bytes;
+
+   u64 guest_es_base;
+   u64 guest_cs_base;
+   u64 guest_ss_base;
+   u64 guest_ds_base;
+

[PATCH v2 0/4] Add new headers for Hyper-V Dom0

2024-11-07 Thread Nuno Das Neves
To support Hyper-V Dom0 (aka Linux as root partition), many new
definitions are required.

The plan going forward is to directly import definitions from
Hyper-V code without waiting for them to land in the TLFS document.
This is a quicker and more maintainable way to import definitions,
and is a step toward the eventual goal of exporting headers directly
from Hyper-V for use in Linux.

This patch series introduces new headers (hvhdk.h, hvgdk.h, etc,
see patch #3) derived directly from Hyper-V code. hyperv-tlfs.h is
replaced with hvhdk.h (which includes the other new headers)
everywhere.

No functional change is expected.

Summary:
Patch 1-2: Minor cleanup patches
Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
Patch 4: Switch to the new headers

Signed-off-by: Nuno Das Neves 
---
Changelog:
v2:
- Rework the series to simply use the new headers everywhere
  instead of fiddling around to keep hyperv-tlfs.h used in some
  places, suggested by Michael Kelley and Easwar Hariharan
- Fix compilation errors with some configs by adding missing
  definitions and changing some names, thanks to Simon Horman for
  catching those
- Add additional definitions to the new headers to support them now
  replacing hyperv-tlfs.h everywhere
- Add additional context in the commit messages for patches #3 and #4
- In patch #2, don't remove indirect includes. Only remove includes
  which truly aren't used, suggested by Michael Kelley

---
Nuno Das Neves (4):
  hyperv: Move hv_connection_id to hyperv-tlfs.h
  hyperv: Clean up unnecessary #includes
  hyperv: Add new Hyper-V headers in include/hyperv
  hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h

 arch/arm64/hyperv/hv_core.c|3 +-
 arch/arm64/hyperv/mshyperv.c   |4 +-
 arch/arm64/include/asm/mshyperv.h  |2 +-
 arch/x86/hyperv/hv_apic.c  |1 -
 arch/x86/hyperv/hv_init.c  |   21 +-
 arch/x86/hyperv/hv_proc.c  |3 +-
 arch/x86/hyperv/ivm.c  |1 -
 arch/x86/hyperv/mmu.c  |1 -
 arch/x86/hyperv/nested.c   |2 +-
 arch/x86/include/asm/kvm_host.h|3 +-
 arch/x86/include/asm/mshyperv.h|3 +-
 arch/x86/include/asm/svm.h |2 +-
 arch/x86/kernel/cpu/mshyperv.c |2 +-
 arch/x86/kvm/vmx/hyperv_evmcs.h|2 +-
 arch/x86/kvm/vmx/vmx_onhyperv.h|2 +-
 arch/x86/mm/pat/set_memory.c   |2 -
 drivers/clocksource/hyperv_timer.c |2 +-
 drivers/hv/hv_balloon.c|4 +-
 drivers/hv/hv_common.c |2 +-
 drivers/hv/hv_kvp.c|2 +-
 drivers/hv/hv_snapshot.c   |2 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 include/asm-generic/hyperv-tlfs.h  |9 +
 include/asm-generic/mshyperv.h |2 +-
 include/clocksource/hyperv_timer.h |2 +-
 include/hyperv/hvgdk.h |  303 +++
 include/hyperv/hvgdk_ext.h |   46 +
 include/hyperv/hvgdk_mini.h| 1295 
 include/hyperv/hvhdk.h |  733 
 include/hyperv/hvhdk_mini.h|  310 +++
 include/linux/hyperv.h |   11 +-
 net/vmw_vsock/hyperv_transport.c   |2 +-
 32 files changed, 2729 insertions(+), 52 deletions(-)
 create mode 100644 include/hyperv/hvgdk.h
 create mode 100644 include/hyperv/hvgdk_ext.h
 create mode 100644 include/hyperv/hvgdk_mini.h
 create mode 100644 include/hyperv/hvhdk.h
 create mode 100644 include/hyperv/hvhdk_mini.h

-- 
2.34.1




[PATCH v2 4/4] hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h

2024-11-07 Thread Nuno Das Neves
Switch to using hvhdk.h everywhere in the kernel. This header includes
all the new Hyper-V headers in include/hyperv, which form a superset of
the definitions found in hyperv-tlfs.h.

This makes it easier to add new Hyper-V interfaces without being
restricted to those in the TLFS doc (reflected in hyperv-tlfs.h).

To be more consistent with the original Hyper-V code, the names of some
definitions are changed slightly. Update those where needed.

hyperv-tlfs.h is no longer included anywhere - hvhdk.h can serve
the same role, but with an easier path for adding new definitions.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c|  2 +-
 arch/arm64/hyperv/mshyperv.c   |  4 ++--
 arch/arm64/include/asm/mshyperv.h  |  2 +-
 arch/x86/hyperv/hv_init.c  | 20 ++--
 arch/x86/hyperv/hv_proc.c  |  2 +-
 arch/x86/hyperv/nested.c   |  2 +-
 arch/x86/include/asm/kvm_host.h|  2 +-
 arch/x86/include/asm/mshyperv.h|  2 +-
 arch/x86/include/asm/svm.h |  2 +-
 arch/x86/kernel/cpu/mshyperv.c |  2 +-
 arch/x86/kvm/vmx/hyperv_evmcs.h|  2 +-
 arch/x86/kvm/vmx/vmx_onhyperv.h|  2 +-
 drivers/clocksource/hyperv_timer.c |  2 +-
 drivers/hv/hv_balloon.c|  4 ++--
 drivers/hv/hv_common.c |  2 +-
 drivers/hv/hv_kvp.c|  2 +-
 drivers/hv/hv_snapshot.c   |  2 +-
 drivers/hv/hyperv_vmbus.h  |  2 +-
 include/asm-generic/mshyperv.h |  2 +-
 include/clocksource/hyperv_timer.h |  2 +-
 include/linux/hyperv.h |  2 +-
 net/vmw_vsock/hyperv_transport.c   |  2 +-
 22 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index 7a746a5a6b42..69004f619c57 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -14,7 +14,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 /*
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index b1a4de4eee29..fc49949b7df6 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -49,12 +49,12 @@ static int __init hyperv_init(void)
hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
 
/* Get the features and hints from Hyper-V */
-   hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
+   hv_get_vpreg_128(HV_REGISTER_PRIVILEGES_AND_FEATURES_INFO, &result);
ms_hyperv.features = result.as32.a;
ms_hyperv.priv_high = result.as32.b;
ms_hyperv.misc_features = result.as32.c;
 
-   hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
+   hv_get_vpreg_128(HV_REGISTER_FEATURES_INFO, &result);
ms_hyperv.hints = result.as32.a;
 
pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc 
0x%x\n",
diff --git a/arch/arm64/include/asm/mshyperv.h 
b/arch/arm64/include/asm/mshyperv.h
index a975e1a689dd..7595fb35fae6 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -20,7 +20,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Declare calls to get and set Hyper-V VP register values on ARM64, which
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 1a6354b3e582..3f9aef157c88 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -19,7 +19,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -416,24 +416,24 @@ static void __init hv_get_partition_id(void)
 static u8 __init get_vtl(void)
 {
u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
-   struct hv_get_vp_registers_input *input;
-   struct hv_get_vp_registers_output *output;
+   struct hv_input_get_vp_registers *input;
+   struct hv_register_assoc *output;
unsigned long flags;
u64 ret;
 
local_irq_save(flags);
input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-   output = (struct hv_get_vp_registers_output *)input;
+   output = (struct hv_register_assoc *)input;
 
-   memset(input, 0, struct_size(input, element, 1));
-   input->header.partitionid = HV_PARTITION_ID_SELF;
-   input->header.vpindex = HV_VP_INDEX_SELF;
-   input->header.inputvtl = 0;
-   input->element[0].name0 = HV_X64_REGISTER_VSM_VP_STATUS;
+   memset(input, 0, struct_size(input, names, 1));
+   input->partition_id = HV_PARTITION_ID_SELF;
+   input->vp_index = HV_VP_INDEX_SELF;
+   input->input_vtl.as_uint8 = 0;
+   input->names[0] = HV_X64_REGISTER_VSM_VP_STATUS;
 
ret = hv_do_hypercall(control, input, output);
if (hv_result_success(ret)) {
-   ret = output->as64.low & HV_X64_VTL_MASK;
+   ret = output->value.reg8 & HV_X64_VTL_MASK;
} else {
pr_err("Failed to get VTL(error: %lld) exiting...\n", ret);
BUG();
diff --git 

[PATCH v2 1/4] hyperv: Move hv_connection_id to hyperv-tlfs.h

2024-11-07 Thread Nuno Das Neves
This definition is in the wrong file; it is part of the TLFS doc.

Acked-by: Wei Liu 
Signed-off-by: Nuno Das Neves 
---
 include/asm-generic/hyperv-tlfs.h | 9 +
 include/linux/hyperv.h| 9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 814207e7c37f..52274c9aefef 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -871,4 +871,13 @@ struct hv_mmio_write_input {
u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
 } __packed;
 
+/* Define connection identifier type. */
+union hv_connection_id {
+   u32 asu32;
+   struct {
+   u32 id:24;
+   u32 reserved:8;
+   } u;
+};
+
 #endif
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 22c22fb91042..d0893ec488ae 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -768,15 +768,6 @@ struct vmbus_close_msg {
struct vmbus_channel_close_channel msg;
 };
 
-/* Define connection identifier type. */
-union hv_connection_id {
-   u32 asu32;
-   struct {
-   u32 id:24;
-   u32 reserved:8;
-   } u;
-};
-
 enum vmbus_device_type {
HV_IDE = 0,
HV_SCSI,
-- 
2.34.1




[PATCH v2 2/4] hyperv: Clean up unnecessary #includes

2024-11-07 Thread Nuno Das Neves
Remove includes of linux/hyperv.h, mshyperv.h, and hyperv-tlfs.h where
they are not used.

Acked-by: Wei Liu 
Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c | 1 -
 arch/x86/hyperv/hv_apic.c   | 1 -
 arch/x86/hyperv/hv_init.c   | 1 -
 arch/x86/hyperv/hv_proc.c   | 1 -
 arch/x86/hyperv/ivm.c   | 1 -
 arch/x86/hyperv/mmu.c   | 1 -
 arch/x86/include/asm/kvm_host.h | 1 -
 arch/x86/include/asm/mshyperv.h | 1 -
 arch/x86/mm/pat/set_memory.c| 2 --
 9 files changed, 10 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index f1ebc025e1df..7a746a5a6b42 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 0569f579338b..f022d5f64fb6 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 17a71e92a343..1a6354b3e582 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 3fa1f2ee7b0d..b74c06c04ff1 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 60fc3ed72830..b56d70612734 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -7,7 +7,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 1cc113200ff5..cc8c3bd0e7c2 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -1,6 +1,5 @@
 #define pr_fmt(fmt)  "Hyper-V: " fmt
 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4a68cb3eba78..3627eab994a3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 390c4d13956d..47ca48062547 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -9,7 +9,6 @@
 #include 
 #include 
 #include 
-#include 
 
 /*
  * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 44f7b2ea6a07..85fa0d4509f0 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -32,8 +32,6 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #include "../mm_internal.h"
 
-- 
2.34.1




Re: [PATCH v2 4/4] hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h

2024-11-15 Thread Nuno Das Neves
On 11/10/2024 8:13 PM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Thursday, 
> November 7, 2024 2:32 PM
>>
>> Switch to using hvhdk.h everywhere in the kernel. This header includes
>> all the new Hyper-V headers in include/hyperv, which form a superset of
>> the definitions found in hyperv-tlfs.h.
>>
>> This makes it easier to add new Hyper-V interfaces without being
>> restricted to those in the TLFS doc (reflected in hyperv-tlfs.h).
>>
>> To be more consistent with the original Hyper-V code, the names of some
>> definitions are changed slightly. Update those where needed.
>>
>> hyperv-tlfs.h is no longer included anywhere - hvhdk.h can serve
>> the same role, but with an easier path for adding new definitions.
> 
> Is hyperv-tlfs.h and friends being deleted? If not, the risk is that
> someone adds a new #include of it without realizing that it has been
> superseded by hvhdk.h.
> 

I was hesitant to delete it because I thought someone may still have
a use for a header file that (mostly) reflects the TLFS document and
nothing more.

But in practical terms, this patchset makes it much more difficult to
use because all the helper code (i.e. mshyperv.h) now uses hvhdk.h.
So, maybe there is no point keeping it.

> Note also that this patch does not apply cleanly to 6.12 rc's, or to
> current linux-next trees. There's an unrelated #include added to
> arch/x86/include/asm/kvm_host.h that causes a merge failure
> in that file.
> 

I've been developing this series based on hyperv-next. Should I be
basing it on linux-next?

> Michael
> 
>>
>> Signed-off-by: Nuno Das Neves 
>> ---
>>  arch/arm64/hyperv/hv_core.c|  2 +-
>>  arch/arm64/hyperv/mshyperv.c   |  4 ++--
>>  arch/arm64/include/asm/mshyperv.h  |  2 +-
>>  arch/x86/hyperv/hv_init.c  | 20 ++--
>>  arch/x86/hyperv/hv_proc.c  |  2 +-
>>  arch/x86/hyperv/nested.c   |  2 +-
>>  arch/x86/include/asm/kvm_host.h|  2 +-
>>  arch/x86/include/asm/mshyperv.h|  2 +-
>>  arch/x86/include/asm/svm.h |  2 +-
>>  arch/x86/kernel/cpu/mshyperv.c |  2 +-
>>  arch/x86/kvm/vmx/hyperv_evmcs.h|  2 +-
>>  arch/x86/kvm/vmx/vmx_onhyperv.h|  2 +-
>>  drivers/clocksource/hyperv_timer.c |  2 +-
>>  drivers/hv/hv_balloon.c|  4 ++--
>>  drivers/hv/hv_common.c |  2 +-
>>  drivers/hv/hv_kvp.c|  2 +-
>>  drivers/hv/hv_snapshot.c   |  2 +-
>>  drivers/hv/hyperv_vmbus.h  |  2 +-
>>  include/asm-generic/mshyperv.h |  2 +-
>>  include/clocksource/hyperv_timer.h |  2 +-
>>  include/linux/hyperv.h |  2 +-
>>  net/vmw_vsock/hyperv_transport.c   |  2 +-
>>  22 files changed, 33 insertions(+), 33 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
>> index 7a746a5a6b42..69004f619c57 100644
>> --- a/arch/arm64/hyperv/hv_core.c
>> +++ b/arch/arm64/hyperv/hv_core.c
>> @@ -14,7 +14,7 @@
>>  #include 
>>  #include 
>>  #include 
>> -#include 
>> +#include 
>>  #include 
>>
>>  /*
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index b1a4de4eee29..fc49949b7df6 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -49,12 +49,12 @@ static int __init hyperv_init(void)
>>  hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
>>
>>  /* Get the features and hints from Hyper-V */
>> -hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
>> +hv_get_vpreg_128(HV_REGISTER_PRIVILEGES_AND_FEATURES_INFO, &result);
>>  ms_hyperv.features = result.as32.a;
>>  ms_hyperv.priv_high = result.as32.b;
>>  ms_hyperv.misc_features = result.as32.c;
>>
>> -hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
>> +hv_get_vpreg_128(HV_REGISTER_FEATURES_INFO, &result);
>>  ms_hyperv.hints = result.as32.a;
>>
>>  pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc
>> 0x%x\n",
>> diff --git a/arch/arm64/include/asm/mshyperv.h
>> b/arch/arm64/include/asm/mshyperv.h
>> index a975e1a689dd..7595fb35fae6 100644
>> --- a/arch/arm64/include/asm/mshyperv.h
>> +++ b/arch/arm64/include/asm/mshyperv.h
>> @@ -20,7 +20,7 @@
>>
>>  #include 
>>  #include 
>> -#include 
>> +#include 
>>
>>  /*
>>   * Declare calls to get and set Hyper-V VP register values on ARM64, which
>> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86

Re: [PATCH v2 3/4] hyperv: Add new Hyper-V headers in include/hyperv

2024-11-13 Thread Nuno Das Neves
On 11/11/2024 11:31 AM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Monday, 
> November 11, 2024 10:45 AM
>>
>> On 11/10/2024 8:13 PM, Michael Kelley wrote:
>>> From: Nuno Das Neves  Sent: Thursday,
>> November 7, 2024 2:32 PM
>>>>
>>>> These headers contain definitions for regular Hyper-V guests (as in
>>>> hyperv-tlfs.h), as well as interfaces for more privileged guests like
>>>> Dom0.
>>>
>>> See my comment on Patch 0/4 about use of "dom0" terminology.
>>>
>>
>> Thanks, noted.
>>
>>>>
>>>> These files are derived from headers exported from Hyper-V, rather than
>>>> being derived from the TLFS document. (Although, to preserve
>>>> compatibility with existing Linux code, some definitions are copied
>>>> directly from hyperv-tlfs.h too).
>>>>
>>>> The new files follow a naming convention according to their original
>>>> use:
>>>> - hdk "host development kit"
>>>> - gdk "guest development kit"
>>>> With postfix "_mini" implying userspace-only headers, and "_ext" for
>>>> extended hypercalls.
>>>>
>>>> These names should be considered a rough guide only - since there are
>>>> many places already where both host and guest code are in the same
>>>> place, hvhdk.h (which includes everything) can be used most of the time.
>>>
>>> Just curious -- are there really cases where hvhdk.h can't be used?
>>> If so, could you summarize why?
>>>
>>
>> No, there aren't cases where it "can't" be used. I suppose if someone
>> doesn't want to include everything, perhaps they could just include
>> hvgdk.h, for example. It doesn't really matter though.
>>
>>> I ask because it would be nice to expand slightly on your paragraph
>>> below, as follows:  (if indeed what I've added is correct)
>>>
>>> The use of multiple files and their original names is primarily to
>>> keep the provenance of exactly where they came from in Hyper-V
>>> code, which is helpful for manual maintenance and extension
>>> of these definitions. Microsoft maintainers importing new definitions
>>> should take care to put them in the right file. However, Linux kernel code
>>> that uses any of the definitions need not be aware of the multiple files
>>> or assign any meaning to the new names. Linux kernel uses should
>>> always just include hvhdk.h
>>>
>>
>> Thanks, I think that additional sentence helps clarify things. I'll
>> include it in the next version, and I think I can probably omit the prior
>> paragraph: "These names should be considered a rough guide only...".
>>
> 
> Omitting that prior paragraph is OK with me.  The key thoughts from my
> standpoint are:
> * The separation into multiple files and the file names come from
>the Windows Hyper-V world and are maintained to ease bringing
>the definitions over from that world
>
> * Linux code can ignore the multiple files and their names. Just
>#include hvhdk.h.
> 

Agreed, thanks for helping clarify the points.

>>>>
>>>> The original names are kept intact primarily to keep the provenance of
>>>> exactly where they came from in Hyper-V code, which is helpful for
>>>> manual maintenance and extension of these definitions. Microsoft
>>>> maintainers importing new definitions should take care to put them in
>>>> the right file.
>>>>
>>>> Note also that the files contain both arm64 and x86_64 code guarded by
>>>> \#ifdefs, which is how the definitions originally appear in Hyper-V.
>>>
>>> Spurious backslash?
>>>
>>
>> Indeed, thanks.
>>
>>> I would suggest some additional clarification:  The #ifdef guards are
>>> employed minimally where necessary to prevent conflicts due to
>>> different definitions for the same thing on x86_64 and arm64. Where
>>> there are no conflicts, the union of x86_64 definitions and arm64
>>> definitions is visible when building for either architecture. In other
>>> words, not all definitions specific to x86_64 are protected by #ifdef
>>> x86_64. Such unprotected definitions may be visible when building
>>> for arm64. And vice versa.
>>>
>>
>> Is there a reason you specifically want to point out that "Such
>> unprotected definitions may be visible when bui

Re: [PATCH v3 5/5] hyperv: Remove the now unused hyperv-tlfs.h files

2024-11-26 Thread Nuno Das Neves
On 11/25/2024 9:59 PM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Monday, 
> November 25, 2024 3:25 PM
>>
>> Remove all hyperv-tlfs.h files. These are no longer included
>> anywhere. hyperv/hvhdk.h serves the same role, but with an easier
>> path for adding new definitions.
>>
>> Remove the relevant lines in MAINTAINERS.
>>
>> Signed-off-by: Nuno Das Neves 
> 
> Reviewed-by: Michael Kelley 

Thanks for the reviews on this series Michael!



[PATCH v3 2/5] hyperv: Clean up unnecessary #includes

2024-11-25 Thread Nuno Das Neves
Remove includes of linux/hyperv.h, mshyperv.h, and hyperv-tlfs.h where
they are not used.

Acked-by: Wei Liu 
Reviewed-by: Michael Kelley 
Reviewed-by: Easwar Hariharan 
Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c | 1 -
 arch/x86/hyperv/hv_apic.c   | 1 -
 arch/x86/hyperv/hv_init.c   | 1 -
 arch/x86/hyperv/hv_proc.c   | 1 -
 arch/x86/hyperv/ivm.c   | 1 -
 arch/x86/hyperv/mmu.c   | 1 -
 arch/x86/include/asm/kvm_host.h | 1 -
 arch/x86/include/asm/mshyperv.h | 1 -
 arch/x86/mm/pat/set_memory.c| 2 --
 9 files changed, 10 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index f1ebc025e1df..7a746a5a6b42 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -11,7 +11,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 0569f579338b..f022d5f64fb6 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 95eada2994e1..3562826915f9 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 3fa1f2ee7b0d..b74c06c04ff1 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 60fc3ed72830..b56d70612734 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -7,7 +7,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 1cc113200ff5..cc8c3bd0e7c2 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -1,6 +1,5 @@
 #define pr_fmt(fmt)  "Hyper-V: " fmt
 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index e159e44a6a1b..46f354b12488 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 5f0bc6a6d025..6f866fb9ffee 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -9,7 +9,6 @@
 #include 
 #include 
 #include 
-#include 
 
 /*
  * Hyper-V always provides a single IO-APIC at this MMIO address.
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 069e421c2247..128e3448ae4f 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -32,8 +32,6 @@
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #include "../mm_internal.h"
 
-- 
2.34.1




[PATCH v3 1/5] hyperv: Move hv_connection_id to hyperv-tlfs.h

2024-11-25 Thread Nuno Das Neves
This definition is in the wrong file; it is part of the TLFS doc.

Acked-by: Wei Liu 
Reviewed-by: Easwar Hariharan 
Reviewed-by: Michael Kelley 
Signed-off-by: Nuno Das Neves 
---
 include/asm-generic/hyperv-tlfs.h | 9 +
 include/linux/hyperv.h| 9 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/asm-generic/hyperv-tlfs.h 
b/include/asm-generic/hyperv-tlfs.h
index 814207e7c37f..52274c9aefef 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -871,4 +871,13 @@ struct hv_mmio_write_input {
u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
 } __packed;
 
+/* Define connection identifier type. */
+union hv_connection_id {
+   u32 asu32;
+   struct {
+   u32 id:24;
+   u32 reserved:8;
+   } u;
+};
+
 #endif
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 22c22fb91042..d0893ec488ae 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -768,15 +768,6 @@ struct vmbus_close_msg {
struct vmbus_channel_close_channel msg;
 };
 
-/* Define connection identifier type. */
-union hv_connection_id {
-   u32 asu32;
-   struct {
-   u32 id:24;
-   u32 reserved:8;
-   } u;
-};
-
 enum vmbus_device_type {
HV_IDE = 0,
HV_SCSI,
-- 
2.34.1




[PATCH v3 0/5] Introduce new headers for Hyper-V

2024-11-25 Thread Nuno Das Neves
To support Linux as root partition[1] on Hyper-V many new definitions
are required.

The plan going forward is to directly import definitions from
Hyper-V code without waiting for them to land in the TLFS document.
This is a quicker and more maintainable way to import definitions,
and is a step toward the eventual goal of exporting the headers
directly from Hyper-V for use in Linux.

This patch series introduces new headers (hvhdk.h, hvgdk.h, etc,
see patch #3) derived directly from Hyper-V code. hyperv-tlfs.h is
replaced with hvhdk.h (which includes the other new headers)
everywhere.

No functional change is expected.

Summary:
Patch 1-2: Minor cleanup patches
Patch 3: Add the new headers (hvhdk.h, etc..) in include/hyperv/
Patch 4: Switch to the new headers
Patch 5: Delete hyperv-tlfs.h files

Signed-off-by: Nuno Das Neves 
---
Changelog:
v3:
- Add patch (#5) to delete the hyperv-tlfs.h files, suggested by
  Michael Kelley and Easwar Hariharan
- Reword commit message on patch #3 to improve clarity, suggested
  by Michael Kelley
- Clarify "Dom0" terminology, suggested by Michael Kelley
v2:
- Rework the series to simply use the new headers everywhere,
  instead of fiddling around to keep hyperv-tlfs.h in some areas,
  suggested by Michael Kelley and Easwar Hariharan
- Fix compilation issues with some configs by adding missing
  definitions and changing some names, thanks to Simon Horman for
  catching those
- Add additional definitions to the new headers due to them now being
  used everywhere
- Don't remove indirect includes in patch #2, only remove those which
  truly aren't used, suggested by Michael Kelley

---
Footnotes:
[1] Linux as root partition on Hyper-V is sometimes referred to as
"Dom0", borrowing the terminology from Xen. Although they are
conceptually similar, note that "Hyper-V Dom0" has nothing to do
with Xen.

Nuno Das Neves (5):
  hyperv: Move hv_connection_id to hyperv-tlfs.h
  hyperv: Clean up unnecessary #includes
  hyperv: Add new Hyper-V headers in include/hyperv
  hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h
  hyperv: Remove the now unused hyperv-tlfs.h files

 MAINTAINERS  |8 +-
 arch/arm64/hyperv/hv_core.c  |3 +-
 arch/arm64/hyperv/mshyperv.c |4 +-
 arch/arm64/include/asm/hyperv-tlfs.h |   71 --
 arch/arm64/include/asm/mshyperv.h|7 +-
 arch/x86/hyperv/hv_apic.c|1 -
 arch/x86/hyperv/hv_init.c|   21 +-
 arch/x86/hyperv/hv_proc.c|3 +-
 arch/x86/hyperv/ivm.c|1 -
 arch/x86/hyperv/mmu.c|1 -
 arch/x86/hyperv/nested.c |2 +-
 arch/x86/include/asm/hyperv-tlfs.h   |  811 
 arch/x86/include/asm/kvm_host.h  |3 +-
 arch/x86/include/asm/mshyperv.h  |3 +-
 arch/x86/include/asm/svm.h   |2 +-
 arch/x86/kernel/cpu/mshyperv.c   |2 +-
 arch/x86/kvm/vmx/hyperv_evmcs.h  |2 +-
 arch/x86/kvm/vmx/vmx_onhyperv.h  |2 +-
 arch/x86/mm/pat/set_memory.c |2 -
 drivers/clocksource/hyperv_timer.c   |2 +-
 drivers/hv/hv_balloon.c  |4 +-
 drivers/hv/hv_common.c   |2 +-
 drivers/hv/hv_kvp.c  |2 +-
 drivers/hv/hv_snapshot.c |2 +-
 drivers/hv/hyperv_vmbus.h|2 +-
 include/asm-generic/hyperv-tlfs.h|  874 -
 include/asm-generic/mshyperv.h   |7 +-
 include/clocksource/hyperv_timer.h   |2 +-
 include/hyperv/hvgdk.h   |  308 ++
 include/hyperv/hvgdk_ext.h   |   46 +
 include/hyperv/hvgdk_mini.h  | 1306 ++
 include/hyperv/hvhdk.h   |  733 +++
 include/hyperv/hvhdk_mini.h  |  311 ++
 include/linux/hyperv.h   |   11 +-
 net/vmw_vsock/hyperv_transport.c |6 +-
 35 files changed, 2748 insertions(+), 1819 deletions(-)
 delete mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 delete mode 100644 arch/x86/include/asm/hyperv-tlfs.h
 delete mode 100644 include/asm-generic/hyperv-tlfs.h
 create mode 100644 include/hyperv/hvgdk.h
 create mode 100644 include/hyperv/hvgdk_ext.h
 create mode 100644 include/hyperv/hvgdk_mini.h
 create mode 100644 include/hyperv/hvhdk.h
 create mode 100644 include/hyperv/hvhdk_mini.h

-- 
2.34.1




[PATCH v3 3/5] hyperv: Add new Hyper-V headers in include/hyperv

2024-11-25 Thread Nuno Das Neves
These headers contain definitions for regular Hyper-V guests (as in
hyperv-tlfs.h), as well as interfaces for more privileged guests like
the root partition (aka Dom0).

These files are derived from headers exported from Hyper-V, rather than
being derived from the TLFS document. (Although, to preserve
compatibility with existing Linux code, some definitions are copied
directly from hyperv-tlfs.h too).

The new files follow a naming convention according to their original
use:
- hdk "host development kit"
- gdk "guest development kit"
With postfix "_mini" implying userspace-only headers, and "_ext" for
extended hypercalls.

The use of multiple files and their original names is primarily to
keep the provenance of exactly where they came from in Hyper-V
code, which is helpful for manual maintenance and extension
of these definitions. Microsoft maintainers importing new definitions
should take care to put them in the right file. However, Linux kernel
code that uses any of the definitions need not be aware of the multiple
files or assign any meaning to the new names. Linux kernel code should
always just include hvhdk.h

Note the new headers contain both arm64 and x86_64 definitions. Some are
guarded by #ifdefs, and some are instead prefixed with the architecture,
e.g. hv_x64_*. These conventions are kept from Hyper-V code as another
tactic to simplify the process of importing and maintaining the
definitions, rather than splitting them up into their own files in
arch/x86/ and arch/arm64/.

These headers are a step toward importing headers directly from Hyper-V
in the future, similar to Xen public files in include/xen/interface/.

Signed-off-by: Nuno Das Neves 
---
 MAINTAINERS |5 +
 include/hyperv/hvgdk.h  |  308 +
 include/hyperv/hvgdk_ext.h  |   46 ++
 include/hyperv/hvgdk_mini.h | 1306 +++
 include/hyperv/hvhdk.h  |  733 
 include/hyperv/hvhdk_mini.h |  311 +
 6 files changed, 2709 insertions(+)
 create mode 100644 include/hyperv/hvgdk.h
 create mode 100644 include/hyperv/hvgdk_ext.h
 create mode 100644 include/hyperv/hvgdk_mini.h
 create mode 100644 include/hyperv/hvhdk.h
 create mode 100644 include/hyperv/hvhdk_mini.h

diff --git a/MAINTAINERS b/MAINTAINERS
index cf1d81bd04a7..6ffa65b5a160 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10694,6 +10694,11 @@ F: drivers/video/fbdev/hyperv_fb.c
 F: include/asm-generic/hyperv-tlfs.h
 F: include/asm-generic/mshyperv.h
 F: include/clocksource/hyperv_timer.h
+F: include/hyperv/hvgdk.h
+F: include/hyperv/hvgdk_ext.h
+F: include/hyperv/hvgdk_mini.h
+F: include/hyperv/hvhdk.h
+F: include/hyperv/hvhdk_mini.h
 F: include/linux/hyperv.h
 F: include/net/mana
 F: include/uapi/linux/hyperv.h
diff --git a/include/hyperv/hvgdk.h b/include/hyperv/hvgdk.h
new file mode 100644
index ..dd6d4939ea29
--- /dev/null
+++ b/include/hyperv/hvgdk.h
@@ -0,0 +1,308 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Type definitions for the Microsoft Hypervisor.
+ */
+#ifndef _HV_HVGDK_H
+#define _HV_HVGDK_H
+
+#include "hvgdk_mini.h"
+#include "hvgdk_ext.h"
+
+/*
+ * The guest OS needs to register the guest ID with the hypervisor.
+ * The guest ID is a 64 bit entity and the structure of this ID is
+ * specified in the Hyper-V TLFS specification.
+ *
+ * While the current guideline does not specify how Linux guest ID(s)
+ * need to be generated, our plan is to publish the guidelines for
+ * Linux and other guest operating systems that currently are hosted
+ * on Hyper-V. The implementation here conforms to this yet
+ * unpublished guidelines.
+ *
+ * Bit(s)
+ * 63 - Indicates if the OS is Open Source or not; 1 is Open Source
+ * 62:56 - Os Type; Linux is 0x100
+ * 55:48 - Distro specific identification
+ * 47:16 - Linux kernel version number
+ * 15:0  - Distro specific identification
+ */
+
+#define HV_LINUX_VENDOR_ID  0x8100
+
+/* HV_VMX_ENLIGHTENED_VMCS */
+struct hv_enlightened_vmcs {
+   u32 revision_id;
+   u32 abort;
+
+   u16 host_es_selector;
+   u16 host_cs_selector;
+   u16 host_ss_selector;
+   u16 host_ds_selector;
+   u16 host_fs_selector;
+   u16 host_gs_selector;
+   u16 host_tr_selector;
+
+   u16 padding16_1;
+
+   u64 host_ia32_pat;
+   u64 host_ia32_efer;
+
+   u64 host_cr0;
+   u64 host_cr3;
+   u64 host_cr4;
+
+   u64 host_ia32_sysenter_esp;
+   u64 host_ia32_sysenter_eip;
+   u64 host_rip;
+   u32 host_ia32_sysenter_cs;
+
+   u32 pin_based_vm_exec_control;
+   u32 vm_exit_controls;
+   u32 secondary_vm_exec_control;
+
+   u64 io_bitmap_a;
+   u64 io_bitmap_b;
+   u64 msr_bitmap;
+
+   u16 guest_es_selector;
+   u16 guest_cs_selector;
+   u16 guest_ss_selector;
+   u16 guest_ds_selector;
+   u16 guest_fs_selector;
+ 

[PATCH v3 5/5] hyperv: Remove the now unused hyperv-tlfs.h files

2024-11-25 Thread Nuno Das Neves
Remove all hyperv-tlfs.h files. These are no longer included
anywhere. hyperv/hvhdk.h serves the same role, but with an easier
path for adding new definitions.

Remove the relevant lines in MAINTAINERS.

Signed-off-by: Nuno Das Neves 
---
 MAINTAINERS  |   3 -
 arch/arm64/include/asm/hyperv-tlfs.h |  71 ---
 arch/x86/include/asm/hyperv-tlfs.h   | 811 
 include/asm-generic/hyperv-tlfs.h| 883 ---
 4 files changed, 1768 deletions(-)
 delete mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 delete mode 100644 arch/x86/include/asm/hyperv-tlfs.h
 delete mode 100644 include/asm-generic/hyperv-tlfs.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6ffa65b5a160..b1fb2a008982 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10672,10 +10672,8 @@ F: 
Documentation/devicetree/bindings/bus/microsoft,vmbus.yaml
 F: Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst
 F: Documentation/virt/hyperv
 F: arch/arm64/hyperv
-F: arch/arm64/include/asm/hyperv-tlfs.h
 F: arch/arm64/include/asm/mshyperv.h
 F: arch/x86/hyperv
-F: arch/x86/include/asm/hyperv-tlfs.h
 F: arch/x86/include/asm/mshyperv.h
 F: arch/x86/include/asm/trace/hyperv.h
 F: arch/x86/kernel/cpu/mshyperv.c
@@ -10691,7 +10689,6 @@ F:  drivers/pci/controller/pci-hyperv.c
 F: drivers/scsi/storvsc_drv.c
 F: drivers/uio/uio_hv_generic.c
 F: drivers/video/fbdev/hyperv_fb.c
-F: include/asm-generic/hyperv-tlfs.h
 F: include/asm-generic/mshyperv.h
 F: include/clocksource/hyperv_timer.h
 F: include/hyperv/hvgdk.h
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
deleted file mode 100644
index bc30aadedfe9..
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/*
- * This file contains definitions from the Hyper-V Hypervisor Top-Level
- * Functional Specification (TLFS):
- * 
https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
- *
- * Copyright (C) 2021, Microsoft, Inc.
- *
- * Author : Michael Kelley 
- */
-
-#ifndef _ASM_HYPERV_TLFS_H
-#define _ASM_HYPERV_TLFS_H
-
-#include 
-
-/*
- * All data structures defined in the TLFS that are shared between Hyper-V
- * and a guest VM use Little Endian byte ordering.  This matches the default
- * byte ordering of Linux running on ARM64, so no special handling is required.
- */
-
-/*
- * Group C Features. See the asm-generic version of hyperv-tlfs.h
- * for a description of Feature Groups.
- */
-
-/* Crash MSRs available */
-#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE   BIT(8)
-
-/* STIMER direct mode is available */
-#define HV_STIMER_DIRECT_MODE_AVAILABLEBIT(13)
-
-/*
- * To support arch-generic code calling hv_set/get_register:
- * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
- * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
- */
-#define HV_MSR_CRASH_P0(HV_REGISTER_GUEST_CRASH_P0)
-#define HV_MSR_CRASH_P1(HV_REGISTER_GUEST_CRASH_P1)
-#define HV_MSR_CRASH_P2(HV_REGISTER_GUEST_CRASH_P2)
-#define HV_MSR_CRASH_P3(HV_REGISTER_GUEST_CRASH_P3)
-#define HV_MSR_CRASH_P4(HV_REGISTER_GUEST_CRASH_P4)
-#define HV_MSR_CRASH_CTL   (HV_REGISTER_GUEST_CRASH_CTL)
-
-#define HV_MSR_VP_INDEX(HV_REGISTER_VP_INDEX)
-#define HV_MSR_TIME_REF_COUNT  (HV_REGISTER_TIME_REF_COUNT)
-#define HV_MSR_REFERENCE_TSC   (HV_REGISTER_REFERENCE_TSC)
-
-#define HV_MSR_SINT0   (HV_REGISTER_SINT0)
-#define HV_MSR_SCONTROL(HV_REGISTER_SCONTROL)
-#define HV_MSR_SIEFP   (HV_REGISTER_SIEFP)
-#define HV_MSR_SIMP(HV_REGISTER_SIMP)
-#define HV_MSR_EOM (HV_REGISTER_EOM)
-
-#define HV_MSR_STIMER0_CONFIG  (HV_REGISTER_STIMER0_CONFIG)
-#define HV_MSR_STIMER0_COUNT   (HV_REGISTER_STIMER0_COUNT)
-
-union hv_msi_entry {
-   u64 as_uint64[2];
-   struct {
-   u64 address;
-   u32 data;
-   u32 reserved;
-   } __packed;
-};
-
-#include 
-
-#endif
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
deleted file mode 100644
index 3787d26810c1..
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ /dev/null
@@ -1,811 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/*
- * This file contains definitions from Hyper-V Hypervisor Top-Level Functional
- * Specification (TLFS):
- * 
https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
- */
-
-#ifndef _ASM_X86_HYPERV_TLFS_H
-#define _ASM_X86_HYPERV_TLFS_H
-
-#include 
-#include 
-/*
- * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
- * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
- */
-#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS  0x4000
-#define HYPERV_CPUID_INTERFACE

[PATCH v3 4/5] hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h

2024-11-25 Thread Nuno Das Neves
Switch to using hvhdk.h everywhere in the kernel. This header
includes all the new Hyper-V headers in include/hyperv, which form a
superset of the definitions found in hyperv-tlfs.h.

This makes it easier to add new Hyper-V interfaces without being
restricted to those in the TLFS doc (reflected in hyperv-tlfs.h).

To be more consistent with the original Hyper-V code, the names of
some definitions are changed slightly. Update those where needed.

Update comments in mshyperv.h files to point to include/hyperv for
adding new definitions.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/hv_core.c|  2 +-
 arch/arm64/hyperv/mshyperv.c   |  4 ++--
 arch/arm64/include/asm/mshyperv.h  |  7 +++
 arch/x86/hyperv/hv_init.c  | 20 ++--
 arch/x86/hyperv/hv_proc.c  |  2 +-
 arch/x86/hyperv/nested.c   |  2 +-
 arch/x86/include/asm/kvm_host.h|  2 +-
 arch/x86/include/asm/mshyperv.h|  2 +-
 arch/x86/include/asm/svm.h |  2 +-
 arch/x86/kernel/cpu/mshyperv.c |  2 +-
 arch/x86/kvm/vmx/hyperv_evmcs.h|  2 +-
 arch/x86/kvm/vmx/vmx_onhyperv.h|  2 +-
 drivers/clocksource/hyperv_timer.c |  2 +-
 drivers/hv/hv_balloon.c|  4 ++--
 drivers/hv/hv_common.c |  2 +-
 drivers/hv/hv_kvp.c|  2 +-
 drivers/hv/hv_snapshot.c   |  2 +-
 drivers/hv/hyperv_vmbus.h  |  2 +-
 include/asm-generic/mshyperv.h |  7 +++
 include/clocksource/hyperv_timer.h |  2 +-
 include/linux/hyperv.h |  2 +-
 net/vmw_vsock/hyperv_transport.c   |  6 +++---
 22 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index 7a746a5a6b42..69004f619c57 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -14,7 +14,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 /*
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index b1a4de4eee29..fc49949b7df6 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -49,12 +49,12 @@ static int __init hyperv_init(void)
hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
 
/* Get the features and hints from Hyper-V */
-   hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
+   hv_get_vpreg_128(HV_REGISTER_PRIVILEGES_AND_FEATURES_INFO, &result);
ms_hyperv.features = result.as32.a;
ms_hyperv.priv_high = result.as32.b;
ms_hyperv.misc_features = result.as32.c;
 
-   hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
+   hv_get_vpreg_128(HV_REGISTER_FEATURES_INFO, &result);
ms_hyperv.hints = result.as32.a;
 
pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc 
0x%x\n",
diff --git a/arch/arm64/include/asm/mshyperv.h 
b/arch/arm64/include/asm/mshyperv.h
index a975e1a689dd..2e2f83bafcfb 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -6,9 +6,8 @@
  * the ARM64 architecture.  See include/asm-generic/mshyperv.h for
  * definitions are that architecture independent.
  *
- * Definitions that are specified in the Hyper-V Top Level Functional
- * Spec (TLFS) should not go in this file, but should instead go in
- * hyperv-tlfs.h.
+ * Definitions that are derived from Hyper-V code or headers should not go in
+ * this file, but should instead go in the relevant files in include/hyperv.
  *
  * Copyright (C) 2021, Microsoft, Inc.
  *
@@ -20,7 +19,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Declare calls to get and set Hyper-V VP register values on ARM64, which
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 3562826915f9..3cf2a227d666 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -19,7 +19,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -415,24 +415,24 @@ static void __init hv_get_partition_id(void)
 static u8 __init get_vtl(void)
 {
u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
-   struct hv_get_vp_registers_input *input;
-   struct hv_get_vp_registers_output *output;
+   struct hv_input_get_vp_registers *input;
+   struct hv_register_assoc *output;
unsigned long flags;
u64 ret;
 
local_irq_save(flags);
input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-   output = (struct hv_get_vp_registers_output *)input;
+   output = (struct hv_register_assoc *)input;
 
-   memset(input, 0, struct_size(input, element, 1));
-   input->header.partitionid = HV_PARTITION_ID_SELF;
-   input->header.vpindex = HV_VP_INDEX_SELF;
-   input->header.inputvtl = 0;
-   input->element[0].name0 = HV_X64_REGISTER_VSM_VP_STATUS;
+   memset(input, 0, struct_size(input, names, 1));
+   input->partition_id = HV_PARTITION_ID_SELF;
+   input->vp_index = HV_VP_INDEX

Re: [PATCH 0/2] hyperv: Move some features to common code

2024-12-09 Thread Nuno Das Neves
On 12/7/2024 6:59 PM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Friday, 
> December 6, 2024 2:22 PM
>>
>> There are several bits of Hyper-V-related code that today live in
>> arch/x86 but are not really specific to x86_64 and will work on arm64
>> too.
>>
>> Some of these will be needed in the upcoming mshv driver code (for
>> Linux as root partition on Hyper-V).
> 
> Previously, Linux as the root partition on Hyper-V was x86 only, which is
> why the code is currently under arch/x86. So evidently the mshv driver
> is being expanded to support both x86 and arm64, correct? Assuming
> that's the case, I have some thoughts about how the source code should
> be organized and built. It's probably best to get this right to start with so
> it doesn't need to be changed again.

Yes, we plan on supporting both architectures (eventually). I completely agree
that it's better to sort out these issues now rather than later.

> 
> * Patch 2 of this series moves hv_call_deposit_pages() and
>hv_call_create_vp() to common code, but does not move
>hv_call_add_logical_proc(). All three are used together, so
>I'm wondering why hv_call_add_logical_proc() isn't moved.
> 

The only reason is that in our internal tree there's no common or arm64 code
yet that uses it - there is no reason it can't also become common code!

> * These three functions were originally put in a separate source
>code file because of being specific to running in the root partition,
>and not needed for generic Linux guest support. I think there's
>value in keeping them in a separate file, rather than merging them
>into hv_common.c. Maybe just move the entire hv_proc.c file?

Agreed. I think it should be renamed too - this file will eventually
contain some additional hypercall helper functions, some of which may also be
shared by the driver code. Something like "hv_call_common.c"?

>And then later, perhaps move the entire irqdomain.c file as well?
Yes, may as well move it too.

>There's also an interesting question of whether to move them into
>drivers/hv, or create a new directory virt/hyperv. Hyper-V support
>started out 15 years ago structured as a driver, hence "drivers/hv".
>But over the time, the support has become significantly more than
>just a driver, so "virt/hyperv" might be a better location for
>non-driver code that had previously been under arch/x86 but is
>now common to all architectures.
> 
I'd be fine with using "virt/hyperv", but I thought "virt" was only for
KVM.

Another option would be to create subdirectories in "drivers/hv" to
organize the different modules more cleanly (i.e. when the /dev/mshv
driver code is introduced).

> * Today, the code for running in the root partition is built along
>with the rest of the Hyper-V support, and so is present in kernels
>built for normal Linux guests on Hyper-V. I haven't thought about
>all the implications, but perhaps there's value in having a CONFIG
>option to build for the root partition, so that code can be dropped
>from normal kernels. There's a significant amount of new code still
>to come for mshv that could be excluded from normal guests in this
>way. Also, the tests of the hv_root_partition variable could be
>changed to a function the compiler detects is always "false" in a
>kernel built without the CONFIG option, in which case it can drop
>the code for where hv_root_partition is "true".
> 
Using hv_root_partition is a good way to do it, since it won't require
many #ifdefs or moving the existing code around too much.

I can certainly give it a try, and create a separate patch series
introducing the option. I suppose "CONFIG_HYPERV_ROOT" makes sense as a
name?

> * The code currently in hv_proc.c is built for x86 only, and validly
>assumes the page size is 4K. But when the code moves to be
>common across architectures, that assumption is no longer
>valid in the general case. Perhaps the intent is that kernels for
>the root partition should always be built with page size 4K on
>arm64, but nothing enforces that intent. Personally, I think the code
>should be made to work with page sizes other than 4K so as to not
>leave technical debt. But I realize you may have other priorities. If
>there were a CONFIG option for building for the root partition,
>that option could be setup to enforce the 4K page size on arm64.
> 
That makes sense. I suppose this can be done by selecting PAGE_SIZE_4KB
under HYPERV in drivers/hv/Kconfig?

I'm not how easy it will be to make the code work w

Re: [PATCH v3 1/5] hyperv: Move hv_connection_id to hyperv-tlfs.h

2024-12-09 Thread Nuno Das Neves
On 12/8/2024 4:07 PM, Wei Liu wrote:
> On Mon, Nov 25, 2024 at 03:24:40PM -0800, Nuno Das Neves wrote:
>> This definition is in the wrong file; it is part of the TLFS doc.
>>
>> Acked-by: Wei Liu 
>> Reviewed-by: Easwar Hariharan 
>> Reviewed-by: Michael Kelley 
>> Signed-off-by: Nuno Das Neves 
> 
> One comment about the ordering of the tags. It is better to organize
> them in the following order:
> 
> Signed-off-by: Nuno Das Neves 
> Acked-by: Wei Liu 
> Reviewed-by: Easwar Hariharan 
> Reviewed-by: Michael Kelley 
> 
> I've made the change for you while applying the patch.
> 

Thank you, noted for next time.

> Thanks,
> Wei.




[PATCH v3 1/2] hyperv: Move hv_current_partition_id to arch-generic code

2025-02-07 Thread Nuno Das Neves
Move hv_current_partition_id and hv_get_partition_id() to hv_common.c,
and call hv_get_partition_id() on arm64 in hyperv_init(). These aren't
specific to x86_64 and will be needed by common code.

Set hv_current_partition_id to HV_PARTITION_ID_SELF by default.

Rename struct hv_get_partition_id to hv_output_get_partition_id, to
make it distinct from the function hv_get_partition_id(), and match
the original Hyper-V struct name.

Remove the BUG()s. Failing to get the id need not crash the machine.

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/mshyperv.c|  3 +++
 arch/x86/hyperv/hv_init.c   | 25 +
 arch/x86/include/asm/mshyperv.h |  2 --
 drivers/hv/hv_common.c  | 22 ++
 include/asm-generic/mshyperv.h  |  2 ++
 include/hyperv/hvgdk_mini.h |  2 +-
 6 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index fc49949b7df6..29fcfd595f48 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -72,6 +72,9 @@ static int __init hyperv_init(void)
return ret;
}
 
+   if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
+   hv_get_partition_id();
+
ms_hyperv_late_init();
 
hyperv_initialized = true;
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 173005e6a95d..9be1446f5bd3 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -34,9 +34,6 @@
 #include 
 #include 
 
-u64 hv_current_partition_id = ~0ull;
-EXPORT_SYMBOL_GPL(hv_current_partition_id);
-
 void *hv_hypercall_pg;
 EXPORT_SYMBOL_GPL(hv_hypercall_pg);
 
@@ -393,24 +390,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
old_setup_percpu_clockev();
 }
 
-static void __init hv_get_partition_id(void)
-{
-   struct hv_get_partition_id *output_page;
-   u64 status;
-   unsigned long flags;
-
-   local_irq_save(flags);
-   output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
-   status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
-   if (!hv_result_success(status)) {
-   /* No point in proceeding if this failed */
-   pr_err("Failed to get partition ID: %lld\n", status);
-   BUG();
-   }
-   hv_current_partition_id = output_page->partition_id;
-   local_irq_restore(flags);
-}
-
 #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
 static u8 __init get_vtl(void)
 {
@@ -605,11 +584,9 @@ void __init hyperv_init(void)
 
register_syscore_ops(&hv_syscore_ops);
 
-   if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
+   if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
hv_get_partition_id();
 
-   BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
-
 #ifdef CONFIG_PCI_MSI
/*
 * If we're running as root, we want to create our own PCI MSI domain.
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index f91ab1e75f9f..8d3ada3e8d0d 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -43,8 +43,6 @@ extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
 
-extern u64 hv_current_partition_id;
-
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
 bool hv_isolation_type_snp(void);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index af5d1dc451f6..cb3ea49020ef 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -31,6 +31,9 @@
 #include 
 #include 
 
+u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
+EXPORT_SYMBOL_GPL(hv_current_partition_id);
+
 /*
  * hv_root_partition, ms_hyperv and hv_nested are defined here with other
  * Hyper-V specific globals so they are shared across all architectures and are
@@ -283,6 +286,25 @@ static inline bool hv_output_page_exists(void)
return hv_root_partition || IS_ENABLED(CONFIG_HYPERV_VTL_MODE);
 }
 
+void __init hv_get_partition_id(void)
+{
+   struct hv_output_get_partition_id *output;
+   unsigned long flags;
+   u64 status, pt_id;
+
+   local_irq_save(flags);
+   output = *this_cpu_ptr(hyperv_pcpu_input_arg);
+   status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, &output);
+   pt_id = output->partition_id;
+   local_irq_restore(flags);
+
+   if (hv_result_success(status))
+   hv_current_partition_id = pt_id;
+   else
+   pr_err("Hyper-V: failed to get partition ID: %#lx\n",
+  hv_result(status));
+}
+
 int __init hv_common_init(void)
 {
int i;
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index a7bbe504e4f3..febeddf6cd8a 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -58,6 +58,7 @@ struct ms_hyperv_info {
 };
 extern struct ms_hyperv_info ms_hyperv;
 extern boo

[PATCH v3 2/2] hyperv: Move arch/x86/hyperv/hv_proc.c to drivers/hv

2025-02-07 Thread Nuno Das Neves
These helpers are not specific to x86_64 and will be needed by common code.
Remove some unnecessary #includes.

Reviewed-by: Michael Kelley 
Signed-off-by: Nuno Das Neves 
---
 arch/x86/hyperv/Makefile  | 2 +-
 arch/x86/include/asm/mshyperv.h   | 4 
 drivers/hv/Makefile   | 2 +-
 {arch/x86/hyperv => drivers/hv}/hv_proc.c | 4 
 include/asm-generic/mshyperv.h| 4 
 5 files changed, 6 insertions(+), 10 deletions(-)
 rename {arch/x86/hyperv => drivers/hv}/hv_proc.c (98%)

diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 3a1548054b48..d55f494f471d 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y  := hv_init.o mmu.o nested.o irqdomain.o ivm.o
-obj-$(CONFIG_X86_64)   += hv_apic.o hv_proc.o
+obj-$(CONFIG_X86_64)   += hv_apic.o
 obj-$(CONFIG_HYPERV_VTL_MODE)  += hv_vtl.o
 
 ifdef CONFIG_X86_64
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 8d3ada3e8d0d..7dfca93ef048 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -56,10 +56,6 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 #define HV_AP_INIT_GPAT_DEFAULT0x0007040600070406ULL
 #define HV_AP_SEGMENT_LIMIT0x
 
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
-int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
-
 /*
  * If the hypercall involves no input or output parameters, the hypervisor
  * ignores the corresponding GPA pointer.
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index b992c0ed182b..9afcabb3fbd2 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -13,4 +13,4 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING) += hv_debugfs.o
 hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o
 
 # Code that must be built-in
-obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o
+obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o hv_proc.o
diff --git a/arch/x86/hyperv/hv_proc.c b/drivers/hv/hv_proc.c
similarity index 98%
rename from arch/x86/hyperv/hv_proc.c
rename to drivers/hv/hv_proc.c
index ac4c834d4435..3e410489f480 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/drivers/hv/hv_proc.c
@@ -6,11 +6,7 @@
 #include 
 #include 
 #include 
-#include 
 #include 
-#include 
-
-#include 
 
 /*
  * See struct hv_deposit_memory. The first u64 is partition ID, the rest
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index febeddf6cd8a..7adc10a4fa3e 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -218,6 +218,10 @@ void *hv_alloc_hyperv_page(void);
 void *hv_alloc_hyperv_zeroed_page(void);
 void hv_free_hyperv_page(void *addr);
 
+int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
+int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
+int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
+
 /**
  * hv_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
-- 
2.34.1




[PATCH v3 0/2] hyperv: Move some features to common code

2025-02-07 Thread Nuno Das Neves
There are several bits of Hyper-V-related code that today live in
arch/x86 but are not really specific to x86_64 and will work on arm64
too.

Some of these will be needed in the upcoming mshv driver code (for
Linux as root partition on Hyper-V). So this is a good time to move
them to drivers/hv.

Signed-off-by: Nuno Das Neves 
---
Changes in v3:
* Just use percpu input page for the hypercall [Michael Kelley]
* Move the calls to hv_get_partition_id() back to arch code [Michael Kelley]
* Rename struct hv_get_partition_id to hv_output_get_partition_id
  [Michael Kelley]

Changes in v2:
* Fix dependence on percpu output page by using a stack variable for the
  hypercall output [Michael Kelley]
* Remove unnecessary WARN()s [Michael Kelley]
* Define hv_current_partition_id in hv_common.c [Michael Kelley]
* Move entire hv_proc.c to drivers/hv [Michael Kelley]

Nuno Das Neves (2):
  hyperv: Move hv_current_partition_id to arch-generic code
  hyperv: Move arch/x86/hyperv/hv_proc.c to drivers/hv

 arch/arm64/hyperv/mshyperv.c  |  3 +++
 arch/x86/hyperv/Makefile  |  2 +-
 arch/x86/hyperv/hv_init.c | 25 +--
 arch/x86/include/asm/mshyperv.h   |  6 --
 drivers/hv/Makefile   |  2 +-
 drivers/hv/hv_common.c| 22 
 {arch/x86/hyperv => drivers/hv}/hv_proc.c |  4 
 include/asm-generic/mshyperv.h|  6 ++
 include/hyperv/hvgdk_mini.h   |  2 +-
 9 files changed, 35 insertions(+), 37 deletions(-)
 rename {arch/x86/hyperv => drivers/hv}/hv_proc.c (98%)

-- 
2.34.1




[PATCH] hyperv: Add CONFIG_MSHV_ROOT to gate hv_root_partition checks

2025-02-11 Thread Nuno Das Neves
Introduce CONFIG_MSHV_ROOT as a tristate to enable root partition
booting and future mshv driver functionality.

Change hv_root_partition into a function which always returns false
if CONFIG_MSHV_ROOT=n.

Introduce hv_current_partition_type to store the type of partition
(guest, root, or other kinds in future), and hv_identify_partition_type()
to it up early in Hyper-V initialization.

Signed-off-by: Nuno Das Neves 
---
Depends on
https://lore.kernel.org/linux-hyperv/1738955002-20821-3-git-send-email-nunodasne...@linux.microsoft.com/

 arch/arm64/hyperv/mshyperv.c   |  2 ++
 arch/x86/hyperv/hv_init.c  | 10 
 arch/x86/kernel/cpu/mshyperv.c | 24 ++
 drivers/clocksource/hyperv_timer.c |  4 +--
 drivers/hv/Kconfig | 12 +
 drivers/hv/Makefile|  3 ++-
 drivers/hv/hv.c| 10 
 drivers/hv/hv_common.c | 32 +++-
 drivers/hv/vmbus_drv.c |  2 +-
 drivers/iommu/hyperv-iommu.c   |  4 +--
 include/asm-generic/mshyperv.h | 39 +-
 11 files changed, 92 insertions(+), 50 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 29fcfd595f48..2265ea5ce5ad 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -61,6 +61,8 @@ static int __init hyperv_init(void)
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
ms_hyperv.misc_features);
 
+   hv_identify_partition_type();
+
ret = hv_common_init();
if (ret)
return ret;
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 9be1446f5bd3..ddeb40930bc8 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -90,7 +90,7 @@ static int hv_cpu_init(unsigned int cpu)
return 0;
 
hvp = &hv_vp_assist_page[cpu];
-   if (hv_root_partition) {
+   if (hv_root_partition()) {
/*
 * For root partition we get the hypervisor provided VP assist
 * page, instead of allocating a new page.
@@ -242,7 +242,7 @@ static int hv_cpu_die(unsigned int cpu)
 
if (hv_vp_assist_page && hv_vp_assist_page[cpu]) {
union hv_vp_assist_msr_contents msr = { 0 };
-   if (hv_root_partition) {
+   if (hv_root_partition()) {
/*
 * For root partition the VP assist page is mapped to
 * hypervisor provided page, and thus we unmap the
@@ -317,7 +317,7 @@ static int hv_suspend(void)
union hv_x64_msr_hypercall_contents hypercall_msr;
int ret;
 
-   if (hv_root_partition)
+   if (hv_root_partition())
return -EPERM;
 
/*
@@ -518,7 +518,7 @@ void __init hyperv_init(void)
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
hypercall_msr.enable = 1;
 
-   if (hv_root_partition) {
+   if (hv_root_partition()) {
struct page *pg;
void *src;
 
@@ -592,7 +592,7 @@ void __init hyperv_init(void)
 * If we're running as root, we want to create our own PCI MSI domain.
 * We can't set this in hv_pci_init because that would be too late.
 */
-   if (hv_root_partition)
+   if (hv_root_partition())
x86_init.irqs.create_pci_msi_domain = hv_create_pci_msi_domain;
 #endif
 
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index f285757618fc..4f01f424ea5b 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -33,8 +33,6 @@
 #include 
 #include 
 
-/* Is Linux running as the root partition? */
-bool hv_root_partition;
 /* Is Linux running on nested Microsoft Hypervisor */
 bool hv_nested;
 struct ms_hyperv_info ms_hyperv;
@@ -451,25 +449,7 @@ static void __init ms_hyperv_init_platform(void)
pr_debug("Hyper-V: max %u virtual processors, %u logical processors\n",
 ms_hyperv.max_vp_index, ms_hyperv.max_lp_index);
 
-   /*
-* Check CPU management privilege.
-*
-* To mirror what Windows does we should extract CPU management
-* features and use the ReservedIdentityBit to detect if Linux is the
-* root partition. But that requires negotiating CPU management
-* interface (a process to be finalized). For now, use the privilege
-* flag as the indicator for running as root.
-*
-* Hyper-V should never specify running as root and as a Confidential
-* VM. But to protect against a compromised/malicious Hyper-V trying
-* to exploit root behavior to expose Confidential VM memory, ignore
-* the root partition setting if also a Confidential VM.
-*/
-   if ((ms_hyperv.priv_high & HV_CPU_MANAGEMENT) &&
-   

Re: [PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic code

2024-12-10 Thread Nuno Das Neves
On 12/7/2024 7:01 PM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Friday, 
> December 6, 2024 2:22 PM
>>
>> Make hv_current_partition_id available in both x86_64 and arm64.
>> This feature isn't specific to x86_64 and will be needed by common
>> code.
>>
>> While at it, replace the BUG()s with WARN()s. Failing to get the id
>> need not crash the machine (although it is a very bad sign).
>>
>> Signed-off-by: Nuno Das Neves 
>> ---
>>  arch/arm64/hyperv/mshyperv.c|  3 +++
>>  arch/x86/hyperv/hv_init.c   | 25 +
>>  arch/x86/include/asm/mshyperv.h |  2 --
>>  drivers/hv/hv_common.c  | 23 +++
>>  include/asm-generic/mshyperv.h  |  2 ++
>>  5 files changed, 29 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index b1a4de4eee29..5050e748d266 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -19,6 +19,9 @@
>>
>>  static bool hyperv_initialized;
>>
>> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>> +EXPORT_SYMBOL_GPL(hv_current_partition_id);
>> +
> 
> Instead of adding a definition of hv_current_partition_id on
> the arm64 side, couldn't the definition on the x86 side in
> hv_init.c be moved to hv_common.c (or maybe somewhere
> else that is specific to running in the root partition, per my
> comments in the cover letter), so there is only one definition
> shared by both architectures?
> 
Yes, that's a better idea.

>>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>>  {
>>  hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
>> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
>> index 95eada2994e1..950f5ccdb9d9 100644
>> --- a/arch/x86/hyperv/hv_init.c
>> +++ b/arch/x86/hyperv/hv_init.c
>> @@ -35,7 +35,7 @@
>>  #include 
>>  #include 
>>
>> -u64 hv_current_partition_id = ~0ull;
>> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>>  EXPORT_SYMBOL_GPL(hv_current_partition_id);
>>
>>  void *hv_hypercall_pg;
>> @@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
>>  old_setup_percpu_clockev();
>>  }
>>
>> -static void __init hv_get_partition_id(void)
>> -{
>> -struct hv_get_partition_id *output_page;
>> -u64 status;
>> -unsigned long flags;
>> -
>> -local_irq_save(flags);
>> -output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
>> -status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
>> -if (!hv_result_success(status)) {
>> -/* No point in proceeding if this failed */
>> -pr_err("Failed to get partition ID: %lld\n", status);
>> -BUG();
>> -}
>> -hv_current_partition_id = output_page->partition_id;
>> -local_irq_restore(flags);
>> -}
>> -
>>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
>>  static u8 __init get_vtl(void)
>>  {
>> @@ -606,11 +588,6 @@ void __init hyperv_init(void)
>>
>>  register_syscore_ops(&hv_syscore_ops);
>>
>> -if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
>> -hv_get_partition_id();
>> -
>> -BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
>> -
>>  #ifdef CONFIG_PCI_MSI
>>  /*
>>   * If we're running as root, we want to create our own PCI MSI domain.
>> diff --git a/arch/x86/include/asm/mshyperv.h 
>> b/arch/x86/include/asm/mshyperv.h
>> index 5f0bc6a6d025..9eeca2a6d047 100644
>> --- a/arch/x86/include/asm/mshyperv.h
>> +++ b/arch/x86/include/asm/mshyperv.h
>> @@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
>>
>>  extern void *hv_hypercall_pg;
>>
>> -extern u64 hv_current_partition_id;
>> -
>>  extern union hv_ghcb * __percpu *hv_ghcb_pg;
>>
>>  bool hv_isolation_type_snp(void);
>> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
>> index 7a35c82976e0..819bcfd2b149 100644
>> --- a/drivers/hv/hv_common.c
>> +++ b/drivers/hv/hv_common.c
>> @@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
>>  }
>>  }
>>
>> +static void __init hv_get_partition_id(void)
>> +{
>> +struct hv_get_partition_id *output_page;
>> +u64 status;
>> +unsigned long flags;
>> +
>> +local_irq_save(flags);
>> +output_page = *this_cpu_pt

Re: [PATCH 1/2] hyperv: Fix pointer type for the output of the hypercall in get_vtl(void)

2024-12-19 Thread Nuno Das Neves
On 12/18/2024 12:54 PM, Roman Kisel wrote:
> Commit bc905fa8b633 ("hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h")
> changed the type of the output pointer to `struct hv_register_assoc` from
> `struct hv_get_vp_registers_output`. That leads to an incorrect computation,
> and leaves the system broken.
> 
My bad! But, lets not use `struct hv_get_registers_output`. Instead, use
`struct hv_register_value`, since that is the more complete definition of a
register value. The output of the get_vp_registers hypercall is just an array
of these values.

Ideally we remove `struct hv_get_vp_registers_output` at some point, since
it serves the same role as `struct hv_register_value` but in a more limited
capacity.

Thanks
Nuno

> Use the correct pointer type for the output of the GetVpRegisters hypercall.
> 
> Fixes: bc905fa8b633 ("hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h")
> Signed-off-by: Roman Kisel 
> ---
>  arch/x86/hyperv/hv_init.c   | 6 +++---
>  include/hyperv/hvgdk_mini.h | 3 ---
>  2 files changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 3cf2a227d666..c7185c6a290b 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -416,13 +416,13 @@ static u8 __init get_vtl(void)
>  {
>   u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
>   struct hv_input_get_vp_registers *input;
> - struct hv_register_assoc *output;
> + struct hv_get_vp_registers_output *output;
>   unsigned long flags;
>   u64 ret;
>  
>   local_irq_save(flags);
>   input = *this_cpu_ptr(hyperv_pcpu_input_arg);
> - output = (struct hv_register_assoc *)input;
> + output = (struct hv_get_vp_registers_output *)input;
>  
>   memset(input, 0, struct_size(input, names, 1));
>   input->partition_id = HV_PARTITION_ID_SELF;
> @@ -432,7 +432,7 @@ static u8 __init get_vtl(void)
>  
>   ret = hv_do_hypercall(control, input, output);
>   if (hv_result_success(ret)) {
> - ret = output->value.reg8 & HV_X64_VTL_MASK;
> + ret = output->as64.low & HV_X64_VTL_MASK;
>   } else {
>   pr_err("Failed to get VTL(error: %lld) exiting...\n", ret);
>   BUG();
> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
> index db3d1aaf7330..0b1a10828f33 100644
> --- a/include/hyperv/hvgdk_mini.h
> +++ b/include/hyperv/hvgdk_mini.h
> @@ -1107,7 +1107,6 @@ union hv_register_value {
>   union hv_x64_pending_interruption_register pending_interruption;
>  };
>  
> -#if defined(CONFIG_ARM64)
>  /* HvGetVpRegisters returns an array of these output elements */
>  struct hv_get_vp_registers_output {
>   union {
> @@ -1124,8 +1123,6 @@ struct hv_get_vp_registers_output {
>   };
>  };
>  
> -#endif /* CONFIG_ARM64 */
> -
>  struct hv_register_assoc {
>   u32 name;   /* enum hv_register_name */
>   u32 reserved1;




Re: [PATCH 1/2] hyperv: Fix pointer type for the output of the hypercall in get_vtl(void)

2024-12-19 Thread Nuno Das Neves
On 12/19/2024 11:13 AM, Easwar Hariharan wrote:
> On 12/19/2024 10:40 AM, Nuno Das Neves wrote:
>> On 12/18/2024 12:54 PM, Roman Kisel wrote:
>>> Commit bc905fa8b633 ("hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h")
>>> changed the type of the output pointer to `struct hv_register_assoc` from
>>> `struct hv_get_vp_registers_output`. That leads to an incorrect computation,
>>> and leaves the system broken.
>>>
>> My bad! But, lets not use `struct hv_get_registers_output`. Instead, use
>> `struct hv_register_value`, since that is the more complete definition of a
>> register value. The output of the get_vp_registers hypercall is just an array
>> of these values.
>>
>> Ideally we remove `struct hv_get_vp_registers_output` at some point, since
>> it serves the same role as `struct hv_register_value` but in a more limited
>> capacity.
>>
>> Thanks
>> Nuno
>>
> 
> I had much the same conversation with Roman off-list yesterday.
> 
> The choice is between using hv_get_registers_output which is clearly the
> output of the GetVpRegisters hypercall by name, albeit limited as you

If it's desirable to have a more 'friendly' naming here, then I'd be okay with:
```
/* NOTE: Linux helper struct - NOT from Hyper-V code */
struct hv_output_get_vp_registers {
DECLARE_FLEX_ARRAY(struct hv_register_value, values);
}
```
Note also the name is prefixed with "hv_output_" to match other hypercall 
outputs.

> said, and hv_register_value which is the more complete definition and
> what the hypervisor actually returns, but does not currently include the
> arm64 definitions in our copy of hvgdk_mini.h. hv_get_registers_output
> and hv_register_value overlap in layout for Roman's purposes.
> 
> FWIW, I'm in favor of adding the arm64 definitions to hv_register_value
> and using it for this get_vtl() patch.
> 

> This could be accompanied with migration of hv_get_vpreg128 in arm64/
> and removal of struct hv_get_registers_output, or that could be deferred
> to a later patch.

I'd be happy to submit a followup patch to update the arm64 code to use
hv_register_value, or a new struct as outlined above.

It is a pretty small change though, it might be easier to just include it in
this series.

Nuno

> 
> - Easwar




[PATCH 2/2] hyperv: Move create_vp and deposit_pages hvcalls to hv_common.c

2024-12-06 Thread Nuno Das Neves
From: Nuno Das Neves 

These are not specific to x86_64 and will be needed by common code.

Signed-off-by: Nuno Das Neves 
---
 arch/x86/hyperv/hv_proc.c   | 144 ---
 arch/x86/include/asm/mshyperv.h |   2 -
 drivers/hv/hv_common.c  | 145 
 include/asm-generic/mshyperv.h  |   2 +
 4 files changed, 147 insertions(+), 146 deletions(-)

diff --git a/arch/x86/hyperv/hv_proc.c b/arch/x86/hyperv/hv_proc.c
index 3fa1f2ee7b0d..119354d00637 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/arch/x86/hyperv/hv_proc.c
@@ -10,109 +10,8 @@
 #include 
 #include 
 #include 
-
 #include 
 
-/*
- * See struct hv_deposit_memory. The first u64 is partition ID, the rest
- * are GPAs.
- */
-#define HV_DEPOSIT_MAX (HV_HYP_PAGE_SIZE / sizeof(u64) - 1)
-
-/* Deposits exact number of pages. Must be called with interrupts enabled.  */
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages)
-{
-   struct page **pages, *page;
-   int *counts;
-   int num_allocations;
-   int i, j, page_count;
-   int order;
-   u64 status;
-   int ret;
-   u64 base_pfn;
-   struct hv_deposit_memory *input_page;
-   unsigned long flags;
-
-   if (num_pages > HV_DEPOSIT_MAX)
-   return -E2BIG;
-   if (!num_pages)
-   return 0;
-
-   /* One buffer for page pointers and counts */
-   page = alloc_page(GFP_KERNEL);
-   if (!page)
-   return -ENOMEM;
-   pages = page_address(page);
-
-   counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL);
-   if (!counts) {
-   free_page((unsigned long)pages);
-   return -ENOMEM;
-   }
-
-   /* Allocate all the pages before disabling interrupts */
-   i = 0;
-
-   while (num_pages) {
-   /* Find highest order we can actually allocate */
-   order = 31 - __builtin_clz(num_pages);
-
-   while (1) {
-   pages[i] = alloc_pages_node(node, GFP_KERNEL, order);
-   if (pages[i])
-   break;
-   if (!order) {
-   ret = -ENOMEM;
-   num_allocations = i;
-   goto err_free_allocations;
-   }
-   --order;
-   }
-
-   split_page(pages[i], order);
-   counts[i] = 1 << order;
-   num_pages -= counts[i];
-   i++;
-   }
-   num_allocations = i;
-
-   local_irq_save(flags);
-
-   input_page = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-   input_page->partition_id = partition_id;
-
-   /* Populate gpa_page_list - these will fit on the input page */
-   for (i = 0, page_count = 0; i < num_allocations; ++i) {
-   base_pfn = page_to_pfn(pages[i]);
-   for (j = 0; j < counts[i]; ++j, ++page_count)
-   input_page->gpa_page_list[page_count] = base_pfn + j;
-   }
-   status = hv_do_rep_hypercall(HVCALL_DEPOSIT_MEMORY,
-page_count, 0, input_page, NULL);
-   local_irq_restore(flags);
-   if (!hv_result_success(status)) {
-   pr_err("Failed to deposit pages: %lld\n", status);
-   ret = hv_result(status);
-   goto err_free_allocations;
-   }
-
-   ret = 0;
-   goto free_buf;
-
-err_free_allocations:
-   for (i = 0; i < num_allocations; ++i) {
-   base_pfn = page_to_pfn(pages[i]);
-   for (j = 0; j < counts[i]; ++j)
-   __free_page(pfn_to_page(base_pfn + j));
-   }
-
-free_buf:
-   free_page((unsigned long)pages);
-   kfree(counts);
-   return ret;
-}
-
 int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id)
 {
struct hv_input_add_logical_processor *input;
@@ -154,46 +53,3 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 
apic_id)
return ret;
 }
 
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
-{
-   struct hv_create_vp *input;
-   u64 status;
-   unsigned long irq_flags;
-   int ret = HV_STATUS_SUCCESS;
-
-   /* Root VPs don't seem to need pages deposited */
-   if (partition_id != hv_current_partition_id) {
-   /* The value 90 is empirically determined. It may change. */
-   ret = hv_call_deposit_pages(node, partition_id, 90);
-   if (ret)
-   return ret;
-   }
-
-   do {
-   local_irq_save(irq_flags);
-
-   input = *this_cpu_ptr(hyperv_pcpu_input_arg);
-
-   input->partition_id = partition_id;
-   input->vp_index = vp_index;
-   input->flags = flags;
-   input->subnode_type = HvSubnodeAny;
-   input-

[PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic code

2024-12-06 Thread Nuno Das Neves
From: Nuno Das Neves 

Make hv_current_partition_id available in both x86_64 and arm64.
This feature isn't specific to x86_64 and will be needed by common
code.

While at it, replace the BUG()s with WARN()s. Failing to get the id
need not crash the machine (although it is a very bad sign).

Signed-off-by: Nuno Das Neves 
---
 arch/arm64/hyperv/mshyperv.c|  3 +++
 arch/x86/hyperv/hv_init.c   | 25 +
 arch/x86/include/asm/mshyperv.h |  2 --
 drivers/hv/hv_common.c  | 23 +++
 include/asm-generic/mshyperv.h  |  2 ++
 5 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index b1a4de4eee29..5050e748d266 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,6 +19,9 @@
 
 static bool hyperv_initialized;
 
+u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
+EXPORT_SYMBOL_GPL(hv_current_partition_id);
+
 int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
 {
hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 95eada2994e1..950f5ccdb9d9 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -35,7 +35,7 @@
 #include 
 #include 
 
-u64 hv_current_partition_id = ~0ull;
+u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
 EXPORT_SYMBOL_GPL(hv_current_partition_id);
 
 void *hv_hypercall_pg;
@@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
old_setup_percpu_clockev();
 }
 
-static void __init hv_get_partition_id(void)
-{
-   struct hv_get_partition_id *output_page;
-   u64 status;
-   unsigned long flags;
-
-   local_irq_save(flags);
-   output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
-   status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
-   if (!hv_result_success(status)) {
-   /* No point in proceeding if this failed */
-   pr_err("Failed to get partition ID: %lld\n", status);
-   BUG();
-   }
-   hv_current_partition_id = output_page->partition_id;
-   local_irq_restore(flags);
-}
-
 #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
 static u8 __init get_vtl(void)
 {
@@ -606,11 +588,6 @@ void __init hyperv_init(void)
 
register_syscore_ops(&hv_syscore_ops);
 
-   if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
-   hv_get_partition_id();
-
-   BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
-
 #ifdef CONFIG_PCI_MSI
/*
 * If we're running as root, we want to create our own PCI MSI domain.
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 5f0bc6a6d025..9eeca2a6d047 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
 
-extern u64 hv_current_partition_id;
-
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
 bool hv_isolation_type_snp(void);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 7a35c82976e0..819bcfd2b149 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
}
 }
 
+static void __init hv_get_partition_id(void)
+{
+   struct hv_get_partition_id *output_page;
+   u64 status;
+   unsigned long flags;
+
+   local_irq_save(flags);
+   output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
+   status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
+   if (!hv_result_success(status)) {
+   local_irq_restore(flags);
+   WARN(true, "Failed to get partition ID: %lld\n", status);
+   return;
+   }
+   hv_current_partition_id = output_page->partition_id;
+   local_irq_restore(flags);
+}
+
 int __init hv_common_init(void)
 {
int i;
union hv_hypervisor_version_info version;
 
+   if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
+   hv_get_partition_id();
+
+   WARN_ON(hv_root_partition && hv_current_partition_id == 
HV_PARTITION_ID_SELF);
+
/* Get information about the Hyper-V host version */
if (!hv_get_hypervisor_version(&version))
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8fe7aaab2599..8c4ff6e9aae7 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -60,6 +60,8 @@ struct ms_hyperv_info {
 extern struct ms_hyperv_info ms_hyperv;
 extern bool hv_nested;
 
+extern u64 hv_current_partition_id;
+
 extern void * __percpu *hyperv_pcpu_input_arg;
 extern void * __percpu *hyperv_pcpu_output_arg;
 
-- 
2.34.1




[PATCH 0/2] hyperv: Move some features to common code

2024-12-06 Thread Nuno Das Neves
There are several bits of Hyper-V-related code that today live in
arch/x86 but are not really specific to x86_64 and will work on arm64
too.

Some of these will be needed in the upcoming mshv driver code (for
Linux as root partition on Hyper-V). So this is a good time to move
them to hv_common.c.

Signed-off-by: Nuno Das Neves 

Nuno Das Neves (2):
  hyperv: Move hv_current_partition_id to arch-generic code
  hyperv: Move create_vp and deposit_pages hvcalls to hv_common.c

 arch/arm64/hyperv/mshyperv.c|   3 +
 arch/x86/hyperv/hv_init.c   |  25 +
 arch/x86/hyperv/hv_proc.c   | 144 ---
 arch/x86/include/asm/mshyperv.h |   4 -
 drivers/hv/hv_common.c  | 168 
 include/asm-generic/mshyperv.h  |   4 +
 6 files changed, 176 insertions(+), 172 deletions(-)

-- 
2.34.1




Re: [PATCH v5 2/5] hyperv: Fix pointer type in get_vtl(void)

2025-01-08 Thread Nuno Das Neves
On 12/30/2024 10:09 AM, Roman Kisel wrote:
> Commit bc905fa8b633 ("hyperv: Switch from hyperv-tlfs.h to hyperv/hvhdk.h")
> changed the type of the output pointer to `struct hv_register_assoc` from
> `struct hv_get_vp_registers_output`. That leads to an incorrect computation,
> and leaves the system broken.
> 
> Use the correct pointer type for the output of the GetVpRegisters hypercall.
> 
> Signed-off-by: Roman Kisel 
> ---
>  arch/x86/hyperv/hv_init.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 9e5e8328df6b..f82d1aefaa8a 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -416,13 +416,13 @@ static u8 __init get_vtl(void)
>  {
>   u64 control = HV_HYPERCALL_REP_COMP_1 | HVCALL_GET_VP_REGISTERS;
>   struct hv_input_get_vp_registers *input;
> - struct hv_register_assoc *output;
> + struct hv_output_get_vp_registers *output;
>   unsigned long flags;
>   u64 ret;
>  
>   local_irq_save(flags);
>   input = *this_cpu_ptr(hyperv_pcpu_input_arg);
> - output = (struct hv_register_assoc *)input;
> + output = (struct hv_output_get_vp_registers *)input;
>  
>   memset(input, 0, struct_size(input, names, 1));
>   input->partition_id = HV_PARTITION_ID_SELF;
> @@ -432,7 +432,7 @@ static u8 __init get_vtl(void)
>  
>   ret = hv_do_hypercall(control, input, output);
>   if (hv_result_success(ret)) {
> - ret = output->value.reg8 & HV_X64_VTL_MASK;
> + ret = output->values[0].reg8 & HV_X64_VTL_MASK;
>   } else {
>   pr_err("Failed to get VTL(error: %lld) exiting...\n", ret);
>   BUG();

Reviewed-by: Nuno Das Neves 



Re: [PATCH v5 1/5] hyperv: Define struct hv_output_get_vp_registers

2025-01-08 Thread Nuno Das Neves
On 1/6/2025 9:37 AM, Michael Kelley wrote:
> From: Roman Kisel  Sent: Monday, December 30, 
> 2024 10:10 AM
>>
>> There is no definition of the output structure for the
>> GetVpRegisters hypercall. Hence, using the hypercall
>> is not possible when the output value has some structure
>> to it. Even getting a datum of a primitive type reads
>> as ad-hoc without that definition.
>>
>> Define struct hv_output_get_vp_registers to enable using
>> the GetVpRegisters hypercall. Make provisions for all
>> supported architectures. No functional changes.
>>
>> Signed-off-by: Roman Kisel 
>> ---
>>  include/hyperv/hvgdk_mini.h | 49 +
>>  1 file changed, 49 insertions(+)
>>
>> diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h
>> index db3d1aaf7330..e8e3faa78e15 100644
>> --- a/include/hyperv/hvgdk_mini.h
>> +++ b/include/hyperv/hvgdk_mini.h
>> @@ -1068,6 +1068,35 @@ union hv_dispatch_suspend_register {
>>  } __packed;
>>  };
>>
>> +union hv_arm64_pending_interruption_register {
>> +u64 as_uint64;
>> +struct {
>> +u64 interruption_pending : 1;
>> +u64 interruption_type : 1;
>> +u64 reserved : 30;
>> +u32 error_code;
> 
> These bit field definitions don't look right. We want to "fill up"
> the field size, so that we're explicit about each bit, and not leave
> it to the compiler to add padding (which __packed tells the
> compiler not to do). So in aggregate, the "u64" bit fields should
> account for all 64 bits, but here you account for only 32 bits.
> There are two ways to fix this:
> 
>   u32 interruption_pending : 1;
>   u32 interruption_type: 1;
>   u32 reserved : 30;
>   u32 error_code;
> Or
>   u64 interruption_pending : 1;
>   u64 interruption_type: 1;
>   u64 reserved : 30;
>   u64 error_code : 32;
> 

Agreed. In the spirit of matching the original headers, I'd prefer
the second one. But either will work.

>> +} __packed;
>> +};
>> +
>> +union hv_arm64_interrupt_state_register {
>> +u64 as_uint64;
>> +struct {
>> +u64 interrupt_shadow : 1;
>> +u64 reserved : 63;
>> +} __packed;
>> +};
>> +
>> +union hv_arm64_pending_synthetic_exception_event {
>> +u64 as_uint64[2];
>> +struct {
>> +u32 event_pending : 1;
>> +u32 event_type : 3;
>> +u32 reserved : 4;
> 
> Same here. Expand the "reserved" field to 28 bits?  Or maybe
> there's a reason to have two separate reserved fields of 4 bits
> and 24 bits. I'm not sure what the register layout is supposed to
> be. Looking at hv_arm64_pending_synthetic_exception_event
> in the OHCL-Linux-Kernel github tree shows the same gap of
> 24 bits, so that doesn't provide any guidance.
> 

Hmm..these should be u8 bitfields according to the Hyper-V code.
However that leaves a 24 bit gap as you pointed out.

In the Hyper-V code, these structures aren't actually packed,
which means sometimes the explicit padding is left out
(unintentionally).

Please add the 24 bits of padding to make it explicit here. I
suggest making the bitfields u8 as in the original code, and adding
another padding field after, like:

u8 event_pending : 1;
u8 event_type : 3;
u8 reserved : 4;
u8 rsvd[3];

>> +u32 exception_type;
>> +u64 context;
>> +} __packed;
>> +};
>> +
>>  union hv_x64_interrupt_state_register {
>>  u64 as_uint64;
>>  struct {
>> @@ -1103,8 +1132,28 @@ union hv_register_value {
>>  union hv_explicit_suspend_register explicit_suspend;
>>  union hv_intercept_suspend_register intercept_suspend;
>>  union hv_dispatch_suspend_register dispatch_suspend;
>> +#ifdef CONFIG_ARM64
>> +union hv_arm64_interrupt_state_register interrupt_state;
>> +union hv_arm64_pending_interruption_register pending_interruption;
>> +#endif
>> +#ifdef CONFIG_X86
>>  union hv_x64_interrupt_state_register interrupt_state;
>>  union hv_x64_pending_interruption_register pending_interruption;
>> +#endif
>> +union hv_arm64_pending_synthetic_exception_event 
>> pending_synthetic_exception_event;
>> +};
> 
> Per the previous discussion, I can see that the #ifdef's are needed
> here to disambiguate the field names that are the same, but have
> different unions on x86 and arm64.
> 
> But on the flip side, I wonder if the field names should really be the
> same. Because of the different unions, it seems like they couldn't be
> accessed by architecture neutral code (unless the access is just using
> the "as_uint64" option?). So giving the fields names like
> "x86_interrupt_state" and "arm64_interrupt_state" instead of just
> "interrupt_state" might be more consistent with how the rest of this
> file handles architecture differences. But I don't know all the implications
> of making such a change.
> 
> Nuno -- your thoughts?

My main preference is to match with the original code unl

Re: [PATCH 1/2] hyperv: Move hv_current_partition_id to arch-generic code

2025-01-22 Thread Nuno Das Neves
On 12/6/2024 11:36 PM, Wei Liu wrote:
> On Fri, Dec 06, 2024 at 02:21:46PM -0800, Nuno Das Neves wrote:
>> From: Nuno Das Neves 
>>
>> Make hv_current_partition_id available in both x86_64 and arm64.
>> This feature isn't specific to x86_64 and will be needed by common
>> code.
>>
>> While at it, replace the BUG()s with WARN()s. Failing to get the id
>> need not crash the machine (although it is a very bad sign).
>>
> 
> A lot of things have changed since it was introduced. I don't remember
> why I decided to use BUG() instead of WARN() in the first place.
> 
> If the system can still function without knowing its partition id, then
> can this be removed completely? We can always use the SELF id.
> 

Missed this earlier, sorry.

I checked the code and it seems that HV_PARTITION_ID_SELF may be sufficient.
However, I'm not sure if there is some case where it is actually needed,
so I'm hesitant to remove it at the moment.

Nuno

> Thanks,
> Wei.
> 
>> Signed-off-by: Nuno Das Neves 
>> ---
>>  arch/arm64/hyperv/mshyperv.c|  3 +++
>>  arch/x86/hyperv/hv_init.c   | 25 +
>>  arch/x86/include/asm/mshyperv.h |  2 --
>>  drivers/hv/hv_common.c  | 23 +++
>>  include/asm-generic/mshyperv.h  |  2 ++
>>  5 files changed, 29 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
>> index b1a4de4eee29..5050e748d266 100644
>> --- a/arch/arm64/hyperv/mshyperv.c
>> +++ b/arch/arm64/hyperv/mshyperv.c
>> @@ -19,6 +19,9 @@
>>  
>>  static bool hyperv_initialized;
>>  
>> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>> +EXPORT_SYMBOL_GPL(hv_current_partition_id);
>> +
>>  int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
>>  {
>>  hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
>> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
>> index 95eada2994e1..950f5ccdb9d9 100644
>> --- a/arch/x86/hyperv/hv_init.c
>> +++ b/arch/x86/hyperv/hv_init.c
>> @@ -35,7 +35,7 @@
>>  #include 
>>  #include 
>>  
>> -u64 hv_current_partition_id = ~0ull;
>> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
>>  EXPORT_SYMBOL_GPL(hv_current_partition_id);
>>  
>>  void *hv_hypercall_pg;
>> @@ -394,24 +394,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
>>  old_setup_percpu_clockev();
>>  }
>>  
>> -static void __init hv_get_partition_id(void)
>> -{
>> -struct hv_get_partition_id *output_page;
>> -u64 status;
>> -unsigned long flags;
>> -
>> -local_irq_save(flags);
>> -output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
>> -status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
>> -if (!hv_result_success(status)) {
>> -/* No point in proceeding if this failed */
>> -pr_err("Failed to get partition ID: %lld\n", status);
>> -BUG();
>> -}
>> -hv_current_partition_id = output_page->partition_id;
>> -local_irq_restore(flags);
>> -}
>> -
>>  #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
>>  static u8 __init get_vtl(void)
>>  {
>> @@ -606,11 +588,6 @@ void __init hyperv_init(void)
>>  
>>  register_syscore_ops(&hv_syscore_ops);
>>  
>> -if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
>> -hv_get_partition_id();
>> -
>> -BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
>> -
>>  #ifdef CONFIG_PCI_MSI
>>  /*
>>   * If we're running as root, we want to create our own PCI MSI domain.
>> diff --git a/arch/x86/include/asm/mshyperv.h 
>> b/arch/x86/include/asm/mshyperv.h
>> index 5f0bc6a6d025..9eeca2a6d047 100644
>> --- a/arch/x86/include/asm/mshyperv.h
>> +++ b/arch/x86/include/asm/mshyperv.h
>> @@ -44,8 +44,6 @@ extern bool hyperv_paravisor_present;
>>  
>>  extern void *hv_hypercall_pg;
>>  
>> -extern u64 hv_current_partition_id;
>> -
>>  extern union hv_ghcb * __percpu *hv_ghcb_pg;
>>  
>>  bool hv_isolation_type_snp(void);
>> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
>> index 7a35c82976e0..819bcfd2b149 100644
>> --- a/drivers/hv/hv_common.c
>> +++ b/drivers/hv/hv_common.c
>> @@ -278,11 +278,34 @@ static void hv_kmsg_dump_register(void)
>>  }
>>  }
>>  
>> +static void __init hv_get_partition_id(void)
>

Re: [PATCH 0/2] hyperv: Move some features to common code

2025-01-22 Thread Nuno Das Neves
On 12/17/2024 9:48 AM, Michael Kelley wrote:
> From: Nuno Das Neves  Sent: Monday, 
> December 9, 2024 12:20 PM
>>
>> On 12/7/2024 6:59 PM, Michael Kelley wrote:
>>> From: Nuno Das Neves  Sent: Friday, 
>>> December 6, 2024 2:22 PM
>>>>
>>>> There are several bits of Hyper-V-related code that today live in
>>>> arch/x86 but are not really specific to x86_64 and will work on arm64
>>>> too.
>>>>
>>>> Some of these will be needed in the upcoming mshv driver code (for
>>>> Linux as root partition on Hyper-V).
>>>
>>> Previously, Linux as the root partition on Hyper-V was x86 only, which is
>>> why the code is currently under arch/x86. So evidently the mshv driver
>>> is being expanded to support both x86 and arm64, correct? Assuming
>>> that's the case, I have some thoughts about how the source code should
>>> be organized and built. It's probably best to get this right to start with 
>>> so
>>> it doesn't need to be changed again.
>>
>> Yes, we plan on supporting both architectures (eventually). I completely 
>> agree
>> that it's better to sort out these issues now rather than later.
>>
>>>
>>> * Patch 2 of this series moves hv_call_deposit_pages() and
>>>hv_call_create_vp() to common code, but does not move
>>>hv_call_add_logical_proc(). All three are used together, so
>>>I'm wondering why hv_call_add_logical_proc() isn't moved.
>>>
>>
>> The only reason is that in our internal tree there's no common or arm64 code
>> yet that uses it - there is no reason it can't also become common code!
> 
> Maybe I'm missing your point, but hv_call_add_logical_proc() and
> hv_call_create_vp() are called in succession in hv_smp_prepare_cpus(),
> so it seems like they very much go together. Presumably a similar
> sequence will be needed on the arm64 side when running as the
> root partition?
> 

Yes that's right, sorry I wasn't being too clear.

>>
>>> * These three functions were originally put in a separate source
>>>code file because of being specific to running in the root partition,
>>>and not needed for generic Linux guest support. I think there's
>>>value in keeping them in a separate file, rather than merging them
>>>into hv_common.c. Maybe just move the entire hv_proc.c file?
>>
>> Agreed. I think it should be renamed too - this file will eventually
>> contain some additional hypercall helper functions, some of which may also be
>> shared by the driver code. Something like "hv_call_common.c"?
> 
> I went back and looked at your patch series from a year ago [1], and
> got a better understanding of where this work is headed. I wanted
> to comment on that series back then, but got subsumed in wrapping
> things up for my retirement. :-(  I see significant portions of that
> series have been posted independently and accepted, so my further
> comments here assume the rest of the series is still the macro-level
> approach you are taking.
> 
>>From that series, you are planning three modules, controlled by
> CONFIG_MSHV, CONFIG_MSHV_ROOT, and CONFIG_MSHV_VTL.
> That makes sense, and addresses one of my top-level concerns,
> which is that normal guest kernels shouldn't include all that code.
> And apparently that code works as a module as well as built-in.
> 
> The code currently in hv_proc.c is similar to the code in hv_call.c
> and mshv_root_hv_call.c from that series -- it's a wrapper around
> Hyper-V hypercalls. But a difference is that the code in hv_proc.c
> can't be a module because it is called from hv_smp_prepare_cpus(),
> which must be built-in. So it can't be added to the proposed
> hv_call.c without making all of hv_call.c built-in. Ideally, there
> would be a separate source file just for the code that must be
> built-in. I'm not familiar enough with root partition requirements
> to understand what hv_smp_prepare_cpus() and its calls to
> hv_call_add_logical_proc() and hv_call_create_vp() are doing.
> Evidently it is related to bringing up CPUs in the root partition,
> and not related to guest VMs. But those two hv_call_* functions
> would also be used for managing guest VMs from /dev/mshv.
> 

It makes sense to keep the different kinds of functionality
separated based on where they are needed. I do wonder if it will be
cumbersome to keep all the cases in their own files - builtin/module,
root/guest, and separated into arch directories vs drivers/hv...

> As for the name, I don't really like "common&qu

[PATCH v2 2/2] hyperv: Move arch/x86/hyperv/hv_proc.c to drivers/hv

2025-01-22 Thread Nuno Das Neves
These helpers are not specific to x86_64 and will be needed by common code.
Remove some unnecessary #includes.

Signed-off-by: Nuno Das Neves 
---
 arch/x86/hyperv/Makefile  | 2 +-
 arch/x86/include/asm/mshyperv.h   | 4 
 drivers/hv/Makefile   | 2 +-
 {arch/x86/hyperv => drivers/hv}/hv_proc.c | 4 
 include/asm-generic/mshyperv.h| 4 
 5 files changed, 6 insertions(+), 10 deletions(-)
 rename {arch/x86/hyperv => drivers/hv}/hv_proc.c (98%)

diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 3a1548054b48..d55f494f471d 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y  := hv_init.o mmu.o nested.o irqdomain.o ivm.o
-obj-$(CONFIG_X86_64)   += hv_apic.o hv_proc.o
+obj-$(CONFIG_X86_64)   += hv_apic.o
 obj-$(CONFIG_HYPERV_VTL_MODE)  += hv_vtl.o
 
 ifdef CONFIG_X86_64
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 8d3ada3e8d0d..7dfca93ef048 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -56,10 +56,6 @@ u64 hv_tdx_hypercall(u64 control, u64 param1, u64 param2);
 #define HV_AP_INIT_GPAT_DEFAULT0x0007040600070406ULL
 #define HV_AP_SEGMENT_LIMIT0x
 
-int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
-int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
-int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
-
 /*
  * If the hypercall involves no input or output parameters, the hypervisor
  * ignores the corresponding GPA pointer.
diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index b992c0ed182b..9afcabb3fbd2 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -13,4 +13,4 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING) += hv_debugfs.o
 hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o
 
 # Code that must be built-in
-obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o
+obj-$(subst m,y,$(CONFIG_HYPERV)) += hv_common.o hv_proc.o
diff --git a/arch/x86/hyperv/hv_proc.c b/drivers/hv/hv_proc.c
similarity index 98%
rename from arch/x86/hyperv/hv_proc.c
rename to drivers/hv/hv_proc.c
index ac4c834d4435..3e410489f480 100644
--- a/arch/x86/hyperv/hv_proc.c
+++ b/drivers/hv/hv_proc.c
@@ -6,11 +6,7 @@
 #include 
 #include 
 #include 
-#include 
 #include 
-#include 
-
-#include 
 
 /*
  * See struct hv_deposit_memory. The first u64 is partition ID, the rest
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 98100466e0b2..faf5d27a76b1 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -217,6 +217,10 @@ void *hv_alloc_hyperv_page(void);
 void *hv_alloc_hyperv_zeroed_page(void);
 void hv_free_hyperv_page(void *addr);
 
+int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages);
+int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id);
+int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags);
+
 /**
  * hv_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
-- 
2.34.1




[PATCH v2 0/2] hyperv: Move some features to common code

2025-01-22 Thread Nuno Das Neves
There are several bits of Hyper-V-related code that today live in
arch/x86 but are not really specific to x86_64 and will work on arm64
too.

Some of these will be needed in the upcoming mshv driver code (for
Linux as root partition on Hyper-V). So this is a good time to move
them to drivers/hv.

Signed-off-by: Nuno Das Neves 
---
Changes in v2:
* Fix dependence on percpu output page by using a stack variable for the
  hypercall output [Michael Kelley]
* Remove unnecessary WARN()s [Michael Kelley]
* Define hv_current_partition_id in hv_common.c [Michael Kelley]
* Move entire hv_proc.c to drivers/hv [Michael Kelley]

Nuno Das Neves (2):
  hyperv: Move hv_current_partition_id to arch-generic code
  hyperv: Move arch/x86/hyperv/hv_proc.c to drivers/hv

 arch/x86/hyperv/Makefile  |  2 +-
 arch/x86/hyperv/hv_init.c | 26 ---
 arch/x86/include/asm/mshyperv.h   |  6 --
 drivers/hv/Makefile   |  2 +-
 drivers/hv/hv_common.c| 23 
 {arch/x86/hyperv => drivers/hv}/hv_proc.c |  4 
 include/asm-generic/mshyperv.h|  5 +
 7 files changed, 30 insertions(+), 38 deletions(-)
 rename {arch/x86/hyperv => drivers/hv}/hv_proc.c (98%)

-- 
2.34.1




[PATCH v2 1/2] hyperv: Move hv_current_partition_id to arch-generic code

2025-01-22 Thread Nuno Das Neves
From: Nuno Das Neves 

Move hv_current_partition_id and hv_get_partition_id() to hv_common.c.
These aren't specific to x86_64 and will be needed by common code.

Set hv_current_partition_id to HV_PARTITION_ID_SELF by default.

Use a stack variable for the output of the hypercall. This allows moving
the call of hv_get_partition_id() to hv_common_init() before the percpu
pages are initialized.

Remove the BUG()s. Failing to get the id need not crash the machine.

Signed-off-by: Nuno Das Neves 
---
 arch/x86/hyperv/hv_init.c   | 26 --
 arch/x86/include/asm/mshyperv.h |  2 --
 drivers/hv/hv_common.c  | 23 +++
 include/asm-generic/mshyperv.h  |  1 +
 4 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 173005e6a95d..6b9f6f9f704d 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -34,9 +34,6 @@
 #include 
 #include 
 
-u64 hv_current_partition_id = ~0ull;
-EXPORT_SYMBOL_GPL(hv_current_partition_id);
-
 void *hv_hypercall_pg;
 EXPORT_SYMBOL_GPL(hv_hypercall_pg);
 
@@ -393,24 +390,6 @@ static void __init hv_stimer_setup_percpu_clockev(void)
old_setup_percpu_clockev();
 }
 
-static void __init hv_get_partition_id(void)
-{
-   struct hv_get_partition_id *output_page;
-   u64 status;
-   unsigned long flags;
-
-   local_irq_save(flags);
-   output_page = *this_cpu_ptr(hyperv_pcpu_output_arg);
-   status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, output_page);
-   if (!hv_result_success(status)) {
-   /* No point in proceeding if this failed */
-   pr_err("Failed to get partition ID: %lld\n", status);
-   BUG();
-   }
-   hv_current_partition_id = output_page->partition_id;
-   local_irq_restore(flags);
-}
-
 #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE)
 static u8 __init get_vtl(void)
 {
@@ -605,11 +584,6 @@ void __init hyperv_init(void)
 
register_syscore_ops(&hv_syscore_ops);
 
-   if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
-   hv_get_partition_id();
-
-   BUG_ON(hv_root_partition && hv_current_partition_id == ~0ull);
-
 #ifdef CONFIG_PCI_MSI
/*
 * If we're running as root, we want to create our own PCI MSI domain.
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index f91ab1e75f9f..8d3ada3e8d0d 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -43,8 +43,6 @@ extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
 
-extern u64 hv_current_partition_id;
-
 extern union hv_ghcb * __percpu *hv_ghcb_pg;
 
 bool hv_isolation_type_snp(void);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index af5d1dc451f6..1da19b64ef16 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -31,6 +31,9 @@
 #include 
 #include 
 
+u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
+EXPORT_SYMBOL_GPL(hv_current_partition_id);
+
 /*
  * hv_root_partition, ms_hyperv and hv_nested are defined here with other
  * Hyper-V specific globals so they are shared across all architectures and are
@@ -283,6 +286,23 @@ static inline bool hv_output_page_exists(void)
return hv_root_partition || IS_ENABLED(CONFIG_HYPERV_VTL_MODE);
 }
 
+static void __init hv_get_partition_id(void)
+{
+   /*
+* Note in this case the output can be on the stack because it is just
+* a single u64 and hence won't cross a page boundary.
+*/
+   struct hv_get_partition_id output;
+   u64 status;
+
+   status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, &output);
+   if (!hv_result_success(status)) {
+   pr_err("Hyper-V: failed to get partition ID: %#lx\n", status);
+   return;
+   }
+   hv_current_partition_id = output.partition_id;
+}
+
 int __init hv_common_init(void)
 {
int i;
@@ -298,6 +318,9 @@ int __init hv_common_init(void)
if (hv_is_isolation_supported())
sysctl_record_panic_msg = 0;
 
+   if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
+   hv_get_partition_id();
+
/*
 * Hyper-V expects to get crash register data or kmsg when
 * crash enlightment is available and system crashes. Set
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index a7bbe504e4f3..98100466e0b2 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -58,6 +58,7 @@ struct ms_hyperv_info {
 };
 extern struct ms_hyperv_info ms_hyperv;
 extern bool hv_nested;
+extern u64 hv_current_partition_id;
 
 extern void * __percpu *hyperv_pcpu_input_arg;
 extern void * __percpu *hyperv_pcpu_output_arg;
-- 
2.34.1




  1   2   >