linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
@ 2021-07-20 14:56 Michael Kelley
  2021-07-20 14:56 ` [PATCH v11 1/5] arm64: hyperv: Add Hyper-V hypercall and register access utilities Michael Kelley
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Michael Kelley @ 2021-07-20 14:56 UTC (permalink / raw)
  To: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb
  Cc: mikelley

This series enables Linux guests running on Hyper-V on ARM64
hardware. New ARM64-specific code in arch/arm64/hyperv initializes
Hyper-V and its hypercall mechanism.  Existing architecture
independent drivers for Hyper-V's VMbus and synthetic devices just
work when built for ARM64. Hyper-V code is built and included in
the image and modules only if CONFIG_HYPERV is enabled.

The five patches are organized as follows:

1) Add definitions and functions for making Hyper-V hypercalls
   and getting/setting virtual processor registers provided by
   Hyper-V

2) Add the function needed by the arch independent VMbus driver
   for reporting a panic to Hyper-V.

3) Add Hyper-V initialization code and utility functions that
   report Hyper-v status.

4) Export screen_info so it may be used by the Hyper-V frame buffer
   driver built as a module. It is already exported for x86,
   powerpc, and alpha architectures.

5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.

Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
with 4K/16K/64K page size. Linux guests with this patch series
work with all three supported ARM64 page sizes.

The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
x86/x64-specific code and is not being built for ARM64. Enabling
Hyper-V vPCI devices on ARM64 is in progress via a separate set
of patches.

This patch set is based on the linux-next20210720 code tree.

Changes in v11:
* Drop the previous Patch 1 as the fixes have already been
  separately accepted upstream.
* Drop the previous Patch 3 for enabling Hyper-V enlightened
  clocks/timers.  Hyper-V is now offering the full ARM64
  architectural Generic Timer in guest VMs, so the existing
  arch_arch_timer.c driver just works. [Mark Rutland, Marc
  Zyngier]
* Simplified the previous Patch 4 and Patch 5 (now Patch 2 and 3)
  by sharing more code between the x86 and ARM64 architectures.
* Combined hyperv_early_init() and hyperv_init() into a single
  initialization function that runs as an early_initcall. This
  is possible because the Hyper-V enlightened clocks/timers
  no longer need to be initialized early in the boot sequence.

Changes in v10:
* Drop previous Patch 1 for SMCCC v1.2 HVC calls in favor of
  Sudeep Holla's patch [Mark Rutland]
* Use new helper functions in 5.13 for checking Hyper-V hypercall
  return status
* Set up per-CPU hypercall argument page that is now used by the
  Hyper-V balloon driver
* Rebase on 5.13-RC1

Changes in v9:
* Added Patch 1 to enable making an SMCCC compliant hypercall
  that returns results in other than registers X0 thru X3, per
  version 1.2 and later of the SMCCC spec.
* Using the ability to return results in registers X6 and X7,
  converted hv_get_vpreg_128() to use a "fast" hypercall that
  passes inputs and outputs in registers, and in doing so eliminated
  a lot of memory allocation complexity.
* Cleaned up some extra blank lines and use of spaces in aligning
  local variables. [Sunil Muthuswamy]
* Based on discussion about future directions, reverted the
  population of hv_vp_index array to use a cpuhp state instead
  of a hypercall, which is like it was in v7 and earlier.

Changes in v8:
* Removed a lot of code based on refactoring the boundary between
  arch independent and arch dependent code for Hyper-V, per comments
  from Arnd Bergmann. The removed code was either duplicated on
  the x86 side, or has been folded into architecture independent
  code as not really being architecture dependent.
* Added config dependency on !CONFIG_CPU_BIG_ENDIAN [Arnd Bergmann]
* Reworked the approach to Hyper-V initialization. The functionality
  is the same, but is now structured like the Xen code with an early
  init function called in setup_arch() and an early initcall to
  finish the initialization. [Arnd Bergmann]

Changes in v7:
* Separately upstreamed split of hyperv-tlfs.h into arch dependent
  and independent versions.  In this patch set, update the ARM64
  hyperv-tlfs.h to include architecture independent definitions.
  This approach eliminates a lot of lines of otherwise duplicated
  code on the ARM64 side.
* Break ARM64 mshyperv.h into smaller pieces. Have an initial
  baseline, and add code along with patches for a particular
  functional area. [Marc Zyngier]
* In mshyperv.h, use static inline functions instead of #defines
  where possible. [Arnd Bergmann]
* Use VMbus INTID obtained from ACPI DSDT instead of hardcoding.
  The STIMER INTID is still hardcoded because it is needed
  before Linux has initialized the ACPI subsystem, so it can't
  be obtained from the DSDT.  Wedging it into the GTDT seems
  dubious, so was not done. [Marc Zyngier]
* Update Hyper-V page size allocation functions to use
  alloc_page() if PAGE_SIZE == HV_HYP_PAGE_SIZE [Arnd
  Bergmann]
* Various other minor changes based on feedback and to rebase
  to latest linux-next [Marc Zyngier and Arnd Bergmann]

Changes in v6:
* Use SMCCC hypercall interface instead of direct invocation
  of HVC instruction and the Hyper-V hypercall interface
  [Marc Zyngier]
* Reimplemented functions to alloc/free Hyper-V size pages
  using kmalloc/kfree since kmalloc now guarantees alignment of
  power of 2 size allocations [Marc Zyngier]
* Export screen_info in arm64 architecture so it can be used
  by the Hyper-V buffer driver built as a module
* Renamed source file arch/arm64/hyperv/hv_init.c to hv_core.c
  to better reflect its content
* Fixed the bit position of certain feature flags presented by
  Hyper-V to the guest.  The bit positions on ARM64 don't match
  the position on x86 like originally thought.
* Minor fixups to rebase to 5.6-rc5 linux-next

Changes in v5:
* Minor fixups to rebase to 5.4-rc1 linux-next

Changes in v4:
* Moved clock-related code into an architecture independent
  Hyper-V clocksource driver that is already upstream. Clock
  related code is removed from this patch set except for the
  ARM64 specific interrupt handler. [Marc Zyngier]
* Separately upstreamed the split of mshyperv.h into arch independent
  and arch dependent portions. The arch independent portion has been
  removed from this patch set.
* Divided patch #2 of the series into multiple smaller patches
  [Marc Zyngier]
* Changed a dozen or so smaller things based on feedback
  [Marc Zyngier, Will Deacon]
* Added functions to alloc/free Hyper-V size pages for use by
  drivers for Hyper-V synthetic devices when updated to not assume
  guest page size and Hyper-v page size are the same

Changes in v3:
* Added initialization of hv_vp_index array like was recently
  added on x86 branch [KY Srinivasan]
* Changed Hyper-V ARM64 register symbols to be all uppercase 
  instead of mixed case [KY Srinivasan]
* Separated mshyperv.h into two files, one architecture
  independent and one architecture dependent. After this code
  is upstream, will make changes to the x86 code to use the
  architecture independent file and remove duplication. And
  once we have a multi-architecture Hyper-V TLFS, will do a
  separate patch to split hyperv-tlfs.h in the same way.
  [KY Srinivasan]
* Minor tweaks to rebase to latest linux-next code

Changes in v2:
* Removed patch to implement slow_virt_to_phys() on ARM64.
  Use of slow_virt_to_phys() in arch independent Hyper-V
  drivers has been eliminated by commit 6ba34171bcbd
  ("Drivers: hv: vmbus: Remove use of slow_virt_to_phys()")
* Minor tweaks to rebase to latest linux-next code

Michael Kelley (5):
  arm64: hyperv: Add Hyper-V hypercall and register access utilities
  arm64: hyperv: Add panic handler
  arm64: hyperv: Initialize hypervisor on boot
  arm64: efi: Export screen_info
  Drivers: hv: Enable Hyper-V code to be built on ARM64

 MAINTAINERS                          |   3 +
 arch/arm64/Kbuild                    |   1 +
 arch/arm64/hyperv/Makefile           |   2 +
 arch/arm64/hyperv/hv_core.c          | 181 +++++++++++++++++++++++++++++++++++
 arch/arm64/hyperv/mshyperv.c         |  83 ++++++++++++++++
 arch/arm64/include/asm/hyperv-tlfs.h |  69 +++++++++++++
 arch/arm64/include/asm/mshyperv.h    |  54 +++++++++++
 arch/arm64/kernel/efi.c              |   1 +
 drivers/hv/Kconfig                   |   5 +-
 9 files changed, 397 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_core.c
 create mode 100644 arch/arm64/hyperv/mshyperv.c
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h

-- 
1.8.3.1


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

* [PATCH v11 1/5] arm64: hyperv: Add Hyper-V hypercall and register access utilities
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
@ 2021-07-20 14:56 ` Michael Kelley
  2021-07-20 14:57 ` [PATCH v11 2/5] arm64: hyperv: Add panic handler Michael Kelley
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Michael Kelley @ 2021-07-20 14:56 UTC (permalink / raw)
  To: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb
  Cc: mikelley

hyperv-tlfs.h defines Hyper-V interfaces from the Hyper-V Top Level
Functional Spec (TLFS), and #includes the architecture-independent
part of hyperv-tlfs.h in include/asm-generic.  The published TLFS
is distinctly oriented to x86/x64, so the ARM64-specific
hyperv-tlfs.h includes information for ARM64 that is not yet formally
published. The TLFS is available here:

  docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs

mshyperv.h defines Linux-specific structures and routines for
interacting with Hyper-V on ARM64, and #includes the architecture-
independent part of mshyperv.h in include/asm-generic.

Use these definitions to provide utility functions to make
Hyper-V hypercalls and to get and set Hyper-V provided
registers associated with a virtual processor.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Sunil Muthuswamy <sunilmut@microsoft.com>

---
 MAINTAINERS                          |   3 +
 arch/arm64/Kbuild                    |   1 +
 arch/arm64/hyperv/Makefile           |   2 +
 arch/arm64/hyperv/hv_core.c          | 129 +++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/hyperv-tlfs.h |  69 +++++++++++++++++++
 arch/arm64/include/asm/mshyperv.h    |  54 +++++++++++++++
 6 files changed, 258 insertions(+)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_core.c
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6993219..8f6f429 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8608,6 +8608,9 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
 F:	Documentation/ABI/stable/sysfs-bus-vmbus
 F:	Documentation/ABI/testing/debugfs-hyperv
 F:	Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst
+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
diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
index 7b393cf..ea7ab4c 100644
--- a/arch/arm64/Kbuild
+++ b/arch/arm64/Kbuild
@@ -2,4 +2,5 @@
 obj-y			+= kernel/ mm/ net/
 obj-$(CONFIG_KVM)	+= kvm/
 obj-$(CONFIG_XEN)	+= xen/
+obj-$(subst m,y,$(CONFIG_HYPERV))	+= hyperv/
 obj-$(CONFIG_CRYPTO)	+= crypto/
diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
new file mode 100644
index 0000000..1697d30
--- /dev/null
+++ b/arch/arm64/hyperv/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y		:= hv_core.o
diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
new file mode 100644
index 0000000..4c5dc0f
--- /dev/null
+++ b/arch/arm64/hyperv/hv_core.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Low level utility routines for interacting with Hyper-V.
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley@microsoft.com>
+ */
+
+#include <linux/types.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/hyperv.h>
+#include <linux/arm-smccc.h>
+#include <linux/module.h>
+#include <asm-generic/bug.h>
+#include <asm/hyperv-tlfs.h>
+#include <asm/mshyperv.h>
+
+/*
+ * hv_do_hypercall- Invoke the specified hypercall
+ */
+u64 hv_do_hypercall(u64 control, void *input, void *output)
+{
+	struct arm_smccc_res	res;
+	u64			input_address;
+	u64			output_address;
+
+	input_address = input ? virt_to_phys(input) : 0;
+	output_address = output ? virt_to_phys(output) : 0;
+
+	arm_smccc_1_1_hvc(HV_FUNC_ID, control,
+			  input_address, output_address, &res);
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
+
+/*
+ * hv_do_fast_hypercall8 -- Invoke the specified hypercall
+ * with arguments in registers instead of physical memory.
+ * Avoids the overhead of virt_to_phys for simple hypercalls.
+ */
+
+u64 hv_do_fast_hypercall8(u16 code, u64 input)
+{
+	struct arm_smccc_res	res;
+	u64			control;
+
+	control = (u64)code | HV_HYPERCALL_FAST_BIT;
+
+	arm_smccc_1_1_hvc(HV_FUNC_ID, control, input, &res);
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(hv_do_fast_hypercall8);
+
+/*
+ * Set a single VP register to a 64-bit value.
+ */
+void hv_set_vpreg(u32 msr, u64 value)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(HV_FUNC_ID,
+		HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
+			HV_HYPERCALL_REP_COMP_1,
+		HV_PARTITION_ID_SELF,
+		HV_VP_INDEX_SELF,
+		msr,
+		0,
+		value,
+		0,
+		&res);
+
+	/*
+	 * Something is fundamentally broken in the hypervisor if
+	 * setting a VP register fails. There's really no way to
+	 * continue as a guest VM, so panic.
+	 */
+	BUG_ON(!hv_result_success(res.a0));
+}
+EXPORT_SYMBOL_GPL(hv_set_vpreg);
+
+/*
+ * Get the value of a single VP register.  One version
+ * returns just 64 bits and another returns the full 128 bits.
+ * The two versions are separate to avoid complicating the
+ * calling sequence for the more frequently used 64 bit version.
+ */
+
+void hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result)
+{
+	struct arm_smccc_1_2_regs args;
+	struct arm_smccc_1_2_regs res;
+
+	args.a0 = HV_FUNC_ID;
+	args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
+			HV_HYPERCALL_REP_COMP_1;
+	args.a2 = HV_PARTITION_ID_SELF;
+	args.a3 = HV_VP_INDEX_SELF;
+	args.a4 = msr;
+
+	/*
+	 * Use the SMCCC 1.2 interface because the results are in registers
+	 * beyond X0-X3.
+	 */
+	arm_smccc_1_2_hvc(&args, &res);
+
+	/*
+	 * Something is fundamentally broken in the hypervisor if
+	 * getting a VP register fails. There's really no way to
+	 * continue as a guest VM, so panic.
+	 */
+	BUG_ON(!hv_result_success(res.a0));
+
+	result->as64.low = res.a6;
+	result->as64.high = res.a7;
+}
+EXPORT_SYMBOL_GPL(hv_get_vpreg_128);
+
+u64 hv_get_vpreg(u32 msr)
+{
+	struct hv_get_vp_registers_output output;
+
+	hv_get_vpreg_128(msr, &output);
+
+	return output.as64.low;
+}
+EXPORT_SYMBOL_GPL(hv_get_vpreg);
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h
new file mode 100644
index 0000000..4d964a7
--- /dev/null
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -0,0 +1,69 @@
+/* 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 <mikelley@microsoft.com>
+ */
+
+#ifndef _ASM_HYPERV_TLFS_H
+#define _ASM_HYPERV_TLFS_H
+
+#include <linux/types.h>
+
+/*
+ * 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.
+ */
+
+/*
+ * These Hyper-V registers provide information equivalent to the CPUID
+ * instruction on x86/x64.
+ */
+#define HV_REGISTER_HYPERVISOR_VERSION		0x00000100 /*CPUID 0x40000002 */
+#define HV_REGISTER_FEATURES			0x00000200 /*CPUID 0x40000003 */
+#define HV_REGISTER_ENLIGHTENMENTS		0x00000201 /*CPUID 0x40000004 */
+
+/*
+ * 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_AVAILABLE		BIT(13)
+
+/*
+ * Synthetic register definitions equivalent to MSRs on x86/x64
+ */
+#define HV_REGISTER_CRASH_P0		0x00000210
+#define HV_REGISTER_CRASH_P1		0x00000211
+#define HV_REGISTER_CRASH_P2		0x00000212
+#define HV_REGISTER_CRASH_P3		0x00000213
+#define HV_REGISTER_CRASH_P4		0x00000214
+#define HV_REGISTER_CRASH_CTL		0x00000215
+
+#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_REGISTER_SINT0		0x000A0000
+#define HV_REGISTER_SCONTROL		0x000A0010
+#define HV_REGISTER_SIEFP		0x000A0012
+#define HV_REGISTER_SIMP		0x000A0013
+#define HV_REGISTER_EOM			0x000A0014
+
+#define HV_REGISTER_STIMER0_CONFIG	0x000B0000
+#define HV_REGISTER_STIMER0_COUNT	0x000B0001
+
+#include <asm-generic/hyperv-tlfs.h>
+
+#endif
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
new file mode 100644
index 0000000..20070a8
--- /dev/null
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Linux-specific definitions for managing interactions with Microsoft's
+ * Hyper-V hypervisor. The definitions in this file are specific to
+ * 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.
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley@microsoft.com>
+ */
+
+#ifndef _ASM_MSHYPERV_H
+#define _ASM_MSHYPERV_H
+
+#include <linux/types.h>
+#include <linux/arm-smccc.h>
+#include <asm/hyperv-tlfs.h>
+
+/*
+ * Declare calls to get and set Hyper-V VP register values on ARM64, which
+ * requires a hypercall.
+ */
+
+void hv_set_vpreg(u32 reg, u64 value);
+u64 hv_get_vpreg(u32 reg);
+void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result);
+
+static inline void hv_set_register(unsigned int reg, u64 value)
+{
+	hv_set_vpreg(reg, value);
+}
+
+static inline u64 hv_get_register(unsigned int reg)
+{
+	return hv_get_vpreg(reg);
+}
+
+/* SMCCC hypercall parameters */
+#define HV_SMCCC_FUNC_NUMBER	1
+#define HV_FUNC_ID	ARM_SMCCC_CALL_VAL(			\
+				ARM_SMCCC_STD_CALL,		\
+				ARM_SMCCC_SMC_64,		\
+				ARM_SMCCC_OWNER_VENDOR_HYP,	\
+				HV_SMCCC_FUNC_NUMBER)
+
+#include <asm-generic/mshyperv.h>
+
+#endif
-- 
1.8.3.1


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

* [PATCH v11 2/5] arm64: hyperv: Add panic handler
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
  2021-07-20 14:56 ` [PATCH v11 1/5] arm64: hyperv: Add Hyper-V hypercall and register access utilities Michael Kelley
@ 2021-07-20 14:57 ` Michael Kelley
  2021-07-21 14:54   ` Boqun Feng
  2021-07-27 17:08   ` Sunil Muthuswamy
  2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 17+ messages in thread
From: Michael Kelley @ 2021-07-20 14:57 UTC (permalink / raw)
  To: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb
  Cc: mikelley

Add a function to inform Hyper-V about a guest panic.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index 4c5dc0f..b54c347 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -127,3 +127,55 @@ u64 hv_get_vpreg(u32 msr)
 	return output.as64.low;
 }
 EXPORT_SYMBOL_GPL(hv_get_vpreg);
+
+/*
+ * hyperv_report_panic - report a panic to Hyper-V.  This function uses
+ * the older version of the Hyper-V interface that admittedly doesn't
+ * pass enough information to be useful beyond just recording the
+ * occurrence of a panic. The parallel hv_kmsg_dump() uses the
+ * new interface that allows reporting 4 Kbytes of data, which is much
+ * more useful. Hyper-V on ARM64 always supports the newer interface, but
+ * we retain support for the older version because the sysadmin is allowed
+ * to disable the newer version via sysctl in case of information security
+ * concerns about the more verbose version.
+ */
+void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
+{
+	static bool	panic_reported;
+	u64		guest_id;
+
+	/* Don't report a panic to Hyper-V if we're not going to panic */
+	if (in_die && !panic_on_oops)
+		return;
+
+	/*
+	 * We prefer to report panic on 'die' chain as we have proper
+	 * registers to report, but if we miss it (e.g. on BUG()) we need
+	 * to report it on 'panic'.
+	 *
+	 * Calling code in the 'die' and 'panic' paths ensures that only
+	 * one CPU is running this code, so no atomicity is needed.
+	 */
+	if (panic_reported)
+		return;
+	panic_reported = true;
+
+	guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);
+
+	/*
+	 * 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);
+
+	/*
+	 * Let Hyper-V know there is crash data available
+	 */
+	hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
+}
+EXPORT_SYMBOL_GPL(hyperv_report_panic);
-- 
1.8.3.1


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

* [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
  2021-07-20 14:56 ` [PATCH v11 1/5] arm64: hyperv: Add Hyper-V hypercall and register access utilities Michael Kelley
  2021-07-20 14:57 ` [PATCH v11 2/5] arm64: hyperv: Add panic handler Michael Kelley
@ 2021-07-20 14:57 ` Michael Kelley
  2021-07-21 14:55   ` Boqun Feng
                     ` (3 more replies)
  2021-07-20 14:57 ` [PATCH v11 4/5] arm64: efi: Export screen_info Michael Kelley
                   ` (3 subsequent siblings)
  6 siblings, 4 replies; 17+ messages in thread
From: Michael Kelley @ 2021-07-20 14:57 UTC (permalink / raw)
  To: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb
  Cc: mikelley

Add ARM64-specific code to initialize the Hyper-V
hypervisor when booting as a guest VM.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
 arch/arm64/hyperv/Makefile   |  2 +-
 arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/hyperv/mshyperv.c

diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
index 1697d30..87c31c0 100644
--- a/arch/arm64/hyperv/Makefile
+++ b/arch/arm64/hyperv/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-y		:= hv_core.o
+obj-y		:= hv_core.o mshyperv.o
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
new file mode 100644
index 0000000..2811fd0
--- /dev/null
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Core routines for interacting with Microsoft's Hyper-V hypervisor,
+ * including hypervisor initialization.
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley@microsoft.com>
+ */
+
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/version.h>
+#include <linux/cpuhotplug.h>
+#include <asm/mshyperv.h>
+
+static bool hyperv_initialized;
+
+static int __init hyperv_init(void)
+{
+	struct hv_get_vp_registers_output	result;
+	u32	a, b, c, d;
+	u64	guest_id;
+	int	ret;
+
+	/*
+	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
+	 * have the string "MsHyperV".
+	 */
+	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
+		return -EINVAL;
+
+	/* Setup the guest ID */
+	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
+	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
+
+	/* Get the features and hints from Hyper-V */
+	hv_get_vpreg_128(HV_REGISTER_FEATURES, &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);
+	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",
+		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 & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
+
+	ret = hv_common_init();
+	if (ret)
+		return ret;
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
+				hv_common_cpu_init, hv_common_cpu_die);
+	if (ret < 0) {
+		hv_common_free();
+		return ret;
+	}
+
+	hyperv_initialized = true;
+	return 0;
+}
+
+early_initcall(hyperv_init);
+
+bool hv_is_hyperv_initialized(void)
+{
+	return hyperv_initialized;
+}
+EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
-- 
1.8.3.1


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

* [PATCH v11 4/5] arm64: efi: Export screen_info
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
                   ` (2 preceding siblings ...)
  2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
@ 2021-07-20 14:57 ` Michael Kelley
  2021-07-20 14:57 ` [PATCH v11 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64 Michael Kelley
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Michael Kelley @ 2021-07-20 14:57 UTC (permalink / raw)
  To: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb
  Cc: mikelley

The Hyper-V frame buffer driver may be built as a module, and
it needs access to screen_info. So export screen_info.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm64/kernel/efi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index fa02efb..e1be6c4 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -55,6 +55,7 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md)
 
 /* we will fill this structure from the stub, so don't put it in .bss */
 struct screen_info screen_info __section(".data");
+EXPORT_SYMBOL(screen_info);
 
 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
 {
-- 
1.8.3.1


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

* [PATCH v11 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
                   ` (3 preceding siblings ...)
  2021-07-20 14:57 ` [PATCH v11 4/5] arm64: efi: Export screen_info Michael Kelley
@ 2021-07-20 14:57 ` Michael Kelley
  2021-07-21 14:52   ` Boqun Feng
  2021-08-02 15:15 ` [PATCH v11 0/5] Enable Linux guests on Hyper-V " Michael Kelley
  2021-08-02 16:01 ` Marc Zyngier
  6 siblings, 1 reply; 17+ messages in thread
From: Michael Kelley @ 2021-07-20 14:57 UTC (permalink / raw)
  To: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb
  Cc: mikelley

Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on
ARM64, causing the Hyper-V specific code to be built. Exclude the
Hyper-V enlightened clocks/timers code from being built for ARM64.

Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
 drivers/hv/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 66c794d..e509d5d 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
 
 config HYPERV
 	tristate "Microsoft Hyper-V client drivers"
-	depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
+	depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
+		|| (ARM64 && !CPU_BIG_ENDIAN))
 	select PARAVIRT
 	select X86_HV_CALLBACK_VECTOR
 	help
@@ -12,7 +13,7 @@ config HYPERV
 	  system.
 
 config HYPERV_TIMER
-	def_bool HYPERV
+	def_bool HYPERV && X86
 
 config HYPERV_UTILS
 	tristate "Microsoft Hyper-V Utilities driver"
-- 
1.8.3.1


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

* Re: [PATCH v11 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64
  2021-07-20 14:57 ` [PATCH v11 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64 Michael Kelley
@ 2021-07-21 14:52   ` Boqun Feng
  0 siblings, 0 replies; 17+ messages in thread
From: Boqun Feng @ 2021-07-21 14:52 UTC (permalink / raw)
  To: Michael Kelley
  Cc: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb

On Tue, Jul 20, 2021 at 07:57:03AM -0700, Michael Kelley wrote:
> Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on
> ARM64, causing the Hyper-V specific code to be built. Exclude the
> Hyper-V enlightened clocks/timers code from being built for ARM64.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>

FWIW,

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Regards,
Boqun

> ---
>  drivers/hv/Kconfig | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> index 66c794d..e509d5d 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
>  
>  config HYPERV
>  	tristate "Microsoft Hyper-V client drivers"
> -	depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
> +	depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
> +		|| (ARM64 && !CPU_BIG_ENDIAN))
>  	select PARAVIRT
>  	select X86_HV_CALLBACK_VECTOR
>  	help
> @@ -12,7 +13,7 @@ config HYPERV
>  	  system.
>  
>  config HYPERV_TIMER
> -	def_bool HYPERV
> +	def_bool HYPERV && X86
>  
>  config HYPERV_UTILS
>  	tristate "Microsoft Hyper-V Utilities driver"
> -- 
> 1.8.3.1
> 

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

* Re: [PATCH v11 2/5] arm64: hyperv: Add panic handler
  2021-07-20 14:57 ` [PATCH v11 2/5] arm64: hyperv: Add panic handler Michael Kelley
@ 2021-07-21 14:54   ` Boqun Feng
  2021-07-27 17:08   ` Sunil Muthuswamy
  1 sibling, 0 replies; 17+ messages in thread
From: Boqun Feng @ 2021-07-21 14:54 UTC (permalink / raw)
  To: Michael Kelley
  Cc: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb

On Tue, Jul 20, 2021 at 07:57:00AM -0700, Michael Kelley wrote:
> Add a function to inform Hyper-V about a guest panic.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Regards,
Boqun

> ---
>  arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
> index 4c5dc0f..b54c347 100644
> --- a/arch/arm64/hyperv/hv_core.c
> +++ b/arch/arm64/hyperv/hv_core.c
> @@ -127,3 +127,55 @@ u64 hv_get_vpreg(u32 msr)
>  	return output.as64.low;
>  }
>  EXPORT_SYMBOL_GPL(hv_get_vpreg);
> +
> +/*
> + * hyperv_report_panic - report a panic to Hyper-V.  This function uses
> + * the older version of the Hyper-V interface that admittedly doesn't
> + * pass enough information to be useful beyond just recording the
> + * occurrence of a panic. The parallel hv_kmsg_dump() uses the
> + * new interface that allows reporting 4 Kbytes of data, which is much
> + * more useful. Hyper-V on ARM64 always supports the newer interface, but
> + * we retain support for the older version because the sysadmin is allowed
> + * to disable the newer version via sysctl in case of information security
> + * concerns about the more verbose version.
> + */
> +void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
> +{
> +	static bool	panic_reported;
> +	u64		guest_id;
> +
> +	/* Don't report a panic to Hyper-V if we're not going to panic */
> +	if (in_die && !panic_on_oops)
> +		return;
> +
> +	/*
> +	 * We prefer to report panic on 'die' chain as we have proper
> +	 * registers to report, but if we miss it (e.g. on BUG()) we need
> +	 * to report it on 'panic'.
> +	 *
> +	 * Calling code in the 'die' and 'panic' paths ensures that only
> +	 * one CPU is running this code, so no atomicity is needed.
> +	 */
> +	if (panic_reported)
> +		return;
> +	panic_reported = true;
> +
> +	guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);
> +
> +	/*
> +	 * 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);
> +
> +	/*
> +	 * Let Hyper-V know there is crash data available
> +	 */
> +	hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
> +}
> +EXPORT_SYMBOL_GPL(hyperv_report_panic);
> -- 
> 1.8.3.1
> 

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

* Re: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
  2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
@ 2021-07-21 14:55   ` Boqun Feng
  2021-07-27 17:05   ` Sunil Muthuswamy
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Boqun Feng @ 2021-07-21 14:55 UTC (permalink / raw)
  To: Michael Kelley
  Cc: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb

On Tue, Jul 20, 2021 at 07:57:01AM -0700, Michael Kelley wrote:
> Add ARM64-specific code to initialize the Hyper-V
> hypervisor when booting as a guest VM.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>

FWIW,

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Regards,
Boqun

> ---
>  arch/arm64/hyperv/Makefile   |  2 +-
>  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 84 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 1697d30..87c31c0 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,2 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-y		:= hv_core.o
> +obj-y		:= hv_core.o mshyperv.o
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> new file mode 100644
> index 0000000..2811fd0
> --- /dev/null
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> + * including hypervisor initialization.
> + *
> + * Copyright (C) 2021, Microsoft, Inc.
> + *
> + * Author : Michael Kelley <mikelley@microsoft.com>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/acpi.h>
> +#include <linux/export.h>
> +#include <linux/errno.h>
> +#include <linux/version.h>
> +#include <linux/cpuhotplug.h>
> +#include <asm/mshyperv.h>
> +
> +static bool hyperv_initialized;
> +
> +static int __init hyperv_init(void)
> +{
> +	struct hv_get_vp_registers_output	result;
> +	u32	a, b, c, d;
> +	u64	guest_id;
> +	int	ret;
> +
> +	/*
> +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> +	 * have the string "MsHyperV".
> +	 */
> +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> +		return -EINVAL;
> +
> +	/* Setup the guest ID */
> +	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
> +	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
> +
> +	/* Get the features and hints from Hyper-V */
> +	hv_get_vpreg_128(HV_REGISTER_FEATURES, &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);
> +	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",
> +		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 & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
> +
> +	ret = hv_common_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
> +				hv_common_cpu_init, hv_common_cpu_die);
> +	if (ret < 0) {
> +		hv_common_free();
> +		return ret;
> +	}
> +
> +	hyperv_initialized = true;
> +	return 0;
> +}
> +
> +early_initcall(hyperv_init);
> +
> +bool hv_is_hyperv_initialized(void)
> +{
> +	return hyperv_initialized;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
> -- 
> 1.8.3.1
> 

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

* RE: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
  2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
  2021-07-21 14:55   ` Boqun Feng
@ 2021-07-27 17:05   ` Sunil Muthuswamy
  2021-08-02 15:55   ` Marc Zyngier
  2021-08-02 16:26   ` Mark Rutland
  3 siblings, 0 replies; 17+ messages in thread
From: Sunil Muthuswamy @ 2021-07-27 17:05 UTC (permalink / raw)
  To: Michael Kelley, will, catalin.marinas, Mark Rutland,
	linux-arm-kernel, linux-kernel, linux-hyperv, linux-efi, wei.liu,
	KY Srinivasan, Stephen Hemminger, ardb
  Cc: Michael Kelley

> Subject: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
> 
> Add ARM64-specific code to initialize the Hyper-V
> hypervisor when booting as a guest VM.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> ---
>  arch/arm64/hyperv/Makefile   |  2 +-
>  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 84 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 1697d30..87c31c0 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,2 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-y		:= hv_core.o
> +obj-y		:= hv_core.o mshyperv.o
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> new file mode 100644
> index 0000000..2811fd0
> --- /dev/null
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> + * including hypervisor initialization.
> + *
> + * Copyright (C) 2021, Microsoft, Inc.
> + *
> + * Author : Michael Kelley <mikelley@microsoft.com>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/acpi.h>
> +#include <linux/export.h>
> +#include <linux/errno.h>
> +#include <linux/version.h>
> +#include <linux/cpuhotplug.h>
> +#include <asm/mshyperv.h>
> +
> +static bool hyperv_initialized;
> +
> +static int __init hyperv_init(void)
> +{
> +	struct hv_get_vp_registers_output	result;
> +	u32	a, b, c, d;
> +	u64	guest_id;
> +	int	ret;
> +
> +	/*
> +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> +	 * have the string "MsHyperV".
> +	 */
> +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> +		return -EINVAL;
> +
> +	/* Setup the guest ID */
> +	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
> +	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
> +
> +	/* Get the features and hints from Hyper-V */
> +	hv_get_vpreg_128(HV_REGISTER_FEATURES, &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);
> +	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",
> +		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 & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
> +
> +	ret = hv_common_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
> +				hv_common_cpu_init, hv_common_cpu_die);
> +	if (ret < 0) {
> +		hv_common_free();
> +		return ret;
> +	}
> +
> +	hyperv_initialized = true;
> +	return 0;
> +}
> +
> +early_initcall(hyperv_init);
> +
> +bool hv_is_hyperv_initialized(void)
> +{
> +	return hyperv_initialized;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
> --
> 1.8.3.1

Reviewed-by: Sunil Muthuswamy <sunilmut@microsoft.com>

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

* RE: [PATCH v11 2/5] arm64: hyperv: Add panic handler
  2021-07-20 14:57 ` [PATCH v11 2/5] arm64: hyperv: Add panic handler Michael Kelley
  2021-07-21 14:54   ` Boqun Feng
@ 2021-07-27 17:08   ` Sunil Muthuswamy
  1 sibling, 0 replies; 17+ messages in thread
From: Sunil Muthuswamy @ 2021-07-27 17:08 UTC (permalink / raw)
  To: Michael Kelley, will, catalin.marinas, Mark Rutland,
	linux-arm-kernel, linux-kernel, linux-hyperv, linux-efi, wei.liu,
	KY Srinivasan, Stephen Hemminger, ardb
  Cc: Michael Kelley

> Add a function to inform Hyper-V about a guest panic.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> ---
>  arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
> 
> diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
> index 4c5dc0f..b54c347 100644
> --- a/arch/arm64/hyperv/hv_core.c
> +++ b/arch/arm64/hyperv/hv_core.c
> @@ -127,3 +127,55 @@ u64 hv_get_vpreg(u32 msr)
>  	return output.as64.low;
>  }
>  EXPORT_SYMBOL_GPL(hv_get_vpreg);
> +
> +/*
> + * hyperv_report_panic - report a panic to Hyper-V.  This function uses
> + * the older version of the Hyper-V interface that admittedly doesn't
> + * pass enough information to be useful beyond just recording the
> + * occurrence of a panic. The parallel hv_kmsg_dump() uses the
> + * new interface that allows reporting 4 Kbytes of data, which is much
> + * more useful. Hyper-V on ARM64 always supports the newer interface, but
> + * we retain support for the older version because the sysadmin is allowed
> + * to disable the newer version via sysctl in case of information security
> + * concerns about the more verbose version.
> + */
> +void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
> +{
> +	static bool	panic_reported;
> +	u64		guest_id;
> +
> +	/* Don't report a panic to Hyper-V if we're not going to panic */
> +	if (in_die && !panic_on_oops)
> +		return;
> +
> +	/*
> +	 * We prefer to report panic on 'die' chain as we have proper
> +	 * registers to report, but if we miss it (e.g. on BUG()) we need
> +	 * to report it on 'panic'.
> +	 *
> +	 * Calling code in the 'die' and 'panic' paths ensures that only
> +	 * one CPU is running this code, so no atomicity is needed.
> +	 */
> +	if (panic_reported)
> +		return;
> +	panic_reported = true;
> +
> +	guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);
> +
> +	/*
> +	 * 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);
> +
> +	/*
> +	 * Let Hyper-V know there is crash data available
> +	 */
> +	hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
> +}
> +EXPORT_SYMBOL_GPL(hyperv_report_panic);
> --
> 1.8.3.1

Reviewed-by: Sunil Muthuswamy <sunilmut@microsoft.com>


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

* RE: [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
                   ` (4 preceding siblings ...)
  2021-07-20 14:57 ` [PATCH v11 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64 Michael Kelley
@ 2021-08-02 15:15 ` Michael Kelley
  2021-08-02 16:01 ` Marc Zyngier
  6 siblings, 0 replies; 17+ messages in thread
From: Michael Kelley @ 2021-08-02 15:15 UTC (permalink / raw)
  To: will, catalin.marinas
  Cc: Mark Rutland, KY Srinivasan, linux-arm-kernel, linux-kernel,
	linux-hyperv, linux-efi, wei.liu, Stephen Hemminger, ardb

From: Michael Kelley <mikelley@microsoft.com> Sent: Tuesday, July 20, 2021 7:57 AM
> 
> This series enables Linux guests running on Hyper-V on ARM64
> hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> Hyper-V and its hypercall mechanism.  Existing architecture
> independent drivers for Hyper-V's VMbus and synthetic devices just
> work when built for ARM64. Hyper-V code is built and included in
> the image and modules only if CONFIG_HYPERV is enabled.

Will and Catalin --

Gentle ping. :-)   The clock/timer issues are now worked out in that
Hyper-V is providing full Generic Timer functionality in guest VMs.
That dropped some code out of the patch set, and making additional
code architecture neutral reduced the ARM64 specific code in this patch
set even further.  

To my knowledge, all issues have been addressed, so I'm looking for
any further review from you as ARM64 maintainers, or your Ack so
this can be ready for the 5.15 merge window.

Thanks!

Michael

> 
> The five patches are organized as follows:
> 
> 1) Add definitions and functions for making Hyper-V hypercalls
>    and getting/setting virtual processor registers provided by
>    Hyper-V
> 
> 2) Add the function needed by the arch independent VMbus driver
>    for reporting a panic to Hyper-V.
> 
> 3) Add Hyper-V initialization code and utility functions that
>    report Hyper-v status.
> 
> 4) Export screen_info so it may be used by the Hyper-V frame buffer
>    driver built as a module. It is already exported for x86,
>    powerpc, and alpha architectures.
> 
> 5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.
> 
> Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> with 4K/16K/64K page size. Linux guests with this patch series
> work with all three supported ARM64 page sizes.
> 
> The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> x86/x64-specific code and is not being built for ARM64. Enabling
> Hyper-V vPCI devices on ARM64 is in progress via a separate set
> of patches.
> 
> This patch set is based on the linux-next20210720 code tree.
> 
> Changes in v11:
> * Drop the previous Patch 1 as the fixes have already been
>   separately accepted upstream.
> * Drop the previous Patch 3 for enabling Hyper-V enlightened
>   clocks/timers.  Hyper-V is now offering the full ARM64
>   architectural Generic Timer in guest VMs, so the existing
>   arch_arch_timer.c driver just works. [Mark Rutland, Marc
>   Zyngier]
> * Simplified the previous Patch 4 and Patch 5 (now Patch 2 and 3)
>   by sharing more code between the x86 and ARM64 architectures.
> * Combined hyperv_early_init() and hyperv_init() into a single
>   initialization function that runs as an early_initcall. This
>   is possible because the Hyper-V enlightened clocks/timers
>   no longer need to be initialized early in the boot sequence.
> 
> Changes in v10:
> * Drop previous Patch 1 for SMCCC v1.2 HVC calls in favor of
>   Sudeep Holla's patch [Mark Rutland]
> * Use new helper functions in 5.13 for checking Hyper-V hypercall
>   return status
> * Set up per-CPU hypercall argument page that is now used by the
>   Hyper-V balloon driver
> * Rebase on 5.13-RC1
> 
> Changes in v9:
> * Added Patch 1 to enable making an SMCCC compliant hypercall
>   that returns results in other than registers X0 thru X3, per
>   version 1.2 and later of the SMCCC spec.
> * Using the ability to return results in registers X6 and X7,
>   converted hv_get_vpreg_128() to use a "fast" hypercall that
>   passes inputs and outputs in registers, and in doing so eliminated
>   a lot of memory allocation complexity.
> * Cleaned up some extra blank lines and use of spaces in aligning
>   local variables. [Sunil Muthuswamy]
> * Based on discussion about future directions, reverted the
>   population of hv_vp_index array to use a cpuhp state instead
>   of a hypercall, which is like it was in v7 and earlier.
> 
> Changes in v8:
> * Removed a lot of code based on refactoring the boundary between
>   arch independent and arch dependent code for Hyper-V, per comments
>   from Arnd Bergmann. The removed code was either duplicated on
>   the x86 side, or has been folded into architecture independent
>   code as not really being architecture dependent.
> * Added config dependency on !CONFIG_CPU_BIG_ENDIAN [Arnd Bergmann]
> * Reworked the approach to Hyper-V initialization. The functionality
>   is the same, but is now structured like the Xen code with an early
>   init function called in setup_arch() and an early initcall to
>   finish the initialization. [Arnd Bergmann]
> 
> Changes in v7:
> * Separately upstreamed split of hyperv-tlfs.h into arch dependent
>   and independent versions.  In this patch set, update the ARM64
>   hyperv-tlfs.h to include architecture independent definitions.
>   This approach eliminates a lot of lines of otherwise duplicated
>   code on the ARM64 side.
> * Break ARM64 mshyperv.h into smaller pieces. Have an initial
>   baseline, and add code along with patches for a particular
>   functional area. [Marc Zyngier]
> * In mshyperv.h, use static inline functions instead of #defines
>   where possible. [Arnd Bergmann]
> * Use VMbus INTID obtained from ACPI DSDT instead of hardcoding.
>   The STIMER INTID is still hardcoded because it is needed
>   before Linux has initialized the ACPI subsystem, so it can't
>   be obtained from the DSDT.  Wedging it into the GTDT seems
>   dubious, so was not done. [Marc Zyngier]
> * Update Hyper-V page size allocation functions to use
>   alloc_page() if PAGE_SIZE == HV_HYP_PAGE_SIZE [Arnd
>   Bergmann]
> * Various other minor changes based on feedback and to rebase
>   to latest linux-next [Marc Zyngier and Arnd Bergmann]
> 
> Changes in v6:
> * Use SMCCC hypercall interface instead of direct invocation
>   of HVC instruction and the Hyper-V hypercall interface
>   [Marc Zyngier]
> * Reimplemented functions to alloc/free Hyper-V size pages
>   using kmalloc/kfree since kmalloc now guarantees alignment of
>   power of 2 size allocations [Marc Zyngier]
> * Export screen_info in arm64 architecture so it can be used
>   by the Hyper-V buffer driver built as a module
> * Renamed source file arch/arm64/hyperv/hv_init.c to hv_core.c
>   to better reflect its content
> * Fixed the bit position of certain feature flags presented by
>   Hyper-V to the guest.  The bit positions on ARM64 don't match
>   the position on x86 like originally thought.
> * Minor fixups to rebase to 5.6-rc5 linux-next
> 
> Changes in v5:
> * Minor fixups to rebase to 5.4-rc1 linux-next
> 
> Changes in v4:
> * Moved clock-related code into an architecture independent
>   Hyper-V clocksource driver that is already upstream. Clock
>   related code is removed from this patch set except for the
>   ARM64 specific interrupt handler. [Marc Zyngier]
> * Separately upstreamed the split of mshyperv.h into arch independent
>   and arch dependent portions. The arch independent portion has been
>   removed from this patch set.
> * Divided patch #2 of the series into multiple smaller patches
>   [Marc Zyngier]
> * Changed a dozen or so smaller things based on feedback
>   [Marc Zyngier, Will Deacon]
> * Added functions to alloc/free Hyper-V size pages for use by
>   drivers for Hyper-V synthetic devices when updated to not assume
>   guest page size and Hyper-v page size are the same
> 
> Changes in v3:
> * Added initialization of hv_vp_index array like was recently
>   added on x86 branch [KY Srinivasan]
> * Changed Hyper-V ARM64 register symbols to be all uppercase
>   instead of mixed case [KY Srinivasan]
> * Separated mshyperv.h into two files, one architecture
>   independent and one architecture dependent. After this code
>   is upstream, will make changes to the x86 code to use the
>   architecture independent file and remove duplication. And
>   once we have a multi-architecture Hyper-V TLFS, will do a
>   separate patch to split hyperv-tlfs.h in the same way.
>   [KY Srinivasan]
> * Minor tweaks to rebase to latest linux-next code
> 
> Changes in v2:
> * Removed patch to implement slow_virt_to_phys() on ARM64.
>   Use of slow_virt_to_phys() in arch independent Hyper-V
>   drivers has been eliminated by commit 6ba34171bcbd
>   ("Drivers: hv: vmbus: Remove use of slow_virt_to_phys()")
> * Minor tweaks to rebase to latest linux-next code
> 
> Michael Kelley (5):
>   arm64: hyperv: Add Hyper-V hypercall and register access utilities
>   arm64: hyperv: Add panic handler
>   arm64: hyperv: Initialize hypervisor on boot
>   arm64: efi: Export screen_info
>   Drivers: hv: Enable Hyper-V code to be built on ARM64
> 
>  MAINTAINERS                          |   3 +
>  arch/arm64/Kbuild                    |   1 +
>  arch/arm64/hyperv/Makefile           |   2 +
>  arch/arm64/hyperv/hv_core.c          | 181 +++++++++++++++++++++++++++++++++++
>  arch/arm64/hyperv/mshyperv.c         |  83 ++++++++++++++++
>  arch/arm64/include/asm/hyperv-tlfs.h |  69 +++++++++++++
>  arch/arm64/include/asm/mshyperv.h    |  54 +++++++++++
>  arch/arm64/kernel/efi.c              |   1 +
>  drivers/hv/Kconfig                   |   5 +-
>  9 files changed, 397 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm64/hyperv/Makefile
>  create mode 100644 arch/arm64/hyperv/hv_core.c
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
>  create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
>  create mode 100644 arch/arm64/include/asm/mshyperv.h
> 
> --
> 1.8.3.1


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

* Re: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
  2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
  2021-07-21 14:55   ` Boqun Feng
  2021-07-27 17:05   ` Sunil Muthuswamy
@ 2021-08-02 15:55   ` Marc Zyngier
  2021-08-02 16:26   ` Mark Rutland
  3 siblings, 0 replies; 17+ messages in thread
From: Marc Zyngier @ 2021-08-02 15:55 UTC (permalink / raw)
  To: Michael Kelley
  Cc: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb

On Tue, 20 Jul 2021 15:57:01 +0100,
Michael Kelley <mikelley@microsoft.com> wrote:
> 
> Add ARM64-specific code to initialize the Hyper-V
> hypervisor when booting as a guest VM.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> ---
>  arch/arm64/hyperv/Makefile   |  2 +-
>  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 84 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 1697d30..87c31c0 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,2 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-y		:= hv_core.o
> +obj-y		:= hv_core.o mshyperv.o
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> new file mode 100644
> index 0000000..2811fd0
> --- /dev/null
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> + * including hypervisor initialization.
> + *
> + * Copyright (C) 2021, Microsoft, Inc.
> + *
> + * Author : Michael Kelley <mikelley@microsoft.com>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/acpi.h>
> +#include <linux/export.h>
> +#include <linux/errno.h>
> +#include <linux/version.h>
> +#include <linux/cpuhotplug.h>
> +#include <asm/mshyperv.h>
> +
> +static bool hyperv_initialized;
> +
> +static int __init hyperv_init(void)
> +{
> +	struct hv_get_vp_registers_output	result;
> +	u32	a, b, c, d;
> +	u64	guest_id;
> +	int	ret;
> +
> +	/*
> +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> +	 * have the string "MsHyperV".
> +	 */
> +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> +		return -EINVAL;

Before going ahead and parsing the local FADT copy, it would be
prudent to test that you are actually on an ACPI system, specially
given that this function is unconditionally called, even on DT
systems.  In the same vein, returning -EINVAL when failing to find
Hyper-V is a bit excessive.

> +
> +	/* Setup the guest ID */
> +	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
> +	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
> +
> +	/* Get the features and hints from Hyper-V */
> +	hv_get_vpreg_128(HV_REGISTER_FEATURES, &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);
> +	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",
> +		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 & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
> +
> +	ret = hv_common_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
> +				hv_common_cpu_init, hv_common_cpu_die);
> +	if (ret < 0) {
> +		hv_common_free();
> +		return ret;
> +	}
> +
> +	hyperv_initialized = true;
> +	return 0;
> +}
> +
> +early_initcall(hyperv_init);
> +
> +bool hv_is_hyperv_initialized(void)
> +{
> +	return hyperv_initialized;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);

Thanks,

	M.

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

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

* Re: [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
  2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
                   ` (5 preceding siblings ...)
  2021-08-02 15:15 ` [PATCH v11 0/5] Enable Linux guests on Hyper-V " Michael Kelley
@ 2021-08-02 16:01 ` Marc Zyngier
  2021-08-02 16:28   ` Mark Rutland
  6 siblings, 1 reply; 17+ messages in thread
From: Marc Zyngier @ 2021-08-02 16:01 UTC (permalink / raw)
  To: Michael Kelley
  Cc: will, catalin.marinas, mark.rutland, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb

On Tue, 20 Jul 2021 15:56:58 +0100,
Michael Kelley <mikelley@microsoft.com> wrote:
> 
> This series enables Linux guests running on Hyper-V on ARM64
> hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> Hyper-V and its hypercall mechanism.  Existing architecture
> independent drivers for Hyper-V's VMbus and synthetic devices just
> work when built for ARM64. Hyper-V code is built and included in
> the image and modules only if CONFIG_HYPERV is enabled.
> 
> The five patches are organized as follows:
> 
> 1) Add definitions and functions for making Hyper-V hypercalls
>    and getting/setting virtual processor registers provided by
>    Hyper-V
> 
> 2) Add the function needed by the arch independent VMbus driver
>    for reporting a panic to Hyper-V.
> 
> 3) Add Hyper-V initialization code and utility functions that
>    report Hyper-v status.
> 
> 4) Export screen_info so it may be used by the Hyper-V frame buffer
>    driver built as a module. It is already exported for x86,
>    powerpc, and alpha architectures.
> 
> 5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.
> 
> Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> with 4K/16K/64K page size. Linux guests with this patch series
> work with all three supported ARM64 page sizes.
> 
> The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> x86/x64-specific code and is not being built for ARM64. Enabling
> Hyper-V vPCI devices on ARM64 is in progress via a separate set
> of patches.
> 
> This patch set is based on the linux-next20210720 code tree.
> 
> Changes in v11:
> * Drop the previous Patch 1 as the fixes have already been
>   separately accepted upstream.
> * Drop the previous Patch 3 for enabling Hyper-V enlightened
>   clocks/timers.  Hyper-V is now offering the full ARM64
>   architectural Generic Timer in guest VMs, so the existing
>   arch_arch_timer.c driver just works. [Mark Rutland, Marc
>   Zyngier]

Thanks for doing this. Assuming you fix the issue I mentioned in my
reply to patch #3. FWIW:

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

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

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

* Re: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
  2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
                     ` (2 preceding siblings ...)
  2021-08-02 15:55   ` Marc Zyngier
@ 2021-08-02 16:26   ` Mark Rutland
  2021-08-02 17:13     ` Michael Kelley
  3 siblings, 1 reply; 17+ messages in thread
From: Mark Rutland @ 2021-08-02 16:26 UTC (permalink / raw)
  To: Michael Kelley
  Cc: will, catalin.marinas, linux-arm-kernel, linux-kernel,
	linux-hyperv, linux-efi, wei.liu, kys, sthemmin, ardb

On Tue, Jul 20, 2021 at 07:57:01AM -0700, Michael Kelley wrote:
> Add ARM64-specific code to initialize the Hyper-V
> hypervisor when booting as a guest VM.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> ---
>  arch/arm64/hyperv/Makefile   |  2 +-
>  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 84 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 1697d30..87c31c0 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,2 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-y		:= hv_core.o
> +obj-y		:= hv_core.o mshyperv.o
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> new file mode 100644
> index 0000000..2811fd0
> --- /dev/null
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> + * including hypervisor initialization.
> + *
> + * Copyright (C) 2021, Microsoft, Inc.
> + *
> + * Author : Michael Kelley <mikelley@microsoft.com>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/acpi.h>
> +#include <linux/export.h>
> +#include <linux/errno.h>
> +#include <linux/version.h>
> +#include <linux/cpuhotplug.h>
> +#include <asm/mshyperv.h>
> +
> +static bool hyperv_initialized;
> +
> +static int __init hyperv_init(void)
> +{
> +	struct hv_get_vp_registers_output	result;
> +	u32	a, b, c, d;
> +	u64	guest_id;
> +	int	ret;

As Marc suggests, before looking at the FADT, you need something like:

	/*
	 * Hyper-V VMs always have ACPI.
	 */
	if (acpi_disabled)
		return 0;

... where `acpi_disabled` is defined in <linux/acpi.h> (or via its
includes), so you don't need to include any additional headers.

> +
> +	/*
> +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> +	 * have the string "MsHyperV".
> +	 */
> +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> +		return -EINVAL;

As Marc suggests, it's no an error for a platform to not have Hyper-V,
so returning 0 in tihs case would be preferable.

Otherwise this looks fine to me.

Thanks,
Mark.

> +
> +	/* Setup the guest I[D */
> +	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
> +	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
> +
> +	/* Get the features and hints from Hyper-V */
> +	hv_get_vpreg_128(HV_REGISTER_FEATURES, &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);
> +	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",
> +		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 & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
> +
> +	ret = hv_common_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
> +				hv_common_cpu_init, hv_common_cpu_die);
> +	if (ret < 0) {
> +		hv_common_free();
> +		return ret;
> +	}
> +
> +	hyperv_initialized = true;
> +	return 0;
> +}
> +
> +early_initcall(hyperv_init);
> +
> +bool hv_is_hyperv_initialized(void)
> +{
> +	return hyperv_initialized;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
> -- 
> 1.8.3.1
> 

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

* Re: [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
  2021-08-02 16:01 ` Marc Zyngier
@ 2021-08-02 16:28   ` Mark Rutland
  0 siblings, 0 replies; 17+ messages in thread
From: Mark Rutland @ 2021-08-02 16:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Michael Kelley, will, catalin.marinas, linux-arm-kernel,
	linux-kernel, linux-hyperv, linux-efi, wei.liu, kys, sthemmin,
	ardb

On Mon, Aug 02, 2021 at 05:01:02PM +0100, Marc Zyngier wrote:
> On Tue, 20 Jul 2021 15:56:58 +0100,
> Michael Kelley <mikelley@microsoft.com> wrote:
> > 
> > This series enables Linux guests running on Hyper-V on ARM64
> > hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> > Hyper-V and its hypercall mechanism.  Existing architecture
> > independent drivers for Hyper-V's VMbus and synthetic devices just
> > work when built for ARM64. Hyper-V code is built and included in
> > the image and modules only if CONFIG_HYPERV is enabled.
> > 
> > The five patches are organized as follows:
> > 
> > 1) Add definitions and functions for making Hyper-V hypercalls
> >    and getting/setting virtual processor registers provided by
> >    Hyper-V
> > 
> > 2) Add the function needed by the arch independent VMbus driver
> >    for reporting a panic to Hyper-V.
> > 
> > 3) Add Hyper-V initialization code and utility functions that
> >    report Hyper-v status.
> > 
> > 4) Export screen_info so it may be used by the Hyper-V frame buffer
> >    driver built as a module. It is already exported for x86,
> >    powerpc, and alpha architectures.
> > 
> > 5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.
> > 
> > Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> > with 4K/16K/64K page size. Linux guests with this patch series
> > work with all three supported ARM64 page sizes.
> > 
> > The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> > x86/x64-specific code and is not being built for ARM64. Enabling
> > Hyper-V vPCI devices on ARM64 is in progress via a separate set
> > of patches.
> > 
> > This patch set is based on the linux-next20210720 code tree.
> > 
> > Changes in v11:
> > * Drop the previous Patch 1 as the fixes have already been
> >   separately accepted upstream.
> > * Drop the previous Patch 3 for enabling Hyper-V enlightened
> >   clocks/timers.  Hyper-V is now offering the full ARM64
> >   architectural Generic Timer in guest VMs, so the existing
> >   arch_arch_timer.c driver just works. [Mark Rutland, Marc
> >   Zyngier]
> 
> Thanks for doing this. Assuming you fix the issue I mentioned in my
> reply to patch #3. FWIW:
> 
> Acked-by: Marc Zyngier <maz@kernel.org>

I've tried to provide concrete options for those. With those fixed up
somehow:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

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

* RE: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
  2021-08-02 16:26   ` Mark Rutland
@ 2021-08-02 17:13     ` Michael Kelley
  0 siblings, 0 replies; 17+ messages in thread
From: Michael Kelley @ 2021-08-02 17:13 UTC (permalink / raw)
  To: Mark Rutland
  Cc: will, catalin.marinas, linux-arm-kernel, linux-kernel,
	linux-hyperv, linux-efi, wei.liu, KY Srinivasan,
	Stephen Hemminger, ardb

From: Mark Rutland <mark.rutland@arm.com> Sent: Monday, August 2, 2021 9:26 AM
> 
> On Tue, Jul 20, 2021 at 07:57:01AM -0700, Michael Kelley wrote:
> > Add ARM64-specific code to initialize the Hyper-V
> > hypervisor when booting as a guest VM.
> >
> > This code is built only when CONFIG_HYPERV is enabled.
> >
> > Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> > ---
> >  arch/arm64/hyperv/Makefile   |  2 +-
> >  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 84 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm64/hyperv/mshyperv.c
> >
> > diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> > index 1697d30..87c31c0 100644
> > --- a/arch/arm64/hyperv/Makefile
> > +++ b/arch/arm64/hyperv/Makefile
> > @@ -1,2 +1,2 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > -obj-y		:= hv_core.o
> > +obj-y		:= hv_core.o mshyperv.o
> > diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> > new file mode 100644
> > index 0000000..2811fd0
> > --- /dev/null
> > +++ b/arch/arm64/hyperv/mshyperv.c
> > @@ -0,0 +1,83 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> > + * including hypervisor initialization.
> > + *
> > + * Copyright (C) 2021, Microsoft, Inc.
> > + *
> > + * Author : Michael Kelley <mikelley@microsoft.com>
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <linux/acpi.h>
> > +#include <linux/export.h>
> > +#include <linux/errno.h>
> > +#include <linux/version.h>
> > +#include <linux/cpuhotplug.h>
> > +#include <asm/mshyperv.h>
> > +
> > +static bool hyperv_initialized;
> > +
> > +static int __init hyperv_init(void)
> > +{
> > +	struct hv_get_vp_registers_output	result;
> > +	u32	a, b, c, d;
> > +	u64	guest_id;
> > +	int	ret;
> 
> As Marc suggests, before looking at the FADT, you need something like:
> 
> 	/*
> 	 * Hyper-V VMs always have ACPI.
> 	 */
> 	if (acpi_disabled)
> 		return 0;
> 
> ... where `acpi_disabled` is defined in <linux/acpi.h> (or via its
> includes), so you don't need to include any additional headers.
> 
> > +
> > +	/*
> > +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> > +	 * have the string "MsHyperV".
> > +	 */
> > +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> > +		return -EINVAL;
> 
> As Marc suggests, it's no an error for a platform to not have Hyper-V,
> so returning 0 in tihs case would be preferable.
> 
> Otherwise this looks fine to me.
> 

Thanks Marc and Mark.  Good point that the code should cleanly
handle the case where a kernel is built with CONFIG_HYPERV but
running somewhere other than as a Hyper-V guest.

Michael



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

end of thread, other threads:[~2021-08-02 17:13 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-20 14:56 [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64 Michael Kelley
2021-07-20 14:56 ` [PATCH v11 1/5] arm64: hyperv: Add Hyper-V hypercall and register access utilities Michael Kelley
2021-07-20 14:57 ` [PATCH v11 2/5] arm64: hyperv: Add panic handler Michael Kelley
2021-07-21 14:54   ` Boqun Feng
2021-07-27 17:08   ` Sunil Muthuswamy
2021-07-20 14:57 ` [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot Michael Kelley
2021-07-21 14:55   ` Boqun Feng
2021-07-27 17:05   ` Sunil Muthuswamy
2021-08-02 15:55   ` Marc Zyngier
2021-08-02 16:26   ` Mark Rutland
2021-08-02 17:13     ` Michael Kelley
2021-07-20 14:57 ` [PATCH v11 4/5] arm64: efi: Export screen_info Michael Kelley
2021-07-20 14:57 ` [PATCH v11 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64 Michael Kelley
2021-07-21 14:52   ` Boqun Feng
2021-08-02 15:15 ` [PATCH v11 0/5] Enable Linux guests on Hyper-V " Michael Kelley
2021-08-02 16:01 ` Marc Zyngier
2021-08-02 16:28   ` Mark Rutland

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