forked from Minki/linux
hyperv-fixes for v6.1-rc5
-----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEIbPD0id6easf0xsudhRwX5BBoF4FAmNtZ+UTHHdlaS5saXVA a2VybmVsLm9yZwAKCRB2FHBfkEGgXm67B/9qQtQbqYHoV6bJKqiAHgh3ZcS/V7sn iYc5egO84YZSTtkbLKeCixYD7i8Ltz+GzC7XgOwkvYKUkjOcs9keomKxhUnGl6jf Z7N66r8zBkR5LlkmmqTSMz90EDGz+WYj/4DaIcna70rSYp9aS4qbXr7AEv8CjGGl VZzt95L0nDx6VWdiP8NoQyqMwFXwgy2L2D4x4bDVlG7zihwl6f7VBvt4MYrunpjo P25ppR+yigAzhtO6LD19jq4MPSqQ2kyv/m5QR1mQvCqELc5ehn3OY70V5vWV7o4e y/qtngfowKeP0TynkWp3aScKwDbD5zSMvDf5obMPSvgbJpfXRi4dM0uA =SaCF -----END PGP SIGNATURE----- Merge tag 'hyperv-fixes-signed-20221110' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux Pull hyperv fixes from Wei Liu: - Fix TSC MSR write for root partition (Anirudh Rayabharam) - Fix definition of vector in pci-hyperv driver (Dexuan Cui) - A few other misc patches * tag 'hyperv-fixes-signed-20221110' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: PCI: hv: Fix the definition of vector in hv_compose_msi_msg() MAINTAINERS: remove sthemmin x86/hyperv: fix invalid writes to MSRs during root partition kexec clocksource/drivers/hyperv: add data structure for reference TSC MSR Drivers: hv: fix repeated words in comments x86/hyperv: Remove BUG_ON() for kmap_local_page()
This commit is contained in:
commit
5be07b3fb5
@ -9507,7 +9507,6 @@ F: drivers/media/i2c/hi847.c
|
|||||||
Hyper-V/Azure CORE AND DRIVERS
|
Hyper-V/Azure CORE AND DRIVERS
|
||||||
M: "K. Y. Srinivasan" <kys@microsoft.com>
|
M: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||||
M: Haiyang Zhang <haiyangz@microsoft.com>
|
M: Haiyang Zhang <haiyangz@microsoft.com>
|
||||||
M: Stephen Hemminger <sthemmin@microsoft.com>
|
|
||||||
M: Wei Liu <wei.liu@kernel.org>
|
M: Wei Liu <wei.liu@kernel.org>
|
||||||
M: Dexuan Cui <decui@microsoft.com>
|
M: Dexuan Cui <decui@microsoft.com>
|
||||||
L: linux-hyperv@vger.kernel.org
|
L: linux-hyperv@vger.kernel.org
|
||||||
|
@ -444,7 +444,7 @@ void __init hyperv_init(void)
|
|||||||
|
|
||||||
if (hv_root_partition) {
|
if (hv_root_partition) {
|
||||||
struct page *pg;
|
struct page *pg;
|
||||||
void *src, *dst;
|
void *src;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the root partition, the hypervisor will set up its
|
* For the root partition, the hypervisor will set up its
|
||||||
@ -459,13 +459,11 @@ void __init hyperv_init(void)
|
|||||||
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
||||||
|
|
||||||
pg = vmalloc_to_page(hv_hypercall_pg);
|
pg = vmalloc_to_page(hv_hypercall_pg);
|
||||||
dst = kmap_local_page(pg);
|
|
||||||
src = memremap(hypercall_msr.guest_physical_address << PAGE_SHIFT, PAGE_SIZE,
|
src = memremap(hypercall_msr.guest_physical_address << PAGE_SHIFT, PAGE_SIZE,
|
||||||
MEMREMAP_WB);
|
MEMREMAP_WB);
|
||||||
BUG_ON(!(src && dst));
|
BUG_ON(!src);
|
||||||
memcpy(dst, src, HV_HYP_PAGE_SIZE);
|
memcpy_to_page(pg, 0, src, HV_HYP_PAGE_SIZE);
|
||||||
memunmap(src);
|
memunmap(src);
|
||||||
kunmap_local(dst);
|
|
||||||
} else {
|
} else {
|
||||||
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
|
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
|
||||||
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
||||||
@ -537,6 +535,7 @@ common_free:
|
|||||||
void hyperv_cleanup(void)
|
void hyperv_cleanup(void)
|
||||||
{
|
{
|
||||||
union hv_x64_msr_hypercall_contents hypercall_msr;
|
union hv_x64_msr_hypercall_contents hypercall_msr;
|
||||||
|
union hv_reference_tsc_msr tsc_msr;
|
||||||
|
|
||||||
unregister_syscore_ops(&hv_syscore_ops);
|
unregister_syscore_ops(&hv_syscore_ops);
|
||||||
|
|
||||||
@ -552,12 +551,14 @@ void hyperv_cleanup(void)
|
|||||||
hv_hypercall_pg = NULL;
|
hv_hypercall_pg = NULL;
|
||||||
|
|
||||||
/* Reset the hypercall page */
|
/* Reset the hypercall page */
|
||||||
hypercall_msr.as_uint64 = 0;
|
hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL);
|
||||||
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
hypercall_msr.enable = 0;
|
||||||
|
hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
||||||
|
|
||||||
/* Reset the TSC page */
|
/* Reset the TSC page */
|
||||||
hypercall_msr.as_uint64 = 0;
|
tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC);
|
||||||
wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
|
tsc_msr.enable = 0;
|
||||||
|
hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
|
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/hyperv.h>
|
||||||
#include <clocksource/hyperv_timer.h>
|
#include <clocksource/hyperv_timer.h>
|
||||||
#include <asm/hyperv-tlfs.h>
|
#include <asm/hyperv-tlfs.h>
|
||||||
#include <asm/mshyperv.h>
|
#include <asm/mshyperv.h>
|
||||||
@ -395,25 +396,25 @@ static u64 notrace read_hv_sched_clock_tsc(void)
|
|||||||
|
|
||||||
static void suspend_hv_clock_tsc(struct clocksource *arg)
|
static void suspend_hv_clock_tsc(struct clocksource *arg)
|
||||||
{
|
{
|
||||||
u64 tsc_msr;
|
union hv_reference_tsc_msr tsc_msr;
|
||||||
|
|
||||||
/* Disable the TSC page */
|
/* Disable the TSC page */
|
||||||
tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
|
tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
|
||||||
tsc_msr &= ~BIT_ULL(0);
|
tsc_msr.enable = 0;
|
||||||
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
|
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void resume_hv_clock_tsc(struct clocksource *arg)
|
static void resume_hv_clock_tsc(struct clocksource *arg)
|
||||||
{
|
{
|
||||||
phys_addr_t phys_addr = virt_to_phys(&tsc_pg);
|
phys_addr_t phys_addr = virt_to_phys(&tsc_pg);
|
||||||
u64 tsc_msr;
|
union hv_reference_tsc_msr tsc_msr;
|
||||||
|
|
||||||
/* Re-enable the TSC page */
|
/* Re-enable the TSC page */
|
||||||
tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
|
tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
|
||||||
tsc_msr &= GENMASK_ULL(11, 0);
|
tsc_msr.enable = 1;
|
||||||
tsc_msr |= BIT_ULL(0) | (u64)phys_addr;
|
tsc_msr.pfn = HVPFN_DOWN(phys_addr);
|
||||||
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
|
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
|
#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
|
||||||
@ -495,7 +496,7 @@ static __always_inline void hv_setup_sched_clock(void *sched_clock) {}
|
|||||||
|
|
||||||
static bool __init hv_init_tsc_clocksource(void)
|
static bool __init hv_init_tsc_clocksource(void)
|
||||||
{
|
{
|
||||||
u64 tsc_msr;
|
union hv_reference_tsc_msr tsc_msr;
|
||||||
phys_addr_t phys_addr;
|
phys_addr_t phys_addr;
|
||||||
|
|
||||||
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
|
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
|
||||||
@ -530,10 +531,10 @@ static bool __init hv_init_tsc_clocksource(void)
|
|||||||
* (which already has at least the low 12 bits set to zero since
|
* (which already has at least the low 12 bits set to zero since
|
||||||
* it is page aligned). Also set the "enable" bit, which is bit 0.
|
* it is page aligned). Also set the "enable" bit, which is bit 0.
|
||||||
*/
|
*/
|
||||||
tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
|
tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
|
||||||
tsc_msr &= GENMASK_ULL(11, 0);
|
tsc_msr.enable = 1;
|
||||||
tsc_msr = tsc_msr | 0x1 | (u64)phys_addr;
|
tsc_msr.pfn = HVPFN_DOWN(phys_addr);
|
||||||
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
|
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
|
||||||
|
|
||||||
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
|
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
|
||||||
|
|
||||||
|
@ -905,7 +905,7 @@ static unsigned long handle_pg_range(unsigned long pg_start,
|
|||||||
* We have some residual hot add range
|
* We have some residual hot add range
|
||||||
* that needs to be hot added; hot add
|
* that needs to be hot added; hot add
|
||||||
* it now. Hot add a multiple of
|
* it now. Hot add a multiple of
|
||||||
* of HA_CHUNK that fully covers the pages
|
* HA_CHUNK that fully covers the pages
|
||||||
* we have.
|
* we have.
|
||||||
*/
|
*/
|
||||||
size = (has->end_pfn - has->ha_end_pfn);
|
size = (has->end_pfn - has->ha_end_pfn);
|
||||||
|
@ -1614,7 +1614,7 @@ out:
|
|||||||
|
|
||||||
static u32 hv_compose_msi_req_v1(
|
static u32 hv_compose_msi_req_v1(
|
||||||
struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
|
struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
|
||||||
u32 slot, u8 vector, u8 vector_count)
|
u32 slot, u8 vector, u16 vector_count)
|
||||||
{
|
{
|
||||||
int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
|
int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
|
||||||
int_pkt->wslot.slot = slot;
|
int_pkt->wslot.slot = slot;
|
||||||
@ -1642,7 +1642,7 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
|
|||||||
|
|
||||||
static u32 hv_compose_msi_req_v2(
|
static u32 hv_compose_msi_req_v2(
|
||||||
struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
|
struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
|
||||||
u32 slot, u8 vector, u8 vector_count)
|
u32 slot, u8 vector, u16 vector_count)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
@ -1661,7 +1661,7 @@ static u32 hv_compose_msi_req_v2(
|
|||||||
|
|
||||||
static u32 hv_compose_msi_req_v3(
|
static u32 hv_compose_msi_req_v3(
|
||||||
struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
|
struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
|
||||||
u32 slot, u32 vector, u8 vector_count)
|
u32 slot, u32 vector, u16 vector_count)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
@ -1701,7 +1701,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
|||||||
struct compose_comp_ctxt comp;
|
struct compose_comp_ctxt comp;
|
||||||
struct tran_int_desc *int_desc;
|
struct tran_int_desc *int_desc;
|
||||||
struct msi_desc *msi_desc;
|
struct msi_desc *msi_desc;
|
||||||
u8 vector, vector_count;
|
/*
|
||||||
|
* vector_count should be u16: see hv_msi_desc, hv_msi_desc2
|
||||||
|
* and hv_msi_desc3. vector must be u32: see hv_msi_desc3.
|
||||||
|
*/
|
||||||
|
u16 vector_count;
|
||||||
|
u32 vector;
|
||||||
struct {
|
struct {
|
||||||
struct pci_packet pci_pkt;
|
struct pci_packet pci_pkt;
|
||||||
union {
|
union {
|
||||||
@ -1767,6 +1772,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
|||||||
vector_count = 1;
|
vector_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hv_compose_msi_req_v1 and v2 are for x86 only, meaning 'vector'
|
||||||
|
* can't exceed u8. Cast 'vector' down to u8 for v1/v2 explicitly
|
||||||
|
* for better readability.
|
||||||
|
*/
|
||||||
memset(&ctxt, 0, sizeof(ctxt));
|
memset(&ctxt, 0, sizeof(ctxt));
|
||||||
init_completion(&comp.comp_pkt.host_event);
|
init_completion(&comp.comp_pkt.host_event);
|
||||||
ctxt.pci_pkt.completion_func = hv_pci_compose_compl;
|
ctxt.pci_pkt.completion_func = hv_pci_compose_compl;
|
||||||
@ -1777,7 +1787,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
|||||||
size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
|
size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
|
||||||
dest,
|
dest,
|
||||||
hpdev->desc.win_slot.slot,
|
hpdev->desc.win_slot.slot,
|
||||||
vector,
|
(u8)vector,
|
||||||
vector_count);
|
vector_count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1786,7 +1796,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
|||||||
size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
|
size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
|
||||||
dest,
|
dest,
|
||||||
hpdev->desc.win_slot.slot,
|
hpdev->desc.win_slot.slot,
|
||||||
vector,
|
(u8)vector,
|
||||||
vector_count);
|
vector_count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -102,6 +102,15 @@ struct ms_hyperv_tsc_page {
|
|||||||
volatile s64 tsc_offset;
|
volatile s64 tsc_offset;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
union hv_reference_tsc_msr {
|
||||||
|
u64 as_uint64;
|
||||||
|
struct {
|
||||||
|
u64 enable:1;
|
||||||
|
u64 reserved:11;
|
||||||
|
u64 pfn:52;
|
||||||
|
} __packed;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The guest OS needs to register the guest ID with the hypervisor.
|
* 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
|
* The guest ID is a 64 bit entity and the structure of this ID is
|
||||||
|
Loading…
Reference in New Issue
Block a user