Commit 5be07b3f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hyperv-fixes-signed-20221110' of...

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()
parents 91c77a6e e70af8d0
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -9507,7 +9507,6 @@ F: drivers/media/i2c/hi847.c
Hyper-V/Azure CORE AND DRIVERS
M:	"K. Y. Srinivasan" <kys@microsoft.com>
M:	Haiyang Zhang <haiyangz@microsoft.com>
M:	Stephen Hemminger <sthemmin@microsoft.com>
M:	Wei Liu <wei.liu@kernel.org>
M:	Dexuan Cui <decui@microsoft.com>
L:	linux-hyperv@vger.kernel.org
+10 −9
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ void __init hyperv_init(void)

	if (hv_root_partition) {
		struct page *pg;
		void *src, *dst;
		void *src;

		/*
		 * 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);

		pg = vmalloc_to_page(hv_hypercall_pg);
		dst = kmap_local_page(pg);
		src = memremap(hypercall_msr.guest_physical_address << PAGE_SHIFT, PAGE_SIZE,
				MEMREMAP_WB);
		BUG_ON(!(src && dst));
		memcpy(dst, src, HV_HYP_PAGE_SIZE);
		BUG_ON(!src);
		memcpy_to_page(pg, 0, src, HV_HYP_PAGE_SIZE);
		memunmap(src);
		kunmap_local(dst);
	} else {
		hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
		wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -537,6 +535,7 @@ void __init hyperv_init(void)
void hyperv_cleanup(void)
{
	union hv_x64_msr_hypercall_contents hypercall_msr;
	union hv_reference_tsc_msr tsc_msr;

	unregister_syscore_ops(&hv_syscore_ops);

@@ -552,12 +551,14 @@ void hyperv_cleanup(void)
	hv_hypercall_pg = NULL;

	/* Reset the hypercall page */
	hypercall_msr.as_uint64 = 0;
	wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
	hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL);
	hypercall_msr.enable = 0;
	hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);

	/* Reset the TSC page */
	hypercall_msr.as_uint64 = 0;
	wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
	tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC);
	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)
+15 −14
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/acpi.h>
#include <linux/hyperv.h>
#include <clocksource/hyperv_timer.h>
#include <asm/hyperv-tlfs.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)
{
	u64 tsc_msr;
	union hv_reference_tsc_msr tsc_msr;

	/* Disable the TSC page */
	tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
	tsc_msr &= ~BIT_ULL(0);
	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
	tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
	tsc_msr.enable = 0;
	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
}


static void resume_hv_clock_tsc(struct clocksource *arg)
{
	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 */
	tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
	tsc_msr &= GENMASK_ULL(11, 0);
	tsc_msr |= BIT_ULL(0) | (u64)phys_addr;
	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
	tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
	tsc_msr.enable = 1;
	tsc_msr.pfn = HVPFN_DOWN(phys_addr);
	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
}

#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)
{
	u64		tsc_msr;
	union hv_reference_tsc_msr tsc_msr;
	phys_addr_t	phys_addr;

	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
	 * it is page aligned). Also set the "enable" bit, which is bit 0.
	 */
	tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
	tsc_msr &= GENMASK_ULL(11, 0);
	tsc_msr = tsc_msr | 0x1 | (u64)phys_addr;
	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
	tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
	tsc_msr.enable = 1;
	tsc_msr.pfn = HVPFN_DOWN(phys_addr);
	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);

	clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);

+1 −1
Original line number Diff line number Diff line
@@ -905,7 +905,7 @@ static unsigned long handle_pg_range(unsigned long pg_start,
			 * We have some residual hot add range
			 * that needs to be hot added; hot add
			 * it now. Hot add a multiple of
			 * of HA_CHUNK that fully covers the pages
			 * HA_CHUNK that fully covers the pages
			 * we have.
			 */
			size = (has->end_pfn - has->ha_end_pfn);
+16 −6
Original line number Diff line number Diff line
@@ -1614,7 +1614,7 @@ static void hv_pci_compose_compl(void *context, struct pci_response *resp,

static u32 hv_compose_msi_req_v1(
	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->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(
	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;

@@ -1661,7 +1661,7 @@ static u32 hv_compose_msi_req_v2(

static u32 hv_compose_msi_req_v3(
	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;

@@ -1701,7 +1701,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
	struct compose_comp_ctxt comp;
	struct tran_int_desc *int_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 pci_packet pci_pkt;
		union {
@@ -1767,6 +1772,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
		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));
	init_completion(&comp.comp_pkt.host_event);
	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,
					dest,
					hpdev->desc.win_slot.slot,
					vector,
					(u8)vector,
					vector_count);
		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,
					dest,
					hpdev->desc.win_slot.slot,
					vector,
					(u8)vector,
					vector_count);
		break;

Loading