Skip to content

Commit 5be07b3

Browse files
committed
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()
2 parents 91c77a6 + e70af8d commit 5be07b3

6 files changed

Lines changed: 51 additions & 31 deletions

File tree

MAINTAINERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9507,7 +9507,6 @@ F: drivers/media/i2c/hi847.c
95079507
Hyper-V/Azure CORE AND DRIVERS
95089508
M: "K. Y. Srinivasan" <kys@microsoft.com>
95099509
M: Haiyang Zhang <haiyangz@microsoft.com>
9510-
M: Stephen Hemminger <sthemmin@microsoft.com>
95119510
M: Wei Liu <wei.liu@kernel.org>
95129511
M: Dexuan Cui <decui@microsoft.com>
95139512
L: linux-hyperv@vger.kernel.org

arch/x86/hyperv/hv_init.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ void __init hyperv_init(void)
444444

445445
if (hv_root_partition) {
446446
struct page *pg;
447-
void *src, *dst;
447+
void *src;
448448

449449
/*
450450
* For the root partition, the hypervisor will set up its
@@ -459,13 +459,11 @@ void __init hyperv_init(void)
459459
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
460460

461461
pg = vmalloc_to_page(hv_hypercall_pg);
462-
dst = kmap_local_page(pg);
463462
src = memremap(hypercall_msr.guest_physical_address << PAGE_SHIFT, PAGE_SIZE,
464463
MEMREMAP_WB);
465-
BUG_ON(!(src && dst));
466-
memcpy(dst, src, HV_HYP_PAGE_SIZE);
464+
BUG_ON(!src);
465+
memcpy_to_page(pg, 0, src, HV_HYP_PAGE_SIZE);
467466
memunmap(src);
468-
kunmap_local(dst);
469467
} else {
470468
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
471469
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -537,6 +535,7 @@ void __init hyperv_init(void)
537535
void hyperv_cleanup(void)
538536
{
539537
union hv_x64_msr_hypercall_contents hypercall_msr;
538+
union hv_reference_tsc_msr tsc_msr;
540539

541540
unregister_syscore_ops(&hv_syscore_ops);
542541

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

554553
/* Reset the hypercall page */
555-
hypercall_msr.as_uint64 = 0;
556-
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
554+
hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL);
555+
hypercall_msr.enable = 0;
556+
hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
557557

558558
/* Reset the TSC page */
559-
hypercall_msr.as_uint64 = 0;
560-
wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
559+
tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC);
560+
tsc_msr.enable = 0;
561+
hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
561562
}
562563

563564
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)

drivers/clocksource/hyperv_timer.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/interrupt.h>
2222
#include <linux/irq.h>
2323
#include <linux/acpi.h>
24+
#include <linux/hyperv.h>
2425
#include <clocksource/hyperv_timer.h>
2526
#include <asm/hyperv-tlfs.h>
2627
#include <asm/mshyperv.h>
@@ -395,25 +396,25 @@ static u64 notrace read_hv_sched_clock_tsc(void)
395396

396397
static void suspend_hv_clock_tsc(struct clocksource *arg)
397398
{
398-
u64 tsc_msr;
399+
union hv_reference_tsc_msr tsc_msr;
399400

400401
/* Disable the TSC page */
401-
tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
402-
tsc_msr &= ~BIT_ULL(0);
403-
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
402+
tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
403+
tsc_msr.enable = 0;
404+
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
404405
}
405406

406407

407408
static void resume_hv_clock_tsc(struct clocksource *arg)
408409
{
409410
phys_addr_t phys_addr = virt_to_phys(&tsc_pg);
410-
u64 tsc_msr;
411+
union hv_reference_tsc_msr tsc_msr;
411412

412413
/* Re-enable the TSC page */
413-
tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
414-
tsc_msr &= GENMASK_ULL(11, 0);
415-
tsc_msr |= BIT_ULL(0) | (u64)phys_addr;
416-
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
414+
tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
415+
tsc_msr.enable = 1;
416+
tsc_msr.pfn = HVPFN_DOWN(phys_addr);
417+
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
417418
}
418419

419420
#ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
@@ -495,7 +496,7 @@ static __always_inline void hv_setup_sched_clock(void *sched_clock) {}
495496

496497
static bool __init hv_init_tsc_clocksource(void)
497498
{
498-
u64 tsc_msr;
499+
union hv_reference_tsc_msr tsc_msr;
499500
phys_addr_t phys_addr;
500501

501502
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
@@ -530,10 +531,10 @@ static bool __init hv_init_tsc_clocksource(void)
530531
* (which already has at least the low 12 bits set to zero since
531532
* it is page aligned). Also set the "enable" bit, which is bit 0.
532533
*/
533-
tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC);
534-
tsc_msr &= GENMASK_ULL(11, 0);
535-
tsc_msr = tsc_msr | 0x1 | (u64)phys_addr;
536-
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr);
534+
tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
535+
tsc_msr.enable = 1;
536+
tsc_msr.pfn = HVPFN_DOWN(phys_addr);
537+
hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
537538

538539
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
539540

drivers/hv/hv_balloon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ static unsigned long handle_pg_range(unsigned long pg_start,
905905
* We have some residual hot add range
906906
* that needs to be hot added; hot add
907907
* it now. Hot add a multiple of
908-
* of HA_CHUNK that fully covers the pages
908+
* HA_CHUNK that fully covers the pages
909909
* we have.
910910
*/
911911
size = (has->end_pfn - has->ha_end_pfn);

drivers/pci/controller/pci-hyperv.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ static void hv_pci_compose_compl(void *context, struct pci_response *resp,
16141614

16151615
static u32 hv_compose_msi_req_v1(
16161616
struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
1617-
u32 slot, u8 vector, u8 vector_count)
1617+
u32 slot, u8 vector, u16 vector_count)
16181618
{
16191619
int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
16201620
int_pkt->wslot.slot = slot;
@@ -1642,7 +1642,7 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
16421642

16431643
static u32 hv_compose_msi_req_v2(
16441644
struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
1645-
u32 slot, u8 vector, u8 vector_count)
1645+
u32 slot, u8 vector, u16 vector_count)
16461646
{
16471647
int cpu;
16481648

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

16621662
static u32 hv_compose_msi_req_v3(
16631663
struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
1664-
u32 slot, u32 vector, u8 vector_count)
1664+
u32 slot, u32 vector, u16 vector_count)
16651665
{
16661666
int cpu;
16671667

@@ -1701,7 +1701,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
17011701
struct compose_comp_ctxt comp;
17021702
struct tran_int_desc *int_desc;
17031703
struct msi_desc *msi_desc;
1704-
u8 vector, vector_count;
1704+
/*
1705+
* vector_count should be u16: see hv_msi_desc, hv_msi_desc2
1706+
* and hv_msi_desc3. vector must be u32: see hv_msi_desc3.
1707+
*/
1708+
u16 vector_count;
1709+
u32 vector;
17051710
struct {
17061711
struct pci_packet pci_pkt;
17071712
union {
@@ -1767,6 +1772,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
17671772
vector_count = 1;
17681773
}
17691774

1775+
/*
1776+
* hv_compose_msi_req_v1 and v2 are for x86 only, meaning 'vector'
1777+
* can't exceed u8. Cast 'vector' down to u8 for v1/v2 explicitly
1778+
* for better readability.
1779+
*/
17701780
memset(&ctxt, 0, sizeof(ctxt));
17711781
init_completion(&comp.comp_pkt.host_event);
17721782
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)
17771787
size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
17781788
dest,
17791789
hpdev->desc.win_slot.slot,
1780-
vector,
1790+
(u8)vector,
17811791
vector_count);
17821792
break;
17831793

@@ -1786,7 +1796,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
17861796
size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
17871797
dest,
17881798
hpdev->desc.win_slot.slot,
1789-
vector,
1799+
(u8)vector,
17901800
vector_count);
17911801
break;
17921802

include/asm-generic/hyperv-tlfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ struct ms_hyperv_tsc_page {
102102
volatile s64 tsc_offset;
103103
} __packed;
104104

105+
union hv_reference_tsc_msr {
106+
u64 as_uint64;
107+
struct {
108+
u64 enable:1;
109+
u64 reserved:11;
110+
u64 pfn:52;
111+
} __packed;
112+
};
113+
105114
/*
106115
* The guest OS needs to register the guest ID with the hypervisor.
107116
* The guest ID is a 64 bit entity and the structure of this ID is

0 commit comments

Comments
 (0)