Linux-HyperV List
 help / color / mirror / Atom feed
* [PATCH v3 07/16] x86/kvm/emulate: Introduce EM_ASM_1SRC2
From: Peter Zijlstra @ 2025-07-14 10:20 UTC (permalink / raw)
  To: x86
  Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, hpa,
	seanjc, pbonzini, ardb, kees, Arnd Bergmann, gregkh, jpoimboe,
	peterz, linux-hyperv, linux-kernel, kvm, linux-efi, samitolvanen,
	ojeda
In-Reply-To: <20250714102011.758008629@infradead.org>

Replace the FASTOP1SRC2*() instructions.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/emulate.c |   34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -317,6 +317,24 @@ static int em_##op(struct x86_emulate_ct
 	ON64(case 8: __EM_ASM_1(op##q, rax); break;) \
 	EM_ASM_END
 
+/* 1-operand, using "c" (src2) */
+#define EM_ASM_1SRC2(op, name) \
+	EM_ASM_START(name) \
+	case 1: __EM_ASM_1(op##b, cl); break; \
+	case 2: __EM_ASM_1(op##w, cx); break; \
+	case 4: __EM_ASM_1(op##l, ecx); break; \
+	ON64(case 8: __EM_ASM_1(op##q, rcx); break;) \
+	EM_ASM_END
+
+/* 1-operand, using "c" (src2) with exception */
+#define EM_ASM_1SRC2EX(op, name) \
+	EM_ASM_START(name) \
+	case 1: __EM_ASM_1_EX(op##b, cl); break; \
+	case 2: __EM_ASM_1_EX(op##w, cx); break; \
+	case 4: __EM_ASM_1_EX(op##l, ecx); break; \
+	ON64(case 8: __EM_ASM_1(op##q, rcx); break;) \
+	EM_ASM_END
+
 /* 2-operand, using "a" (dst), "d" (src) */
 #define EM_ASM_2(op) \
 	EM_ASM_START(op) \
@@ -1074,10 +1092,10 @@ EM_ASM_2(cmp);
 EM_ASM_2(test);
 EM_ASM_2(xadd);
 
-FASTOP1SRC2(mul, mul_ex);
-FASTOP1SRC2(imul, imul_ex);
-FASTOP1SRC2EX(div, div_ex);
-FASTOP1SRC2EX(idiv, idiv_ex);
+EM_ASM_1SRC2(mul, mul_ex);
+EM_ASM_1SRC2(imul, imul_ex);
+EM_ASM_1SRC2EX(div, div_ex);
+EM_ASM_1SRC2EX(idiv, idiv_ex);
 
 FASTOP3WCL(shld);
 FASTOP3WCL(shrd);
@@ -4103,10 +4121,10 @@ static const struct opcode group3[] = {
 	I(DstMem | SrcImm | NoWrite, em_test),
 	I(DstMem | SrcNone | Lock, em_not),
 	I(DstMem | SrcNone | Lock, em_neg),
-	F(DstXacc | Src2Mem, em_mul_ex),
-	F(DstXacc | Src2Mem, em_imul_ex),
-	F(DstXacc | Src2Mem, em_div_ex),
-	F(DstXacc | Src2Mem, em_idiv_ex),
+	I(DstXacc | Src2Mem, em_mul_ex),
+	I(DstXacc | Src2Mem, em_imul_ex),
+	I(DstXacc | Src2Mem, em_div_ex),
+	I(DstXacc | Src2Mem, em_idiv_ex),
 };
 
 static const struct opcode group4[] = {



^ permalink raw reply

* [PATCH v3 05/16] x86/kvm/emulate: Introduce EM_ASM_2W
From: Peter Zijlstra @ 2025-07-14 10:20 UTC (permalink / raw)
  To: x86
  Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, hpa,
	seanjc, pbonzini, ardb, kees, Arnd Bergmann, gregkh, jpoimboe,
	peterz, linux-hyperv, linux-kernel, kvm, linux-efi, samitolvanen,
	ojeda
In-Reply-To: <20250714102011.758008629@infradead.org>

Replace the FASTOP2W instructions.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/emulate.c |   47 ++++++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 19 deletions(-)

--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -335,6 +335,15 @@ static int em_##op(struct x86_emulate_ct
 	ON64(case 8: __EM_ASM_2(op##q, rdx, rax); break;) \
 	EM_ASM_END
 
+/* 2-operand, word only (no byte op) */
+#define EM_ASM_2W(op) \
+	EM_ASM_START(op) \
+	case 1: break; \
+	case 2: __EM_ASM_2(op##w, ax, dx); break; \
+	case 4: __EM_ASM_2(op##l, eax, edx); break; \
+	ON64(case 8: __EM_ASM_2(op##q, rax, rdx); break;) \
+	EM_ASM_END
+
 /*
  * fastop functions have a special calling convention:
  *
@@ -1064,7 +1073,7 @@ FASTOP1SRC2EX(idiv, idiv_ex);
 FASTOP3WCL(shld);
 FASTOP3WCL(shrd);
 
-FASTOP2W(imul);
+EM_ASM_2W(imul);
 
 EM_ASM_1(not);
 EM_ASM_1(neg);
@@ -1079,12 +1088,12 @@ FASTOP2CL(shl);
 FASTOP2CL(shr);
 FASTOP2CL(sar);
 
-FASTOP2W(bsf);
-FASTOP2W(bsr);
-FASTOP2W(bt);
-FASTOP2W(bts);
-FASTOP2W(btr);
-FASTOP2W(btc);
+EM_ASM_2W(bsf);
+EM_ASM_2W(bsr);
+EM_ASM_2W(bt);
+EM_ASM_2W(bts);
+EM_ASM_2W(btr);
+EM_ASM_2W(btc);
 
 EM_ASM_2R(cmp, cmp_r);
 
@@ -1093,7 +1102,7 @@ static int em_bsf_c(struct x86_emulate_c
 	/* If src is zero, do not writeback, but update flags */
 	if (ctxt->src.val == 0)
 		ctxt->dst.type = OP_NONE;
-	return fastop(ctxt, em_bsf);
+	return em_bsf(ctxt);
 }
 
 static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
@@ -1101,7 +1110,7 @@ static int em_bsr_c(struct x86_emulate_c
 	/* If src is zero, do not writeback, but update flags */
 	if (ctxt->src.val == 0)
 		ctxt->dst.type = OP_NONE;
-	return fastop(ctxt, em_bsr);
+	return em_bsr(ctxt);
 }
 
 static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
@@ -3221,7 +3230,7 @@ static int em_xchg(struct x86_emulate_ct
 static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
 {
 	ctxt->dst.val = ctxt->src2.val;
-	return fastop(ctxt, em_imul);
+	return em_imul(ctxt);
 }
 
 static int em_cwd(struct x86_emulate_ctxt *ctxt)
@@ -4135,10 +4144,10 @@ static const struct group_dual group7 =
 
 static const struct opcode group8[] = {
 	N, N, N, N,
-	F(DstMem | SrcImmByte | NoWrite,		em_bt),
-	F(DstMem | SrcImmByte | Lock | PageTable,	em_bts),
-	F(DstMem | SrcImmByte | Lock,			em_btr),
-	F(DstMem | SrcImmByte | Lock | PageTable,	em_btc),
+	I(DstMem | SrcImmByte | NoWrite,		em_bt),
+	I(DstMem | SrcImmByte | Lock | PageTable,	em_bts),
+	I(DstMem | SrcImmByte | Lock,			em_btr),
+	I(DstMem | SrcImmByte | Lock | PageTable,	em_btc),
 };
 
 /*
@@ -4459,27 +4468,27 @@ static const struct opcode twobyte_table
 	/* 0xA0 - 0xA7 */
 	I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg),
 	II(ImplicitOps, em_cpuid, cpuid),
-	F(DstMem | SrcReg | ModRM | BitOp | NoWrite, em_bt),
+	I(DstMem | SrcReg | ModRM | BitOp | NoWrite, em_bt),
 	F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shld),
 	F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
 	/* 0xA8 - 0xAF */
 	I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
 	II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
-	F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
+	I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
 	F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
 	F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
-	GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul),
+	GD(0, &group15), I(DstReg | SrcMem | ModRM, em_imul),
 	/* 0xB0 - 0xB7 */
 	I2bv(DstMem | SrcReg | ModRM | Lock | PageTable | SrcWrite, em_cmpxchg),
 	I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
-	F(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
+	I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
 	I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
 	I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg),
 	D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xB8 - 0xBF */
 	N, N,
 	G(BitOp, group8),
-	F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
+	I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
 	I(DstReg | SrcMem | ModRM, em_bsf_c),
 	I(DstReg | SrcMem | ModRM, em_bsr_c),
 	D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),



^ permalink raw reply

* [PATCH v3 06/16] x86/kvm/emulate: Introduce EM_ASM_2CL
From: Peter Zijlstra @ 2025-07-14 10:20 UTC (permalink / raw)
  To: x86
  Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, hpa,
	seanjc, pbonzini, ardb, kees, Arnd Bergmann, gregkh, jpoimboe,
	peterz, linux-hyperv, linux-kernel, kvm, linux-efi, samitolvanen,
	ojeda
In-Reply-To: <20250714102011.758008629@infradead.org>

Replace the FASTOP2CL instructions.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/emulate.c |   39 ++++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 15 deletions(-)

--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -344,6 +344,15 @@ static int em_##op(struct x86_emulate_ct
 	ON64(case 8: __EM_ASM_2(op##q, rax, rdx); break;) \
 	EM_ASM_END
 
+/* 2-operand, using "a" (dst) and CL (src2) */
+#define EM_ASM_2CL(op) \
+	EM_ASM_START(op) \
+	case 1: __EM_ASM_2(op##b, al, cl); break; \
+	case 2: __EM_ASM_2(op##w, ax, cl); break; \
+	case 4: __EM_ASM_2(op##l, eax, cl); break; \
+	ON64(case 8: __EM_ASM_2(op##q, rax, cl); break;) \
+	EM_ASM_END
+
 /*
  * fastop functions have a special calling convention:
  *
@@ -1080,13 +1089,13 @@ EM_ASM_1(neg);
 EM_ASM_1(inc);
 EM_ASM_1(dec);
 
-FASTOP2CL(rol);
-FASTOP2CL(ror);
-FASTOP2CL(rcl);
-FASTOP2CL(rcr);
-FASTOP2CL(shl);
-FASTOP2CL(shr);
-FASTOP2CL(sar);
+EM_ASM_2CL(rol);
+EM_ASM_2CL(ror);
+EM_ASM_2CL(rcl);
+EM_ASM_2CL(rcr);
+EM_ASM_2CL(shl);
+EM_ASM_2CL(shr);
+EM_ASM_2CL(sar);
 
 EM_ASM_2W(bsf);
 EM_ASM_2W(bsr);
@@ -4079,14 +4088,14 @@ static const struct opcode group1A[] = {
 };
 
 static const struct opcode group2[] = {
-	F(DstMem | ModRM, em_rol),
-	F(DstMem | ModRM, em_ror),
-	F(DstMem | ModRM, em_rcl),
-	F(DstMem | ModRM, em_rcr),
-	F(DstMem | ModRM, em_shl),
-	F(DstMem | ModRM, em_shr),
-	F(DstMem | ModRM, em_shl),
-	F(DstMem | ModRM, em_sar),
+	I(DstMem | ModRM, em_rol),
+	I(DstMem | ModRM, em_ror),
+	I(DstMem | ModRM, em_rcl),
+	I(DstMem | ModRM, em_rcr),
+	I(DstMem | ModRM, em_shl),
+	I(DstMem | ModRM, em_shr),
+	I(DstMem | ModRM, em_shl),
+	I(DstMem | ModRM, em_sar),
 };
 
 static const struct opcode group3[] = {



^ permalink raw reply

* [PATCH v3 04/16] x86/kvm/emulate: Introduce EM_ASM_2R
From: Peter Zijlstra @ 2025-07-14 10:20 UTC (permalink / raw)
  To: x86
  Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, hpa,
	seanjc, pbonzini, ardb, kees, Arnd Bergmann, gregkh, jpoimboe,
	peterz, linux-hyperv, linux-kernel, kvm, linux-efi, samitolvanen,
	ojeda
In-Reply-To: <20250714102011.758008629@infradead.org>

Replace the FASTOP2R instruction.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/emulate.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -326,6 +326,15 @@ static int em_##op(struct x86_emulate_ct
 	ON64(case 8: __EM_ASM_2(op##q, rax, rdx); break;) \
 	EM_ASM_END
 
+/* 2-operand, reversed */
+#define EM_ASM_2R(op, name) \
+	EM_ASM_START(name) \
+	case 1: __EM_ASM_2(op##b, dl, al); break; \
+	case 2: __EM_ASM_2(op##w, dx, ax); break; \
+	case 4: __EM_ASM_2(op##l, edx, eax); break; \
+	ON64(case 8: __EM_ASM_2(op##q, rdx, rax); break;) \
+	EM_ASM_END
+
 /*
  * fastop functions have a special calling convention:
  *
@@ -1077,8 +1086,7 @@ FASTOP2W(bts);
 FASTOP2W(btr);
 FASTOP2W(btc);
 
-
-FASTOP2R(cmp, cmp_r);
+EM_ASM_2R(cmp, cmp_r);
 
 static int em_bsf_c(struct x86_emulate_ctxt *ctxt)
 {
@@ -4336,12 +4344,12 @@ static const struct opcode opcode_table[
 	I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
 	I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov),
 	I2bv(SrcSI | DstDI | Mov | String | TwoMemOp, em_mov),
-	F2bv(SrcSI | DstDI | String | NoWrite | TwoMemOp, em_cmp_r),
+	I2bv(SrcSI | DstDI | String | NoWrite | TwoMemOp, em_cmp_r),
 	/* 0xA8 - 0xAF */
 	I2bv(DstAcc | SrcImm | NoWrite, em_test),
 	I2bv(SrcAcc | DstDI | Mov | String, em_mov),
 	I2bv(SrcSI | DstAcc | Mov | String, em_mov),
-	F2bv(SrcAcc | DstDI | String | NoWrite, em_cmp_r),
+	I2bv(SrcAcc | DstDI | String | NoWrite, em_cmp_r),
 	/* 0xB0 - 0xB7 */
 	X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)),
 	/* 0xB8 - 0xBF */



^ permalink raw reply

* [PATCH v3 15/16] x86/fred: KVM: VMX: Always use FRED for IRQs when CONFIG_X86_FRED=y
From: Peter Zijlstra @ 2025-07-14 10:20 UTC (permalink / raw)
  To: x86
  Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, hpa,
	seanjc, pbonzini, ardb, kees, Arnd Bergmann, gregkh, jpoimboe,
	peterz, linux-hyperv, linux-kernel, kvm, linux-efi, samitolvanen,
	ojeda
In-Reply-To: <20250714102011.758008629@infradead.org>

From: Sean Christopherson <seanjc@google.com>

Now that FRED provides C-code entry points for handling IRQs, use the
FRED infrastructure for forwarding IRQs even if FRED is fully
disabled, e.g. isn't supported in hardware. Avoiding the non-FRED
assembly trampolines into the IDT handlers for IRQs eliminates the
associated non-CFI indirect call (KVM performs a CALL by doing a
lookup on the IDT using the IRQ vector).

Keep NMIs on the legacy IDT path, as the FRED NMI entry code relies on
FRED's architectural behavior with respect to NMI blocking, i.e. doesn't
jump through the myriad hoops needed to deal with IRET "unexpectedly"
unmasking NMIs.  KVM's NMI path already makes a direct CALL to C-code,
i.e. isn't problematic for CFI.  KVM does make a short detour through
assembly code to build the stack frame, but the "FRED entry from KVM"
path does the same.

Force FRED for 64-bit kernels if KVM_INTEL is enabled, as the benefits of
eliminating the IRQ trampoline usage far outwieghts the code overhead for
FRED.

Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/kvm/Kconfig   |    1 +
 arch/x86/kvm/vmx/vmx.c |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -97,6 +97,7 @@ config KVM_INTEL
 	depends on KVM && IA32_FEAT_CTL
 	select KVM_GENERIC_PRIVATE_MEM if INTEL_TDX_HOST
 	select KVM_GENERIC_MEMORY_ATTRIBUTES if INTEL_TDX_HOST
+	select X86_FRED if X86_64
 	help
 	  Provides support for KVM on processors equipped with Intel's VT
 	  extensions, a.k.a. Virtual Machine Extensions (VMX).
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6989,8 +6989,14 @@ static void handle_external_interrupt_ir
 	    "unexpected VM-Exit interrupt info: 0x%x", intr_info))
 		return;
 
+	/*
+	 * Invoke the kernel's IRQ handler for the vector.  Use the FRED path
+	 * when it's available even if FRED isn't fully enabled, e.g. even if
+	 * FRED isn't supported in hardware, in order to avoid the indirect
+	 * CALL in the non-FRED path.
+	 */
 	kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ);
-	if (cpu_feature_enabled(X86_FEATURE_FRED))
+	if (IS_ENABLED(CONFIG_X86_FRED))
 		fred_entry_from_kvm(EVENT_TYPE_EXTINT, vector);
 	else
 		vmx_do_interrupt_irqoff(gate_offset((gate_desc *)host_idt_base + vector));



^ permalink raw reply

* Re: [PATCH v4 1/2] dt-bindings: microsoft: Add vmbus message-connection-id property
From: Krzysztof Kozlowski @ 2025-07-14  7:56 UTC (permalink / raw)
  To: Hardik Garg
  Cc: apais, conor+dt, decui, devicetree, haiyangz, hargar, krzk+dt,
	kys, linux-hyperv, linux-kernel, robh, ssengar, wei.liu
In-Reply-To: <1752479327-19753-1-git-send-email-hargar@linux.microsoft.com>

On 14/07/2025 09:48, Hardik Garg wrote:
> Thank you for your review, Krzysztof. I apologize for the delay in 
> my response.

You got review after 8 hours.

You respond after 3 weeks.

> 
>>> What is a connection ID and why it cannot be inferred from existing
>>> system API?
> 
> The connection-id determines which hypervisor communication channel the
> guest should use to talk to the VMBus host. Reading from DeviceTree allows
> platforms to specify their preferred communication channel, making it more
> flexible (I will add this detail in the commit message). Presently, this

We don't add properties to make things flexible.



> value is hardcoded and there is no existing API to read it.
> 
>>> There's a reason why you have here generic property - this is generic
>>> and/or discoverable and/or whatever software interface. Adding now more
>>> properties, just because you made it generic, is not the way.
> 
> Presently the value is hardcoded and we want to provide a functionality to
> the user to specify their prefered communication channel. This is a
> virtualized hardware property for us.

That's not really acceptable reason. With such approach I would add 100
properties to make various things "flexible".

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v4 1/2] dt-bindings: microsoft: Add vmbus message-connection-id property
From: Hardik Garg @ 2025-07-14  7:48 UTC (permalink / raw)
  To: krzk
  Cc: apais, conor+dt, decui, devicetree, haiyangz, hargar, hargar,
	krzk+dt, kys, linux-hyperv, linux-kernel, robh, ssengar, wei.liu
In-Reply-To: <20250620-strange-rough-gharial-d2bc73@kuoka>

Thank you for your review, Krzysztof. I apologize for the delay in 
my response.

>> What is a connection ID and why it cannot be inferred from existing
>> system API?

The connection-id determines which hypervisor communication channel the
guest should use to talk to the VMBus host. Reading from DeviceTree allows
platforms to specify their preferred communication channel, making it more
flexible (I will add this detail in the commit message). Presently, this
value is hardcoded and there is no existing API to read it.

>> There's a reason why you have here generic property - this is generic
>> and/or discoverable and/or whatever software interface. Adding now more
>> properties, just because you made it generic, is not the way.

Presently the value is hardcoded and we want to provide a functionality to
the user to specify their prefered communication channel. This is a
virtualized hardware property for us.

>> Drop |

I will remove "|".

>> Missing constraints, defaults, if this stays, but frankly speaking it
>> looks really not appropriate, considering lack of any explanation in the
>> binding or in commit msg.

I will add constraints, and defaults.

Please let me know if there are any other issues that I should fix with
the next version of the patch and thank you again for the review.




Regards,
Hardik

^ permalink raw reply

* RE: [PATCH v4] tools/hv: fcopy: Fix irregularities with size of ring buffer
From: Long Li @ 2025-07-12 20:00 UTC (permalink / raw)
  To: Naman Jain, KY Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
	Michael Kelley
  Cc: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
	Olaf Hering, Saurabh Sengar
In-Reply-To: <326fcccb-1563-4cb7-a137-993d4ce3cedc@linux.microsoft.com>

> Subject: Re: [PATCH v4] tools/hv: fcopy: Fix irregularities with size of ring buffer
>
>
>
> On 7/11/2025 11:38 AM, Naman Jain wrote:
> > Size of ring buffer, as defined in uio_hv_generic driver, is no longer
> > fixed to 16 KB. This creates a problem in fcopy, since this size was
> > hardcoded. With the change in place to make ring sysfs node actually
> > reflect the size of underlying ring buffer, it is safe to get the size
> > of ring sysfs file and use it for ring buffer size in fcopy daemon.
> > Fix the issue of disparity in ring buffer size, by making it dynamic
> > in fcopy uio daemon.
> >
> > Cc: stable@vger.kernel.org
> > Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
> > Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> > Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>

Reviewed-by: Long Li <longli@microsoft.com>

> > ---
>
> Noticed that I missed adding change logs (again). Adding them now.
>
> Changes since v3:
> https://lore.kern/
> el.org%2Fall%2F20250708080319.3904-1-
> namjain%40linux.microsoft.com%2F&data=05%7C02%7Clongli%40microsoft.com
> %7C5061a1ac57814cbe542b08ddc042614e%7C72f988bf86f141af91ab2d7cd011
> db47%7C1%7C0%7C638878113544016320%7CUnknown%7CTWFpbGZsb3d8eyJ
> FbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWF
> pbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=loiQdbSCzLluXmFECiIrrHbbK9
> fqxJBbLTSAB26%2Bd0k%3D&reserved=0
> * Added a goto label for freeing desc memory. (Saurabh)
> * Avoided declaring device path twice by using FCOPY_DEVICE_PATH(subdir)
> (Saurabh)
> * Removed extra len variable assignment in main() (Saurabh)
> * added Reviewed-by tag from Saurabh
>
> Changes since v2:
> https://lore.kern/
> el.org%2Fall%2F20250701104837.3006-1-
> namjain%40linux.microsoft.com%2F&data=05%7C02%7Clongli%40microsoft.com
> %7C5061a1ac57814cbe542b08ddc042614e%7C72f988bf86f141af91ab2d7cd011
> db47%7C1%7C0%7C638878113544051861%7CUnknown%7CTWFpbGZsb3d8eyJ
> FbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWF
> pbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=PZ9GdNL7%2FD6NfxZPhCOX
> 7zQ2DbspDgQs%2BS75PFGAFG4%3D&reserved=0
> * Removed fallback mechanism to default size, to keep fcopy behavior consistent
> (Long's suggestion). If ring sysfs file is not present for some reason, things are
> already bad and its the right thing for fcopy to abort.
>
> Changes since v1:
> https://lore.kern/
> el.org%2Fall%2F20250620070618.3097-1-
> namjain%40linux.microsoft.com%2F&data=05%7C02%7Clongli%40microsoft.com
> %7C5061a1ac57814cbe542b08ddc042614e%7C72f988bf86f141af91ab2d7cd011
> db47%7C1%7C0%7C638878113544063634%7CUnknown%7CTWFpbGZsb3d8eyJ
> FbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWF
> pbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=LQsSaTjbam4DPAzMQmy1%
> 2BMB0%2BKb6L7d3xKkM954mpls%3D&reserved=0
>
> * Removed unnecessary type casting in malloc for desc variable (Olaf)
> * Added retry mechanisms to avoid potential race conditions (Michael)
> * Moved the logic to fetch ring size to a later part in main (Michael)
>
>
>
> >   tools/hv/hv_fcopy_uio_daemon.c | 91 ++++++++++++++++++++++++++++++--
> --
> >   1 file changed, 81 insertions(+), 10 deletions(-)
> >
> > diff --git a/tools/hv/hv_fcopy_uio_daemon.c
> > b/tools/hv/hv_fcopy_uio_daemon.c index 0198321d14a2..7d9bcb066d3f
> > 100644
> > --- a/tools/hv/hv_fcopy_uio_daemon.c
> > +++ b/tools/hv/hv_fcopy_uio_daemon.c
> > @@ -35,7 +35,10 @@
> >   #define WIN8_SRV_MINOR            1
> >   #define WIN8_SRV_VERSION  (WIN8_SRV_MAJOR << 16 |
> WIN8_SRV_MINOR)
> >
> > -#define FCOPY_UIO          "/sys/bus/vmbus/devices/eb765408-105f-49b6-
> b4aa-c123b64d17d4/uio"
> > +#define FCOPY_DEVICE_PATH(subdir) \
> > +   "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/"
> #subdir
> > +#define FCOPY_UIO_PATH          FCOPY_DEVICE_PATH(uio)
> > +#define FCOPY_CHANNELS_PATH     FCOPY_DEVICE_PATH(channels)
> >
> >   #define FCOPY_VER_COUNT           1
> >   static const int fcopy_versions[] = { @@ -47,9 +50,62 @@ static
> > const int fw_versions[] = {
> >     UTIL_FW_VERSION
> >   };
> >
> > -#define HV_RING_SIZE               0x4000 /* 16KB ring buffer size */
> > +static uint32_t get_ring_buffer_size(void) {
> > +   char ring_path[PATH_MAX];
> > +   DIR *dir;
> > +   struct dirent *entry;
> > +   struct stat st;
> > +   uint32_t ring_size = 0;
> > +   int retry_count = 0;
> > +
> > +   /* Find the channel directory */
> > +   dir = opendir(FCOPY_CHANNELS_PATH);
> > +   if (!dir) {
> > +           usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and
> retry once */
> > +           dir = opendir(FCOPY_CHANNELS_PATH);
> > +           if (!dir) {
> > +                   syslog(LOG_ERR, "Failed to open channels
> directory: %s", strerror(errno));
> > +                   return 0;
> > +           }
> > +   }
> > +
> > +retry_once:
> > +   while ((entry = readdir(dir)) != NULL) {
> > +           if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0
> &&
> > +               strcmp(entry->d_name, "..") != 0) {
> > +                   snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
> > +                            FCOPY_CHANNELS_PATH, entry->d_name);
> > +
> > +                   if (stat(ring_path, &st) == 0) {
> > +                           /*
> > +                            * stat returns size of Tx, Rx rings combined,
> > +                            * so take half of it for individual ring size.
> > +                            */
> > +                           ring_size = (uint32_t)st.st_size / 2;
> > +                           syslog(LOG_INFO, "Ring buffer size from %s: %u
> bytes",
> > +                                  ring_path, ring_size);
> > +                           break;
> > +                   }
> > +           }
> > +   }
> >
> > -static unsigned char desc[HV_RING_SIZE];
> > +   if (!ring_size && retry_count == 0) {
> > +           retry_count = 1;
> > +           rewinddir(dir);
> > +           usleep(100 * 1000); /* Wait 100ms and retry once */
> > +           goto retry_once;
> > +   }
> > +
> > +   closedir(dir);
> > +
> > +   if (!ring_size)
> > +           syslog(LOG_ERR, "Could not determine ring size");
> > +
> > +   return ring_size;
> > +}
> > +
> > +static unsigned char *desc;
> >
> >   static int target_fd;
> >   static char target_fname[PATH_MAX];
> > @@ -406,7 +462,7 @@ int main(int argc, char *argv[])
> >     int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
> >     struct vmbus_br txbr, rxbr;
> >     void *ring;
> > -   uint32_t len = HV_RING_SIZE;
> > +   uint32_t ring_size, len;
> >     char uio_name[NAME_MAX] = {0};
> >     char uio_dev_path[PATH_MAX] = {0};
> >
> > @@ -437,7 +493,20 @@ int main(int argc, char *argv[])
> >     openlog("HV_UIO_FCOPY", 0, LOG_USER);
> >     syslog(LOG_INFO, "starting; pid is:%d", getpid());
> >
> > -   fcopy_get_first_folder(FCOPY_UIO, uio_name);
> > +   ring_size = get_ring_buffer_size();
> > +   if (!ring_size) {
> > +           ret = -ENODEV;
> > +           goto exit;
> > +   }
> > +
> > +   desc = malloc(ring_size * sizeof(unsigned char));
> > +   if (!desc) {
> > +           syslog(LOG_ERR, "malloc failed for desc buffer");
> > +           ret = -ENOMEM;
> > +           goto exit;
> > +   }
> > +
> > +   fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name);
> >     snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
> >     fcopy_fd = open(uio_dev_path, O_RDWR);
> >
> > @@ -445,17 +514,17 @@ int main(int argc, char *argv[])
> >             syslog(LOG_ERR, "open %s failed; error: %d %s",
> >                    uio_dev_path, errno, strerror(errno));
> >             ret = fcopy_fd;
> > -           goto exit;
> > +           goto free_desc;
> >     }
> >
> > -   ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
> > +   ring = vmbus_uio_map(&fcopy_fd, ring_size);
> >     if (!ring) {
> >             ret = errno;
> >             syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret,
> strerror(ret));
> >             goto close;
> >     }
> > -   vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
> > -   vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
> > +   vmbus_br_setup(&txbr, ring, ring_size);
> > +   vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
> >
> >     rxbr.vbr->imask = 0;
> >
> > @@ -472,7 +541,7 @@ int main(int argc, char *argv[])
> >                     goto close;
> >             }
> >
> > -           len = HV_RING_SIZE;
> > +           len = ring_size;
> >             ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
> >             if (unlikely(ret <= 0)) {
> >                     /* This indicates a failure to communicate (or worse) */
> @@
> > -492,6 +561,8 @@ int main(int argc, char *argv[])
> >     }
> >   close:
> >     close(fcopy_fd);
> > +free_desc:
> > +   free(desc);
> >   exit:
> >     return ret;
> >   }
> >
> > base-commit: b551c4e2a98a177a06148cf16505643cd2108386


^ permalink raw reply

* [PATCH] mshv_eventfd: convert to CLASS(fd)
From: Al Viro @ 2025-07-12 16:52 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: linux-hyperv

[in viro/vfs.git #work.fd; if nobody objects, into #for-next it goes...]

similar to 66635b077624 ("assorted variants of irqfd setup: convert
to CLASS(fd)") a year ago...
    
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c
index 8dd22be2ca0b..48c514da34eb 100644
--- a/drivers/hv/mshv_eventfd.c
+++ b/drivers/hv/mshv_eventfd.c
@@ -377,10 +377,11 @@ static int mshv_irqfd_assign(struct mshv_partition *pt,
 	struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
 	struct mshv_irqfd *irqfd, *tmp;
 	unsigned int events;
-	struct fd f;
 	int ret;
 	int idx;
 
+	CLASS(fd, f)(args->fd);
+
 	irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
 	if (!irqfd)
 		return -ENOMEM;
@@ -390,8 +391,7 @@ static int mshv_irqfd_assign(struct mshv_partition *pt,
 	INIT_WORK(&irqfd->irqfd_shutdown, mshv_irqfd_shutdown);
 	seqcount_spinlock_init(&irqfd->irqfd_irqe_sc, &pt->pt_irqfds_lock);
 
-	f = fdget(args->fd);
-	if (!fd_file(f)) {
+	if (fd_empty(f)) {
 		ret = -EBADF;
 		goto out;
 	}
@@ -496,12 +496,6 @@ static int mshv_irqfd_assign(struct mshv_partition *pt,
 		mshv_assert_irq_slow(irqfd);
 
 	srcu_read_unlock(&pt->pt_irq_srcu, idx);
-	/*
-	 * do not drop the file until the irqfd is fully initialized, otherwise
-	 * we might race against the POLLHUP
-	 */
-	fdput(f);
-
 	return 0;
 
 fail:
@@ -514,8 +508,6 @@ static int mshv_irqfd_assign(struct mshv_partition *pt,
 	if (eventfd && !IS_ERR(eventfd))
 		eventfd_ctx_put(eventfd);
 
-	fdput(f);
-
 out:
 	kfree(irqfd);
 	return ret;

^ permalink raw reply related

* [PATCH net v3] hv_netvsc: Set VF priv_flags to IFF_NO_ADDRCONF before open to prevent IPv6 addrconf
From: Li Tian @ 2025-07-12 10:07 UTC (permalink / raw)
  To: netdev, linux-hyperv
  Cc: linux-kernel, Haiyang Zhang, Dexuan Cui, Stephen Hemminger,
	Long Li

Set an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.

Commit 8a321cf7becc
("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")

This new flag change was not made to hv_netvsc resulting in the VF being
assinged an IPv6.

Fixes: 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")
Suggested-by: Cathy Avery <cavery@redhat.com>
Signed-off-by: Li Tian <litian@redhat.com>
---
v3:
  - only fix commit message.
v2: https://lore.kernel.org/netdev/20250710024603.10162-1-litian@redhat.com/
  - instead of replacing flag, add it.
v1: https://lore.kernel.org/netdev/20250710024603.10162-1-litian@redhat.com/
---
 drivers/net/hyperv/netvsc_drv.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c41a025c66f0..8be9bce66a4e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2317,8 +2317,11 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
 	if (!ndev)
 		return NOTIFY_DONE;
 
-	/* set slave flag before open to prevent IPv6 addrconf */
+	/* Set slave flag and no addrconf flag before open
+	 * to prevent IPv6 addrconf.
+	 */
 	vf_netdev->flags |= IFF_SLAVE;
+	vf_netdev->priv_flags |= IFF_NO_ADDRCONF;
 	return NOTIFY_DONE;
 }
 
-- 
2.50.0


^ permalink raw reply related

* Re: [PATCH v2] hv_netvsc: Set VF priv_flags to IFF_NO_ADDRCONF before open to prevent IPv6 addrconf
From: Jakub Kicinski @ 2025-07-11 23:12 UTC (permalink / raw)
  To: Li Tian
  Cc: netdev, linux-hyperv, linux-kernel, Haiyang Zhang, Dexuan Cui,
	Stephen Hemminger, Long Li
In-Reply-To: <20250711041700.13103-1-litian@redhat.com>

On Fri, 11 Jul 2025 12:17:00 +0800 Li Tian wrote:
> Commit 8a321cf7becc6c065ae595b837b826a2a81036b9
> ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")

Please trim the hash to the same length as in the Fixes tag.
 
> This new flag change was not made to hv_netvsc resulting in the VF being
> assinged an IPv6.
> 
> Fixes: 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")
> 
> Suggested-by: Cathy Avery <cavery@redhat.com>
> 
> Signed-off-by: Li Tian <litian@redhat.com>

Please remove the empty lines between the Fixes tag, and the ...-by:
tags.

Please remember to increase the patch version between revisions.

Please don't post the new versions in reply to old versions.

Please don't post new versions within 24 of the previous one.

Please read:
https://www.kernel.org/doc/html/next/process/maintainer-netdev.html
-- 
pw-bot: cr

^ permalink raw reply

* [PATCH net] hv_netvsc: Switch VF namespace in netvsc_open instead
From: Haiyang Zhang @ 2025-07-11 20:57 UTC (permalink / raw)
  To: linux-hyperv, netdev
  Cc: haiyangz, kys, wei.liu, decui, edumazet, kuba, pabeni, stephen,
	davem, linux-kernel, stable

From: Haiyang Zhang <haiyangz@microsoft.com>

The existing code move the VF NIC to new namespace when NETDEV_REGISTER is
received on netvsc NIC. During deletion of the namespace,
default_device_exit_batch() >> default_device_exit_net() is called. When
netvsc NIC is moved back and registered to the default namespace, it
automatically brings VF NIC back to the default namespace. This will cause
the default_device_exit_net() >> for_each_netdev_safe loop unable to detect
the list end, and hit NULL ptr:

[  231.449420] mana 7870:00:00.0 enP30832s1: Moved VF to namespace with: eth0
[  231.449656] BUG: kernel NULL pointer dereference, address: 0000000000000010
[  231.450246] #PF: supervisor read access in kernel mode
[  231.450579] #PF: error_code(0x0000) - not-present page
[  231.450916] PGD 17b8a8067 P4D 0 
[  231.451163] Oops: Oops: 0000 [#1] SMP NOPTI
[  231.451450] CPU: 82 UID: 0 PID: 1394 Comm: kworker/u768:1 Not tainted 6.16.0-rc4+ #3 VOLUNTARY 
[  231.452042] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/21/2024
[  231.452692] Workqueue: netns cleanup_net
[  231.452947] RIP: 0010:default_device_exit_batch+0x16c/0x3f0
[  231.453326] Code: c0 0c f5 b3 e8 d5 db fe ff 48 85 c0 74 15 48 c7 c2 f8 fd ca b2 be 10 00 00 00 48 8d 7d c0 e8 7b 77 25 00 49 8b 86 28 01 00 00 <48> 8b 50 10 4c 8b 2a 4c 8d 62 f0 49 83 ed 10 4c 39 e0 0f 84 d6 00
[  231.454294] RSP: 0018:ff75fc7c9bf9fd00 EFLAGS: 00010246
[  231.454610] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 61c8864680b583eb
[  231.455094] RDX: ff1fa9f71462d800 RSI: ff75fc7c9bf9fd38 RDI: 0000000030766564
[  231.455686] RBP: ff75fc7c9bf9fd78 R08: 0000000000000000 R09: 0000000000000000
[  231.456126] R10: 0000000000000001 R11: 0000000000000004 R12: ff1fa9f70088e340
[  231.456621] R13: ff1fa9f70088e340 R14: ffffffffb3f50c20 R15: ff1fa9f7103e6340
[  231.457161] FS:  0000000000000000(0000) GS:ff1faa6783a08000(0000) knlGS:0000000000000000
[  231.457707] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  231.458031] CR2: 0000000000000010 CR3: 0000000179ab2006 CR4: 0000000000b73ef0
[  231.458434] Call Trace:
[  231.458600]  <TASK>
[  231.458777]  ops_undo_list+0x100/0x220
[  231.459015]  cleanup_net+0x1b8/0x300
[  231.459285]  process_one_work+0x184/0x340

To fix it, move the VF namespace switching code from the NETDEV_REGISTER
event handler to netvsc_open().


Cc: stable@vger.kernel.org
Fixes: 4c262801ea60 ("hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event")
Reported-by: Cathy Avery <cavery@redhat.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/netvsc_drv.c | 43 ++++++++++-----------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 42d98e99566e..074ecc346108 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -135,6 +135,19 @@ static int netvsc_open(struct net_device *net)
 	}
 
 	if (vf_netdev) {
+		if (!net_eq(dev_net(net), dev_net(vf_netdev))) {
+			ret = dev_change_net_namespace(vf_netdev, dev_net(net),
+						       "eth%d");
+			if (ret)
+				netdev_err(vf_netdev,
+					   "Cannot move to same ns as %s: %d\n",
+					   net->name, ret);
+			else
+				netdev_info(vf_netdev,
+					    "Moved VF to namespace with: %s\n",
+					    net->name);
+		}
+
 		/* Setting synthetic device up transparently sets
 		 * slave as up. If open fails, then slave will be
 		 * still be offline (and not used).
@@ -2772,31 +2785,6 @@ static struct  hv_driver netvsc_drv = {
 	},
 };
 
-/* Set VF's namespace same as the synthetic NIC */
-static void netvsc_event_set_vf_ns(struct net_device *ndev)
-{
-	struct net_device_context *ndev_ctx = netdev_priv(ndev);
-	struct net_device *vf_netdev;
-	int ret;
-
-	vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
-	if (!vf_netdev)
-		return;
-
-	if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) {
-		ret = dev_change_net_namespace(vf_netdev, dev_net(ndev),
-					       "eth%d");
-		if (ret)
-			netdev_err(vf_netdev,
-				   "Cannot move to same namespace as %s: %d\n",
-				   ndev->name, ret);
-		else
-			netdev_info(vf_netdev,
-				    "Moved VF to namespace with: %s\n",
-				    ndev->name);
-	}
-}
-
 /*
  * On Hyper-V, every VF interface is matched with a corresponding
  * synthetic interface. The synthetic interface is presented first
@@ -2809,11 +2797,6 @@ static int netvsc_netdev_event(struct notifier_block *this,
 	struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
 	int ret = 0;
 
-	if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) {
-		netvsc_event_set_vf_ns(event_dev);
-		return NOTIFY_DONE;
-	}
-
 	ret = check_dev_is_matching_vf(event_dev);
 	if (ret != 0)
 		return NOTIFY_DONE;
-- 
2.34.1


^ permalink raw reply related

* RE: [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt()
From: Michael Kelley @ 2025-07-11 19:28 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	wei.liu@kernel.org, tglx@linutronix.de, bhelgaas@google.com,
	romank@linux.microsoft.com
  Cc: kys@microsoft.com, haiyangz@microsoft.com, decui@microsoft.com,
	catalin.marinas@arm.com, will@kernel.org, mingo@redhat.com,
	bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com,
	lpieralisi@kernel.org, kw@linux.com, robh@kernel.org,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org
In-Reply-To: <1752261532-7225-3-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Friday, July 11, 2025 12:19 PM
> From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> 
> Move some of the logic of hv_irq_compose_irq_message() into
> hv_map_msi_interrupt(). Make hv_map_msi_interrupt() a globally-available
> helper function, which will be used to map PCI interrupts when running
> in the root partition.
> 
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
> ---
>  arch/x86/hyperv/irqdomain.c     | 40 ++++++++++++++++++++++++---------
>  arch/x86/include/asm/mshyperv.h |  2 ++
>  2 files changed, 31 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
> index ad4dff48cf14..090f5ac9f492 100644
> --- a/arch/x86/hyperv/irqdomain.c
> +++ b/arch/x86/hyperv/irqdomain.c
> @@ -173,13 +173,34 @@ static union hv_device_id hv_build_pci_dev_id(struct pci_dev *dev)
>  	return dev_id;
>  }
> 
> -static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector,
> -				struct hv_interrupt_entry *entry)
> +/**
> + * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
> + * @data:      Describes the IRQ
> + * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
> + *
> + * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +int hv_map_msi_interrupt(struct irq_data *data,
> +			 struct hv_interrupt_entry *out_entry)
>  {
> -	union hv_device_id device_id = hv_build_pci_dev_id(dev);
> +	struct irq_cfg *cfg = irqd_cfg(data);
> +	struct hv_interrupt_entry dummy;
> +	union hv_device_id device_id;
> +	struct msi_desc *msidesc;
> +	struct pci_dev *dev;
> +	int cpu;
> 
> -	return hv_map_interrupt(device_id, false, cpu, vector, entry);
> +	msidesc = irq_data_get_msi_desc(data);
> +	dev = msi_desc_to_pci_dev(msidesc);
> +	device_id = hv_build_pci_dev_id(dev);
> +	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
> +
> +	return hv_map_interrupt(device_id, false, cpu, cfg->vector,
> +				out_entry ? out_entry : &dummy);
>  }
> +EXPORT_SYMBOL_GPL(hv_map_msi_interrupt);
> 
>  static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg)
>  {
> @@ -192,11 +213,11 @@ static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi
>  static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry);
>  static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  {
> -	struct hv_interrupt_entry out_entry, *stored_entry;
> +	struct hv_interrupt_entry *stored_entry;
>  	struct irq_cfg *cfg = irqd_cfg(data);
>  	struct msi_desc *msidesc;
>  	struct pci_dev *dev;
> -	int cpu, ret;
> +	int ret;
> 
>  	msidesc = irq_data_get_msi_desc(data);
>  	dev = msi_desc_to_pci_dev(msidesc);
> @@ -206,8 +227,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  		return;
>  	}
> 
> -	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
> -
>  	if (data->chip_data) {
>  		/*
>  		 * This interrupt is already mapped. Let's unmap first.
> @@ -234,15 +253,14 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  		return;
>  	}
> 
> -	ret = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
> +	ret = hv_map_msi_interrupt(data, stored_entry);
>  	if (ret) {
>  		kfree(stored_entry);
>  		return;
>  	}
> 
> -	*stored_entry = out_entry;
>  	data->chip_data = stored_entry;
> -	entry_to_msi_msg(&out_entry, msg);
> +	entry_to_msi_msg(data->chip_data, msg);
> 
>  	return;
>  }
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index ab097a3a8b75..abc4659f5809 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -242,6 +242,8 @@ static inline void hv_apic_init(void) {}
> 
>  struct irq_domain *hv_create_pci_msi_domain(void);
> 
> +int hv_map_msi_interrupt(struct irq_data *data,
> +			 struct hv_interrupt_entry *out_entry);
>  int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
>  		struct hv_interrupt_entry *entry);
>  int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
> --
> 2.34.1

Reviewed-by: Michael Kelley <mhklinux@outlook.com>

^ permalink raw reply

* RE: [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event
From: Michael Kelley @ 2025-07-11 19:25 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	wei.liu@kernel.org, tglx@linutronix.de, bhelgaas@google.com,
	romank@linux.microsoft.com
  Cc: kys@microsoft.com, haiyangz@microsoft.com, decui@microsoft.com,
	catalin.marinas@arm.com, will@kernel.org, mingo@redhat.com,
	bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com,
	lpieralisi@kernel.org, kw@linux.com, robh@kernel.org,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org
In-Reply-To: <1752261532-7225-2-git-send-email-nunodasneves@linux.microsoft.com>

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Friday, July 11, 2025 12:19 PM
> 
> When running nested, these hypercalls must be sent to the L0 hypervisor
> or VMBus will fail.
> 
> Remove hv_do_nested_hypercall() and hv_do_fast_nested_hypercall8()
> altogether and open-code these cases, since there are only 2 and all
> they do is add the nested bit.
> 
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
> ---
>  arch/x86/include/asm/mshyperv.h | 20 --------------------
>  drivers/hv/connection.c         |  5 ++++-
>  drivers/hv/hv.c                 |  6 ++++--
>  3 files changed, 8 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index e1752ba47e67..ab097a3a8b75 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -112,12 +112,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
>  	return hv_status;
>  }
> 
> -/* Hypercall to the L0 hypervisor */
> -static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output)
> -{
> -	return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output);
> -}
> -
>  /* Fast hypercall with 8 bytes of input and no output */
>  static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
>  {
> @@ -165,13 +159,6 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
>  	return _hv_do_fast_hypercall8(control, input1);
>  }
> 
> -static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1)
> -{
> -	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
> -
> -	return _hv_do_fast_hypercall8(control, input1);
> -}
> -
>  /* Fast hypercall with 16 bytes of input */
>  static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
>  {
> @@ -223,13 +210,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
>  	return _hv_do_fast_hypercall16(control, input1, input2);
>  }
> 
> -static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2)
> -{
> -	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
> -
> -	return _hv_do_fast_hypercall16(control, input1, input2);
> -}
> -
>  extern struct hv_vp_assist_page **hv_vp_assist_page;
> 
>  static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
> diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
> index be490c598785..1fe3573ae52a 100644
> --- a/drivers/hv/connection.c
> +++ b/drivers/hv/connection.c
> @@ -519,7 +519,10 @@ void vmbus_set_event(struct vmbus_channel *channel)
>  		else
>  			WARN_ON_ONCE(1);
>  	} else {
> -		hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
> +		u64 control = HVCALL_SIGNAL_EVENT;
> +
> +		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
> +		hv_do_fast_hypercall8(control, channel->sig_event);
>  	}
>  }
>  EXPORT_SYMBOL_GPL(vmbus_set_event);
> diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
> index 308c8f279df8..b14c5f9e0ef2 100644
> --- a/drivers/hv/hv.c
> +++ b/drivers/hv/hv.c
> @@ -85,8 +85,10 @@ int hv_post_message(union hv_connection_id connection_id,
>  		else
>  			status = HV_STATUS_INVALID_PARAMETER;
>  	} else {
> -		status = hv_do_hypercall(HVCALL_POST_MESSAGE,
> -					 aligned_msg, NULL);
> +		u64 control = HVCALL_POST_MESSAGE;
> +
> +		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
> +		status = hv_do_hypercall(control, aligned_msg, NULL);
>  	}
> 
>  	local_irq_restore(flags);
> --
> 2.34.1

Reviewed-by: Michael Kelley <mhklinux@outlook.com>


^ permalink raw reply

* [PATCH v3 3/3] PCI: hv: Use the correct hypercall for unmasking interrupts on nested
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves
In-Reply-To: <1752261532-7225-1-git-send-email-nunodasneves@linux.microsoft.com>

From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>

Running as nested root on MSHV imposes a different requirement
for the pci-hyperv controller.

In this setup, the interrupt will first come to the L1 (nested) hypervisor,
which will deliver it to the appropriate root CPU. Instead of issuing the
RETARGET hypercall, issue the MAP_DEVICE_INTERRUPT hypercall to L1 to
complete the setup.

Rename hv_arch_irq_unmask() to hv_irq_retarget_interrupt().

Co-developed-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/controller/pci-hyperv.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 275b23af3de2..13680363ff19 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -600,7 +600,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
 #define hv_msi_prepare		pci_msi_prepare
 
 /**
- * hv_arch_irq_unmask() - "Unmask" the IRQ by setting its current
+ * hv_irq_retarget_interrupt() - "Unmask" the IRQ by setting its current
  * affinity.
  * @data:	Describes the IRQ
  *
@@ -609,7 +609,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
  * is built out of this PCI bus's instance GUID and the function
  * number of the device.
  */
-static void hv_arch_irq_unmask(struct irq_data *data)
+static void hv_irq_retarget_interrupt(struct irq_data *data)
 {
 	struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
 	struct hv_retarget_device_interrupt *params;
@@ -714,6 +714,20 @@ static void hv_arch_irq_unmask(struct irq_data *data)
 		dev_err(&hbus->hdev->device,
 			"%s() failed: %#llx", __func__, res);
 }
+
+static void hv_arch_irq_unmask(struct irq_data *data)
+{
+	if (hv_root_partition())
+		/*
+		 * In case of the nested root partition, the nested hypervisor
+		 * is taking care of interrupt remapping and thus the
+		 * MAP_DEVICE_INTERRUPT hypercall is required instead of
+		 * RETARGET_INTERRUPT.
+		 */
+		(void)hv_map_msi_interrupt(data, NULL);
+	else
+		hv_irq_retarget_interrupt(data);
+}
 #elif defined(CONFIG_ARM64)
 /*
  * SPI vectors to use for vPCI; arch SPIs range is [32, 1019], but leaving a bit
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt()
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves
In-Reply-To: <1752261532-7225-1-git-send-email-nunodasneves@linux.microsoft.com>

From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>

Move some of the logic of hv_irq_compose_irq_message() into
hv_map_msi_interrupt(). Make hv_map_msi_interrupt() a globally-available
helper function, which will be used to map PCI interrupts when running
in the root partition.

Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
---
 arch/x86/hyperv/irqdomain.c     | 40 ++++++++++++++++++++++++---------
 arch/x86/include/asm/mshyperv.h |  2 ++
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index ad4dff48cf14..090f5ac9f492 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -173,13 +173,34 @@ static union hv_device_id hv_build_pci_dev_id(struct pci_dev *dev)
 	return dev_id;
 }
 
-static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector,
-				struct hv_interrupt_entry *entry)
+/**
+ * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
+ * @data:      Describes the IRQ
+ * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
+ *
+ * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int hv_map_msi_interrupt(struct irq_data *data,
+			 struct hv_interrupt_entry *out_entry)
 {
-	union hv_device_id device_id = hv_build_pci_dev_id(dev);
+	struct irq_cfg *cfg = irqd_cfg(data);
+	struct hv_interrupt_entry dummy;
+	union hv_device_id device_id;
+	struct msi_desc *msidesc;
+	struct pci_dev *dev;
+	int cpu;
 
-	return hv_map_interrupt(device_id, false, cpu, vector, entry);
+	msidesc = irq_data_get_msi_desc(data);
+	dev = msi_desc_to_pci_dev(msidesc);
+	device_id = hv_build_pci_dev_id(dev);
+	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
+
+	return hv_map_interrupt(device_id, false, cpu, cfg->vector,
+				out_entry ? out_entry : &dummy);
 }
+EXPORT_SYMBOL_GPL(hv_map_msi_interrupt);
 
 static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg)
 {
@@ -192,11 +213,11 @@ static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi
 static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry);
 static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
-	struct hv_interrupt_entry out_entry, *stored_entry;
+	struct hv_interrupt_entry *stored_entry;
 	struct irq_cfg *cfg = irqd_cfg(data);
 	struct msi_desc *msidesc;
 	struct pci_dev *dev;
-	int cpu, ret;
+	int ret;
 
 	msidesc = irq_data_get_msi_desc(data);
 	dev = msi_desc_to_pci_dev(msidesc);
@@ -206,8 +227,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 		return;
 	}
 
-	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
-
 	if (data->chip_data) {
 		/*
 		 * This interrupt is already mapped. Let's unmap first.
@@ -234,15 +253,14 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 		return;
 	}
 
-	ret = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
+	ret = hv_map_msi_interrupt(data, stored_entry);
 	if (ret) {
 		kfree(stored_entry);
 		return;
 	}
 
-	*stored_entry = out_entry;
 	data->chip_data = stored_entry;
-	entry_to_msi_msg(&out_entry, msg);
+	entry_to_msi_msg(data->chip_data, msg);
 
 	return;
 }
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index ab097a3a8b75..abc4659f5809 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -242,6 +242,8 @@ static inline void hv_apic_init(void) {}
 
 struct irq_domain *hv_create_pci_msi_domain(void);
 
+int hv_map_msi_interrupt(struct irq_data *data,
+			 struct hv_interrupt_entry *out_entry);
 int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
 		struct hv_interrupt_entry *entry);
 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves
In-Reply-To: <1752261532-7225-1-git-send-email-nunodasneves@linux.microsoft.com>

When running nested, these hypercalls must be sent to the L0 hypervisor
or VMBus will fail.

Remove hv_do_nested_hypercall() and hv_do_fast_nested_hypercall8()
altogether and open-code these cases, since there are only 2 and all
they do is add the nested bit.

Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
---
 arch/x86/include/asm/mshyperv.h | 20 --------------------
 drivers/hv/connection.c         |  5 ++++-
 drivers/hv/hv.c                 |  6 ++++--
 3 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index e1752ba47e67..ab097a3a8b75 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -112,12 +112,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 	return hv_status;
 }
 
-/* Hypercall to the L0 hypervisor */
-static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output)
-{
-	return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output);
-}
-
 /* Fast hypercall with 8 bytes of input and no output */
 static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
 {
@@ -165,13 +159,6 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
 	return _hv_do_fast_hypercall8(control, input1);
 }
 
-static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1)
-{
-	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
-
-	return _hv_do_fast_hypercall8(control, input1);
-}
-
 /* Fast hypercall with 16 bytes of input */
 static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
 {
@@ -223,13 +210,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
 	return _hv_do_fast_hypercall16(control, input1, input2);
 }
 
-static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2)
-{
-	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
-
-	return _hv_do_fast_hypercall16(control, input1, input2);
-}
-
 extern struct hv_vp_assist_page **hv_vp_assist_page;
 
 static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index be490c598785..1fe3573ae52a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -519,7 +519,10 @@ void vmbus_set_event(struct vmbus_channel *channel)
 		else
 			WARN_ON_ONCE(1);
 	} else {
-		hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
+		u64 control = HVCALL_SIGNAL_EVENT;
+
+		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
+		hv_do_fast_hypercall8(control, channel->sig_event);
 	}
 }
 EXPORT_SYMBOL_GPL(vmbus_set_event);
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 308c8f279df8..b14c5f9e0ef2 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -85,8 +85,10 @@ int hv_post_message(union hv_connection_id connection_id,
 		else
 			status = HV_STATUS_INVALID_PARAMETER;
 	} else {
-		status = hv_do_hypercall(HVCALL_POST_MESSAGE,
-					 aligned_msg, NULL);
+		u64 control = HVCALL_POST_MESSAGE;
+
+		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
+		status = hv_do_hypercall(control, aligned_msg, NULL);
 	}
 
 	local_irq_restore(flags);
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 0/3] Nested virtualization fixes for root partition
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves

Fixes for running as nested root partition on the Microsoft Hypervisor.

The first patch changes vmbus to make hypercalls to the L0 hypervisor
instead of the L1. This is needed because L0 hypervisor, not the L1, is
the one hosting the Windows root partition with the VMM that provides
vmbus.

The 2nd and 3rd patches fix interrupt unmasking on nested. In this
scenario, the L1 (nested) hypervisor does the interrupt mapping to root
partition cores. The vectors just need to be mapped with
MAP_DEVICE_INTERRUPT instead of affinitized with RETARGET_INTERRUPT.

Changes in v3:
- Remove 3 patches (#1,#3,#4 from v2) which were merged already (Wei Liu)
- Fix bug in #1 introduced in v2 (Michael Kelley)
- Improve commit message in #2 (Michael Kelley)
- Document return value of hv_map_msi_interrupt() in #2 (Michael Kelley)

Changes in v2:
- Reword commit messages for clarity (Michael Kelley, Bjorn Helgaas)
- Open-code nested hypercalls to reduce unnecessary code (Michael Kelley)
- Add patch (#3) to fix cpu_online_mask issue (Thomas Gleixner)
- Add patch (#4) to fix error return values (Michael Kelley)
- Remove several redundant error messages and checks (Michael Kelley)

Nuno Das Neves (1):
  Drivers: hv: Use nested hypercall for post message and signal event

Stanislav Kinsburskii (2):
  x86/hyperv: Expose hv_map_msi_interrupt()
  PCI: hv: Use the correct hypercall for unmasking interrupts on nested

 arch/x86/hyperv/irqdomain.c         | 40 +++++++++++++++++++++--------
 arch/x86/include/asm/mshyperv.h     | 22 ++--------------
 drivers/hv/connection.c             |  5 +++-
 drivers/hv/hv.c                     |  6 +++--
 drivers/pci/controller/pci-hyperv.c | 18 +++++++++++--
 5 files changed, 55 insertions(+), 36 deletions(-)

-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v2] hv_netvsc: Set VF priv_flags to IFF_NO_ADDRCONF before open to prevent IPv6 addrconf
From: Stephen Hemminger @ 2025-07-11 14:58 UTC (permalink / raw)
  To: Li Tian; +Cc: netdev, linux-hyperv, linux-kernel, Haiyang Zhang, Dexuan Cui
In-Reply-To: <20250711040623.12605-1-litian@redhat.com>

On Fri, 11 Jul 2025 12:06:23 +0800
Li Tian <litian@redhat.com> wrote:

> Set an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.
> 
> Commit 8a321cf7becc6c065ae595b837b826a2a81036b9
> ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")


Should be Fixes: tag since the reference commit caused the regression.
Yes, it is a way to blame and track.

^ permalink raw reply

* Re: [PATCH v4] tools/hv: fcopy: Fix irregularities with size of ring buffer
From: Naman Jain @ 2025-07-11  6:15 UTC (permalink / raw)
  To: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Michael Kelley
  Cc: linux-hyperv, linux-kernel, Olaf Hering, Saurabh Sengar
In-Reply-To: <20250711060846.9168-1-namjain@linux.microsoft.com>



On 7/11/2025 11:38 AM, Naman Jain wrote:
> Size of ring buffer, as defined in uio_hv_generic driver, is no longer
> fixed to 16 KB. This creates a problem in fcopy, since this size was
> hardcoded. With the change in place to make ring sysfs node actually
> reflect the size of underlying ring buffer, it is safe to get the size
> of ring sysfs file and use it for ring buffer size in fcopy daemon.
> Fix the issue of disparity in ring buffer size, by making it dynamic
> in fcopy uio daemon.
> 
> Cc: stable@vger.kernel.org
> Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
> ---

Noticed that I missed adding change logs (again). Adding them now.

Changes since v3:
https://lore.kernel.org/all/20250708080319.3904-1-namjain@linux.microsoft.com/
* Added a goto label for freeing desc memory. (Saurabh)
* Avoided declaring device path twice by using FCOPY_DEVICE_PATH(subdir)
(Saurabh)
* Removed extra len variable assignment in main() (Saurabh)
* added Reviewed-by tag from Saurabh

Changes since v2:
https://lore.kernel.org/all/20250701104837.3006-1-namjain@linux.microsoft.com/
* Removed fallback mechanism to default size, to keep fcopy behavior
consistent (Long's suggestion). If ring sysfs file is not present for
some reason, things are already bad and its the right thing for fcopy to
abort.

Changes since v1:
https://lore.kernel.org/all/20250620070618.3097-1-namjain@linux.microsoft.com/

* Removed unnecessary type casting in malloc for desc variable (Olaf)
* Added retry mechanisms to avoid potential race conditions (Michael)
* Moved the logic to fetch ring size to a later part in main (Michael)



>   tools/hv/hv_fcopy_uio_daemon.c | 91 ++++++++++++++++++++++++++++++----
>   1 file changed, 81 insertions(+), 10 deletions(-)
> 
> diff --git a/tools/hv/hv_fcopy_uio_daemon.c b/tools/hv/hv_fcopy_uio_daemon.c
> index 0198321d14a2..7d9bcb066d3f 100644
> --- a/tools/hv/hv_fcopy_uio_daemon.c
> +++ b/tools/hv/hv_fcopy_uio_daemon.c
> @@ -35,7 +35,10 @@
>   #define WIN8_SRV_MINOR		1
>   #define WIN8_SRV_VERSION	(WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
>   
> -#define FCOPY_UIO		"/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio"
> +#define FCOPY_DEVICE_PATH(subdir) \
> +	"/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir
> +#define FCOPY_UIO_PATH          FCOPY_DEVICE_PATH(uio)
> +#define FCOPY_CHANNELS_PATH     FCOPY_DEVICE_PATH(channels)
>   
>   #define FCOPY_VER_COUNT		1
>   static const int fcopy_versions[] = {
> @@ -47,9 +50,62 @@ static const int fw_versions[] = {
>   	UTIL_FW_VERSION
>   };
>   
> -#define HV_RING_SIZE		0x4000 /* 16KB ring buffer size */
> +static uint32_t get_ring_buffer_size(void)
> +{
> +	char ring_path[PATH_MAX];
> +	DIR *dir;
> +	struct dirent *entry;
> +	struct stat st;
> +	uint32_t ring_size = 0;
> +	int retry_count = 0;
> +
> +	/* Find the channel directory */
> +	dir = opendir(FCOPY_CHANNELS_PATH);
> +	if (!dir) {
> +		usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
> +		dir = opendir(FCOPY_CHANNELS_PATH);
> +		if (!dir) {
> +			syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno));
> +			return 0;
> +		}
> +	}
> +
> +retry_once:
> +	while ((entry = readdir(dir)) != NULL) {
> +		if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
> +		    strcmp(entry->d_name, "..") != 0) {
> +			snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
> +				 FCOPY_CHANNELS_PATH, entry->d_name);
> +
> +			if (stat(ring_path, &st) == 0) {
> +				/*
> +				 * stat returns size of Tx, Rx rings combined,
> +				 * so take half of it for individual ring size.
> +				 */
> +				ring_size = (uint32_t)st.st_size / 2;
> +				syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
> +				       ring_path, ring_size);
> +				break;
> +			}
> +		}
> +	}
>   
> -static unsigned char desc[HV_RING_SIZE];
> +	if (!ring_size && retry_count == 0) {
> +		retry_count = 1;
> +		rewinddir(dir);
> +		usleep(100 * 1000); /* Wait 100ms and retry once */
> +		goto retry_once;
> +	}
> +
> +	closedir(dir);
> +
> +	if (!ring_size)
> +		syslog(LOG_ERR, "Could not determine ring size");
> +
> +	return ring_size;
> +}
> +
> +static unsigned char *desc;
>   
>   static int target_fd;
>   static char target_fname[PATH_MAX];
> @@ -406,7 +462,7 @@ int main(int argc, char *argv[])
>   	int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
>   	struct vmbus_br txbr, rxbr;
>   	void *ring;
> -	uint32_t len = HV_RING_SIZE;
> +	uint32_t ring_size, len;
>   	char uio_name[NAME_MAX] = {0};
>   	char uio_dev_path[PATH_MAX] = {0};
>   
> @@ -437,7 +493,20 @@ int main(int argc, char *argv[])
>   	openlog("HV_UIO_FCOPY", 0, LOG_USER);
>   	syslog(LOG_INFO, "starting; pid is:%d", getpid());
>   
> -	fcopy_get_first_folder(FCOPY_UIO, uio_name);
> +	ring_size = get_ring_buffer_size();
> +	if (!ring_size) {
> +		ret = -ENODEV;
> +		goto exit;
> +	}
> +
> +	desc = malloc(ring_size * sizeof(unsigned char));
> +	if (!desc) {
> +		syslog(LOG_ERR, "malloc failed for desc buffer");
> +		ret = -ENOMEM;
> +		goto exit;
> +	}
> +
> +	fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name);
>   	snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
>   	fcopy_fd = open(uio_dev_path, O_RDWR);
>   
> @@ -445,17 +514,17 @@ int main(int argc, char *argv[])
>   		syslog(LOG_ERR, "open %s failed; error: %d %s",
>   		       uio_dev_path, errno, strerror(errno));
>   		ret = fcopy_fd;
> -		goto exit;
> +		goto free_desc;
>   	}
>   
> -	ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
> +	ring = vmbus_uio_map(&fcopy_fd, ring_size);
>   	if (!ring) {
>   		ret = errno;
>   		syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret));
>   		goto close;
>   	}
> -	vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
> -	vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
> +	vmbus_br_setup(&txbr, ring, ring_size);
> +	vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
>   
>   	rxbr.vbr->imask = 0;
>   
> @@ -472,7 +541,7 @@ int main(int argc, char *argv[])
>   			goto close;
>   		}
>   
> -		len = HV_RING_SIZE;
> +		len = ring_size;
>   		ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
>   		if (unlikely(ret <= 0)) {
>   			/* This indicates a failure to communicate (or worse) */
> @@ -492,6 +561,8 @@ int main(int argc, char *argv[])
>   	}
>   close:
>   	close(fcopy_fd);
> +free_desc:
> +	free(desc);
>   exit:
>   	return ret;
>   }
> 
> base-commit: b551c4e2a98a177a06148cf16505643cd2108386


^ permalink raw reply

* [PATCH v4] tools/hv: fcopy: Fix irregularities with size of ring buffer
From: Naman Jain @ 2025-07-11  6:08 UTC (permalink / raw)
  To: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
	Michael Kelley
  Cc: linux-hyperv, linux-kernel, Olaf Hering, Saurabh Sengar,
	Naman Jain

Size of ring buffer, as defined in uio_hv_generic driver, is no longer
fixed to 16 KB. This creates a problem in fcopy, since this size was
hardcoded. With the change in place to make ring sysfs node actually
reflect the size of underlying ring buffer, it is safe to get the size
of ring sysfs file and use it for ring buffer size in fcopy daemon.
Fix the issue of disparity in ring buffer size, by making it dynamic
in fcopy uio daemon.

Cc: stable@vger.kernel.org
Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page")
Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
---
 tools/hv/hv_fcopy_uio_daemon.c | 91 ++++++++++++++++++++++++++++++----
 1 file changed, 81 insertions(+), 10 deletions(-)

diff --git a/tools/hv/hv_fcopy_uio_daemon.c b/tools/hv/hv_fcopy_uio_daemon.c
index 0198321d14a2..7d9bcb066d3f 100644
--- a/tools/hv/hv_fcopy_uio_daemon.c
+++ b/tools/hv/hv_fcopy_uio_daemon.c
@@ -35,7 +35,10 @@
 #define WIN8_SRV_MINOR		1
 #define WIN8_SRV_VERSION	(WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
 
-#define FCOPY_UIO		"/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio"
+#define FCOPY_DEVICE_PATH(subdir) \
+	"/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir
+#define FCOPY_UIO_PATH          FCOPY_DEVICE_PATH(uio)
+#define FCOPY_CHANNELS_PATH     FCOPY_DEVICE_PATH(channels)
 
 #define FCOPY_VER_COUNT		1
 static const int fcopy_versions[] = {
@@ -47,9 +50,62 @@ static const int fw_versions[] = {
 	UTIL_FW_VERSION
 };
 
-#define HV_RING_SIZE		0x4000 /* 16KB ring buffer size */
+static uint32_t get_ring_buffer_size(void)
+{
+	char ring_path[PATH_MAX];
+	DIR *dir;
+	struct dirent *entry;
+	struct stat st;
+	uint32_t ring_size = 0;
+	int retry_count = 0;
+
+	/* Find the channel directory */
+	dir = opendir(FCOPY_CHANNELS_PATH);
+	if (!dir) {
+		usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
+		dir = opendir(FCOPY_CHANNELS_PATH);
+		if (!dir) {
+			syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno));
+			return 0;
+		}
+	}
+
+retry_once:
+	while ((entry = readdir(dir)) != NULL) {
+		if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
+		    strcmp(entry->d_name, "..") != 0) {
+			snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
+				 FCOPY_CHANNELS_PATH, entry->d_name);
+
+			if (stat(ring_path, &st) == 0) {
+				/*
+				 * stat returns size of Tx, Rx rings combined,
+				 * so take half of it for individual ring size.
+				 */
+				ring_size = (uint32_t)st.st_size / 2;
+				syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
+				       ring_path, ring_size);
+				break;
+			}
+		}
+	}
 
-static unsigned char desc[HV_RING_SIZE];
+	if (!ring_size && retry_count == 0) {
+		retry_count = 1;
+		rewinddir(dir);
+		usleep(100 * 1000); /* Wait 100ms and retry once */
+		goto retry_once;
+	}
+
+	closedir(dir);
+
+	if (!ring_size)
+		syslog(LOG_ERR, "Could not determine ring size");
+
+	return ring_size;
+}
+
+static unsigned char *desc;
 
 static int target_fd;
 static char target_fname[PATH_MAX];
@@ -406,7 +462,7 @@ int main(int argc, char *argv[])
 	int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
 	struct vmbus_br txbr, rxbr;
 	void *ring;
-	uint32_t len = HV_RING_SIZE;
+	uint32_t ring_size, len;
 	char uio_name[NAME_MAX] = {0};
 	char uio_dev_path[PATH_MAX] = {0};
 
@@ -437,7 +493,20 @@ int main(int argc, char *argv[])
 	openlog("HV_UIO_FCOPY", 0, LOG_USER);
 	syslog(LOG_INFO, "starting; pid is:%d", getpid());
 
-	fcopy_get_first_folder(FCOPY_UIO, uio_name);
+	ring_size = get_ring_buffer_size();
+	if (!ring_size) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	desc = malloc(ring_size * sizeof(unsigned char));
+	if (!desc) {
+		syslog(LOG_ERR, "malloc failed for desc buffer");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name);
 	snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
 	fcopy_fd = open(uio_dev_path, O_RDWR);
 
@@ -445,17 +514,17 @@ int main(int argc, char *argv[])
 		syslog(LOG_ERR, "open %s failed; error: %d %s",
 		       uio_dev_path, errno, strerror(errno));
 		ret = fcopy_fd;
-		goto exit;
+		goto free_desc;
 	}
 
-	ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
+	ring = vmbus_uio_map(&fcopy_fd, ring_size);
 	if (!ring) {
 		ret = errno;
 		syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret));
 		goto close;
 	}
-	vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
-	vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
+	vmbus_br_setup(&txbr, ring, ring_size);
+	vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
 
 	rxbr.vbr->imask = 0;
 
@@ -472,7 +541,7 @@ int main(int argc, char *argv[])
 			goto close;
 		}
 
-		len = HV_RING_SIZE;
+		len = ring_size;
 		ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
 		if (unlikely(ret <= 0)) {
 			/* This indicates a failure to communicate (or worse) */
@@ -492,6 +561,8 @@ int main(int argc, char *argv[])
 	}
 close:
 	close(fcopy_fd);
+free_desc:
+	free(desc);
 exit:
 	return ret;
 }

base-commit: b551c4e2a98a177a06148cf16505643cd2108386
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2] hv_netvsc: Set VF priv_flags to IFF_NO_ADDRCONF before open to prevent IPv6 addrconf
From: Li Tian @ 2025-07-11  4:17 UTC (permalink / raw)
  To: netdev, linux-hyperv
  Cc: linux-kernel, Haiyang Zhang, Dexuan Cui, Stephen Hemminger,
	Long Li
In-Reply-To: <20250710024603.10162-1-litian@redhat.com>

Set an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.

Commit 8a321cf7becc6c065ae595b837b826a2a81036b9
("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")

This new flag change was not made to hv_netvsc resulting in the VF being
assinged an IPv6.

Fixes: 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")

Suggested-by: Cathy Avery <cavery@redhat.com>

Signed-off-by: Li Tian <litian@redhat.com>
---
 drivers/net/hyperv/netvsc_drv.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c41a025c66f0..8be9bce66a4e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2317,8 +2317,11 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
 	if (!ndev)
 		return NOTIFY_DONE;
 
-	/* set slave flag before open to prevent IPv6 addrconf */
+	/* Set slave flag and no addrconf flag before open
+	 * to prevent IPv6 addrconf.
+	 */
 	vf_netdev->flags |= IFF_SLAVE;
+	vf_netdev->priv_flags |= IFF_NO_ADDRCONF;
 	return NOTIFY_DONE;
 }
 
-- 
2.50.0


^ permalink raw reply related

* Re: [PATCH v2] hv_netvsc: Add IFF_NO_ADDRCONF to VF priv_flags before
From: Stephen Hemminger @ 2025-07-11  4:07 UTC (permalink / raw)
  To: Li Tian; +Cc: netdev, linux-hyperv, linux-kernel, Haiyang Zhang, Dexuan Cui
In-Reply-To: <20250711034021.11668-1-litian@redhat.com>

On Fri, 11 Jul 2025 11:39:58 +0800
Li Tian <litian@redhat.com> wrote:

> Add an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.
> 
> Commit 8a321cf7becc6c065ae595b837b826a2a81036b9
> ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")
> 
> This new flag change was not made to hv_netvsc resulting in the VF being
> assinged an IPv6.
> 
> Suggested-by: Cathy Avery <cavery@redhat.com>
> 
> Signed-off-by: Li Tian <litian@redhat.com>
> ---
>  drivers/net/hyperv/netvsc_drv.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index c41a025c66f0..8be9bce66a4e 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -2317,8 +2317,11 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
>  	if (!ndev)
>  		return NOTIFY_DONE;
>  
> -	/* set slave flag before open to prevent IPv6 addrconf */
> +	/* Set slave flag and no addrconf flag before open
> +	 * to prevent IPv6 addrconf.
> +	 */
>  	vf_netdev->flags |= IFF_SLAVE;
> +	vf_netdev->priv_flags |= IFF_NO_ADDRCONF;
>  	return NOTIFY_DONE;
>  }
>  


Thanks this worked originally but got broken, please add:

Fixes: 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")
Cc: lucien.xin@gmail.com

Looks like team and failover have the same problem.

^ permalink raw reply

* [PATCH v2] hv_netvsc: Set VF priv_flags to IFF_NO_ADDRCONF before open to prevent IPv6 addrconf
From: Li Tian @ 2025-07-11  4:06 UTC (permalink / raw)
  To: netdev, linux-hyperv; +Cc: linux-kernel, Haiyang Zhang, Dexuan Cui
In-Reply-To: <20250710024603.10162-1-litian@redhat.com>

Set an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.

Commit 8a321cf7becc6c065ae595b837b826a2a81036b9
("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")

This new flag change was not made to hv_netvsc resulting in the VF being
assinged an IPv6.

Suggested-by: Cathy Avery <cavery@redhat.com>

Signed-off-by: Li Tian <litian@redhat.com>
---
 drivers/net/hyperv/netvsc_drv.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c41a025c66f0..8be9bce66a4e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2317,8 +2317,11 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
 	if (!ndev)
 		return NOTIFY_DONE;
 
-	/* set slave flag before open to prevent IPv6 addrconf */
+	/* Set slave flag and no addrconf flag before open
+	 * to prevent IPv6 addrconf.
+	 */
 	vf_netdev->flags |= IFF_SLAVE;
+	vf_netdev->priv_flags |= IFF_NO_ADDRCONF;
 	return NOTIFY_DONE;
 }
 
-- 
2.50.0


^ permalink raw reply related

* [PATCH v2] hv_netvsc: Add IFF_NO_ADDRCONF to VF priv_flags before
From: Li Tian @ 2025-07-11  3:39 UTC (permalink / raw)
  To: netdev, linux-hyperv; +Cc: linux-kernel, Haiyang Zhang, Dexuan Cui
In-Reply-To: <20250710024603.10162-1-litian@redhat.com>

Add an additional flag IFF_NO_ADDRCONF to prevent ipv6 addrconf.

Commit 8a321cf7becc6c065ae595b837b826a2a81036b9
("net: add IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf")

This new flag change was not made to hv_netvsc resulting in the VF being
assinged an IPv6.

Suggested-by: Cathy Avery <cavery@redhat.com>

Signed-off-by: Li Tian <litian@redhat.com>
---
 drivers/net/hyperv/netvsc_drv.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c41a025c66f0..8be9bce66a4e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2317,8 +2317,11 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
 	if (!ndev)
 		return NOTIFY_DONE;
 
-	/* set slave flag before open to prevent IPv6 addrconf */
+	/* Set slave flag and no addrconf flag before open
+	 * to prevent IPv6 addrconf.
+	 */
 	vf_netdev->flags |= IFF_SLAVE;
+	vf_netdev->priv_flags |= IFF_NO_ADDRCONF;
 	return NOTIFY_DONE;
 }
 
-- 
2.50.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox