Skip to content

Commit c3d1378

Browse files
committed
Merge tag 'hyperv-fixes-signed-20260319' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux
Pull Hyper-V fixes from Wei Liu: - Fix ARM64 MSHV support (Anirudh Rayabharam) - Fix MSHV driver memory handling issues (Stanislav Kinsburskii) - Update maintainers for Hyper-V DRM driver (Saurabh Sengar) - Misc clean up in MSHV crashdump code (Ard Biesheuvel, Uros Bizjak) - Minor improvements to MSHV code (Mukesh R, Wei Liu) - Revert not yet released MSHV scrub partition hypercall (Wei Liu) * tag 'hyperv-fixes-signed-20260319' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: mshv: Fix error handling in mshv_region_pin MAINTAINERS: Update maintainers for Hyper-V DRM driver mshv: Fix use-after-free in mshv_map_user_memory error path mshv: pass struct mshv_user_mem_region by reference x86/hyperv: Use any general-purpose register when saving %cr2 and %cr8 x86/hyperv: Use current_stack_pointer to avoid asm() in hv_hvcrash_ctxt_save() x86/hyperv: Save segment registers directly to memory in hv_hvcrash_ctxt_save() x86/hyperv: Use __naked attribute to fix stackless C function Revert "mshv: expose the scrub partition hypercall" mshv: add arm64 support for doorbell & intercept SINTs mshv: refactor synic init and cleanup x86/hyperv: print out reserved vectors in hexadecimal
2 parents 7006433 + c0e296f commit c3d1378

8 files changed

Lines changed: 261 additions & 143 deletions

File tree

MAINTAINERS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7998,7 +7998,9 @@ F: Documentation/devicetree/bindings/display/himax,hx8357.yaml
79987998
F: drivers/gpu/drm/tiny/hx8357d.c
79997999

80008000
DRM DRIVER FOR HYPERV SYNTHETIC VIDEO DEVICE
8001-
M: Deepak Rawat <drawat.floss@gmail.com>
8001+
M: Dexuan Cui <decui@microsoft.com>
8002+
M: Long Li <longli@microsoft.com>
8003+
M: Saurabh Sengar <ssengar@linux.microsoft.com>
80028004
L: linux-hyperv@vger.kernel.org
80038005
L: dri-devel@lists.freedesktop.org
80048006
S: Maintained

arch/x86/hyperv/hv_crash.c

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,12 @@ static void __noreturn hv_panic_timeout_reboot(void)
107107
cpu_relax();
108108
}
109109

110-
/* This cannot be inlined as it needs stack */
111-
static noinline __noclone void hv_crash_restore_tss(void)
110+
static void hv_crash_restore_tss(void)
112111
{
113112
load_TR_desc();
114113
}
115114

116-
/* This cannot be inlined as it needs stack */
117-
static noinline void hv_crash_clear_kernpt(void)
115+
static void hv_crash_clear_kernpt(void)
118116
{
119117
pgd_t *pgd;
120118
p4d_t *p4d;
@@ -125,6 +123,25 @@ static noinline void hv_crash_clear_kernpt(void)
125123
native_p4d_clear(p4d);
126124
}
127125

126+
127+
static void __noreturn hv_crash_handle(void)
128+
{
129+
hv_crash_restore_tss();
130+
hv_crash_clear_kernpt();
131+
132+
/* we are now fully in devirtualized normal kernel mode */
133+
__crash_kexec(NULL);
134+
135+
hv_panic_timeout_reboot();
136+
}
137+
138+
/*
139+
* __naked functions do not permit function calls, not even to __always_inline
140+
* functions that only contain asm() blocks themselves. So use a macro instead.
141+
*/
142+
#define hv_wrmsr(msr, val) \
143+
asm volatile("wrmsr" :: "c"(msr), "a"((u32)val), "d"((u32)(val >> 32)) : "memory")
144+
128145
/*
129146
* This is the C entry point from the asm glue code after the disable hypercall.
130147
* We enter here in IA32-e long mode, ie, full 64bit mode running on kernel
@@ -133,51 +150,38 @@ static noinline void hv_crash_clear_kernpt(void)
133150
* available. We restore kernel GDT, and rest of the context, and continue
134151
* to kexec.
135152
*/
136-
static asmlinkage void __noreturn hv_crash_c_entry(void)
153+
static void __naked hv_crash_c_entry(void)
137154
{
138-
struct hv_crash_ctxt *ctxt = &hv_crash_ctxt;
139-
140155
/* first thing, restore kernel gdt */
141-
native_load_gdt(&ctxt->gdtr);
156+
asm volatile("lgdt %0" : : "m" (hv_crash_ctxt.gdtr));
142157

143-
asm volatile("movw %%ax, %%ss" : : "a"(ctxt->ss));
144-
asm volatile("movq %0, %%rsp" : : "m"(ctxt->rsp));
158+
asm volatile("movw %0, %%ss\n\t"
159+
"movq %1, %%rsp"
160+
:: "m"(hv_crash_ctxt.ss), "m"(hv_crash_ctxt.rsp));
145161

146-
asm volatile("movw %%ax, %%ds" : : "a"(ctxt->ds));
147-
asm volatile("movw %%ax, %%es" : : "a"(ctxt->es));
148-
asm volatile("movw %%ax, %%fs" : : "a"(ctxt->fs));
149-
asm volatile("movw %%ax, %%gs" : : "a"(ctxt->gs));
162+
asm volatile("movw %0, %%ds" : : "m"(hv_crash_ctxt.ds));
163+
asm volatile("movw %0, %%es" : : "m"(hv_crash_ctxt.es));
164+
asm volatile("movw %0, %%fs" : : "m"(hv_crash_ctxt.fs));
165+
asm volatile("movw %0, %%gs" : : "m"(hv_crash_ctxt.gs));
150166

151-
native_wrmsrq(MSR_IA32_CR_PAT, ctxt->pat);
152-
asm volatile("movq %0, %%cr0" : : "r"(ctxt->cr0));
167+
hv_wrmsr(MSR_IA32_CR_PAT, hv_crash_ctxt.pat);
168+
asm volatile("movq %0, %%cr0" : : "r"(hv_crash_ctxt.cr0));
153169

154-
asm volatile("movq %0, %%cr8" : : "r"(ctxt->cr8));
155-
asm volatile("movq %0, %%cr4" : : "r"(ctxt->cr4));
156-
asm volatile("movq %0, %%cr2" : : "r"(ctxt->cr4));
170+
asm volatile("movq %0, %%cr8" : : "r"(hv_crash_ctxt.cr8));
171+
asm volatile("movq %0, %%cr4" : : "r"(hv_crash_ctxt.cr4));
172+
asm volatile("movq %0, %%cr2" : : "r"(hv_crash_ctxt.cr2));
157173

158-
native_load_idt(&ctxt->idtr);
159-
native_wrmsrq(MSR_GS_BASE, ctxt->gsbase);
160-
native_wrmsrq(MSR_EFER, ctxt->efer);
174+
asm volatile("lidt %0" : : "m" (hv_crash_ctxt.idtr));
175+
hv_wrmsr(MSR_GS_BASE, hv_crash_ctxt.gsbase);
176+
hv_wrmsr(MSR_EFER, hv_crash_ctxt.efer);
161177

162178
/* restore the original kernel CS now via far return */
163-
asm volatile("movzwq %0, %%rax\n\t"
164-
"pushq %%rax\n\t"
165-
"pushq $1f\n\t"
166-
"lretq\n\t"
167-
"1:nop\n\t" : : "m"(ctxt->cs) : "rax");
168-
169-
/* We are in asmlinkage without stack frame, hence make C function
170-
* calls which will buy stack frames.
171-
*/
172-
hv_crash_restore_tss();
173-
hv_crash_clear_kernpt();
174-
175-
/* we are now fully in devirtualized normal kernel mode */
176-
__crash_kexec(NULL);
177-
178-
hv_panic_timeout_reboot();
179+
asm volatile("pushq %q0\n\t"
180+
"pushq %q1\n\t"
181+
"lretq"
182+
:: "r"(hv_crash_ctxt.cs), "r"(hv_crash_handle));
179183
}
180-
/* Tell gcc we are using lretq long jump in the above function intentionally */
184+
/* Tell objtool we are using lretq long jump in the above function intentionally */
181185
STACK_FRAME_NON_STANDARD(hv_crash_c_entry);
182186

183187
static void hv_mark_tss_not_busy(void)
@@ -195,20 +199,20 @@ static void hv_hvcrash_ctxt_save(void)
195199
{
196200
struct hv_crash_ctxt *ctxt = &hv_crash_ctxt;
197201

198-
asm volatile("movq %%rsp,%0" : "=m"(ctxt->rsp));
202+
ctxt->rsp = current_stack_pointer;
199203

200204
ctxt->cr0 = native_read_cr0();
201205
ctxt->cr4 = native_read_cr4();
202206

203-
asm volatile("movq %%cr2, %0" : "=a"(ctxt->cr2));
204-
asm volatile("movq %%cr8, %0" : "=a"(ctxt->cr8));
207+
asm volatile("movq %%cr2, %0" : "=r"(ctxt->cr2));
208+
asm volatile("movq %%cr8, %0" : "=r"(ctxt->cr8));
205209

206-
asm volatile("movl %%cs, %%eax" : "=a"(ctxt->cs));
207-
asm volatile("movl %%ss, %%eax" : "=a"(ctxt->ss));
208-
asm volatile("movl %%ds, %%eax" : "=a"(ctxt->ds));
209-
asm volatile("movl %%es, %%eax" : "=a"(ctxt->es));
210-
asm volatile("movl %%fs, %%eax" : "=a"(ctxt->fs));
211-
asm volatile("movl %%gs, %%eax" : "=a"(ctxt->gs));
210+
asm volatile("movw %%cs, %0" : "=m"(ctxt->cs));
211+
asm volatile("movw %%ss, %0" : "=m"(ctxt->ss));
212+
asm volatile("movw %%ds, %0" : "=m"(ctxt->ds));
213+
asm volatile("movw %%es, %0" : "=m"(ctxt->es));
214+
asm volatile("movw %%fs, %0" : "=m"(ctxt->fs));
215+
asm volatile("movw %%gs, %0" : "=m"(ctxt->gs));
212216

213217
native_store_gdt(&ctxt->gdtr);
214218
store_idt(&ctxt->idtr);

arch/x86/kernel/cpu/mshyperv.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,9 @@ static void hv_reserve_irq_vectors(void)
496496
test_and_set_bit(HYPERV_DBG_FASTFAIL_VECTOR, system_vectors))
497497
BUG();
498498

499-
pr_info("Hyper-V: reserve vectors: %d %d %d\n", HYPERV_DBG_ASSERT_VECTOR,
500-
HYPERV_DBG_SERVICE_VECTOR, HYPERV_DBG_FASTFAIL_VECTOR);
499+
pr_info("Hyper-V: reserve vectors: 0x%x 0x%x 0x%x\n",
500+
HYPERV_DBG_ASSERT_VECTOR, HYPERV_DBG_SERVICE_VECTOR,
501+
HYPERV_DBG_FASTFAIL_VECTOR);
501502
}
502503

503504
static void __init ms_hyperv_init_platform(void)

drivers/hv/mshv_regions.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,17 @@ int mshv_region_pin(struct mshv_mem_region *region)
314314
ret = pin_user_pages_fast(userspace_addr, nr_pages,
315315
FOLL_WRITE | FOLL_LONGTERM,
316316
pages);
317-
if (ret < 0)
317+
if (ret != nr_pages)
318318
goto release_pages;
319319
}
320320

321321
return 0;
322322

323323
release_pages:
324+
if (ret > 0)
325+
done_count += ret;
324326
mshv_region_invalidate_pages(region, 0, done_count);
325-
return ret;
327+
return ret < 0 ? ret : -ENOMEM;
326328
}
327329

328330
static int mshv_region_chunk_unmap(struct mshv_mem_region *region,

drivers/hv/mshv_root.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ struct hv_synic_pages {
190190
};
191191

192192
struct mshv_root {
193-
struct hv_synic_pages __percpu *synic_pages;
194193
spinlock_t pt_ht_lock;
195194
DECLARE_HASHTABLE(pt_htable, MSHV_PARTITIONS_HASH_BITS);
196195
struct hv_partition_property_vmm_capabilities vmm_caps;
@@ -249,8 +248,8 @@ int mshv_register_doorbell(u64 partition_id, doorbell_cb_t doorbell_cb,
249248
void mshv_unregister_doorbell(u64 partition_id, int doorbell_portid);
250249

251250
void mshv_isr(void);
252-
int mshv_synic_init(unsigned int cpu);
253-
int mshv_synic_cleanup(unsigned int cpu);
251+
int mshv_synic_init(struct device *dev);
252+
void mshv_synic_exit(void);
254253

255254
static inline bool mshv_partition_encrypted(struct mshv_partition *partition)
256255
{

0 commit comments

Comments
 (0)