* Re: [PATCH v1] hyper-v: Remove internal types from UAPI header
From: Wei Liu @ 2020-04-22 19:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Wei Liu, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
linux-hyperv
In-Reply-To: <20200422141507.GI185537@smile.fi.intel.com>
On Wed, Apr 22, 2020 at 05:15:07PM +0300, Andy Shevchenko wrote:
> On Wed, Apr 22, 2020 at 02:41:27PM +0100, Wei Liu wrote:
> > On Wed, Apr 22, 2020 at 04:18:18PM +0300, Andy Shevchenko wrote:
> > > The uuid_le mistakenly comes to be an UAPI type. Since it's luckily not used by
> > > Hyper-V APIs, we may replace with POD types, i.e. __u8 array.
> > >
> > > Note, previously shared uuid_be had been removed from UAPI few releases ago.
> > > This is a continuation of that process towards removing uuid_le one.
> > >
> > > Note, there is no ABI change!
> > >
> > > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> >
> > Can you clarify why guid_t is not used instead?
>
> It's internal type to the kernel. The libuuid or so should provide a compatible
> type(s) for user space.
>
> > Is the plan to remove it
> > from UAPI as well?
>
> Yes.
>
OK. Thanks for explaining.
Wei.
> > Wei.
> >
> > > ---
> > > include/uapi/linux/hyperv.h | 4 ++--
> > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h
> > > index 991b2b7ada7a3..8f24404ad04f1 100644
> > > --- a/include/uapi/linux/hyperv.h
> > > +++ b/include/uapi/linux/hyperv.h
> > > @@ -119,8 +119,8 @@ enum hv_fcopy_op {
> > >
> > > struct hv_fcopy_hdr {
> > > __u32 operation;
> > > - uuid_le service_id0; /* currently unused */
> > > - uuid_le service_id1; /* currently unused */
> > > + __u8 service_id0[16]; /* currently unused */
> > > + __u8 service_id1[16]; /* currently unused */
> > > } __attribute__((packed));
> > >
> > > #define OVER_WRITE 0x1
> > > --
> > > 2.26.1
> > >
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply
* Re: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Bart Van Assche @ 2020-04-22 19:56 UTC (permalink / raw)
To: Dexuan Cui, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <HK0P153MB027395755C14233F09A8F352BFD20@HK0P153MB0273.APCP153.PROD.OUTLOOK.COM>
On 4/21/20 11:24 PM, Dexuan Cui wrote:
> Upon suspend, I suppose the other LLDs can not accept I/O either, then
> what do they do when some kernel thread still tries to submit I/O? Do
> they "block" the I/O until resume, or just return an error immediately?
This is my understanding of how other SCSI LLDs handle suspend/resume:
- The ULP driver, e.g. the SCSI sd driver, implements power management
support by providing callbacks in struct scsi_driver.gendrv.pm and also
in scsi_bus_type.pm. The SCSI sd suspend callbacks flush the device
cache and send a STOP command to the device.
- SCSI LLDs for PCIe devices optionally provide pci_driver.suspend and
resume callbacks. These callbacks can be used to make the PCIe device
enter/leave a power saving state. No new SCSI commands should be
submitted after pci_driver.suspend has been called.
> I had a look at drivers/scsi/xen-scsifront.c. It looks this LLD implements
> a mechanism of marking the device busy upon suspend, so any I/O will
> immediately get an error SCSI_MLQUEUE_HOST_BUSY. IMO the
> disadvantage is: the mechanism of marking the device busy looks
> complex, and the hot path .queuecommand() has to take the
> spinlock shost->host_lock, which should affect the performance.
I think the code you are referring to is the code in
scsifront_suspend(). A pointer to that function is stored in a struct
xenbus_driver instance. That's another structure than the structures
mentioned above.
Wouldn't it be better to make sure that any hypervisor suspend
operations happen after it is guaranteed that no further SCSI commands
will be submitted such that hypervisor suspend operations do not have to
deal with SCSI commands submitted during or after the hypervisor suspend
callback?
> It looks drivers/scsi/nsp32.c: nsp32_suspend() and
> drivers/scsi/3w-9xxx.c: twa_suspend() do nothing to handle new I/O
> after suspend. I doubt this is correct.
nsp32_suspend() is a PCI suspend callback. If any SCSI commands would be
submitted after that callback has started that would mean that the SCSI
suspend and PCIe suspend operations are called in the wrong order. I do
not agree that code for suspending SCSI commands should be added in
nsp32_suspend().
> So it looks to me there is no simple mechanism to handle the scenario
> here, and I guess that's why the scsi_host_block/unblock APIs are
> introduced, and actually there is already an user of the APIs:
> 3d3ca53b1639 ("scsi: aacraid: use scsi_host_(block,unblock) to block I/O").
>
> The aacraid patch says: "This has the advantage that the block layer will
> stop sending I/O to the adapter instead of having the SCSI midlayer
> requeueing I/O internally". It looks this may imply that using the new
> APIs is encouraged?
I'm fine with using these new functions in device reset handlers. Using
these functions in power management handlers seems wrong to me.
> PS, here storvsc has to destroy and re-construct the I/O queues: the
> I/O queues are shared memory ringbufers between the guest and the
> host; in the resume path of the hibernation procedure, the memory
> pages allocated by the 'new' kernel is different from that allocated by
> the 'old' kernel, so before jumping to the 'old' kernel, the 'new' kernel
> must destroy the mapping of the pages, and later after we jump to
> the 'old' kernel, we'll re-create the mapping using the pages allocated
> by the 'old' kernel. Here "create the mapping" means the guest tells
> the host about the physical addresses of the pages.
Thank you for having clarified this. This helps me to understand the HV
driver framework better. I think this means that the hv_driver.suspend
function should be called at a later time than SCSI suspend. From
Documentation/driver-api/device_link.rst: "By default, the driver core
only enforces dependencies between devices that are borne out of a
parent/child relationship within the device hierarchy: When suspending,
resuming or shutting down the system, devices are ordered based on this
relationship, i.e. children are always suspended before their parent,
and the parent is always resumed before its children." Is there a single
storvsc_drv instance for all SCSI devices supported by storvsc_drv? Has
it been considered to make storvsc_drv the parent device of all SCSI
devices created by the storvsc driver?
Thanks,
Bart.
^ permalink raw reply
* [PATCH] PCI: export and use pci_msi_get_hwirq in pci-hyperv.c
From: Wei Liu @ 2020-04-22 19:58 UTC (permalink / raw)
To: linux-pci
Cc: linux-hyperv, linux-kernel, Wei Liu, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H. Peter Anvin, x86, K. Y. Srinivasan,
Haiyang Zhang, Stephen Hemminger, Lorenzo Pieralisi,
Andrew Murray, Bjorn Helgaas, Allison Randal, Greg Kroah-Hartman,
Enrico Weigelt
There is a functionally identical function in pci-hyperv.c. Drop it and
use pci_msi_get_hwirq instead.
This requires exporting pci_msi_get_hwirq and declaring it in msi.h.
No functional change intended.
Signed-off-by: Wei Liu <wei.liu@kernel.org>
---
arch/x86/include/asm/msi.h | 4 ++++
arch/x86/kernel/apic/msi.c | 5 +++--
drivers/pci/controller/pci-hyperv.c | 8 +-------
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 25ddd0916bb2..353b80122b2e 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -11,4 +11,8 @@ int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+struct msi_domain_info;
+irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
+ msi_alloc_info_t *arg);
+
#endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 159bd0cb8548..56dcdd912564 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -204,11 +204,12 @@ void native_teardown_msi_irq(unsigned int irq)
irq_domain_free_irqs(irq, 1);
}
-static irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
- msi_alloc_info_t *arg)
+irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
+ msi_alloc_info_t *arg)
{
return arg->msi_hwirq;
}
+EXPORT_SYMBOL_GPL(pci_msi_get_hwirq);
int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
msi_alloc_info_t *arg)
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index e6020480a28b..2b4a6452095f 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -1520,14 +1520,8 @@ static struct irq_chip hv_msi_irq_chip = {
.irq_unmask = hv_irq_unmask,
};
-static irq_hw_number_t hv_msi_domain_ops_get_hwirq(struct msi_domain_info *info,
- msi_alloc_info_t *arg)
-{
- return arg->msi_hwirq;
-}
-
static struct msi_domain_ops hv_msi_ops = {
- .get_hwirq = hv_msi_domain_ops_get_hwirq,
+ .get_hwirq = pci_msi_get_hwirq,
.msi_prepare = pci_msi_prepare,
.set_desc = pci_msi_set_desc,
.msi_free = hv_msi_free,
--
2.20.1
^ permalink raw reply related
* [PATCH v2 3/4] x86/hyperv: Split hyperv-tlfs.h into arch dependent and independent files
From: Michael Kelley @ 2020-04-22 19:57 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86, hpa,
pbonzini, sean.j.christopherson, vkuznets, wanpengli, jmattson,
joro, kvm, linux-kernel, linux-hyperv
Cc: mikelley
In-Reply-To: <20200422195737.10223-1-mikelley@microsoft.com>
In preparation for adding ARM64 support, split hyperv-tlfs.h into
architecture dependent and architecture independent files, similar
to what has been done with mshyperv.h. Move architecture independent
definitions into include/asm-generic/hyperv-tlfs.h. The split will
avoid duplicating significant lines of code in the ARM64 version of
hyperv-tlfs.h. The split has no functional impact.
Some of the common definitions have "X64" in the symbol name. Change
these to remove the "X64" in the architecture independent version of
hyperv-tlfs.h, but add aliases with the "X64" in the x86 version so
that x86 code will continue to compile. A later patch set will
change all the references and allow removal of the aliases.
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
MAINTAINERS | 1 +
arch/x86/include/asm/hyperv-tlfs.h | 459 +++--------------------------
include/asm-generic/hyperv-tlfs.h | 442 +++++++++++++++++++++++++++
3 files changed, 479 insertions(+), 423 deletions(-)
create mode 100644 include/asm-generic/hyperv-tlfs.h
diff --git a/MAINTAINERS b/MAINTAINERS
index cb68a9437eff..843f2f30648f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7884,6 +7884,7 @@ 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/linux/hyperv.h
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 2dd1ceb2bcf8..4e91f6118d5d 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -11,17 +11,6 @@
#include <linux/types.h>
#include <asm/page.h>
-
-/*
- * While not explicitly listed in the TLFS, Hyper-V always runs with a page size
- * of 4096. These definitions are used when communicating with Hyper-V using
- * guest physical pages and guest physical page addresses, since the guest page
- * size may not be 4096 on all architectures.
- */
-#define HV_HYP_PAGE_SHIFT 12
-#define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)
-#define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
-
/*
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
* is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
@@ -39,78 +28,41 @@
#define HYPERV_CPUID_MAX 0x4000ffff
/*
- * Feature identification. EAX indicates which features are available
- * to the partition based upon the current partition privileges.
- * These are HYPERV_CPUID_FEATURES.EAX bits.
+ * Aliases for Group A features that have X64 in the name.
+ * On x86/x64 these are HYPERV_CPUID_FEATURES.EAX bits.
*/
-/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
-#define HV_X64_MSR_VP_RUNTIME_AVAILABLE BIT(0)
-/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
-#define HV_MSR_TIME_REF_COUNT_AVAILABLE BIT(1)
-/*
- * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
- * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
- */
-#define HV_X64_MSR_SYNIC_AVAILABLE BIT(2)
-/*
- * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
- * HV_X64_MSR_STIMER3_COUNT) available
- */
-#define HV_MSR_SYNTIMER_AVAILABLE BIT(3)
-/*
- * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
- * are available
- */
-#define HV_X64_MSR_APIC_ACCESS_AVAILABLE BIT(4)
-/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
-#define HV_X64_MSR_HYPERCALL_AVAILABLE BIT(5)
-/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
-#define HV_X64_MSR_VP_INDEX_AVAILABLE BIT(6)
-/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
-#define HV_X64_MSR_RESET_AVAILABLE BIT(7)
-/*
- * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
- * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
- * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
- */
-#define HV_X64_MSR_STAT_PAGES_AVAILABLE BIT(8)
-/* Partition reference TSC MSR is available */
-#define HV_MSR_REFERENCE_TSC_AVAILABLE BIT(9)
-/* Partition Guest IDLE MSR is available */
-#define HV_X64_MSR_GUEST_IDLE_AVAILABLE BIT(10)
-/*
- * There is a single feature flag that signifies if the partition has access
- * to MSRs with local APIC and TSC frequencies.
- */
-#define HV_X64_ACCESS_FREQUENCY_MSRS BIT(11)
-/* AccessReenlightenmentControls privilege */
-#define HV_X64_ACCESS_REENLIGHTENMENT BIT(13)
-/* AccessTscInvariantControls privilege */
-#define HV_X64_ACCESS_TSC_INVARIANT BIT(15)
+#define HV_X64_MSR_VP_RUNTIME_AVAILABLE \
+ HV_MSR_VP_RUNTIME_AVAILABLE
+#define HV_X64_MSR_SYNIC_AVAILABLE \
+ HV_MSR_SYNIC_AVAILABLE
+#define HV_X64_MSR_APIC_ACCESS_AVAILABLE \
+ HV_MSR_APIC_ACCESS_AVAILABLE
+#define HV_X64_MSR_HYPERCALL_AVAILABLE \
+ HV_MSR_HYPERCALL_AVAILABLE
+#define HV_X64_MSR_VP_INDEX_AVAILABLE \
+ HV_MSR_VP_INDEX_AVAILABLE
+#define HV_X64_MSR_RESET_AVAILABLE \
+ HV_MSR_RESET_AVAILABLE
+#define HV_X64_MSR_GUEST_IDLE_AVAILABLE \
+ HV_MSR_GUEST_IDLE_AVAILABLE
+#define HV_X64_ACCESS_FREQUENCY_MSRS \
+ HV_ACCESS_FREQUENCY_MSRS
+#define HV_X64_ACCESS_REENLIGHTENMENT \
+ HV_ACCESS_REENLIGHTENMENT
+#define HV_X64_ACCESS_TSC_INVARIANT \
+ HV_ACCESS_TSC_INVARIANT
/*
- * Feature identification: indicates which flags were specified at partition
- * creation. The format is the same as the partition creation flag structure
- * defined in section Partition Creation Flags.
- * These are HYPERV_CPUID_FEATURES.EBX bits.
+ * Aliases for Group B features that have X64 in the name.
+ * On x86/x64 these are HYPERV_CPUID_FEATURES.EBX bits.
*/
-#define HV_X64_CREATE_PARTITIONS BIT(0)
-#define HV_X64_ACCESS_PARTITION_ID BIT(1)
-#define HV_X64_ACCESS_MEMORY_POOL BIT(2)
-#define HV_X64_ADJUST_MESSAGE_BUFFERS BIT(3)
-#define HV_X64_POST_MESSAGES BIT(4)
-#define HV_X64_SIGNAL_EVENTS BIT(5)
-#define HV_X64_CREATE_PORT BIT(6)
-#define HV_X64_CONNECT_PORT BIT(7)
-#define HV_X64_ACCESS_STATS BIT(8)
-#define HV_X64_DEBUGGING BIT(11)
-#define HV_X64_CPU_POWER_MANAGEMENT BIT(12)
+#define HV_X64_POST_MESSAGES HV_POST_MESSAGES
+#define HV_X64_SIGNAL_EVENTS HV_SIGNAL_EVENTS
/*
- * Feature identification. EDX indicates which miscellaneous features
- * are available to the partition.
- * These are HYPERV_CPUID_FEATURES.EDX bits.
+ * Group D Features. The bit assignments are custom to each architecture.
+ * On x86/x64 these are HYPERV_CPUID_FEATURES.EDX bits.
*/
/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
#define HV_X64_MWAIT_AVAILABLE BIT(0)
@@ -187,7 +139,7 @@
* processor, except for virtual processors that are reported as sibling SMT
* threads.
*/
-#define HV_X64_NO_NONARCH_CORESHARING BIT(18)
+#define HV_X64_NO_NONARCH_CORESHARING BIT(18)
/* Nested features. These are HYPERV_CPUID_NESTED_FEATURES.EAX bits. */
#define HV_X64_NESTED_DIRECT_FLUSH BIT(17)
@@ -295,42 +247,6 @@ union hv_x64_msr_hypercall_contents {
} __packed;
};
-/*
- * TSC page layout.
- */
-struct ms_hyperv_tsc_page {
- volatile u32 tsc_sequence;
- u32 reserved1;
- volatile u64 tsc_scale;
- volatile s64 tsc_offset;
-} __packed;
-
-/*
- * 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 specification:
- *
- * msdn.microsoft.com/en-us/library/windows/hardware/ff542653%28v=vs.85%29.aspx
- *
- * 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
-
struct hv_reenlightenment_control {
__u64 vector:8;
__u64 reserved1:8;
@@ -354,31 +270,12 @@ struct hv_tsc_emulation_status {
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
-/*
- * Crash notification (HV_X64_MSR_CRASH_CTL) flags.
- */
-#define HV_CRASH_CTL_CRASH_NOTIFY_MSG BIT_ULL(62)
-#define HV_CRASH_CTL_CRASH_NOTIFY BIT_ULL(63)
#define HV_X64_MSR_CRASH_PARAMS \
(1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
#define HV_IPI_LOW_VECTOR 0x10
#define HV_IPI_HIGH_VECTOR 0xff
-/* Declare the various hypercall operations. */
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
-#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
-#define HVCALL_SEND_IPI 0x000b
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
-#define HVCALL_SEND_IPI_EX 0x0015
-#define HVCALL_POST_MESSAGE 0x005c
-#define HVCALL_SIGNAL_EVENT 0x005d
-#define HVCALL_RETARGET_INTERRUPT 0x007e
-#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
-#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
-
#define HV_X64_MSR_VP_ASSIST_PAGE_ENABLE 0x00000001
#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12
#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK \
@@ -390,63 +287,6 @@ struct hv_tsc_emulation_status {
#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001
#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12
-#define HV_FLUSH_ALL_PROCESSORS BIT(0)
-#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
-#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
-#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
-
-enum HV_GENERIC_SET_FORMAT {
- HV_GENERIC_SET_SPARSE_4K,
- HV_GENERIC_SET_ALL,
-};
-
-#define HV_PARTITION_ID_SELF ((u64)-1)
-
-#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
-#define HV_HYPERCALL_FAST_BIT BIT(16)
-#define HV_HYPERCALL_VARHEAD_OFFSET 17
-#define HV_HYPERCALL_REP_COMP_OFFSET 32
-#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32)
-#define HV_HYPERCALL_REP_START_OFFSET 48
-#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48)
-
-/* 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_ALIGNMENT 4
-#define HV_STATUS_INVALID_PARAMETER 5
-#define HV_STATUS_INSUFFICIENT_MEMORY 11
-#define HV_STATUS_INVALID_PORT_ID 17
-#define HV_STATUS_INVALID_CONNECTION_ID 18
-#define HV_STATUS_INSUFFICIENT_BUFFERS 19
-
-/*
- * The Hyper-V TimeRefCount register and the TSC
- * page provide a guest VM clock with 100ns tick rate
- */
-#define HV_CLOCK_HZ (NSEC_PER_SEC/100)
-
-/* Define the number of synthetic interrupt sources. */
-#define HV_SYNIC_SINT_COUNT (16)
-/* Define the expected SynIC version. */
-#define HV_SYNIC_VERSION_1 (0x1)
-/* Valid SynIC vectors are 16-255. */
-#define HV_SYNIC_FIRST_VALID_VECTOR (16)
-
-#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
-#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
-#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
-#define HV_SYNIC_SINT_MASKED (1ULL << 16)
-#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
-#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
-
-#define HV_SYNIC_STIMER_COUNT (4)
-
-/* Define synthetic interrupt controller message constants. */
-#define HV_MESSAGE_SIZE (256)
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
/* Define hypervisor message types. */
enum hv_message_type {
@@ -457,76 +297,25 @@ enum hv_message_type {
HVMSG_GPA_INTERCEPT = 0x80000001,
/* Timer notification messages. */
- HVMSG_TIMER_EXPIRED = 0x80000010,
+ HVMSG_TIMER_EXPIRED = 0x80000010,
/* Error messages. */
HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
- HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
+ HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
/* Trace buffer complete messages. */
HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
/* Platform-specific processor intercept messages. */
- HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
+ HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
HVMSG_X64_MSR_INTERCEPT = 0x80010001,
- HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
+ HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
- HVMSG_X64_APIC_EOI = 0x80010004,
- HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
+ HVMSG_X64_APIC_EOI = 0x80010004,
+ HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
};
-/* Define synthetic interrupt controller message flags. */
-union hv_message_flags {
- __u8 asu8;
- struct {
- __u8 msg_pending:1;
- __u8 reserved:7;
- } __packed;
-};
-
-/* Define port identifier type. */
-union hv_port_id {
- __u32 asu32;
- struct {
- __u32 id:24;
- __u32 reserved:8;
- } __packed u;
-};
-
-/* Define synthetic interrupt controller message header. */
-struct hv_message_header {
- __u32 message_type;
- __u8 payload_size;
- union hv_message_flags message_flags;
- __u8 reserved[2];
- union {
- __u64 sender;
- union hv_port_id port;
- };
-} __packed;
-
-/* Define synthetic interrupt controller message format. */
-struct hv_message {
- struct hv_message_header header;
- union {
- __u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
- } u;
-} __packed;
-
-/* Define the synthetic interrupt message page layout. */
-struct hv_message_page {
- struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
-} __packed;
-
-/* Define timer message payload structure. */
-struct hv_timer_message_payload {
- __u32 timer_index;
- __u32 reserved;
- __u64 expiration_time; /* When the timer expired */
- __u64 delivery_time; /* When the message was delivered */
-} __packed;
-
struct hv_nested_enlightenments_control {
struct {
__u32 directhypercall:1;
@@ -754,187 +543,11 @@ struct hv_enlightened_vmcs {
#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL 0xFFFF
-/* Define synthetic interrupt controller flag constants. */
-#define HV_EVENT_FLAGS_COUNT (256 * 8)
-#define HV_EVENT_FLAGS_LONG_COUNT (256 / sizeof(unsigned long))
-
-/*
- * Synthetic timer configuration.
- */
-union hv_stimer_config {
- u64 as_uint64;
- struct {
- u64 enable:1;
- u64 periodic:1;
- u64 lazy:1;
- u64 auto_enable:1;
- u64 apic_vector:8;
- u64 direct_mode:1;
- u64 reserved_z0:3;
- u64 sintx:4;
- u64 reserved_z1:44;
- } __packed;
-};
-
-
-/* Define the synthetic interrupt controller event flags format. */
-union hv_synic_event_flags {
- unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
-};
-
-/* Define SynIC control register. */
-union hv_synic_scontrol {
- u64 as_uint64;
- struct {
- u64 enable:1;
- u64 reserved:63;
- } __packed;
-};
-
-/* Define synthetic interrupt source. */
-union hv_synic_sint {
- u64 as_uint64;
- struct {
- u64 vector:8;
- u64 reserved1:8;
- u64 masked:1;
- u64 auto_eoi:1;
- u64 polling:1;
- u64 reserved2:45;
- } __packed;
-};
-
-/* Define the format of the SIMP register */
-union hv_synic_simp {
- u64 as_uint64;
- struct {
- u64 simp_enabled:1;
- u64 preserved:11;
- u64 base_simp_gpa:52;
- } __packed;
-};
-
-/* Define the format of the SIEFP register */
-union hv_synic_siefp {
- u64 as_uint64;
- struct {
- u64 siefp_enabled:1;
- u64 preserved:11;
- u64 base_siefp_gpa:52;
- } __packed;
-};
-
-struct hv_vpset {
- u64 format;
- u64 valid_bank_mask;
- u64 bank_contents[];
-} __packed;
-
-/* HvCallSendSyntheticClusterIpi hypercall */
-struct hv_send_ipi {
- u32 vector;
- u32 reserved;
- u64 cpu_mask;
-} __packed;
-
-/* HvCallSendSyntheticClusterIpiEx hypercall */
-struct hv_send_ipi_ex {
- u32 vector;
- u32 reserved;
- struct hv_vpset vp_set;
-} __packed;
-
-/* HvFlushGuestPhysicalAddressSpace hypercalls */
-struct hv_guest_mapping_flush {
- u64 address_space;
- u64 flags;
-} __packed;
-
-/*
- * HV_MAX_FLUSH_PAGES = "additional_pages" + 1. It's limited
- * by the bitwidth of "additional_pages" in union hv_gpa_page_range.
- */
-#define HV_MAX_FLUSH_PAGES (2048)
-
-/* HvFlushGuestPhysicalAddressList hypercall */
-union hv_gpa_page_range {
- u64 address_space;
- struct {
- u64 additional_pages:11;
- u64 largepage:1;
- u64 basepfn:52;
- } page;
-};
-
-/*
- * All input flush parameters should be in single page. The max flush
- * count is equal with how many entries of union hv_gpa_page_range can
- * be populated into the input parameter page.
- */
-#define HV_MAX_FLUSH_REP_COUNT ((HV_HYP_PAGE_SIZE - 2 * sizeof(u64)) / \
- sizeof(union hv_gpa_page_range))
-
-struct hv_guest_mapping_flush_list {
- u64 address_space;
- u64 flags;
- union hv_gpa_page_range gpa_list[HV_MAX_FLUSH_REP_COUNT];
-};
-
-/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
-struct hv_tlb_flush {
- u64 address_space;
- u64 flags;
- u64 processor_mask;
- u64 gva_list[];
-} __packed;
-
-/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
-struct hv_tlb_flush_ex {
- u64 address_space;
- u64 flags;
- struct hv_vpset hv_vp_set;
- u64 gva_list[];
-} __packed;
-
struct hv_partition_assist_pg {
u32 tlb_lock_count;
};
-union hv_msi_entry {
- u64 as_uint64;
- struct {
- u32 address;
- u32 data;
- } __packed;
-};
-
-struct hv_interrupt_entry {
- u32 source; /* 1 for MSI(-X) */
- u32 reserved1;
- union hv_msi_entry msi_entry;
-} __packed;
-/*
- * flags for hv_device_interrupt_target.flags
- */
-#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1
-#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2
-
-struct hv_device_interrupt_target {
- u32 vector;
- u32 flags;
- union {
- u64 vp_mask;
- struct hv_vpset vp_set;
- };
-} __packed;
+#include <asm-generic/hyperv-tlfs.h>
-/* HvRetargetDeviceInterrupt hypercall */
-struct hv_retarget_device_interrupt {
- u64 partition_id; /* use "self" */
- u64 device_id;
- struct hv_interrupt_entry int_entry;
- u64 reserved2;
- struct hv_device_interrupt_target int_target;
-} __packed __aligned(8);
#endif
diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
new file mode 100644
index 000000000000..1f92ef92eb56
--- /dev/null
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -0,0 +1,442 @@
+/* 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_GENERIC_HYPERV_TLFS_H
+#define _ASM_GENERIC_HYPERV_TLFS_H
+
+#include <linux/types.h>
+#include <linux/bits.h>
+#include <linux/time64.h>
+
+/*
+ * While not explicitly listed in the TLFS, Hyper-V always runs with a page size
+ * of 4096. These definitions are used when communicating with Hyper-V using
+ * guest physical pages and guest physical page addresses, since the guest page
+ * size may not be 4096 on all architectures.
+ */
+#define HV_HYP_PAGE_SHIFT 12
+#define HV_HYP_PAGE_SIZE BIT(HV_HYP_PAGE_SHIFT)
+#define HV_HYP_PAGE_MASK (~(HV_HYP_PAGE_SIZE - 1))
+
+/*
+ * Hyper-V provides two categories of flags relevant to guest VMs. The
+ * "Features" category indicates specific functionality that is available
+ * to guests on this particular instance of Hyper-V. The "Features"
+ * are presented in four groups, each of which is 32 bits. The group A
+ * and B definitions are common across architectures and are listed here.
+ * However, not all flags are relevant on all architectures.
+ *
+ * Groups C and D vary across architectures and are listed in the
+ * architecture specific portion of hyperv-tlfs.h. Some of these flags exist
+ * on multiple architectures, but the bit positions are different so they
+ * cannot appear in the generic portion of hyperv-tlfs.h.
+ *
+ * The "Enlightenments" category provides recommendations on whether to use
+ * specific enlightenments that are available. The Enlighenments are a single
+ * group of 32 bits, but they vary across architectures and are listed in
+ * the architecture specific portion of hyperv-tlfs.h.
+ */
+
+/*
+ * Group A Features.
+ */
+
+/* VP Runtime register available */
+#define HV_MSR_VP_RUNTIME_AVAILABLE BIT(0)
+/* Partition Reference Counter available*/
+#define HV_MSR_TIME_REF_COUNT_AVAILABLE BIT(1)
+/* Basic SynIC register available */
+#define HV_MSR_SYNIC_AVAILABLE BIT(2)
+/* Synthetic Timer registers available */
+#define HV_MSR_SYNTIMER_AVAILABLE BIT(3)
+/* Virtual APIC assist and VP assist page registers available */
+#define HV_MSR_APIC_ACCESS_AVAILABLE BIT(4)
+/* Hypercall and Guest OS ID registers available*/
+#define HV_MSR_HYPERCALL_AVAILABLE BIT(5)
+/* Access virtual processor index register available*/
+#define HV_MSR_VP_INDEX_AVAILABLE BIT(6)
+/* Virtual system reset register available*/
+#define HV_MSR_RESET_AVAILABLE BIT(7)
+/* Access statistics page registers available */
+#define HV_MSR_STAT_PAGES_AVAILABLE BIT(8)
+/* Partition reference TSC register is available */
+#define HV_MSR_REFERENCE_TSC_AVAILABLE BIT(9)
+/* Partition Guest IDLE register is available */
+#define HV_MSR_GUEST_IDLE_AVAILABLE BIT(10)
+/* Partition local APIC and TSC frequency registers available */
+#define HV_ACCESS_FREQUENCY_MSRS BIT(11)
+/* AccessReenlightenmentControls privilege */
+#define HV_ACCESS_REENLIGHTENMENT BIT(13)
+/* AccessTscInvariantControls privilege */
+#define HV_ACCESS_TSC_INVARIANT BIT(15)
+
+/*
+ * Group B features.
+ */
+#define HV_CREATE_PARTITIONS BIT(0)
+#define HV_ACCESS_PARTITION_ID BIT(1)
+#define HV_ACCESS_MEMORY_POOL BIT(2)
+#define HV_ADJUST_MESSAGE_BUFFERS BIT(3)
+#define HV_POST_MESSAGES BIT(4)
+#define HV_SIGNAL_EVENTS BIT(5)
+#define HV_CREATE_PORT BIT(6)
+#define HV_CONNECT_PORT BIT(7)
+#define HV_ACCESS_STATS BIT(8)
+#define HV_DEBUGGING BIT(11)
+#define HV_CPU_POWER_MANAGEMENT BIT(12)
+
+
+/*
+ * TSC page layout.
+ */
+struct ms_hyperv_tsc_page {
+ volatile u32 tsc_sequence;
+ u32 reserved1;
+ volatile u64 tsc_scale;
+ volatile s64 tsc_offset;
+} __packed;
+
+/*
+ * 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 specification:
+ *
+ * msdn.microsoft.com/en-us/library/windows/hardware/ff542653%28v=vs.85%29.aspx
+ *
+ * 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
+
+/*
+ * Crash notification flags.
+ */
+#define HV_CRASH_CTL_CRASH_NOTIFY_MSG BIT_ULL(62)
+#define HV_CRASH_CTL_CRASH_NOTIFY BIT_ULL(63)
+
+/* Declare the various hypercall operations. */
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
+#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_SEND_IPI 0x000b
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
+#define HVCALL_SEND_IPI_EX 0x0015
+#define HVCALL_POST_MESSAGE 0x005c
+#define HVCALL_SIGNAL_EVENT 0x005d
+#define HVCALL_RETARGET_INTERRUPT 0x007e
+#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af
+#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_LIST 0x00b0
+
+#define HV_FLUSH_ALL_PROCESSORS BIT(0)
+#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
+#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
+#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
+
+enum HV_GENERIC_SET_FORMAT {
+ HV_GENERIC_SET_SPARSE_4K,
+ HV_GENERIC_SET_ALL,
+};
+
+#define HV_PARTITION_ID_SELF ((u64)-1)
+#define HV_VP_INDEX_SELF ((u32)-2)
+
+#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0)
+#define HV_HYPERCALL_FAST_BIT BIT(16)
+#define HV_HYPERCALL_VARHEAD_OFFSET 17
+#define HV_HYPERCALL_REP_COMP_OFFSET 32
+#define HV_HYPERCALL_REP_COMP_1 BIT_ULL(32)
+#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32)
+#define HV_HYPERCALL_REP_START_OFFSET 48
+#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48)
+
+/* 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_ALIGNMENT 4
+#define HV_STATUS_INVALID_PARAMETER 5
+#define HV_STATUS_INSUFFICIENT_MEMORY 11
+#define HV_STATUS_INVALID_PORT_ID 17
+#define HV_STATUS_INVALID_CONNECTION_ID 18
+#define HV_STATUS_INSUFFICIENT_BUFFERS 19
+
+/*
+ * The Hyper-V TimeRefCount register and the TSC
+ * page provide a guest VM clock with 100ns tick rate
+ */
+#define HV_CLOCK_HZ (NSEC_PER_SEC/100)
+
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT (16)
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1 (0x1)
+/* Valid SynIC vectors are 16-255. */
+#define HV_SYNIC_FIRST_VALID_VECTOR (16)
+
+#define HV_SYNIC_CONTROL_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIMP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SIEFP_ENABLE (1ULL << 0)
+#define HV_SYNIC_SINT_MASKED (1ULL << 16)
+#define HV_SYNIC_SINT_AUTO_EOI (1ULL << 17)
+#define HV_SYNIC_SINT_VECTOR_MASK (0xFF)
+
+#define HV_SYNIC_STIMER_COUNT (4)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE (256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+ __u8 asu8;
+ struct {
+ __u8 msg_pending:1;
+ __u8 reserved:7;
+ } __packed;
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+ __u32 asu32;
+ struct {
+ __u32 id:24;
+ __u32 reserved:8;
+ } __packed u;
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+ __u32 message_type;
+ __u8 payload_size;
+ union hv_message_flags message_flags;
+ __u8 reserved[2];
+ union {
+ __u64 sender;
+ union hv_port_id port;
+ };
+} __packed;
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+ struct hv_message_header header;
+ union {
+ __u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+ } u;
+} __packed;
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+ struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+} __packed;
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+ __u32 timer_index;
+ __u32 reserved;
+ __u64 expiration_time; /* When the timer expired */
+ __u64 delivery_time; /* When the message was delivered */
+} __packed;
+
+
+/* Define synthetic interrupt controller flag constants. */
+#define HV_EVENT_FLAGS_COUNT (256 * 8)
+#define HV_EVENT_FLAGS_LONG_COUNT (256 / sizeof(unsigned long))
+
+/*
+ * Synthetic timer configuration.
+ */
+union hv_stimer_config {
+ u64 as_uint64;
+ struct {
+ u64 enable:1;
+ u64 periodic:1;
+ u64 lazy:1;
+ u64 auto_enable:1;
+ u64 apic_vector:8;
+ u64 direct_mode:1;
+ u64 reserved_z0:3;
+ u64 sintx:4;
+ u64 reserved_z1:44;
+ } __packed;
+};
+
+
+/* Define the synthetic interrupt controller event flags format. */
+union hv_synic_event_flags {
+ unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
+};
+
+/* Define SynIC control register. */
+union hv_synic_scontrol {
+ u64 as_uint64;
+ struct {
+ u64 enable:1;
+ u64 reserved:63;
+ } __packed;
+};
+
+/* Define synthetic interrupt source. */
+union hv_synic_sint {
+ u64 as_uint64;
+ struct {
+ u64 vector:8;
+ u64 reserved1:8;
+ u64 masked:1;
+ u64 auto_eoi:1;
+ u64 polling:1;
+ u64 reserved2:45;
+ } __packed;
+};
+
+/* Define the format of the SIMP register */
+union hv_synic_simp {
+ u64 as_uint64;
+ struct {
+ u64 simp_enabled:1;
+ u64 preserved:11;
+ u64 base_simp_gpa:52;
+ } __packed;
+};
+
+/* Define the format of the SIEFP register */
+union hv_synic_siefp {
+ u64 as_uint64;
+ struct {
+ u64 siefp_enabled:1;
+ u64 preserved:11;
+ u64 base_siefp_gpa:52;
+ } __packed;
+};
+
+struct hv_vpset {
+ u64 format;
+ u64 valid_bank_mask;
+ u64 bank_contents[];
+} __packed;
+
+/* HvCallSendSyntheticClusterIpi hypercall */
+struct hv_send_ipi {
+ u32 vector;
+ u32 reserved;
+ u64 cpu_mask;
+} __packed;
+
+/* HvCallSendSyntheticClusterIpiEx hypercall */
+struct hv_send_ipi_ex {
+ u32 vector;
+ u32 reserved;
+ struct hv_vpset vp_set;
+} __packed;
+
+/* HvFlushGuestPhysicalAddressSpace hypercalls */
+struct hv_guest_mapping_flush {
+ u64 address_space;
+ u64 flags;
+} __packed;
+
+/*
+ * HV_MAX_FLUSH_PAGES = "additional_pages" + 1. It's limited
+ * by the bitwidth of "additional_pages" in union hv_gpa_page_range.
+ */
+#define HV_MAX_FLUSH_PAGES (2048)
+
+/* HvFlushGuestPhysicalAddressList hypercall */
+union hv_gpa_page_range {
+ u64 address_space;
+ struct {
+ u64 additional_pages:11;
+ u64 largepage:1;
+ u64 basepfn:52;
+ } page;
+};
+
+/*
+ * All input flush parameters should be in single page. The max flush
+ * count is equal with how many entries of union hv_gpa_page_range can
+ * be populated into the input parameter page.
+ */
+#define HV_MAX_FLUSH_REP_COUNT ((HV_HYP_PAGE_SIZE - 2 * sizeof(u64)) / \
+ sizeof(union hv_gpa_page_range))
+
+struct hv_guest_mapping_flush_list {
+ u64 address_space;
+ u64 flags;
+ union hv_gpa_page_range gpa_list[HV_MAX_FLUSH_REP_COUNT];
+};
+
+/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
+struct hv_tlb_flush {
+ u64 address_space;
+ u64 flags;
+ u64 processor_mask;
+ u64 gva_list[];
+} __packed;
+
+/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */
+struct hv_tlb_flush_ex {
+ u64 address_space;
+ u64 flags;
+ struct hv_vpset hv_vp_set;
+ u64 gva_list[];
+} __packed;
+
+/* HvRetargetDeviceInterrupt hypercall */
+union hv_msi_entry {
+ u64 as_uint64;
+ struct {
+ u32 address;
+ u32 data;
+ } __packed;
+};
+
+struct hv_interrupt_entry {
+ u32 source; /* 1 for MSI(-X) */
+ u32 reserved1;
+ union hv_msi_entry msi_entry;
+} __packed;
+
+/*
+ * flags for hv_device_interrupt_target.flags
+ */
+#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1
+#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2
+
+struct hv_device_interrupt_target {
+ u32 vector;
+ u32 flags;
+ union {
+ u64 vp_mask;
+ struct hv_vpset vp_set;
+ };
+} __packed;
+
+struct hv_retarget_device_interrupt {
+ u64 partition_id; /* use "self" */
+ u64 device_id;
+ struct hv_interrupt_entry int_entry;
+ u64 reserved2;
+ struct hv_device_interrupt_target int_target;
+} __packed __aligned(8);
+
+#endif
--
2.18.2
^ permalink raw reply related
* [PATCH v2 4/4] asm-generic/hyperv: Add definitions for Get/SetVpRegister hypercalls
From: Michael Kelley @ 2020-04-22 19:57 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86, hpa,
pbonzini, sean.j.christopherson, vkuznets, wanpengli, jmattson,
joro, kvm, linux-kernel, linux-hyperv
Cc: mikelley
In-Reply-To: <20200422195737.10223-1-mikelley@microsoft.com>
Add definitions for GetVpRegister and SetVpRegister hypercalls, which
are implemented for both x86 and ARM64.
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
include/asm-generic/hyperv-tlfs.h | 51 +++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
index 1f92ef92eb56..262fae9526b1 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -141,6 +141,8 @@ struct ms_hyperv_tsc_page {
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
#define HVCALL_SEND_IPI_EX 0x0015
+#define HVCALL_GET_VP_REGISTERS 0x0050
+#define HVCALL_SET_VP_REGISTERS 0x0051
#define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d
#define HVCALL_RETARGET_INTERRUPT 0x007e
@@ -439,4 +441,53 @@ struct hv_retarget_device_interrupt {
struct hv_device_interrupt_target int_target;
} __packed __aligned(8);
+
+/* HvGetVpRegisters hypercall input with variable size reg name list*/
+struct hv_get_vp_registers_input {
+ struct {
+ u64 partitionid;
+ u32 vpindex;
+ u8 inputvtl;
+ u8 padding[3];
+ } header;
+ struct input {
+ u32 name0;
+ u32 name1;
+ } element[];
+} __packed;
+
+
+/* HvGetVpRegisters returns an array of these output elements */
+struct hv_get_vp_registers_output {
+ union {
+ struct {
+ u32 a;
+ u32 b;
+ u32 c;
+ u32 d;
+ } as32 __packed;
+ struct {
+ u64 low;
+ u64 high;
+ } as64 __packed;
+ };
+};
+
+/* HvSetVpRegisters hypercall with variable size reg name/value list*/
+struct hv_set_vp_registers_input {
+ struct {
+ u64 partitionid;
+ u32 vpindex;
+ u8 inputvtl;
+ u8 padding[3];
+ } header;
+ struct {
+ u32 name;
+ u32 padding1;
+ u64 padding2;
+ u64 valuelow;
+ u64 valuehigh;
+ } element[];
+} __packed;
+
#endif
--
2.18.2
^ permalink raw reply related
* [PATCH v2 2/4] x86/hyperv: Remove HV_PROCESSOR_POWER_STATE #defines
From: Michael Kelley @ 2020-04-22 19:57 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86, hpa,
pbonzini, sean.j.christopherson, vkuznets, wanpengli, jmattson,
joro, kvm, linux-kernel, linux-hyperv
Cc: mikelley
In-Reply-To: <20200422195737.10223-1-mikelley@microsoft.com>
The HV_PROCESSOR_POWER_STATE_C<n> #defines date back to year 2010,
but they are not in the TLFS v6.0 document and are not used anywhere
in Linux. Remove them.
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
---
arch/x86/include/asm/hyperv-tlfs.h | 5 -----
1 file changed, 5 deletions(-)
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 0e4d76920957..2dd1ceb2bcf8 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -390,11 +390,6 @@ struct hv_tsc_emulation_status {
#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001
#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12
-#define HV_PROCESSOR_POWER_STATE_C0 0
-#define HV_PROCESSOR_POWER_STATE_C1 1
-#define HV_PROCESSOR_POWER_STATE_C2 2
-#define HV_PROCESSOR_POWER_STATE_C3 3
-
#define HV_FLUSH_ALL_PROCESSORS BIT(0)
#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
--
2.18.2
^ permalink raw reply related
* [PATCH v2 0/4] Split hyperv-tlfs.h into generic and arch specific files
From: Michael Kelley @ 2020-04-22 19:57 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86, hpa,
pbonzini, sean.j.christopherson, vkuznets, wanpengli, jmattson,
joro, kvm, linux-kernel, linux-hyperv
Cc: mikelley
This series splits hyperv-tlfs.h into architecture independent and
architecture specific files so that the arch independent portion can
be shared between the x86/x64 and ARM64 code for Hyper-V. While the
Hyper-V team has not released a version of the TLFS document that
clearly specifies which portions of the interface are arch independent,
we can make a fairly good assessment based on implementation work done
to support Linux guests on Hyper-V on ARM64, and on private communication
with the Hyper-V team. Definitions are considered arch independent if
they are implemented by Hyper-V on both architectures (x86/x64 and ARM64),
even if they are currently needed by Linux code only on one architecture.
Many definitions in hyperv-tlfs.h have historically contained "X64" in the
name, which doesn't make sense for architecture independent definitions.
While many of the occurrences of "X64" have already been removed, some
still remain in definitions that should be arch independent. The
split removes the "X64" from the definitions so that the arch
independent hyper-tlfs.h has no occurrences of "X64". However, to
keep this patch set separate from a wider change in the names, aliases
are added in the x86/x64 specific hyperv-tlfs.h so that existing code
continues to compile. The definitions can be fixed throughout the code
in a more incremental fashion in separate patches, and then the aliases
can be removed.
Where it is not clear if definitions are arch independent, they have been
kept in the x86/x64 specific file. The Hyper-V team is aiming to have a
version of the TLFS document covering ARM64 by the end of calendar 2020,
so additional definitions may be moved into the arch independent portion
after the new TLFS document is released.
The first two patches in the series clean up the existing hyperv-tlfs.h
file a bit by removing duplicate or unnecessary definitions so they are
not propagated across the split. The third patch does the split, and the
fourth patch adds new definitions that are needed on ARM64 but are generic.
These changes have no functional impact.
These patches are built against linux-next-20200415
---
Changes in v2:
* Improved definitions for Get/SetVpRegisters hypercalls in
include/asm-generic/hyperv-tlfs.h in Patch 4 [Vitaly Kuznetsov]
* Updated MAINTAINERS with new file in Patch 3
Michael Kelley (4):
KVM: x86: hyperv: Remove duplicate definitions of Reference TSC Page
x86/hyperv: Remove HV_PROCESSOR_POWER_STATE #defines
x86/hyperv: Split hyperv-tlfs.h into arch dependent and independent
files
asm-generic/hyperv: Add definitions for Get/SetVpRegister hypercalls
MAINTAINERS | 1 +
arch/x86/include/asm/hyperv-tlfs.h | 472 +++------------------------
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/hyperv.c | 4 +-
include/asm-generic/hyperv-tlfs.h | 493 +++++++++++++++++++++++++++++
5 files changed, 533 insertions(+), 439 deletions(-)
create mode 100644 include/asm-generic/hyperv-tlfs.h
--
2.18.2
^ permalink raw reply
* [PATCH v2 1/4] KVM: x86: hyperv: Remove duplicate definitions of Reference TSC Page
From: Michael Kelley @ 2020-04-22 19:57 UTC (permalink / raw)
To: kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86, hpa,
pbonzini, sean.j.christopherson, vkuznets, wanpengli, jmattson,
joro, kvm, linux-kernel, linux-hyperv
Cc: mikelley
In-Reply-To: <20200422195737.10223-1-mikelley@microsoft.com>
The Hyper-V Reference TSC Page structure is defined twice. struct
ms_hyperv_tsc_page has padding out to a full 4 Kbyte page size. But
the padding is not needed because the declaration includes a union
with HV_HYP_PAGE_SIZE. KVM uses the second definition, which is
struct _HV_REFERENCE_TSC_PAGE, because it does not have the padding.
Fix the duplication by removing the padding from ms_hyperv_tsc_page.
Fix up the KVM code to use it. Remove the no longer used struct
_HV_REFERENCE_TSC_PAGE.
There is no functional change.
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
arch/x86/include/asm/hyperv-tlfs.h | 8 --------
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/hyperv.c | 4 ++--
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 29336574d0bc..0e4d76920957 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -303,7 +303,6 @@ struct ms_hyperv_tsc_page {
u32 reserved1;
volatile u64 tsc_scale;
volatile s64 tsc_offset;
- u64 reserved2[509];
} __packed;
/*
@@ -433,13 +432,6 @@ enum HV_GENERIC_SET_FORMAT {
*/
#define HV_CLOCK_HZ (NSEC_PER_SEC/100)
-typedef struct _HV_REFERENCE_TSC_PAGE {
- __u32 tsc_sequence;
- __u32 res1;
- __u64 tsc_scale;
- __s64 tsc_offset;
-} __packed HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
-
/* Define the number of synthetic interrupt sources. */
#define HV_SYNIC_SINT_COUNT (16)
/* Define the expected SynIC version. */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 42a2d0d3984a..4698343b9a05 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -865,7 +865,7 @@ struct kvm_hv {
u64 hv_crash_param[HV_X64_MSR_CRASH_PARAMS];
u64 hv_crash_ctl;
- HV_REFERENCE_TSC_PAGE tsc_ref;
+ struct ms_hyperv_tsc_page tsc_ref;
struct idr conn_to_evt;
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index bcefa9d4e57e..1f3c6fd3cdaa 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -900,7 +900,7 @@ static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
* These two equivalencies are implemented in this function.
*/
static bool compute_tsc_page_parameters(struct pvclock_vcpu_time_info *hv_clock,
- HV_REFERENCE_TSC_PAGE *tsc_ref)
+ struct ms_hyperv_tsc_page *tsc_ref)
{
u64 max_mul;
@@ -941,7 +941,7 @@ void kvm_hv_setup_tsc_page(struct kvm *kvm,
u64 gfn;
BUILD_BUG_ON(sizeof(tsc_seq) != sizeof(hv->tsc_ref.tsc_sequence));
- BUILD_BUG_ON(offsetof(HV_REFERENCE_TSC_PAGE, tsc_sequence) != 0);
+ BUILD_BUG_ON(offsetof(struct ms_hyperv_tsc_page, tsc_sequence) != 0);
if (!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE))
return;
--
2.18.2
^ permalink raw reply related
* RE: [PATCH 4/4] asm-generic/hyperv: Add definitions for Get/SetVpRegister hypercalls
From: Michael Kelley @ 2020-04-22 20:04 UTC (permalink / raw)
To: vkuznets
Cc: KY Srinivasan, Haiyang Zhang, Stephen Hemminger,
wei.liu@kernel.org, tglx@linutronix.de, mingo@redhat.com,
bp@alien8.de, x86@kernel.org, hpa@zytor.com, pbonzini@redhat.com,
sean.j.christopherson@intel.com, wanpengli@tencent.com,
jmattson@google.com, joro@8bytes.org, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org
In-Reply-To: <MW2PR2101MB1052EF4972CDCF9BF2B0356AD7D50@MW2PR2101MB1052.namprd21.prod.outlook.com>
From: Michael Kelley Sent: Tuesday, April 21, 2020 8:50 AM
>
> From: Vitaly Kuznetsov <vkuznets@redhat.com> Sent: Tuesday, April 21, 2020 6:03 AM
> >
> > Michael Kelley <mikelley@microsoft.com> writes:
> >
> > > Add definitions for GetVpRegister and SetVpRegister hypercalls, which
> > > are implemented for both x86 and ARM64.
> > >
> > > Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> > > ---
> > > include/asm-generic/hyperv-tlfs.h | 28 ++++++++++++++++++++++++++++
> > > 1 file changed, 28 insertions(+)
> > >
> > > diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
> > > index 1f92ef92eb56..29b60f5b6323 100644
> > > --- a/include/asm-generic/hyperv-tlfs.h
> > > +++ b/include/asm-generic/hyperv-tlfs.h
> > > @@ -141,6 +141,8 @@ struct ms_hyperv_tsc_page {
> > > #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
> > > #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
> > > #define HVCALL_SEND_IPI_EX 0x0015
> > > +#define HVCALL_GET_VP_REGISTERS 0x0050
> > > +#define HVCALL_SET_VP_REGISTERS 0x0051
> > > #define HVCALL_POST_MESSAGE 0x005c
> > > #define HVCALL_SIGNAL_EVENT 0x005d
> > > #define HVCALL_RETARGET_INTERRUPT 0x007e
> > > @@ -439,4 +441,30 @@ struct hv_retarget_device_interrupt {
> > > struct hv_device_interrupt_target int_target;
> > > } __packed __aligned(8);
> > >
> > > +
> > > +/* HvGetVPRegister hypercall */
> >
> > Nit: 'HvGetVpRegisters' in TLFS
> >
> > > +struct hv_get_vp_register_input {
> >
> > Nit: I would also to name it 'hv_get_vp_registers_input' (plural, like
> > the hypercall).
> >
> > > + u64 partitionid;
> > > + u32 vpindex;
> > > + u8 inputvtl;
> > > + u8 padding[3];
> > > + u32 name0;
> > > + u32 name1;
> > > +} __packed;
> >
> > Isn't it a REP hypercall where we can we can pass a list? In that case
> > this should look like
> >
> > struct hv_get_vp_registers_input {
> > struct {
> > u64 partitionid;
> > u32 vpindex;
> > u8 inputvtl;
> > u8 padding[3];
> > } header;
> > struct {
> > u32 name0;
> > u32 name1;
> > } elem[];
> > } __packed;
> >
> > > +
> > > +struct hv_get_vp_register_output {
> >
> > Ditto.
I've sent out a new version, but didn't change
hv_get_vp_register_output except to make
it hv_get_vp_registers_output. The C compiler
wont' let me put a variable size array as the
only field in the struct.
> >
> > > + union {
> > > + struct {
> > > + u32 a;
> > > + u32 b;
> > > + u32 c;
> > > + u32 d;
> > > + } as32 __packed;
> > > + struct {
> > > + u64 low;
> > > + u64 high;
> > > + } as64 __packed;
> > > + };
> > > +};
> >
> > I'm wondering why you define both
> > HVCALL_GET_VP_REGISTERS/HVCALL_SET_VP_REGISTERS but only add 'struct
> > hv_get_vp_register_input' and not 'struct hv_set_vp_register_input'.
> >
> > The later should look similar, AFAIU it is:
> >
> > struct hv_set_vp_registers_input {
> > struct {
> > u64 partitionid;
> > u32 vpindex;
> > u8 inputvtl;
> > u8 padding[3];
> > } header;
> > struct {
> > u32 name;
> > u32 padding1;
> > u64 padding2; //not sure this is not a mistake in TLFS
The additional padding is not a mistake. Hyper-V wants
the register value to be aligned to 128 bits even though
it is described in the TLFS document as two 64 bit fields.
> > u64 regvallow;
> > u64 regvalhigh;
> > } elem[];
> > } __packed;
> >
> > > +
> > > #endif
> >
Michael
^ permalink raw reply
* RE: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Dexuan Cui @ 2020-04-23 7:04 UTC (permalink / raw)
To: Bart Van Assche, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <c55d643c-c13f-70f1-7a44-608f94fbfd5f@acm.org>
> From: Bart Van Assche <bvanassche@acm.org>
> Sent: Wednesday, April 22, 2020 12:56 PM
> On 4/21/20 11:24 PM, Dexuan Cui wrote:
> > Upon suspend, I suppose the other LLDs can not accept I/O either, then
> > what do they do when some kernel thread still tries to submit I/O? Do
> > they "block" the I/O until resume, or just return an error immediately?
>
> This is my understanding of how other SCSI LLDs handle suspend/resume:
> - The ULP driver, e.g. the SCSI sd driver, implements power management
> support by providing callbacks in struct scsi_driver.gendrv.pm and also
> in scsi_bus_type.pm. The SCSI sd suspend callbacks flush the device
> cache and send a STOP command to the device.
It looks the sd suspend callbacks are only for the I/O from the disk, e.g.
from the file system that lives in some partition of some disk.
The panic I'm seeing is not from sd. I think it's from a kernel thread
that tries to detect the status of the SCSI CDROM. This is the snipped
messages (the full version is at https://lkml.org/lkml/2020/4/10/47): here
the suspend callbacks of the sd, sr and scsi_bus_type.pm have been called,
and later the storvsc LLD's suspend callback is also called, but
sr_block_check_events() can still try to submit SCSI commands to storvsc:
[ 11.668741] sr 0:0:0:1: bus quiesce
[ 11.668804] sd 0:0:0:0: bus quiesce
[ 11.698082] scsi target0:0:0: bus quiesce
[ 11.703296] scsi host0: bus quiesce
[ 11.781730] hv_storvsc bf78936f-7d8f-45ce-ab03-6c341452e55d: noirq bus quiesce
[ 11.796479] hv_netvsc dda5a2be-b8b8-4237-b330-be8a516a72c0: noirq bus quiesce
[ 11.804042] BUG: kernel NULL pointer dereference, address: 0000000000000090
[ 11.804996] Workqueue: events_freezable_power_ disk_events_workfn
[ 11.804996] RIP: 0010:storvsc_queuecommand+0x261/0x714 [hv_storvsc]
[ 11.804996] Call Trace:
[ 11.804996] scsi_queue_rq+0x593/0xa10
[ 11.804996] blk_mq_dispatch_rq_list+0x8d/0x510
[ 11.804996] blk_mq_sched_dispatch_requests+0xed/0x170
[ 11.804996] __blk_mq_run_hw_queue+0x55/0x110
[ 11.804996] __blk_mq_delay_run_hw_queue+0x141/0x160
[ 11.804996] blk_mq_sched_insert_request+0xc3/0x170
[ 11.804996] blk_execute_rq+0x4b/0xa0
[ 11.804996] __scsi_execute+0xeb/0x250
[ 11.804996] sr_check_events+0x9f/0x270 [sr_mod]
[ 11.804996] cdrom_check_events+0x1a/0x30 [cdrom]
[ 11.804996] sr_block_check_events+0xcc/0x110 [sr_mod]
[ 11.804996] disk_check_events+0x68/0x160
[ 11.804996] process_one_work+0x20c/0x3d0
[ 11.804996] worker_thread+0x2d/0x3e0
[ 11.804996] kthread+0x10c/0x130
[ 11.804996] ret_from_fork+0x35/0x40
It looks the issue is: scsi_bus_freeze() -> ... -> scsi_dev_type_suspend ->
scsi_device_quiesce() does not guarantee the device is totally quiescent:
/**
* scsi_device_quiesce - Block user issued commands.
* @sdev: scsi device to quiesce.
*
* This works by trying to transition to the SDEV_QUIESCE state
* (which must be a legal transition). When the device is in this
* state, only special requests will be accepted, all others will
* be deferred. Since special requests may also be requeued requests,
* a successful return doesn't guarantee the device will be
* totally quiescent.
I guess the "special requests" may include the "detect the status of the
SCSI CDROM" request from sr_block_check_events().
It looks scsi_device_quiesce() does not freeze the queue and it just puts the
device to the SDEV_QUIESCE state, which is not enough to prevent
sr_block_check_events from submitting SCSI commands.
It looks scsi_host_block() freezes the queue and flushes all the pending I/O,
so it can fix the aforementioned NULL pointer deference panic for me.
> - SCSI LLDs for PCIe devices optionally provide pci_driver.suspend and
> resume callbacks. These callbacks can be used to make the PCIe device
> enter/leave a power saving state. No new SCSI commands should be
> submitted after pci_driver.suspend has been called.
>
> > I had a look at drivers/scsi/xen-scsifront.c. It looks this LLD implements
> > a mechanism of marking the device busy upon suspend, so any I/O will
> > immediately get an error SCSI_MLQUEUE_HOST_BUSY. IMO the
> > disadvantage is: the mechanism of marking the device busy looks
> > complex, and the hot path .queuecommand() has to take the
> > spinlock shost->host_lock, which should affect the performance.
>
> I think the code you are referring to is the code in
> scsifront_suspend(). A pointer to that function is stored in a struct
> xenbus_driver instance. That's another structure than the structures
> mentioned above.
>
> Wouldn't it be better to make sure that any hypervisor suspend
> operations happen after it is guaranteed that no further SCSI commands
> will be submitted such that hypervisor suspend operations do not have to
> deal with SCSI commands submitted during or after the hypervisor suspend
> callback?
I agree with you, but it looks scsi_bus_freeze() doesn't guarantee no
further SCSI commands will be submitted, as I described above. Maybe that
is why scsifront_suspend() has to invent a mechanism to cope with the issue.
> > It looks drivers/scsi/nsp32.c: nsp32_suspend() and
> > drivers/scsi/3w-9xxx.c: twa_suspend() do nothing to handle new I/O
> > after suspend. I doubt this is correct.
>
> nsp32_suspend() is a PCI suspend callback. If any SCSI commands would be
> submitted after that callback has started that would mean that the SCSI
> suspend and PCIe suspend operations are called in the wrong order. I do
> not agree that code for suspending SCSI commands should be added in
> nsp32_suspend().
>
> > So it looks to me there is no simple mechanism to handle the scenario
> > here, and I guess that's why the scsi_host_block/unblock APIs are
> > introduced, and actually there is already an user of the APIs:
> > 3d3ca53b1639 ("scsi: aacraid: use scsi_host_(block,unblock) to block I/O").
> >
> > The aacraid patch says: "This has the advantage that the block layer will
> > stop sending I/O to the adapter instead of having the SCSI midlayer
> > requeueing I/O internally". It looks this may imply that using the new
> > APIs is encouraged?
>
> I'm fine with using these new functions in device reset handlers. Using
> these functions in power management handlers seems wrong to me.
It looks you're suggesting the scsi_host_block() in aac_suspend() should
be removed? :-)
> > PS, here storvsc has to destroy and re-construct the I/O queues: the
> > I/O queues are shared memory ringbufers between the guest and the
> > host; in the resume path of the hibernation procedure, the memory
> > pages allocated by the 'new' kernel is different from that allocated by
> > the 'old' kernel, so before jumping to the 'old' kernel, the 'new' kernel
> > must destroy the mapping of the pages, and later after we jump to
> > the 'old' kernel, we'll re-create the mapping using the pages allocated
> > by the 'old' kernel. Here "create the mapping" means the guest tells
> > the host about the physical addresses of the pages.
>
> Thank you for having clarified this. This helps me to understand the HV
> driver framework better. I think this means that the hv_driver.suspend
> function should be called at a later time than SCSI suspend. From
I agree, but it looks here scsi_bus_freeze() doesn't work as we expected?
> Documentation/driver-api/device_link.rst: "By default, the driver core
> only enforces dependencies between devices that are borne out of a
> parent/child relationship within the device hierarchy: When suspending,
> resuming or shutting down the system, devices are ordered based on this
> relationship, i.e. children are always suspended before their parent,
> and the parent is always resumed before its children." Is there a single
> storvsc_drv instance for all SCSI devices supported by storvsc_drv? Has
Yes.
> it been considered to make storvsc_drv the parent device of all SCSI
> devices created by the storvsc driver?
>
> Thanks,
>
> Bart.
Yes, I think so:
root@localhost:~# ls -rtl /sys/bus/vmbus/devices/9be03cb2-d37b-409f-b09b-81059b4f6943/host3/target3:0:0/3:0:0:0/driver
lrwxrwxrwx 1 root root 0 Apr 22 01:10 /sys/bus/vmbus/devices/9be03cb2-d37b-409f-b09b-81059b4f6943/host3/target3:0:0/3:0:0:0/driver -> ../../../../../../../../../../bus/scsi/drivers/sd
Here the driver of /sys/bus/vmbus/devices/9be03cb2-d37b-409f-b09b-81059b4f6943
is storvsc, which creates host3/target3:0:0/3:0:0:0.
So it looks there is no ordering issue.
Thanks,
-- Dexuan
^ permalink raw reply
* Re: [PATCH v2 4/4] asm-generic/hyperv: Add definitions for Get/SetVpRegister hypercalls
From: Vitaly Kuznetsov @ 2020-04-23 9:46 UTC (permalink / raw)
To: Michael Kelley
Cc: mikelley, kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86,
hpa, pbonzini, sean.j.christopherson, wanpengli, jmattson, joro,
kvm, linux-kernel, linux-hyperv
In-Reply-To: <20200422195737.10223-5-mikelley@microsoft.com>
Michael Kelley <mikelley@microsoft.com> writes:
> Add definitions for GetVpRegister and SetVpRegister hypercalls, which
> are implemented for both x86 and ARM64.
>
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> ---
> include/asm-generic/hyperv-tlfs.h | 51 +++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
> index 1f92ef92eb56..262fae9526b1 100644
> --- a/include/asm-generic/hyperv-tlfs.h
> +++ b/include/asm-generic/hyperv-tlfs.h
> @@ -141,6 +141,8 @@ struct ms_hyperv_tsc_page {
> #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
> #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
> #define HVCALL_SEND_IPI_EX 0x0015
> +#define HVCALL_GET_VP_REGISTERS 0x0050
> +#define HVCALL_SET_VP_REGISTERS 0x0051
> #define HVCALL_POST_MESSAGE 0x005c
> #define HVCALL_SIGNAL_EVENT 0x005d
> #define HVCALL_RETARGET_INTERRUPT 0x007e
> @@ -439,4 +441,53 @@ struct hv_retarget_device_interrupt {
> struct hv_device_interrupt_target int_target;
> } __packed __aligned(8);
>
> +
> +/* HvGetVpRegisters hypercall input with variable size reg name list*/
> +struct hv_get_vp_registers_input {
> + struct {
> + u64 partitionid;
> + u32 vpindex;
> + u8 inputvtl;
> + u8 padding[3];
> + } header;
> + struct input {
> + u32 name0;
> + u32 name1;
> + } element[];
> +} __packed;
> +
> +
> +/* HvGetVpRegisters returns an array of these output elements */
> +struct hv_get_vp_registers_output {
> + union {
> + struct {
> + u32 a;
> + u32 b;
> + u32 c;
> + u32 d;
> + } as32 __packed;
> + struct {
> + u64 low;
> + u64 high;
> + } as64 __packed;
> + };
> +};
> +
> +/* HvSetVpRegisters hypercall with variable size reg name/value list*/
> +struct hv_set_vp_registers_input {
> + struct {
> + u64 partitionid;
> + u32 vpindex;
> + u8 inputvtl;
> + u8 padding[3];
> + } header;
> + struct {
> + u32 name;
> + u32 padding1;
> + u64 padding2;
> + u64 valuelow;
> + u64 valuehigh;
> + } element[];
> +} __packed;
> +
> #endif
Thank you for making these changes,
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
--
Vitaly
^ permalink raw reply
* Re: [PATCH 04/29] staging: media: ipu3: use vmap instead of reimplementing it
From: Sakari Ailus @ 2020-04-23 10:32 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Andrew Morton, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
Wei Liu, x86, David Airlie, Daniel Vetter, Laura Abbott,
Sumit Semwal, Minchan Kim, Nitin Gupta, Robin Murphy,
Christophe Leroy, Peter Zijlstra, linuxppc-dev, linux-hyperv,
dri-devel, linaro-mm-sig, linux-arch, linux-mm, iommu,
linux-arm-kernel, linux-s390, bpf, linux-kernel
In-Reply-To: <20200414131348.444715-5-hch@lst.de>
On Tue, Apr 14, 2020 at 03:13:23PM +0200, Christoph Hellwig wrote:
> Just use vmap instead of messing with vmalloc internals.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Thanks!
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
--
Sakari Ailus
^ permalink raw reply
* Re: [PATCH v2 0/4] Split hyperv-tlfs.h into generic and arch specific files
From: Wei Liu @ 2020-04-23 13:22 UTC (permalink / raw)
To: Michael Kelley
Cc: kys, haiyangz, sthemmin, wei.liu, tglx, mingo, bp, x86, hpa,
pbonzini, sean.j.christopherson, vkuznets, wanpengli, jmattson,
joro, kvm, linux-kernel, linux-hyperv
In-Reply-To: <20200422195737.10223-1-mikelley@microsoft.com>
On Wed, Apr 22, 2020 at 12:57:33PM -0700, Michael Kelley wrote:
> This series splits hyperv-tlfs.h into architecture independent and
> architecture specific files so that the arch independent portion can
> be shared between the x86/x64 and ARM64 code for Hyper-V. While the
> Hyper-V team has not released a version of the TLFS document that
> clearly specifies which portions of the interface are arch independent,
> we can make a fairly good assessment based on implementation work done
> to support Linux guests on Hyper-V on ARM64, and on private communication
> with the Hyper-V team. Definitions are considered arch independent if
> they are implemented by Hyper-V on both architectures (x86/x64 and ARM64),
> even if they are currently needed by Linux code only on one architecture.
>
> Many definitions in hyperv-tlfs.h have historically contained "X64" in the
> name, which doesn't make sense for architecture independent definitions.
> While many of the occurrences of "X64" have already been removed, some
> still remain in definitions that should be arch independent. The
> split removes the "X64" from the definitions so that the arch
> independent hyper-tlfs.h has no occurrences of "X64". However, to
> keep this patch set separate from a wider change in the names, aliases
> are added in the x86/x64 specific hyperv-tlfs.h so that existing code
> continues to compile. The definitions can be fixed throughout the code
> in a more incremental fashion in separate patches, and then the aliases
> can be removed.
>
> Where it is not clear if definitions are arch independent, they have been
> kept in the x86/x64 specific file. The Hyper-V team is aiming to have a
> version of the TLFS document covering ARM64 by the end of calendar 2020,
> so additional definitions may be moved into the arch independent portion
> after the new TLFS document is released.
>
> The first two patches in the series clean up the existing hyperv-tlfs.h
> file a bit by removing duplicate or unnecessary definitions so they are
> not propagated across the split. The third patch does the split, and the
> fourth patch adds new definitions that are needed on ARM64 but are generic.
>
> These changes have no functional impact.
>
> These patches are built against linux-next-20200415
Applied to hyperv-next. Thanks.
Wei.
^ permalink raw reply
* [PATCH v1 2/4] hyper-v: Supply GUID pointer to printf() like functions
From: Andy Shevchenko @ 2020-04-23 13:45 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger, Wei Liu,
linux-hyperv
Cc: Andy Shevchenko
In-Reply-To: <20200423134505.78221-1-andriy.shevchenko@linux.intel.com>
Drop dereference when printing the GUID with printf() like functions.
This allows to hide the uuid_t internals.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/hv/vmbus_drv.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 84c9985d83918c..3d03a26216b7b8 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -201,7 +201,7 @@ static ssize_t class_id_show(struct device *dev,
if (!hv_dev->channel)
return -ENODEV;
return sprintf(buf, "{%pUl}\n",
- hv_dev->channel->offermsg.offer.if_type.b);
+ &hv_dev->channel->offermsg.offer.if_type);
}
static DEVICE_ATTR_RO(class_id);
@@ -213,7 +213,7 @@ static ssize_t device_id_show(struct device *dev,
if (!hv_dev->channel)
return -ENODEV;
return sprintf(buf, "{%pUl}\n",
- hv_dev->channel->offermsg.offer.if_instance.b);
+ &hv_dev->channel->offermsg.offer.if_instance);
}
static DEVICE_ATTR_RO(device_id);
@@ -2005,7 +2005,7 @@ int vmbus_device_register(struct hv_device *child_device_obj)
int ret;
dev_set_name(&child_device_obj->device, "%pUl",
- child_device_obj->channel->offermsg.offer.if_instance.b);
+ &child_device_obj->channel->offermsg.offer.if_instance);
child_device_obj->device.bus = &hv_bus;
child_device_obj->device.parent = &hv_acpi_dev->dev;
--
2.26.1
^ permalink raw reply related
* [PATCH v1 4/4] hyper-v: Switch to use UUID types directly
From: Andy Shevchenko @ 2020-04-23 13:45 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger, Wei Liu,
linux-hyperv
Cc: Andy Shevchenko
In-Reply-To: <20200423134505.78221-1-andriy.shevchenko@linux.intel.com>
uuid_le is an alias for guid_t and is going to be removed in the future.
Replace it with original type.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
include/linux/mod_devicetable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 4b3d0a4945dfc6..c97195fe865852 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -434,7 +434,7 @@ struct virtio_device_id {
* For Hyper-V devices we use the device guid as the id.
*/
struct hv_vmbus_device_id {
- uuid_le guid;
+ guid_t guid;
kernel_ulong_t driver_data; /* Data private to the driver */
};
--
2.26.1
^ permalink raw reply related
* [PATCH v1 1/4] hyper-v: Use UUID API for exporting the GUID (part 2)
From: Andy Shevchenko @ 2020-04-23 13:45 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger, Wei Liu,
linux-hyperv
Cc: Andy Shevchenko
This is a follow up to the commit 1d3c9c075462
("hyper-v: Use UUID API for exporting the GUID")
which starts the conversion.
There is export_guid() function which exports guid_t to the u8 array.
Use it instead of open coding variant.
This allows to hide the uuid_t internals.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/hv/hv_trace.h | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/hv/hv_trace.h b/drivers/hv/hv_trace.h
index 579d19bdc0981b..6063bb21bb1371 100644
--- a/drivers/hv/hv_trace.h
+++ b/drivers/hv/hv_trace.h
@@ -44,10 +44,8 @@ TRACE_EVENT(vmbus_onoffer,
__entry->monitorid = offer->monitorid;
__entry->is_ddc_int = offer->is_dedicated_interrupt;
__entry->connection_id = offer->connection_id;
- memcpy(__entry->if_type,
- &offer->offer.if_type.b, 16);
- memcpy(__entry->if_instance,
- &offer->offer.if_instance.b, 16);
+ export_guid(__entry->if_type, &offer->offer.if_type);
+ export_guid(__entry->if_instance, &offer->offer.if_instance);
__entry->chn_flags = offer->offer.chn_flags;
__entry->mmio_mb = offer->offer.mmio_megabytes;
__entry->sub_idx = offer->offer.sub_channel_index;
--
2.26.1
^ permalink raw reply related
* [PATCH v1 3/4] hyper-v: Replace open-coded variant of %*phN specifier
From: Andy Shevchenko @ 2020-04-23 13:45 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger, Wei Liu,
linux-hyperv
Cc: Andy Shevchenko
In-Reply-To: <20200423134505.78221-1-andriy.shevchenko@linux.intel.com>
printf() like functions in the kernel have extensions, such as
%*phN to dump small pieces of memory as hex values.
Replace print_alias_name() with the direct use of %*phN.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/hv/vmbus_drv.c | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 3d03a26216b7b8..8651c58e892230 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -117,14 +117,6 @@ static int vmbus_exists(void)
return 0;
}
-#define VMBUS_ALIAS_LEN ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2)
-static void print_alias_name(struct hv_device *hv_dev, char *alias_name)
-{
- int i;
- for (i = 0; i < VMBUS_ALIAS_LEN; i += 2)
- sprintf(&alias_name[i], "%02x", hv_dev->dev_type.b[i/2]);
-}
-
static u8 channel_monitor_group(const struct vmbus_channel *channel)
{
return (u8)channel->offermsg.monitorid / 32;
@@ -221,10 +213,8 @@ static ssize_t modalias_show(struct device *dev,
struct device_attribute *dev_attr, char *buf)
{
struct hv_device *hv_dev = device_to_hv_device(dev);
- char alias_name[VMBUS_ALIAS_LEN + 1];
- print_alias_name(hv_dev, alias_name);
- return sprintf(buf, "vmbus:%s\n", alias_name);
+ return sprintf(buf, "vmbus:%*phN\n", UUID_SIZE, &hv_dev->dev_type);
}
static DEVICE_ATTR_RO(modalias);
@@ -693,12 +683,9 @@ __ATTRIBUTE_GROUPS(vmbus_dev);
static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
{
struct hv_device *dev = device_to_hv_device(device);
- int ret;
- char alias_name[VMBUS_ALIAS_LEN + 1];
+ const char *format = "MODALIAS=vmbus:%*phN";
- print_alias_name(dev, alias_name);
- ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name);
- return ret;
+ return add_uevent_var(env, format, UUID_SIZE, &dev->dev_type);
}
static const struct hv_vmbus_device_id *
--
2.26.1
^ permalink raw reply related
* Re: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Bart Van Assche @ 2020-04-23 16:37 UTC (permalink / raw)
To: Dexuan Cui, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <HK0P153MB02737524F120829405C6DE68BFD30@HK0P153MB0273.APCP153.PROD.OUTLOOK.COM>
On 4/23/20 12:04 AM, Dexuan Cui wrote:
> It looks the sd suspend callbacks are only for the I/O from the disk, e.g.
> from the file system that lives in some partition of some disk.
>
> The panic I'm seeing is not from sd. I think it's from a kernel thread
> that tries to detect the status of the SCSI CDROM. This is the snipped
> messages (the full version is at https://lkml.org/lkml/2020/4/10/47): here
> the suspend callbacks of the sd, sr and scsi_bus_type.pm have been called,
> and later the storvsc LLD's suspend callback is also called, but
> sr_block_check_events() can still try to submit SCSI commands to storvsc:
>
> [ 11.668741] sr 0:0:0:1: bus quiesce
> [ 11.668804] sd 0:0:0:0: bus quiesce
> [ 11.698082] scsi target0:0:0: bus quiesce
> [ 11.703296] scsi host0: bus quiesce
> [ 11.781730] hv_storvsc bf78936f-7d8f-45ce-ab03-6c341452e55d: noirq bus quiesce
> [ 11.796479] hv_netvsc dda5a2be-b8b8-4237-b330-be8a516a72c0: noirq bus quiesce
> [ 11.804042] BUG: kernel NULL pointer dereference, address: 0000000000000090
> [ 11.804996] Workqueue: events_freezable_power_ disk_events_workfn
> [ 11.804996] RIP: 0010:storvsc_queuecommand+0x261/0x714 [hv_storvsc]
> [ 11.804996] Call Trace:
> [ 11.804996] scsi_queue_rq+0x593/0xa10
> [ 11.804996] blk_mq_dispatch_rq_list+0x8d/0x510
> [ 11.804996] blk_mq_sched_dispatch_requests+0xed/0x170
> [ 11.804996] __blk_mq_run_hw_queue+0x55/0x110
> [ 11.804996] __blk_mq_delay_run_hw_queue+0x141/0x160
> [ 11.804996] blk_mq_sched_insert_request+0xc3/0x170
> [ 11.804996] blk_execute_rq+0x4b/0xa0
> [ 11.804996] __scsi_execute+0xeb/0x250
> [ 11.804996] sr_check_events+0x9f/0x270 [sr_mod]
> [ 11.804996] cdrom_check_events+0x1a/0x30 [cdrom]
> [ 11.804996] sr_block_check_events+0xcc/0x110 [sr_mod]
> [ 11.804996] disk_check_events+0x68/0x160
> [ 11.804996] process_one_work+0x20c/0x3d0
> [ 11.804996] worker_thread+0x2d/0x3e0
> [ 11.804996] kthread+0x10c/0x130
> [ 11.804996] ret_from_fork+0x35/0x40
>
> It looks the issue is: scsi_bus_freeze() -> ... -> scsi_dev_type_suspend ->
> scsi_device_quiesce() does not guarantee the device is totally quiescent:
During hibernation processes are frozen before devices are quiesced.
freeze_processes() calls try_to_freeze_tasks() and that function in turn
calls freeze_workqueues_begin() and freeze_workqueues_busy().
freeze_workqueues_busy() freezes all freezable workqueues including
system_freezable_power_efficient_wq, the workqueue from which
check_events functions are called. Some time after freezable workqueues
are frozen dpm_suspend(PMSG_FREEZE) is called. That last call triggers
the pm_ops.freeze callbacks, including the pm_ops.freeze callbacks
defined in the SCSI core.
The above trace seems to indicate that freezing workqueues has not
happened before devices were frozen. How about doing the following to
retrieve more information about what is going on?
* Enable CONFIG_PM_DEBUG in the kernel configuration.
* Run echo 1 > /sys/power/pm_print_times and echo 1 >
/sys/power/pm_debug_messages before hibernation starts.
>> Documentation/driver-api/device_link.rst: "By default, the driver core
>> only enforces dependencies between devices that are borne out of a
>> parent/child relationship within the device hierarchy: When suspending,
>> resuming or shutting down the system, devices are ordered based on this
>> relationship, i.e. children are always suspended before their parent,
>> and the parent is always resumed before its children." Is there a single
>> storvsc_drv instance for all SCSI devices supported by storvsc_drv? Has
>> it been considered to make storvsc_drv the parent device of all SCSI
>> devices created by the storvsc driver?
>
> Yes, I think so:
>
> root@localhost:~# ls -rtl /sys/bus/vmbus/devices/9be03cb2-d37b-409f-b09b-81059b4f6943/host3/target3:0:0/3:0:0:0/driver
> lrwxrwxrwx 1 root root 0 Apr 22 01:10 /sys/bus/vmbus/devices/9be03cb2-d37b-409f-b09b-81059b4f6943/host3/target3:0:0/3:0:0:0/driver -> ../../../../../../../../../../bus/scsi/drivers/sd
>
> Here the driver of /sys/bus/vmbus/devices/9be03cb2-d37b-409f-b09b-81059b4f6943
> is storvsc, which creates host3/target3:0:0/3:0:0:0.
>
> So it looks there is no ordering issue.
Right, I had overlooked the code in storvsc_probe() that associates SCSI
devices with storvsc_drv.
Bart.
^ permalink raw reply
* RE: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Dexuan Cui @ 2020-04-23 18:29 UTC (permalink / raw)
To: Bart Van Assche, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <ade7f096-4a09-4d4e-753a-f9e4acb7b550@acm.org>
> From: Bart Van Assche <bvanassche@acm.org>
> Sent: Thursday, April 23, 2020 9:38 AM
>
> On 4/23/20 12:04 AM, Dexuan Cui wrote:
> > It looks the sd suspend callbacks are only for the I/O from the disk, e.g.
> > from the file system that lives in some partition of some disk.
> >
> > The panic I'm seeing is not from sd. I think it's from a kernel thread
> > that tries to detect the status of the SCSI CDROM. This is the snipped
> > messages (the full version is at ...): here
> > the suspend callbacks of the sd, sr and scsi_bus_type.pm have been called,
> > and later the storvsc LLD's suspend callback is also called, but
> > sr_block_check_events() can still try to submit SCSI commands to storvsc:
> >
> > [ 11.668741] sr 0:0:0:1: bus quiesce
> > [ 11.668804] sd 0:0:0:0: bus quiesce
> > [ 11.698082] scsi target0:0:0: bus quiesce
> > [ 11.703296] scsi host0: bus quiesce
> > [ 11.781730] hv_storvsc bf78936f-7d8f-45ce-ab03-6c341452e55d: noirq
> bus quiesce
> > [ 11.796479] hv_netvsc dda5a2be-b8b8-4237-b330-be8a516a72c0: noirq
> bus quiesce
> > [ 11.804042] BUG: kernel NULL pointer dereference, address:
> 0000000000000090
> > [ 11.804996] Workqueue: events_freezable_power_ disk_events_workfn
> > [ 11.804996] RIP: 0010:storvsc_queuecommand+0x261/0x714
> [hv_storvsc]
> > [ 11.804996] Call Trace:
> > [ 11.804996] scsi_queue_rq+0x593/0xa10
> > [ 11.804996] blk_mq_dispatch_rq_list+0x8d/0x510
> > [ 11.804996] blk_mq_sched_dispatch_requests+0xed/0x170
> > [ 11.804996] __blk_mq_run_hw_queue+0x55/0x110
> > [ 11.804996] __blk_mq_delay_run_hw_queue+0x141/0x160
> > [ 11.804996] blk_mq_sched_insert_request+0xc3/0x170
> > [ 11.804996] blk_execute_rq+0x4b/0xa0
> > [ 11.804996] __scsi_execute+0xeb/0x250
> > [ 11.804996] sr_check_events+0x9f/0x270 [sr_mod]
> > [ 11.804996] cdrom_check_events+0x1a/0x30 [cdrom]
> > [ 11.804996] sr_block_check_events+0xcc/0x110 [sr_mod]
> > [ 11.804996] disk_check_events+0x68/0x160
> > [ 11.804996] process_one_work+0x20c/0x3d0
> > [ 11.804996] worker_thread+0x2d/0x3e0
> > [ 11.804996] kthread+0x10c/0x130
> > [ 11.804996] ret_from_fork+0x35/0x40
> >
> > It looks the issue is: scsi_bus_freeze() -> ... -> scsi_dev_type_suspend ->
> > scsi_device_quiesce() does not guarantee the device is totally quiescent:
>
> During hibernation processes are frozen before devices are quiesced.
> freeze_processes() calls try_to_freeze_tasks() and that function in turn
> calls freeze_workqueues_begin() and freeze_workqueues_busy().
> freeze_workqueues_busy() freezes all freezable workqueues including
> system_freezable_power_efficient_wq, the workqueue from which
> check_events functions are called. Some time after freezable workqueues
> are frozen dpm_suspend(PMSG_FREEZE) is called. That last call triggers
> the pm_ops.freeze callbacks, including the pm_ops.freeze callbacks
> defined in the SCSI core.
>
> The above trace seems to indicate that freezing workqueues has not
> happened before devices were frozen. How about doing the following to
> retrieve more information about what is going on?
> * Enable CONFIG_PM_DEBUG in the kernel configuration.
> * Run echo 1 > /sys/power/pm_print_times and echo 1 >
> /sys/power/pm_debug_messages before hibernation starts.
>
> Bart.
Good point! My panic happens in the "restore" path, not the "save" path.
In the "save" path, as you described, it looks everything is done correctly.
BTW, freeze_processes() only freezes the userspace processes. After
hibernate() -> freeze_processes(), hibernate() -> hibernation_snapshot()
-> freeze_kernel_threads() also freezes the "freezable" kernel processes,
and then we call dpm_suspend(PMSG_FREEZE), and next we do a lot of
other things, and finally the system is powered off.
In the "restore" path of the hibernation:
1. We start the system and a fresh new kernel starts to run.
2. The 'new' kernel itself finishes the initialization and the 'init' script
in the initramfs starts to run. The 'init' script notices there is a saved
state of the previous 'old' kernel in some swap file/partition, so it won't
do a usual start-up; instead, the 'init' script runs a program called 'resume'.
3. The 'resume' program talks to the kernel via /sys/power/resume and
asks the kernel to do a resume-from-disk.
4. The kernel starts to run resume_store() -> software_resume ->
freeze_processes(), which freezes the userspace, but the "freezable"
kernel threads are not frozen!!!
So it looks the below patch also works for me:
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -898,6 +898,11 @@ static int software_resume(void)
error = freeze_processes();
if (error)
goto Close_Finish;
+
+ error = freeze_kernel_threads();
+ if (error)
+ goto Close_Finish;
+
error = load_image_and_restore();
thaw_processes();
Finish:
Just to be sure, I'll do more tests, but I believe the panic can be fixed
by this according to my tests I have done so far.
I'm still not sure what the comment before scsi_device_quiesce() means:
* ... Since special requests may also be requeued requests,
* a successful return doesn't guarantee the device will be
* totally quiescent.
I don't know if there can be some other I/O submitted after
scsi_device_quiesce() returns in the case of hibernation, and I don't
know if aac_suspend() -> scsi_host_block() should be fixed/removed,
but as far as the panic is concerned, I'm very glad I have found a better
fix with your help.
Thank you so much, Bart!
Thanks,
-- Dexuan
^ permalink raw reply
* Re: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Bart Van Assche @ 2020-04-23 23:25 UTC (permalink / raw)
To: Dexuan Cui, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <HK0P153MB02731F9C5FC61C466715362CBFD30@HK0P153MB0273.APCP153.PROD.OUTLOOK.COM>
On 2020-04-23 11:29, Dexuan Cui wrote:
> So it looks the below patch also works for me:
>
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -898,6 +898,11 @@ static int software_resume(void)
> error = freeze_processes();
> if (error)
> goto Close_Finish;
> +
> + error = freeze_kernel_threads();
> + if (error)
> + goto Close_Finish;
> +
> error = load_image_and_restore();
> thaw_processes();
> Finish:
>
> Just to be sure, I'll do more tests, but I believe the panic can be fixed
> by this according to my tests I have done so far.
If a freeze_kernel_threads() call is added in software_resume(), should
a thaw_kernel_threads() call be added too?
Anyway, please Cc me if a patch for software_resume() is submitted.
> I'm still not sure what the comment before scsi_device_quiesce() means:
> * ... Since special requests may also be requeued requests,
> * a successful return doesn't guarantee the device will be
> * totally quiescent.
>
> I don't know if there can be some other I/O submitted after
> scsi_device_quiesce() returns in the case of hibernation, and I don't
> know if aac_suspend() -> scsi_host_block() should be fixed/removed,
> but as far as the panic is concerned, I'm very glad I have found a better
> fix with your help.
The function blk_set_pm_only() increments the q->pm_only counter while
the blk_clear_pm_only() function decrements the q->pm_only counter.
If q->pm_only > 0, blk_queue_enter() only succeeds if the flag
BLK_MQ_REQ_PREEMPT is set in the second argument passed to that
function. blk_get_request() calls blk_queue_enter(). The result is that
while q->pm_only > 0 blk_get_request() only submits a request without
waiting if the BLK_MQ_REQ_PREEMPT flag is set in its second argument.
scsi_execute() sets the BLK_MQ_REQ_PREEMPT flag. In other words,
scsi_device_quiesce() blocks requests submitted by filesystems but still
allows SCSI commands submitted by the SCSI core to be executed.
"special" refers to requests with the BLK_MQ_REQ_PREEMPT flag set.
Bart.
^ permalink raw reply
* RE: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Dexuan Cui @ 2020-04-24 2:40 UTC (permalink / raw)
To: Bart Van Assche, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <f23cb660-13e4-8466-4c78-163fcc857caa@acm.org>
> From: Bart Van Assche <bvanassche@acm.org>
> Sent: Thursday, April 23, 2020 4:25 PM
> On 2020-04-23 11:29, Dexuan Cui wrote:
> > So it looks the below patch also works for me:
> >
> > --- a/kernel/power/hibernate.c
> > +++ b/kernel/power/hibernate.c
> > @@ -898,6 +898,11 @@ static int software_resume(void)
> > error = freeze_processes();
> > if (error)
> > goto Close_Finish;
> > +
> > + error = freeze_kernel_threads();
> > + if (error)
> > + goto Close_Finish;
> > +
> > error = load_image_and_restore();
> > thaw_processes();
> > Finish:
> >
> > Just to be sure, I'll do more tests, but I believe the panic can be fixed
> > by this according to my tests I have done so far.
>
> If a freeze_kernel_threads() call is added in software_resume(), should
> a thaw_kernel_threads() call be added too?
Good catch!
Note: thaw_processes() thaws every frozen process, including both user
space processes and kernel processes.
In software_resume():
1. If freeze_kernel_threads() fails, I should add a "thaw_processes(); "
before "goto Close_Finish; " so that all the user space processes can
be thawed.
2. If freeze_kernel_threads() succeeds, but load_image_and_restore()
Fails, there is already a thaw_processes().
3. If load_image_and_restore() succeeds, it won't return, and the
execution will return from the 'old' kernel's hibernate() ->
hibernation_snapshot() -> create_image() -> swsusp_arch_suspend(),
and later hibernate() -> thaw_processes() will thaw every frozen
process of the 'old' kernel.
> Anyway, please Cc me if a patch for software_resume() is submitted.
Sure. Will do.
> > I'm still not sure what the comment before scsi_device_quiesce() means:
> > * ... Since special requests may also be requeued requests,
> > * a successful return doesn't guarantee the device will be
> > * totally quiescent.
> >
> > I don't know if there can be some other I/O submitted after
> > scsi_device_quiesce() returns in the case of hibernation, and I don't
> > know if aac_suspend() -> scsi_host_block() should be fixed/removed,
> > but as far as the panic is concerned, I'm very glad I have found a better
> > fix with your help.
>
> The function blk_set_pm_only() increments the q->pm_only counter while
> the blk_clear_pm_only() function decrements the q->pm_only counter.
> If q->pm_only > 0, blk_queue_enter() only succeeds if the flag
> BLK_MQ_REQ_PREEMPT is set in the second argument passed to that
> function. blk_get_request() calls blk_queue_enter(). The result is that
> while q->pm_only > 0 blk_get_request() only submits a request without
> waiting if the BLK_MQ_REQ_PREEMPT flag is set in its second argument.
> scsi_execute() sets the BLK_MQ_REQ_PREEMPT flag. In other words,
> scsi_device_quiesce() blocks requests submitted by filesystems but still
> allows SCSI commands submitted by the SCSI core to be executed.
> "special" refers to requests with the BLK_MQ_REQ_PREEMPT flag set.
>
> Bart.
Thanks for the detailed clarification! So it sounds like we're safe here,
and I guess the scsi_host_block() in aac_suspend() should be removed
to discourage people from trying to use scsi_host_block() in a .suspend()
callback. :-)
Thanks,
-- Dexuan
^ permalink raw reply
* RE: [PATCH] scsi: storvsc: Fix a panic in the hibernation procedure
From: Dexuan Cui @ 2020-04-24 3:45 UTC (permalink / raw)
To: Bart Van Assche, jejb@linux.ibm.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
hch@lst.de, hare@suse.de, Michael Kelley, Long Li,
ming.lei@redhat.com, Balsundar P
Cc: linux-hyperv@vger.kernel.org, wei.liu@kernel.org,
Stephen Hemminger, Haiyang Zhang, KY Srinivasan
In-Reply-To: <f23cb660-13e4-8466-4c78-163fcc857caa@acm.org>
> From: Bart Van Assche <bvanassche@acm.org>
> Sent: Thursday, April 23, 2020 4:25 PM
> On 2020-04-23 11:29, Dexuan Cui wrote:
> > So it looks the below patch also works for me:
> >
> > --- a/kernel/power/hibernate.c
> > +++ b/kernel/power/hibernate.c
> > @@ -898,6 +898,11 @@ static int software_resume(void)
> > error = freeze_processes();
> > if (error)
> > goto Close_Finish;
> > +
> > + error = freeze_kernel_threads();
> > + if (error)
> > + goto Close_Finish;
> > +
> > error = load_image_and_restore();
> > thaw_processes();
> > Finish:
> >
> > Just to be sure, I'll do more tests, but I believe the panic can be fixed
> > by this according to my tests I have done so far.
>
> If a freeze_kernel_threads() call is added in software_resume(), should
> a thaw_kernel_threads() call be added too?
>
> Anyway, please Cc me if a patch for software_resume() is submitted.
FYI, I posted a fix: https://lkml.org/lkml/2020/4/23/1540
Thanks,
-- Dexuan
^ permalink raw reply
* Re: [PATCH v1 1/4] hyper-v: Use UUID API for exporting the GUID (part 2)
From: Wei Liu @ 2020-04-24 10:21 UTC (permalink / raw)
To: Andy Shevchenko
Cc: K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger, Wei Liu,
linux-hyperv
In-Reply-To: <20200423134505.78221-1-andriy.shevchenko@linux.intel.com>
On Thu, Apr 23, 2020 at 04:45:02PM +0300, Andy Shevchenko wrote:
> This is a follow up to the commit 1d3c9c075462
> ("hyper-v: Use UUID API for exporting the GUID")
> which starts the conversion.
>
> There is export_guid() function which exports guid_t to the u8 array.
> Use it instead of open coding variant.
>
> This allows to hide the uuid_t internals.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Thanks.
I have queued the whole series to hyperv-next.
Wei.
^ permalink raw reply
* [PATCH v11 0/7] x86/kvm/hyper-v: add support for synthetic debugger
From: Jon Doron @ 2020-04-24 11:37 UTC (permalink / raw)
To: kvm, linux-hyperv; +Cc: vkuznets, Jon Doron
Add support for the synthetic debugger interface of hyper-v, the
synthetic debugger has 2 modes.
1. Use a set of MSRs to send/recv information (undocumented so it's not
going to the hyperv-tlfs.h)
2. Use hypercalls
The first mode is based the following MSRs:
1. Control/Status MSRs which either asks for a send/recv .
2. Send/Recv MSRs each holds GPA where the send/recv buffers are.
3. Pending MSR, holds a GPA to a PAGE that simply has a boolean that
indicates if there is data pending to issue a recv VMEXIT.
The first mode implementation is to simply exit to user-space when
either the control MSR or the pending MSR are being set.
Then it's up-to userspace to implement the rest of the logic of sending/recving.
In the second mode instead of using MSRs KNet will simply issue
Hypercalls with the information to send/recv, in this mode the data
being transferred is UDP encapsulated, unlike in the previous mode in
which you get just the data to send.
The new hypercalls will exit to userspace which will be incharge of
re-encapsulating if needed the UDP packets to be sent.
There is an issue though in which KDNet does not respect the hypercall
page and simply issues vmcall/vmmcall instructions depending on the cpu
type expecting them to be handled as it a real hypercall was issued.
It's important to note that part of this feature has been subject to be
removed in future versions of Windows, which is why some of the
defintions will not be present the the TLFS but in the kvm hyperv header
instead.
v11:
Fixed all reviewed by and rebased on latest origin/master
Jon Doron (6):
x86/kvm/hyper-v: Explicitly align hcall param for kvm_hyperv_exit
x86/kvm/hyper-v: Simplify addition for custom cpuid leafs
x86/hyper-v: Add synthetic debugger definitions
x86/kvm/hyper-v: Add support for synthetic debugger capability
x86/kvm/hyper-v: enable hypercalls without hypercall page with syndbg
x86/kvm/hyper-v: Add support for synthetic debugger via hypercalls
Vitaly Kuznetsov (1):
KVM: selftests: update hyperv_cpuid with SynDBG tests
Documentation/virt/kvm/api.rst | 18 ++
arch/x86/include/asm/hyperv-tlfs.h | 6 +
arch/x86/include/asm/kvm_host.h | 14 +
arch/x86/kvm/hyperv.c | 242 ++++++++++++++++--
arch/x86/kvm/hyperv.h | 33 +++
arch/x86/kvm/trace.h | 51 ++++
arch/x86/kvm/x86.c | 13 +
include/uapi/linux/kvm.h | 13 +
.../selftests/kvm/x86_64/hyperv_cpuid.c | 143 +++++++----
9 files changed, 468 insertions(+), 65 deletions(-)
--
2.24.1
^ permalink raw reply
* [PATCH v11 2/7] x86/kvm/hyper-v: Simplify addition for custom cpuid leafs
From: Jon Doron @ 2020-04-24 11:37 UTC (permalink / raw)
To: kvm, linux-hyperv; +Cc: vkuznets, Jon Doron
In-Reply-To: <20200424113746.3473563-1-arilou@gmail.com>
Simlify the code to define a new cpuid leaf group by enabled feature.
This also fixes a bug in which the max cpuid leaf was always set to
HYPERV_CPUID_NESTED_FEATURES regardless if nesting is supported or not.
Any new CPUID group needs to consider the max leaf and be added in the
correct order, in this method there are two rules:
1. Each cpuid leaf group must be order in an ascending order
2. The appending for the cpuid leafs by features also needs to happen by
ascending order.
Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Jon Doron <arilou@gmail.com>
---
arch/x86/kvm/hyperv.c | 46 ++++++++++++++++++++++++++++++-------------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index bcefa9d4e57e..ab3e9dbcabbe 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -1785,27 +1785,45 @@ int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args)
return kvm_hv_eventfd_assign(kvm, args->conn_id, args->fd);
}
+/* Must be sorted in ascending order by function */
+static struct kvm_cpuid_entry2 core_cpuid_entries[] = {
+ { .function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS },
+ { .function = HYPERV_CPUID_INTERFACE },
+ { .function = HYPERV_CPUID_VERSION },
+ { .function = HYPERV_CPUID_FEATURES },
+ { .function = HYPERV_CPUID_ENLIGHTMENT_INFO },
+ { .function = HYPERV_CPUID_IMPLEMENT_LIMITS },
+};
+
+static struct kvm_cpuid_entry2 evmcs_cpuid_entries[] = {
+ { .function = HYPERV_CPUID_NESTED_FEATURES },
+};
+
+#define HV_MAX_CPUID_ENTRIES \
+ (ARRAY_SIZE(core_cpuid_entries) +\
+ ARRAY_SIZE(evmcs_cpuid_entries))
+
int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries)
{
uint16_t evmcs_ver = 0;
- struct kvm_cpuid_entry2 cpuid_entries[] = {
- { .function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS },
- { .function = HYPERV_CPUID_INTERFACE },
- { .function = HYPERV_CPUID_VERSION },
- { .function = HYPERV_CPUID_FEATURES },
- { .function = HYPERV_CPUID_ENLIGHTMENT_INFO },
- { .function = HYPERV_CPUID_IMPLEMENT_LIMITS },
- { .function = HYPERV_CPUID_NESTED_FEATURES },
- };
- int i, nent = ARRAY_SIZE(cpuid_entries);
+ struct kvm_cpuid_entry2 cpuid_entries[HV_MAX_CPUID_ENTRIES];
+ int i, nent = 0;
+
+ /* Set the core cpuid entries required for Hyper-V */
+ memcpy(&cpuid_entries[nent], &core_cpuid_entries,
+ sizeof(core_cpuid_entries));
+ nent = ARRAY_SIZE(core_cpuid_entries);
if (kvm_x86_ops.nested_get_evmcs_version)
evmcs_ver = kvm_x86_ops.nested_get_evmcs_version(vcpu);
- /* Skip NESTED_FEATURES if eVMCS is not supported */
- if (!evmcs_ver)
- --nent;
+ if (evmcs_ver) {
+ /* EVMCS is enabled, add the required EVMCS CPUID leafs */
+ memcpy(&cpuid_entries[nent], &evmcs_cpuid_entries,
+ sizeof(evmcs_cpuid_entries));
+ nent += ARRAY_SIZE(evmcs_cpuid_entries);
+ }
if (cpuid->nent < nent)
return -E2BIG;
@@ -1821,7 +1839,7 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
case HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS:
memcpy(signature, "Linux KVM Hv", 12);
- ent->eax = HYPERV_CPUID_NESTED_FEATURES;
+ ent->eax = cpuid_entries[nent - 1].function;
ent->ebx = signature[0];
ent->ecx = signature[1];
ent->edx = signature[2];
--
2.24.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox