* [PATCH v2 00/12] x86/msr: Inline rdmsr/wrmsr instructions
From: Juergen Gross @ 2025-09-30 7:03 UTC (permalink / raw)
To: linux-kernel, x86, linux-coco, kvm, linux-hyperv, virtualization,
llvm
Cc: xin, Juergen Gross, Kirill A. Shutemov, Dave Hansen,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin,
Sean Christopherson, Paolo Bonzini, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Vitaly Kuznetsov,
Boris Ostrovsky, xen-devel, Ajay Kaher, Alexey Makhalov,
Broadcom internal kernel review list, Andy Lutomirski,
Peter Zijlstra, Nathan Chancellor, Nick Desaulniers,
Bill Wendling, Justin Stitt
When building a kernel with CONFIG_PARAVIRT_XXL the paravirt
infrastructure will always use functions for reading or writing MSRs,
even when running on bare metal.
Switch to inline RDMSR/WRMSR instructions in this case, reducing the
paravirt overhead.
In order to make this less intrusive, some further reorganization of
the MSR access helpers is done in the first 5 patches.
The next 5 patches are converting the non-paravirt case to use direct
inlining of the MSR access instructions, including the WRMSRNS
instruction and the immediate variants of RDMSR and WRMSR if possible.
Patch 11 removes the PV hooks for MSR accesses and implements the
Xen PV cases via calls depending on X86_FEATURE_XENPV, which results
in runtime patching those calls away for the non-XenPV case.
Patch 12 is a final little cleanup patch.
This series has been tested to work with Xen PV and on bare metal.
This series is inspired by Xin Li, who used a similar approach, but
(in my opinion) with some flaws. Originally I thought it should be
possible to use the paravirt infrastructure, but this turned out to be
rather complicated, especially for the Xen PV case in the *_safe()
variants of the MSR access functions.
Changes since V1:
- Use Xin Li's approach for inlining
- Several new patches
Juergen Gross (9):
coco/tdx: Rename MSR access helpers
x86/sev: replace call of native_wrmsr() with native_wrmsrq()
x86/kvm: Remove the KVM private read_msr() function
x86/msr: minimize usage of native_*() msr access functions
x86/msr: Move MSR trace calls one function level up
x86/msr: Use the alternatives mechanism for WRMSR
x86/msr: Use the alternatives mechanism for RDMSR
x86/paravirt: Don't use pv_ops vector for MSR access functions
x86/msr: Reduce number of low level MSR access helpers
Xin Li (Intel) (3):
x86/cpufeatures: Add a CPU feature bit for MSR immediate form
instructions
x86/opcode: Add immediate form MSR instructions
x86/extable: Add support for immediate form MSR instructions
arch/x86/coco/tdx/tdx.c | 8 +-
arch/x86/hyperv/ivm.c | 2 +-
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/fred.h | 2 +-
arch/x86/include/asm/kvm_host.h | 10 -
arch/x86/include/asm/msr.h | 409 +++++++++++++++++++-------
arch/x86/include/asm/paravirt.h | 67 -----
arch/x86/include/asm/paravirt_types.h | 13 -
arch/x86/include/asm/sev-internal.h | 7 +-
arch/x86/kernel/cpu/scattered.c | 1 +
arch/x86/kernel/kvmclock.c | 2 +-
arch/x86/kernel/paravirt.c | 5 -
arch/x86/kvm/svm/svm.c | 16 +-
arch/x86/kvm/vmx/vmx.c | 4 +-
arch/x86/lib/x86-opcode-map.txt | 5 +-
arch/x86/mm/extable.c | 39 ++-
arch/x86/xen/enlighten_pv.c | 24 +-
arch/x86/xen/pmu.c | 5 +-
tools/arch/x86/lib/x86-opcode-map.txt | 5 +-
19 files changed, 383 insertions(+), 242 deletions(-)
--
2.51.0
^ permalink raw reply
* [PATCH v2 04/12] x86/msr: Minimize usage of native_*() msr access functions
From: Juergen Gross @ 2025-09-30 7:03 UTC (permalink / raw)
To: linux-kernel, x86, linux-hyperv, kvm
Cc: xin, Juergen Gross, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Paolo Bonzini, Vitaly Kuznetsov,
Sean Christopherson, Boris Ostrovsky, xen-devel
In-Reply-To: <20250930070356.30695-1-jgross@suse.com>
In order to prepare for some MSR access function reorg work, switch
most users of native_{read|write}_msr[_safe]() to the more generic
rdmsr*()/wrmsr*() variants.
For now this will have some intermediate performance impact with
paravirtualization configured when running on bare metal, but this
is a prereq change for the planned direct inlining of the rdmsr/wrmsr
instructions with this configuration.
The main reason for this switch is the planned move of the MSR trace
function invocation from the native_*() functions to the generic
rdmsr*()/wrmsr*() variants. Without this switch the users of the
native_*() functions would lose the related tracing entries.
Note that the Xen related MSR access functions will not be switched,
as these will be handled after the move of the trace hooks.
Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Sean Christopherson <seanjc@google.com>
Acked-by: Wei Liu <wei.liu@kernel.org>
---
arch/x86/hyperv/ivm.c | 2 +-
arch/x86/kernel/kvmclock.c | 2 +-
arch/x86/kvm/svm/svm.c | 16 ++++++++--------
arch/x86/xen/pmu.c | 4 ++--
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index ade6c665c97e..202ed01dc151 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -327,7 +327,7 @@ int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu)
asm volatile("movl %%ds, %%eax;" : "=a" (vmsa->ds.selector));
hv_populate_vmcb_seg(vmsa->ds, vmsa->gdtr.base);
- vmsa->efer = native_read_msr(MSR_EFER);
+ rdmsrq(MSR_EFER, vmsa->efer);
vmsa->cr4 = native_read_cr4();
vmsa->cr3 = __native_read_cr3();
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index ca0a49eeac4a..b6cd45cce5fe 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -196,7 +196,7 @@ static void kvm_setup_secondary_clock(void)
void kvmclock_disable(void)
{
if (msr_kvm_system_time)
- native_write_msr(msr_kvm_system_time, 0);
+ wrmsrq(msr_kvm_system_time, 0);
}
static void __init kvmclock_init_mem(void)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 1bfebe40854f..105d5c2aae46 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -393,12 +393,12 @@ static void svm_init_erratum_383(void)
return;
/* Use _safe variants to not break nested virtualization */
- if (native_read_msr_safe(MSR_AMD64_DC_CFG, &val))
+ if (rdmsrq_safe(MSR_AMD64_DC_CFG, &val))
return;
val |= (1ULL << 47);
- native_write_msr_safe(MSR_AMD64_DC_CFG, val);
+ wrmsrq_safe(MSR_AMD64_DC_CFG, val);
erratum_383_found = true;
}
@@ -558,9 +558,9 @@ static int svm_enable_virtualization_cpu(void)
u64 len, status = 0;
int err;
- err = native_read_msr_safe(MSR_AMD64_OSVW_ID_LENGTH, &len);
+ err = rdmsrq_safe(MSR_AMD64_OSVW_ID_LENGTH, &len);
if (!err)
- err = native_read_msr_safe(MSR_AMD64_OSVW_STATUS, &status);
+ err = rdmsrq_safe(MSR_AMD64_OSVW_STATUS, &status);
if (err)
osvw_status = osvw_len = 0;
@@ -2032,7 +2032,7 @@ static bool is_erratum_383(void)
if (!erratum_383_found)
return false;
- if (native_read_msr_safe(MSR_IA32_MC0_STATUS, &value))
+ if (rdmsrq_safe(MSR_IA32_MC0_STATUS, &value))
return false;
/* Bit 62 may or may not be set for this mce */
@@ -2043,11 +2043,11 @@ static bool is_erratum_383(void)
/* Clear MCi_STATUS registers */
for (i = 0; i < 6; ++i)
- native_write_msr_safe(MSR_IA32_MCx_STATUS(i), 0);
+ wrmsrq_safe(MSR_IA32_MCx_STATUS(i), 0);
- if (!native_read_msr_safe(MSR_IA32_MCG_STATUS, &value)) {
+ if (!rdmsrq_safe(MSR_IA32_MCG_STATUS, &value)) {
value &= ~(1ULL << 2);
- native_write_msr_safe(MSR_IA32_MCG_STATUS, value);
+ wrmsrq_safe(MSR_IA32_MCG_STATUS, value);
}
/* Flush tlb to evict multi-match entries */
diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index 8f89ce0b67e3..d49a3bdc448b 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -323,7 +323,7 @@ static u64 xen_amd_read_pmc(int counter)
u64 val;
msr = amd_counters_base + (counter * amd_msr_step);
- native_read_msr_safe(msr, &val);
+ rdmsrq_safe(msr, &val);
return val;
}
@@ -349,7 +349,7 @@ static u64 xen_intel_read_pmc(int counter)
else
msr = MSR_IA32_PERFCTR0 + counter;
- native_read_msr_safe(msr, &val);
+ rdmsrq_safe(msr, &val);
return val;
}
--
2.51.0
^ permalink raw reply related
* Re: [PATCH net-next v6 7/9] selftests/vsock: improve logging in vmtest.sh
From: Stefano Garzarella @ 2025-09-30 8:26 UTC (permalink / raw)
To: Bobby Eshleman
Cc: Shuah Khan, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Stefan Hajnoczi, Michael S. Tsirkin,
Jason Wang, Xuan Zhuo, Eugenio Pérez, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Bryan Tan, Vishnu Dasa,
Broadcom internal kernel review list, virtualization, netdev,
linux-kselftest, linux-kernel, kvm, linux-hyperv, berrange,
Bobby Eshleman
In-Reply-To: <20250916-vsock-vmtest-v6-7-064d2eb0c89d@meta.com>
On Tue, Sep 16, 2025 at 04:43:51PM -0700, Bobby Eshleman wrote:
>From: Bobby Eshleman <bobbyeshleman@meta.com>
>
>Improve logging by adding configurable log levels. Additionally, improve
>usability of logging functions. Remove the test name prefix from logging
>functions so that logging calls can be made deeper into the call stack
>without passing down the test name or setting some global. Teach log
>function to accept a LOG_PREFIX variable to avoid unnecessary argument
>shifting.
>
>Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
>---
> tools/testing/selftests/vsock/vmtest.sh | 75 ++++++++++++++++-----------------
> 1 file changed, 37 insertions(+), 38 deletions(-)
>
>diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh
>index edacebfc1632..183647a86c8a 100755
>--- a/tools/testing/selftests/vsock/vmtest.sh
>+++ b/tools/testing/selftests/vsock/vmtest.sh
>@@ -51,7 +51,12 @@ readonly TEST_DESCS=(
> "Run vsock_test using the loopback transport in the VM."
> )
>
>-VERBOSE=0
>+readonly LOG_LEVEL_DEBUG=0
>+readonly LOG_LEVEL_INFO=1
>+readonly LOG_LEVEL_WARN=2
>+readonly LOG_LEVEL_ERROR=3
>+
>+VERBOSE="${LOG_LEVEL_WARN}"
If the default is 2, how the user can set 3 (error) ?
BTW I find a bit strange the reverse order.
Is this something specific to selftest?
The rest LGTM.
Thanks,
Stefano
>
> usage() {
> local name
>@@ -196,7 +201,7 @@ vm_start() {
>
> qemu=$(command -v "${QEMU}")
>
>- if [[ "${VERBOSE}" -eq 1 ]]; then
>+ if [[ ${VERBOSE} -le ${LOG_LEVEL_DEBUG} ]]; then
> verbose_opt="--verbose"
> logfile=/dev/stdout
> fi
>@@ -271,60 +276,56 @@ EOF
>
> host_wait_for_listener() {
> wait_for_listener "${TEST_HOST_PORT_LISTENER}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}"
>-}
>-
>-__log_stdin() {
>- cat | awk '{ printf "%s:\t%s\n","'"${prefix}"'", $0 }'
>-}
>
>-__log_args() {
>- echo "$*" | awk '{ printf "%s:\t%s\n","'"${prefix}"'", $0 }'
> }
>
> log() {
>- local prefix="$1"
>+ local redirect
>+ local prefix
>
>- shift
>- local redirect=
>- if [[ ${VERBOSE} -eq 0 ]]; then
>+ if [[ ${VERBOSE} -gt ${LOG_LEVEL_INFO} ]]; then
> redirect=/dev/null
> else
> redirect=/dev/stdout
> fi
>
>+ prefix="${LOG_PREFIX:-}"
>+
> if [[ "$#" -eq 0 ]]; then
>- __log_stdin | tee -a "${LOG}" > ${redirect}
>+ if [[ -n "${prefix}" ]]; then
>+ cat | awk -v prefix="${prefix}" '{printf "%s: %s\n", prefix, $0}'
>+ else
>+ cat
>+ fi
> else
>- __log_args "$@" | tee -a "${LOG}" > ${redirect}
>- fi
>+ if [[ -n "${prefix}" ]]; then
>+ echo "${prefix}: " "$@"
>+ else
>+ echo "$@"
>+ fi
>+ fi | tee -a "${LOG}" > ${redirect}
> }
>
>-log_setup() {
>- log "setup" "$@"
>+log_host() {
>+ LOG_PREFIX=host log $@
> }
>
>-log_host() {
>- local testname=$1
>+log_guest() {
>+ LOG_PREFIX=guest log $@
>+}
>
>- shift
>- log "test:${testname}:host" "$@"
> }
>
>-log_guest() {
>- local testname=$1
>
>- shift
>- log "test:${testname}:guest" "$@"
> }
>
> test_vm_server_host_client() {
>- local testname="${FUNCNAME[0]#test_}"
>
> vm_ssh -- "${VSOCK_TEST}" \
> --mode=server \
> --control-port="${TEST_GUEST_PORT}" \
> --peer-cid=2 \
>- 2>&1 | log_guest "${testname}" &
>+ 2>&1 | log_guest &
>
> vm_wait_for_listener "${TEST_GUEST_PORT}"
>
>@@ -332,18 +333,17 @@ test_vm_server_host_client() {
> --mode=client \
> --control-host=127.0.0.1 \
> --peer-cid="${VSOCK_CID}" \
>- --control-port="${TEST_HOST_PORT}" 2>&1 | log_host "${testname}"
>+ --control-port="${TEST_HOST_PORT}" 2>&1 | log_host
>
> return $?
> }
>
> test_vm_client_host_server() {
>- local testname="${FUNCNAME[0]#test_}"
>
> ${VSOCK_TEST} \
> --mode "server" \
> --control-port "${TEST_HOST_PORT_LISTENER}" \
>- --peer-cid "${VSOCK_CID}" 2>&1 | log_host "${testname}" &
>+ --peer-cid "${VSOCK_CID}" 2>&1 | log_host &
>
> host_wait_for_listener
>
>@@ -351,19 +351,18 @@ test_vm_client_host_server() {
> --mode=client \
> --control-host=10.0.2.2 \
> --peer-cid=2 \
>- --control-port="${TEST_HOST_PORT_LISTENER}" 2>&1 | log_guest "${testname}"
>+ --control-port="${TEST_HOST_PORT_LISTENER}" 2>&1 | log_guest
>
> return $?
> }
>
> test_vm_loopback() {
>- local testname="${FUNCNAME[0]#test_}"
> local port=60000 # non-forwarded local port
>
> vm_ssh -- "${VSOCK_TEST}" \
> --mode=server \
> --control-port="${port}" \
>- --peer-cid=1 2>&1 | log_guest "${testname}" &
>+ --peer-cid=1 2>&1 | log_guest &
>
> vm_wait_for_listener "${port}"
>
>@@ -371,7 +370,7 @@ test_vm_loopback() {
> --mode=client \
> --control-host="127.0.0.1" \
> --control-port="${port}" \
>- --peer-cid=1 2>&1 | log_guest "${testname}"
>+ --peer-cid=1 2>&1 | log_guest
>
> return $?
> }
>@@ -429,7 +428,7 @@ QEMU="qemu-system-$(uname -m)"
> while getopts :hvsq:b o
> do
> case $o in
>- v) VERBOSE=1;;
>+ v) VERBOSE=$(( VERBOSE - 1 ));;
> b) BUILD=1;;
> q) QEMU=$OPTARG;;
> h|*) usage;;
>@@ -452,10 +451,10 @@ handle_build
>
> echo "1..${#ARGS[@]}"
>
>-log_setup "Booting up VM"
>+log_host "Booting up VM"
> vm_start
> vm_wait_for_ssh
>-log_setup "VM booted up"
>+log_host "VM booted up"
>
> cnt_pass=0
> cnt_fail=0
>
>--
>2.47.3
>
^ permalink raw reply
* Re: [PATCH net-next v6 8/9] selftests/vsock: invoke vsock_test through helpers
From: Stefano Garzarella @ 2025-09-30 8:37 UTC (permalink / raw)
To: Bobby Eshleman
Cc: Shuah Khan, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Stefan Hajnoczi, Michael S. Tsirkin,
Jason Wang, Xuan Zhuo, Eugenio Pérez, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Bryan Tan, Vishnu Dasa,
Broadcom internal kernel review list, virtualization, netdev,
linux-kselftest, linux-kernel, kvm, linux-hyperv, berrange,
Bobby Eshleman
In-Reply-To: <20250916-vsock-vmtest-v6-8-064d2eb0c89d@meta.com>
On Tue, Sep 16, 2025 at 04:43:52PM -0700, Bobby Eshleman wrote:
>From: Bobby Eshleman <bobbyeshleman@meta.com>
>
>Add helper calls vm_vsock_test() and host_vsock_test() to invoke the
>vsock_test binary. This encapsulates several items of repeat logic, such
>as waiting for the server to reach listening state and
>enabling/disabling the bash option pipefail to avoid pipe-style logging
>from hiding failures.
>
>Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
>---
> tools/testing/selftests/vsock/vmtest.sh | 120 ++++++++++++++++++++++++++++----
> 1 file changed, 108 insertions(+), 12 deletions(-)
>
>diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh
>index 183647a86c8a..5e36d1068f6f 100755
>--- a/tools/testing/selftests/vsock/vmtest.sh
>+++ b/tools/testing/selftests/vsock/vmtest.sh
>@@ -248,6 +248,7 @@ wait_for_listener()
> local port=$1
> local interval=$2
> local max_intervals=$3
>+ local old_pipefail
> local protocol=tcp
> local pattern
> local i
>@@ -256,6 +257,13 @@ wait_for_listener()
>
> # for tcp protocol additionally check the socket state
> [ "${protocol}" = "tcp" ] && pattern="${pattern}0A"
>+
>+ # 'grep -q' exits on match, sending SIGPIPE to 'awk', which exits with
>+ # an error, causing the if-condition to fail when pipefail is set.
>+ # Instead, temporarily disable pipefail and restore it later.
>+ old_pipefail=$(set -o | awk '/^pipefail[[:space:]]+(on|off)$/{print $2}')
>+ set +o pipefail
>+
> for i in $(seq "${max_intervals}"); do
> if awk '{print $2" "$4}' /proc/net/"${protocol}"* | \
> grep -q "${pattern}"; then
>@@ -263,6 +271,10 @@ wait_for_listener()
> fi
> sleep "${interval}"
> done
>+
>+ if [[ "${old_pipefail}" == on ]]; then
>+ set -o pipefail
>+ fi
> }
>
> vm_wait_for_listener() {
>@@ -314,28 +326,112 @@ log_guest() {
> LOG_PREFIX=guest log $@
> }
>
>+vm_vsock_test() {
>+ local ns=$1
>+ local mode=$2
>+ local rc
>+
>+ set -o pipefail
>+ if [[ "${mode}" == client ]]; then
>+ local host=$3
I don't really like having the number and type of parameters of a
function depend on others, maintaining it could become a mess.
Can we avoid “mode” altogether and use “host” to discriminate between
server and client?
e.g. if “host” == server then we launch the server, otherwise we
interpret it as IP, or something else.
>+ local cid=$4
>+ local port=$5
>+
>+ # log output and use pipefail to respect vsock_test errors
>+ vm_ssh "${ns}" -- "${VSOCK_TEST}" \
>+ --mode=client \
>+ --control-host="${host}" \
>+ --peer-cid="${cid}" \
>+ --control-port="${port}" \
>+ 2>&1 | log_guest
>+ rc=$?
>+ else
>+ local cid=$3
>+ local port=$4
>+
>+ # log output and use pipefail to respect vsock_test errors
>+ vm_ssh "${ns}" -- "${VSOCK_TEST}" \
>+ --mode=server \
>+ --peer-cid="${cid}" \
>+ --control-port="${port}" \
>+ 2>&1 | log_guest &
>+ rc=$?
>+
>+ if [[ $rc -ne 0 ]]; then
>+ set +o pipefail
>+ return $rc
>+ fi
>+
>+ vm_wait_for_listener "${ns}" "${port}"
>+ rc=$?
>+ fi
>+ set +o pipefail
>+
>+ return $rc
> }
>
>+host_vsock_test() {
>+ local ns=$1
>+ local mode=$2
>+ local cmd
>+
>+ if [[ "${ns}" == none ]]; then
>+ cmd="${VSOCK_TEST}"
>+ else
>+ cmd="ip netns exec ${ns} ${VSOCK_TEST}"
>+ fi
>+
>+ # log output and use pipefail to respect vsock_test errors
>+ set -o pipefail
>+ if [[ "${mode}" == client ]]; then
>+ local host=$3
Ditto.
The rest LGTM.
Thanks,
Stefano
>+ local cid=$4
>+ local port=$5
>+
>+ ${cmd} \
>+ --mode="${mode}" \
>+ --peer-cid="${cid}" \
>+ --control-host="${host}" \
>+ --control-port="${port}" 2>&1 | log_host
>+ rc=$?
>+ else
>+ local cid=$3
>+ local port=$4
>+
>+ ${cmd} \
>+ --mode="${mode}" \
>+ --peer-cid="${cid}" \
>+ --control-port="${port}" 2>&1 | log_host &
>+ rc=$?
>+
>+ if [[ $rc -ne 0 ]]; then
>+ return $rc
>+ fi
>+
>+ host_wait_for_listener "${ns}" "${port}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}"
>+ rc=$?
>+ fi
>+ set +o pipefail
>
>+ return $rc
> }
>
> test_vm_server_host_client() {
>+ vm_vsock_test "none" "server" 2 "${TEST_GUEST_PORT}"
>+ host_vsock_test "none" "client" "127.0.0.1" "${VSOCK_CID}" "${TEST_HOST_PORT}"
>+}
>
>- vm_ssh -- "${VSOCK_TEST}" \
>- --mode=server \
>- --control-port="${TEST_GUEST_PORT}" \
>- --peer-cid=2 \
>- 2>&1 | log_guest &
>+test_vm_client_host_server() {
>+ host_vsock_test "none" "server" "${VSOCK_CID}" "${TEST_HOST_PORT_LISTENER}"
>+ vm_vsock_test "none" "client" "10.0.2.2" 2 "${TEST_HOST_PORT_LISTENER}"
>+}
>
>- vm_wait_for_listener "${TEST_GUEST_PORT}"
>+test_vm_loopback() {
>+ vm_vsock_test "none" "server" 1 "${TEST_HOST_PORT_LISTENER}"
>+ vm_vsock_test "none" "client" "127.0.0.1" 1 "${TEST_HOST_PORT_LISTENER}"
>+}
>
>- ${VSOCK_TEST} \
>- --mode=client \
>- --control-host=127.0.0.1 \
>- --peer-cid="${VSOCK_CID}" \
>- --control-port="${TEST_HOST_PORT}" 2>&1 | log_host
>
>- return $?
> }
>
> test_vm_client_host_server() {
>
>--
>2.47.3
>
^ permalink raw reply
* Re: [PATCH net-next v6 9/9] selftests/vsock: add namespace tests
From: Stefano Garzarella @ 2025-09-30 8:58 UTC (permalink / raw)
To: Bobby Eshleman
Cc: Shuah Khan, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Stefan Hajnoczi, Michael S. Tsirkin,
Jason Wang, Xuan Zhuo, Eugenio Pérez, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Bryan Tan, Vishnu Dasa,
Broadcom internal kernel review list, virtualization, netdev,
linux-kselftest, linux-kernel, kvm, linux-hyperv, berrange,
Bobby Eshleman
In-Reply-To: <20250916-vsock-vmtest-v6-9-064d2eb0c89d@meta.com>
On Tue, Sep 16, 2025 at 04:43:53PM -0700, Bobby Eshleman wrote:
>From: Bobby Eshleman <bobbyeshleman@meta.com>
>
>Add tests for namespace support in vsock. Use socat for basic connection
>failure tests and vsock_test for full functionality tests when
>communication is expected to succeed. vsock_test is not used for failure
>cases because in theory vsock_test could allow connection and some
>traffic flow but fail on some other case (e.g., fail on MSG_ZEROCOPY).
>
>Tests cover all cases of clients and servers being in all variants of
>local ns, global ns, host process, and VM process.
>
>Legacy tests are retained and executed in the init ns.
>
>Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
>
>---
>Changes in v6:
>- check for namespace support in vmtest.sh
>
>Changes in v5:
>- use /proc/sys/net/vsock/ns_mode
>- clarify logic of tests that reuse the same VM and tests that require
> netns setup
>- fix unassigned BUILD bug
>---
> tools/testing/selftests/vsock/vmtest.sh | 954 ++++++++++++++++++++++++++++----
> 1 file changed, 849 insertions(+), 105 deletions(-)
>
>diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh
>index 5e36d1068f6f..59621b32cf1a 100755
>--- a/tools/testing/selftests/vsock/vmtest.sh
>+++ b/tools/testing/selftests/vsock/vmtest.sh
>@@ -7,6 +7,7 @@
> # * virtme-ng
> # * busybox-static (used by virtme-ng)
> # * qemu (used by virtme-ng)
>+# * socat
>
> readonly SCRIPT_DIR="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
> readonly KERNEL_CHECKOUT=$(realpath "${SCRIPT_DIR}"/../../../../)
>@@ -23,7 +24,7 @@ readonly VSOCK_CID=1234
> readonly WAIT_PERIOD=3
> readonly WAIT_PERIOD_MAX=60
> readonly WAIT_TOTAL=$(( WAIT_PERIOD * WAIT_PERIOD_MAX ))
>-readonly QEMU_PIDFILE=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+readonly WAIT_QEMU=5
>
> # virtme-ng offers a netdev for ssh when using "--ssh", but we also need a
> # control port forwarded for vsock_test. Because virtme-ng doesn't support
>@@ -33,23 +34,146 @@ readonly QEMU_PIDFILE=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
> # add the kernel cmdline options that virtme-init uses to setup the interface.
> readonly QEMU_TEST_PORT_FWD="hostfwd=tcp::${TEST_HOST_PORT}-:${TEST_GUEST_PORT}"
> readonly QEMU_SSH_PORT_FWD="hostfwd=tcp::${SSH_HOST_PORT}-:${SSH_GUEST_PORT}"
>-readonly QEMU_OPTS="\
>- -netdev user,id=n0,${QEMU_TEST_PORT_FWD},${QEMU_SSH_PORT_FWD} \
>- -device virtio-net-pci,netdev=n0 \
>- -device vhost-vsock-pci,guest-cid=${VSOCK_CID} \
>- --pidfile ${QEMU_PIDFILE} \
>-"
I expected this patch to only add new tests, but we are changing a few things.
Are they related, or can they be moved to another preparation patch?
> readonly KERNEL_CMDLINE="\
> virtme.dhcp net.ifnames=0 biosdevname=0 \
> virtme.ssh virtme_ssh_channel=tcp virtme_ssh_user=$USER \
> "
> readonly LOG=$(mktemp /tmp/vsock_vmtest_XXXX.log)
>-readonly TEST_NAMES=(vm_server_host_client vm_client_host_server vm_loopback)
>+readonly TEST_NAMES=(
>+ vm_server_host_client
>+ vm_client_host_server
>+ vm_loopback
>+ host_vsock_ns_mode_ok
can we use a `ns_` prefix for all ns related tests?
>+ host_vsock_ns_mode_write_once_ok
>+ global_same_cid_fails
>+ local_same_cid_ok
>+ global_local_same_cid_ok
>+ local_global_same_cid_ok
>+ diff_ns_global_host_connect_to_global_vm_ok
>+ diff_ns_global_host_connect_to_local_vm_fails
>+ diff_ns_global_vm_connect_to_global_host_ok
>+ diff_ns_global_vm_connect_to_local_host_fails
>+ diff_ns_local_host_connect_to_local_vm_fails
>+ diff_ns_local_vm_connect_to_local_host_fails
>+ diff_ns_global_to_local_loopback_local_fails
>+ diff_ns_local_to_global_loopback_fails
>+ diff_ns_local_to_local_loopback_fails
>+ diff_ns_global_to_global_loopback_ok
>+ same_ns_local_loopback_ok
>+ same_ns_local_host_connect_to_local_vm_ok
>+ same_ns_local_vm_connect_to_local_host_ok
>+)
>+
> readonly TEST_DESCS=(
>+ # vm_server_host_client
> "Run vsock_test in server mode on the VM and in client mode on the host."
>+
>+ # vm_client_host_server
> "Run vsock_test in client mode on the VM and in server mode on the host."
>+
>+ # vm_loopback
> "Run vsock_test using the loopback transport in the VM."
>+
>+ # host_vsock_ns_mode_ok
>+ "Check /proc/sys/net/vsock/ns_mode strings on the host."
>+
>+ # host_vsock_ns_mode_write_once_ok
>+ "Check /proc/sys/net/vsock/ns_mode is write-once on the host."
>+
>+ # global_same_cid_fails
>+ "Check QEMU fails to start two VMs with same CID in two different global namespaces."
>+
>+ # local_same_cid_ok
>+ "Check QEMU successfully starts two VMs with same CID in two different local namespaces."
>+
>+ # global_local_same_cid_ok
>+ "Check QEMU successfully starts one VM in a global ns and then another VM in a local ns with the same CID."
>+
>+ # local_global_same_cid_ok
>+ "Check QEMU successfully starts one VM in a local ns and then another VM in a global ns with the same CID."
>+
>+ # diff_ns_global_host_connect_to_global_vm_ok
>+ "Run vsock_test client in global ns with server in VM in another global ns."
>+
>+ # diff_ns_global_host_connect_to_local_vm_fails
>+ "Run socat to test a process in a global ns fails to connect to a VM in a local ns."
>+
>+ # diff_ns_global_vm_connect_to_global_host_ok
>+ "Run vsock_test client in VM in a global ns with server in another global ns."
>+
>+ # diff_ns_global_vm_connect_to_local_host_fails
>+ "Run socat to test a VM in a global ns fails to connect to a host process in a local ns."
>+
>+ # diff_ns_local_host_connect_to_local_vm_fails
>+ "Run socat to test a host process in a local ns fails to connect to a VM in another local ns."
>+
>+ # diff_ns_local_vm_connect_to_local_host_fails
>+ "Run socat to test a VM in a local ns fails to connect to a host process in another local ns."
>+
>+ # diff_ns_global_to_local_loopback_local_fails
>+ "Run socat to test a loopback vsock in a global ns fails to connect to a vsock in a local ns."
>+
>+ # diff_ns_local_to_global_loopback_fails
>+ "Run socat to test a loopback vsock in a local ns fails to connect to a vsock in a global ns."
>+
>+ # diff_ns_local_to_local_loopback_fails
>+ "Run socat to test a loopback vsock in a local ns fails to connect to a vsock in another local ns."
>+
>+ # diff_ns_global_to_global_loopback_ok
>+ "Run socat to test a loopback vsock in a global ns successfully connects to a vsock in another global ns."
>+
>+ # same_ns_local_loopback_ok
>+ "Run socat to test a loopback vsock in a local ns successfully connects to a vsock in the same ns."
>+
>+ # same_ns_local_host_connect_to_local_vm_ok
>+ "Run vsock_test client in a local ns with server in VM in same ns."
>+
>+ # same_ns_local_vm_connect_to_local_host_ok
>+ "Run vsock_test client in VM in a local ns with server in same ns."
Should we run some test to check edge cases like namespace deletion
during active connections or changing ns mode from global to local while
running.
>+)
>+
>+readonly USE_SHARED_VM=(vm_server_host_client vm_client_host_server vm_loopback)
>+readonly USE_INIT_NETNS=(
>+ global_same_cid_fails
>+ local_same_cid_ok
>+ global_local_same_cid_ok
>+ local_global_same_cid_ok
>+ diff_ns_global_host_connect_to_global_vm_ok
>+ diff_ns_global_host_connect_to_local_vm_fails
>+ diff_ns_global_vm_connect_to_global_host_ok
>+ diff_ns_global_vm_connect_to_local_host_fails
>+ diff_ns_local_host_connect_to_local_vm_fails
>+ diff_ns_local_vm_connect_to_local_host_fails
>+ diff_ns_global_to_local_loopback_local_fails
>+ diff_ns_local_to_global_loopback_fails
>+ diff_ns_local_to_local_loopback_fails
>+ diff_ns_global_to_global_loopback_ok
>+ same_ns_local_loopback_ok
>+ same_ns_local_host_connect_to_local_vm_ok
>+ same_ns_local_vm_connect_to_local_host_ok
>+)
>+readonly REQUIRES_NETNS=(
>+ host_vsock_ns_mode_ok
>+ host_vsock_ns_mode_write_once_ok
>+ global_same_cid_fails
>+ local_same_cid_ok
>+ global_local_same_cid_ok
>+ local_global_same_cid_ok
>+ diff_ns_global_host_connect_to_global_vm_ok
>+ diff_ns_global_host_connect_to_local_vm_fails
>+ diff_ns_global_vm_connect_to_global_host_ok
>+ diff_ns_global_vm_connect_to_local_host_fails
>+ diff_ns_local_host_connect_to_local_vm_fails
>+ diff_ns_local_vm_connect_to_local_host_fails
>+ diff_ns_global_to_local_loopback_local_fails
>+ diff_ns_local_to_global_loopback_fails
>+ diff_ns_local_to_local_loopback_fails
>+ diff_ns_global_to_global_loopback_ok
>+ same_ns_local_loopback_ok
>+ same_ns_local_host_connect_to_local_vm_ok
>+ same_ns_local_vm_connect_to_local_host_ok
> )
>+readonly MODES=("local" "global")
What about NS_MODES ?
>
> readonly LOG_LEVEL_DEBUG=0
> readonly LOG_LEVEL_INFO=1
>@@ -58,6 +182,12 @@ readonly LOG_LEVEL_ERROR=3
>
> VERBOSE="${LOG_LEVEL_WARN}"
>
>+# Test pass/fail counters
>+cnt_pass=0
>+cnt_fail=0
>+cnt_skip=0
>+cnt_total=0
>+
> usage() {
> local name
> local desc
>@@ -77,7 +207,7 @@ usage() {
> for ((i = 0; i < ${#TEST_NAMES[@]}; i++)); do
> name=${TEST_NAMES[${i}]}
> desc=${TEST_DESCS[${i}]}
>- printf "\t%-35s%-35s\n" "${name}" "${desc}"
>+ printf "\t%-55s%-35s\n" "${name}" "${desc}"
> done
> echo
>
>@@ -89,21 +219,87 @@ die() {
> exit "${KSFT_FAIL}"
> }
>
>+add_namespaces() {
>+ # add namespaces local0, local1, global0, and global1
>+ for mode in "${MODES[@]}"; do
>+ ip netns add "${mode}0" 2>/dev/null
>+ ip netns add "${mode}1" 2>/dev/null
>+ done
>+}
>+
>+init_namespaces() {
>+ for mode in "${MODES[@]}"; do
>+ ns_set_mode "${mode}0" "${mode}"
>+ ns_set_mode "${mode}1" "${mode}"
>+
>+ log_host "set ns ${mode}0 to mode ${mode}"
>+ log_host "set ns ${mode}1 to mode ${mode}"
>+
>+ # we need lo for qemu port forwarding
>+ ip netns exec "${mode}0" ip link set dev lo up
>+ ip netns exec "${mode}1" ip link set dev lo up
>+ done
>+}
>+
>+del_namespaces() {
>+ for mode in "${MODES[@]}"; do
>+ ip netns del "${mode}0"
>+ ip netns del "${mode}1"
>+ log_host "removed ns ${mode}0"
>+ log_host "removed ns ${mode}1"
>+ done &>/dev/null
>+}
>+
>+ns_set_mode() {
>+ local ns=$1
>+ local mode=$2
>+
>+ echo "${mode}" | ip netns exec "${ns}" \
>+ tee /proc/sys/net/vsock/ns_mode &>/dev/null
>+}
>+
> vm_ssh() {
>- ssh -q -o UserKnownHostsFile=/dev/null -p ${SSH_HOST_PORT} localhost "$@"
>+ local ns_exec
>+
>+ if [[ "${1}" == none ]]; then
>+ local ns_exec=""
>+ else
>+ local ns_exec="ip netns exec ${1}"
>+ fi
>+
>+ shift
>+
>+ ${ns_exec} ssh -q -o UserKnownHostsFile=/dev/null -p ${SSH_HOST_PORT} localhost $*
>+
> return $?
> }
>
> cleanup() {
>- if [[ -s "${QEMU_PIDFILE}" ]]; then
>- pkill -SIGTERM -F "${QEMU_PIDFILE}" > /dev/null 2>&1
>- fi
>+ del_namespaces
>+}
>
>- # If failure occurred during or before qemu start up, then we need
>- # to clean this up ourselves.
>- if [[ -e "${QEMU_PIDFILE}" ]]; then
>- rm "${QEMU_PIDFILE}"
>- fi
>+terminate_pidfiles() {
>+ local pidfile
>+
>+ for pidfile in "$@"; do
>+ if [[ -s "${pidfile}" ]]; then
>+ pkill -SIGTERM -F "${pidfile}" 2>&1 > /dev/null
>+ fi
>+
>+ # If failure occurred during or before qemu start up, then we need
>+ # to clean this up ourselves.
>+ if [[ -e "${pidfile}" ]]; then
>+ rm -f "${pidfile}"
>+ fi
>+ done
>+}
>+
>+terminate_pids() {
>+ local pid
>+
>+ for pid in "$@"; do
>+ kill -SIGTERM "${pid}" &>/dev/null || :
>+ done
> }
>
> check_args() {
>@@ -133,7 +329,7 @@ check_args() {
> }
>
> check_deps() {
>- for dep in vng ${QEMU} busybox pkill ssh; do
>+ for dep in vng ${QEMU} busybox pkill ssh socat; do
> if [[ ! -x $(command -v "${dep}") ]]; then
> echo -e "skip: dependency ${dep} not found!\n"
> exit "${KSFT_SKIP}"
>@@ -147,6 +343,20 @@ check_deps() {
> fi
> }
>
>+check_test_deps() {
>+ local tname=$1
>+
>+ # If the test requires NS support, check if NS support exists
>+ # using /proc/self/ns
>+ if [[ "${tname}" =~ "${REQUIRES_NETNS[@]}" ]] &&
>+ [[ ! -e /proc/self/ns ]]; then
>+ log_host "No NS support detected for test ${tname}"
>+ return 1
>+ fi
>+
>+ return 0
>+}
>+
> check_vng() {
> local tested_versions
> local version
>@@ -170,6 +380,20 @@ check_vng() {
> fi
> }
>
>+check_socat() {
>+ local support_string
>+
>+ support_string="$(socat -V)"
>+
>+ if [[ "${support_string}" != *"WITH_VSOCK 1"* ]]; then
>+ die "err: socat is missing vsock support"
>+ fi
>+
>+ if [[ "${support_string}" != *"WITH_UNIX 1"* ]]; then
>+ die "err: socat is missing unix support"
>+ fi
>+}
>+
> handle_build() {
> if [[ ! "${BUILD}" -eq 1 ]]; then
> return
>@@ -194,9 +418,14 @@ handle_build() {
> }
>
> vm_start() {
>+ local cid=$1
>+ local ns=$2
>+ local pidfile=$3
> local logfile=/dev/null
> local verbose_opt=""
>+ local qemu_opts=""
> local kernel_opt=""
>+ local ns_exec=""
> local qemu
>
> qemu=$(command -v "${QEMU}")
>@@ -206,27 +435,37 @@ vm_start() {
> logfile=/dev/stdout
> fi
>
>+ qemu_opts="\
>+ -netdev
>user,id=n0,${QEMU_TEST_PORT_FWD},${QEMU_SSH_PORT_FWD} \
>+ -device virtio-net-pci,netdev=n0 \
>+ ${QEMU_OPTS} -device vhost-vsock-pci,guest-cid=${cid} \
Have we removed QEMU_OPTS, right?
(I still prefer to have it defined on top, but maybe there is a reason
to remove it)
>+ --pidfile ${pidfile}
>+ "
>+
> if [[ "${BUILD}" -eq 1 ]]; then
> kernel_opt="${KERNEL_CHECKOUT}"
> fi
>
>- vng \
>+ if [[ "${ns}" != "none" ]]; then
>+ ns_exec="ip netns exec ${ns}"
>+ fi
>+
>+ ${ns_exec} vng \
> --run \
> ${kernel_opt} \
> ${verbose_opt} \
>- --qemu-opts="${QEMU_OPTS}" \
>+ --qemu-opts="${qemu_opts}" \
> --qemu="${qemu}" \
> --user root \
> --append "${KERNEL_CMDLINE}" \
> --rw &> ${logfile} &
>
>- if ! timeout ${WAIT_TOTAL} \
So WAIT_TOTAL is now unused, right?
Can you explain better this change?
>- bash -c 'while [[ ! -s '"${QEMU_PIDFILE}"' ]]; do sleep 1; done; exit 0'; then
>- die "failed to boot VM"
>- fi
>+ timeout "${WAIT_QEMU}" \
>+ bash -c 'while [[ ! -s '"${pidfile}"' ]]; do sleep 1; done; exit 0'
> }
>
> vm_wait_for_ssh() {
>+ local ns=$1
> local i
>
> i=0
>@@ -234,7 +473,8 @@ vm_wait_for_ssh() {
> if [[ ${i} -gt ${WAIT_PERIOD_MAX} ]]; then
> die "Timed out waiting for guest ssh"
> fi
>- if vm_ssh -- true; then
>+
>+ if vm_ssh "${ns}" -- true; then
> break
> fi
> i=$(( i + 1 ))
>@@ -269,6 +509,7 @@ wait_for_listener()
> grep -q "${pattern}"; then
> break
> fi
>+
> sleep "${interval}"
> done
>
>@@ -278,17 +519,29 @@ wait_for_listener()
> }
>
> vm_wait_for_listener() {
>- local port=$1
>+ local ns=$1
>+ local port=$2
>+
>+ log "Waiting for listener on port ${port} on vm"
>
>- vm_ssh <<EOF
>+ vm_ssh "${ns}" <<EOF
> $(declare -f wait_for_listener)
> wait_for_listener ${port} ${WAIT_PERIOD} ${WAIT_PERIOD_MAX}
> EOF
> }
>
> host_wait_for_listener() {
>- wait_for_listener "${TEST_HOST_PORT_LISTENER}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}"
>+ local ns=$1
>+ local port=$2
>
>+ if [[ "${ns}" == none ]]; then
>+ wait_for_listener "${port}" "${WAIT_PERIOD}" "${WAIT_PERIOD_MAX}"
>+ else
>+ ip netns exec "${ns}" bash <<-EOF
>+ $(declare -f wait_for_listener)
>+ wait_for_listener ${port} ${WAIT_PERIOD} ${WAIT_PERIOD_MAX}
>+ EOF
>+ fi
> }
>
> log() {
>@@ -427,51 +680,506 @@ test_vm_client_host_server() {
> }
>
> test_vm_loopback() {
>+ vm_ssh "none" modprobe vsock_loopback || :
> vm_vsock_test "none" "server" 1 "${TEST_HOST_PORT_LISTENER}"
> vm_vsock_test "none" "client" "127.0.0.1" 1 "${TEST_HOST_PORT_LISTENER}"
> }
>
>+test_host_vsock_ns_mode_ok() {
>+ add_namespaces
>
>+ for mode in "${MODES[@]}"; do
>+ if ! ns_set_mode "${mode}0" "${mode}"; then
>+ del_namespaces
>+ return "${KSFT_FAIL}"
>+ fi
>+ done
>+
>+ del_namespaces
> }
>
>-test_vm_client_host_server() {
>+test_host_vsock_ns_mode_write_once_ok() {
>+ add_namespaces
>
>- ${VSOCK_TEST} \
>- --mode "server" \
>- --control-port "${TEST_HOST_PORT_LISTENER}" \
>- --peer-cid "${VSOCK_CID}" 2>&1 | log_host &
>+ for mode in "${MODES[@]}"; do
>+ local ns="${mode}0"
>+ if ! ns_set_mode "${ns}" "${mode}"; then
>+ del_namespaces
>+ return "${KSFT_FAIL}"
>+ fi
>
>- host_wait_for_listener
>+ # try writing again and expect failure
>+ if ns_set_mode "${ns}" "${mode}"; then
>+ del_namespaces
>+ return "${KSFT_FAIL}"
>+ fi
>+ done
>
>- vm_ssh -- "${VSOCK_TEST}" \
>- --mode=client \
>- --control-host=10.0.2.2 \
>- --peer-cid=2 \
>- --control-port="${TEST_HOST_PORT_LISTENER}" 2>&1 | log_guest
>+ del_namespaces
>
>- return $?
>+ return "${KSFT_PASS}"
> }
>
>-test_vm_loopback() {
>- local port=60000 # non-forwarded local port
>+namespaces_can_boot_same_cid() {
>+ local ns0=$1
>+ local ns1=$2
>+ local pidfile1 pidfile2
>+ local cid=20
>+ readonly cid
>+ local rc
>
>- vm_ssh -- "${VSOCK_TEST}" \
>- --mode=server \
>- --control-port="${port}" \
>- --peer-cid=1 2>&1 | log_guest &
>+ pidfile1=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ vm_start "${cid}" "${ns0}" "${pidfile1}"
>
>- vm_wait_for_listener "${port}"
>+ pidfile2=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ vm_start "${cid}" "${ns1}" "${pidfile2}"
>
>- vm_ssh -- "${VSOCK_TEST}" \
>- --mode=client \
>- --control-host="127.0.0.1" \
>- --control-port="${port}" \
>- --peer-cid=1 2>&1 | log_guest
>+ rc=$?
>+ terminate_pidfiles "${pidfile1}" "${pidfile2}"
>
>- return $?
>+ return $rc
>+}
>+
>+test_global_same_cid_fails() {
>+ if namespaces_can_boot_same_cid "global0" "global1"; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ return "${KSFT_PASS}"
>+}
>+
>+test_local_global_same_cid_ok() {
>+ if namespaces_can_boot_same_cid "local0" "global0"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_global_local_same_cid_ok() {
>+ if namespaces_can_boot_same_cid "global0" "local0"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_local_same_cid_ok() {
>+ if namespaces_can_boot_same_cid "local0" "local0"; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ return "${KSFT_PASS}"
>+}
>+
>+test_diff_ns_global_host_connect_to_global_vm_ok() {
>+ local pids pid pidfile
>+ local ns0 ns1 port
>+ declare -a pids
>+ local unixfile
>+ ns0="global0"
>+ ns1="global1"
>+ port=1234
>+ local rc
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+
>+ if ! vm_start "${VSOCK_CID}" "${ns0}" "${pidfile}"; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ unixfile=$(mktemp -u /tmp/XXXX.sock)
>+ ip netns exec "${ns1}" \
>+ socat TCP-LISTEN:"${TEST_HOST_PORT}",fork \
>+ UNIX-CONNECT:"${unixfile}" &
>+ pids+=($!)
>+ host_wait_for_listener "${ns1}" "${TEST_HOST_PORT}"
>+
>+ ip netns exec "${ns0}" socat UNIX-LISTEN:"${unixfile}",fork \
>+ TCP-CONNECT:localhost:"${TEST_HOST_PORT}" &
>+ pids+=($!)
>+
>+ vm_vsock_test "${ns0}" "server" 2 "${TEST_GUEST_PORT}"
>+ vm_wait_for_listener "${ns0}" "${TEST_GUEST_PORT}"
>+ host_vsock_test "${ns1}" "client" "127.0.0.1" "${VSOCK_CID}" "${TEST_HOST_PORT}"
>+ rc=$?
>+
>+ for pid in "${pids[@]}"; do
>+ if [[ "$(jobs -p)" = *"${pid}"* ]]; then
>+ kill -SIGTERM "${pid}" &>/dev/null
>+ fi
>+ done
>+
>+ terminate_pidfiles "${pidfile}"
>+
>+ if [[ $rc -ne 0 ]]; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ return "${KSFT_PASS}"
>+}
>+
>+test_diff_ns_global_host_connect_to_local_vm_fails() {
>+ local ns0="global0"
>+ local ns1="local0"
>+ local port=12345
>+ local pidfile
>+ local result
>+ local pid
>+
>+ outfile=$(mktemp)
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ if ! vm_start "${VSOCK_CID}" "${ns1}" "${pidfile}"; then
>+ log_host "failed to start vm (cid=${VSOCK_CID}, ns=${ns0})"
>+ return $KSFT_FAIL
>+ fi
>+
>+ vm_wait_for_ssh "${ns1}"
>+ vm_ssh "${ns1}" -- socat VSOCK-LISTEN:"${port}" STDOUT > "${outfile}" &
>+ echo TEST | ip netns exec "${ns0}" \
>+ socat STDIN VSOCK-CONNECT:"${VSOCK_CID}":"${port}" 2>/dev/null
>+
>+ terminate_pidfiles "${pidfile}"
>+
>+ result=$(cat "${outfile}")
>+ rm -f "${outfile}"
>+
>+ if [[ "${result}" != TEST ]]; then
>+ return $KSFT_PASS
>+ fi
>+
>+ return $KSFT_FAIL
>+}
>+
>+test_diff_ns_global_vm_connect_to_global_host_ok() {
>+ local ns0="global0"
>+ local ns1="global1"
>+ local port=12345
>+ local unixfile
>+ local pidfile
>+ local pids
>+
>+ declare -a pids
>+
>+ log_host "Setup socat bridge from ns ${ns0} to ns ${ns1} over port ${port}"
>+
>+ unixfile=$(mktemp -u /tmp/XXXX.sock)
>+
>+ ip netns exec "${ns0}" \
>+ socat TCP-LISTEN:"${port}" UNIX-CONNECT:"${unixfile}" &
>+ pids+=($!)
>+
>+ ip netns exec "${ns1}" \
>+ socat UNIX-LISTEN:"${unixfile}" TCP-CONNECT:127.0.0.1:"${port}" &
>+ pids+=($!)
>+
>+ log_host "Launching ${VSOCK_TEST} in ns ${ns1}"
>+ host_vsock_test "${ns1}" "server" "${VSOCK_CID}" "${port}"
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ if ! vm_start "${VSOCK_CID}" "${ns0}" "${pidfile}"; then
>+ log_host "failed to start vm (cid=${cid}, ns=${ns0})"
>+ terminate_pids "${pids[@]}"
>+ rm -f "${unixfile}"
>+ return $KSFT_FAIL
>+ fi
>+
>+ vm_wait_for_ssh "${ns0}"
>+ vm_vsock_test "${ns0}" "client" "10.0.2.2" 2 "${port}"
>+ rc=$?
>+
>+ terminate_pidfiles "${pidfile}"
>+ terminate_pids "${pids[@]}"
>+ rm -f "${unixfile}"
>+
>+ if [[ ! $rc -eq 0 ]]; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ return "${KSFT_PASS}"
>+
>+}
>+
>+test_diff_ns_global_vm_connect_to_local_host_fails() {
>+ local ns0="global0"
>+ local ns1="local0"
>+ local port=12345
>+ local pidfile
>+ local result
>+ local pid
>+
>+ log_host "Launching socat in ns ${ns1}"
>+ outfile=$(mktemp)
>+ ip netns exec "${ns1}" socat VSOCK-LISTEN:${port} STDOUT &> "${outfile}" &
>+ pid=$!
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ if ! vm_start "${VSOCK_CID}" "${ns0}" "${pidfile}"; then
>+ log_host "failed to start vm (cid=${cid}, ns=${ns0})"
>+ terminate_pids "${pid}"
>+ rm -f "${outfile}"
>+ return $KSFT_FAIL
>+ fi
>+
>+ vm_wait_for_ssh "${ns0}"
>+
>+ vm_ssh "${ns0}" -- \
>+ bash -c "echo TEST | socat STDIN VSOCK-CONNECT:2:${port}" 2>&1 | log_guest
>+
>+ terminate_pidfiles "${pidfile}"
>+ terminate_pids "${pid}"
>+
>+ result=$(cat "${outfile}")
>+ rm -f "${outfile}"
>+
>+ if [[ "${result}" != TEST ]]; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_diff_ns_local_host_connect_to_local_vm_fails() {
>+ local ns0="local0"
>+ local ns1="local1"
>+ local port=12345
>+ local pidfile
>+ local result
>+ local pid
>+
>+ outfile=$(mktemp)
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ if ! vm_start "${VSOCK_CID}" "${ns1}" "${pidfile}"; then
>+ log_host "failed to start vm (cid=${cid}, ns=${ns0})"
>+ return $KSFT_FAIL
>+ fi
>+
>+ vm_wait_for_ssh "${ns1}"
>+ vm_ssh "${ns1}" -- socat VSOCK-LISTEN:"${port}" STDOUT > "${outfile}" &
>+ echo TEST | ip netns exec "${ns0}" \
>+ socat STDIN VSOCK-CONNECT:"${VSOCK_CID}":"${port}" 2>/dev/null
>+
>+ terminate_pidfiles "${pidfile}"
>+
>+ result=$(cat "${outfile}")
>+ rm -f "${outfile}"
>+
>+ if [[ "${result}" != TEST ]]; then
>+ return $KSFT_PASS
>+ fi
>+
>+ return $KSFT_FAIL
>+}
>+
>+test_diff_ns_local_vm_connect_to_local_host_fails() {
>+ local ns0="local0"
>+ local ns1="local1"
>+ local port=12345
>+ local pidfile
>+ local result
>+ local pid
>+
>+ log_host "Launching socat in ns ${ns1}"
>+ outfile=$(mktemp)
>+ ip netns exec "${ns1}" socat VSOCK-LISTEN:"${port}" STDOUT &> "${outfile}" &
>+ pid=$!
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+ if ! vm_start "${VSOCK_CID}" "${ns0}" "${pidfile}"; then
>+ log_host "failed to start vm (cid=${cid}, ns=${ns0})"
>+ rm -f "${outfile}"
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ vm_wait_for_ssh "${ns0}"
>+
>+ vm_ssh "${ns0}" -- \
>+ bash -c "echo TEST | socat STDIN VSOCK-CONNECT:2:${port}" 2>&1 | log_guest
>+
>+ terminate_pidfiles "${pidfile}"
>+ terminate_pids "${pid}"
>+
>+ result=$(cat "${outfile}")
>+ rm -f "${outfile}"
>+
>+ if [[ "${result}" != TEST ]]; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+__test_loopback_two_netns() {
>+ local ns0=$1
>+ local ns1=$2
>+ local port=12345
>+ local result
>+ local pid
>+
>+ modprobe vsock_loopback &> /dev/null || :
>+
>+ log_host "Launching socat in ns ${ns1}"
>+ outfile=$(mktemp)
>+ ip netns exec "${ns1}" socat VSOCK-LISTEN:"${port}" STDOUT > "${outfile}" 2>/dev/null &
>+ pid=$!
>+
>+ log_host "Launching socat in ns ${ns0}"
>+ echo TEST | ip netns exec "${ns0}" socat STDIN VSOCK-CONNECT:1:"${port}" 2>/dev/null
>+ terminate_pids "${pid}"
>+
>+ result=$(cat "${outfile}")
>+ rm -f "${outfile}"
>+
>+ if [[ "${result}" == TEST ]]; then
>+ return 0
>+ fi
>+
>+ return 1
>+}
>+
>+test_diff_ns_global_to_local_loopback_local_fails() {
>+ if ! __test_loopback_two_netns "global0" "local0"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_diff_ns_local_to_global_loopback_fails() {
>+ if ! __test_loopback_two_netns "local0" "global0"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_diff_ns_local_to_local_loopback_fails() {
>+ if ! __test_loopback_two_netns "local0" "local1"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_diff_ns_global_to_global_loopback_ok() {
>+ if __test_loopback_two_netns "global0" "global1"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_same_ns_local_loopback_ok() {
>+ if __test_loopback_two_netns "local0" "local0"; then
>+ return "${KSFT_PASS}"
>+ fi
>+
>+ return "${KSFT_FAIL}"
>+}
>+
>+test_same_ns_local_host_connect_to_local_vm_ok() {
>+ local ns="local0"
>+ local port=1234
>+ local pidfile
>+ local rc
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+
>+ if ! vm_start "${VSOCK_CID}" "${ns}" "${pidfile}"; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ vm_vsock_test "${ns}" "server" 2 "${TEST_GUEST_PORT}"
>+ host_vsock_test "${ns}" "client" "127.0.0.1" "${VSOCK_CID}" "${TEST_HOST_PORT}"
>+ rc=$?
>+
>+ terminate_pidfiles "${pidfile}"
>+
>+ if [[ $rc -ne 0 ]]; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ return "${KSFT_PASS}"
>+}
>+
>+test_same_ns_local_vm_connect_to_local_host_ok() {
>+ local ns="local0"
>+ local port=1234
>+ local pidfile
>+ local rc
>+
>+ pidfile=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
>+
>+ if ! vm_start "${VSOCK_CID}" "${ns}" "${pidfile}"; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ vm_vsock_test "${ns}" "server" 2 "${TEST_GUEST_PORT}"
>+ host_vsock_test "${ns}" "client" "127.0.0.1" "${VSOCK_CID}" "${TEST_HOST_PORT}"
>+ rc=$?
>+
>+ terminate_pidfiles "${pidfile}"
>+
>+ if [[ $rc -ne 0 ]]; then
>+ return "${KSFT_FAIL}"
>+ fi
>+
>+ return "${KSFT_PASS}"
>+}
>+
>+shared_vm_test() {
>+ local tname
>+
>+ tname="${1}"
>+
>+ for testname in "${USE_SHARED_VM[@]}"; do
>+ if [[ "${tname}" == "${testname}" ]]; then
>+ return 0
>+ fi
>+ done
>+
>+ return 1
>+}
>+
>+
>+init_netns_test() {
>+ local tname
>+
>+ tname="${1}"
>+
>+ for testname in "${USE_INIT_NETNS[@]}"; do
>+ if [[ "${tname}" == "${testname}" ]]; then
>+ return 0
>+ fi
>+ done
>+
>+ return 1
>+}
>+
>+check_result() {
>+ local rc num
>+
>+ rc=$1
>+ num=$(( cnt_total + 1 ))
>+
>+ if [[ ${rc} -eq $KSFT_PASS ]]; then
>+ cnt_pass=$(( cnt_pass + 1 ))
>+ echo "ok ${num} ${arg}"
>+ elif [[ ${rc} -eq $KSFT_SKIP ]]; then
>+ cnt_skip=$(( cnt_skip + 1 ))
>+ echo "ok ${num} ${arg} # SKIP"
>+ elif [[ ${rc} -eq $KSFT_FAIL ]]; then
>+ cnt_fail=$(( cnt_fail + 1 ))
>+ echo "not ok ${num} ${arg} # exit=$rc"
>+ fi
>+
>+ cnt_total=$(( cnt_total + 1 ))
> }
>
>-run_test() {
>+run_shared_vm_tests() {
>+ local start_shared_vm pidfile
> local host_oops_cnt_before
> local host_warn_cnt_before
> local vm_oops_cnt_before
>@@ -483,42 +1191,99 @@ run_test() {
> local name
> local rc
>
>- host_oops_cnt_before=$(dmesg | grep -c -i 'Oops')
>- host_warn_cnt_before=$(dmesg --level=warn | wc -l)
>- vm_oops_cnt_before=$(vm_ssh -- dmesg | grep -c -i 'Oops')
>- vm_warn_cnt_before=$(vm_ssh -- dmesg --level=warn | wc -l)
>+ start_shared_vm=0
>
>- name=$(echo "${1}" | awk '{ print $1 }')
>- eval test_"${name}"
>- rc=$?
>+ for arg in "${ARGS[@]}"; do
>+ if shared_vm_test "${arg}"; then
>+ start_shared_vm=1
>+ break
>+ fi
>+ done
>
>- host_oops_cnt_after=$(dmesg | grep -i 'Oops' | wc -l)
>- if [[ ${host_oops_cnt_after} -gt ${host_oops_cnt_before} ]]; then
>- echo "FAIL: kernel oops detected on host" | log_host "${name}"
>- rc=$KSFT_FAIL
>+ pidfile=""
>+ if [[ "${start_shared_vm}" == 1 ]]; then
>+ pidfile=$(mktemp $PIDFILE_TEMPLATE)
PIDFILE_TEMPLATE is undefined.
>+ log_host "Booting up VM"
>+ vm_start "${VSOCK_CID}" "none" "${pidfile}"
>+ vm_wait_for_ssh "none"
>+ log_host "VM booted up"
> fi
>
>- host_warn_cnt_after=$(dmesg --level=warn | wc -l)
>- if [[ ${host_warn_cnt_after} -gt ${host_warn_cnt_before} ]]; then
>- echo "FAIL: kernel warning detected on host" | log_host "${name}"
>- rc=$KSFT_FAIL
>- fi
>+ for arg in "${ARGS[@]}"; do
>+ if ! shared_vm_test "${arg}"; then
>+ continue
>+ fi
>
>- vm_oops_cnt_after=$(vm_ssh -- dmesg | grep -i 'Oops' | wc -l)
>- if [[ ${vm_oops_cnt_after} -gt ${vm_oops_cnt_before} ]]; then
>- echo "FAIL: kernel oops detected on vm" | log_host "${name}"
>- rc=$KSFT_FAIL
>- fi
>+ if ! check_test_deps "${arg}"; then
>+ log_host "Skipping ${arg}"
>+ check_result "${KSFT_SKIP}"
>+ continue
>+ fi
>+
>+ host_oops_cnt_before=$(dmesg | grep -c -i 'Oops')
>+ host_warn_cnt_before=$(dmesg --level=warn | wc -l)
>+ vm_oops_cnt_before=$(vm_ssh none -- dmesg | grep -c -i 'Oops')
>+ vm_warn_cnt_before=$(vm_ssh none -- dmesg --level=warn | wc -l)
>+
>+ name=$(echo "${arg}" | awk '{ print $1 }')
>+ log_host "Executing test_${name}"
>+ eval test_"${name}"
>+ rc=$?
>+
>+ host_oops_cnt_after=$(dmesg | grep -i 'Oops' | wc -l)
>+ if [[ ${host_oops_cnt_after} -gt ${host_oops_cnt_before} ]]; then
>+ echo "FAIL: kernel oops detected on host" | log_host "${name}"
>+ rc=$KSFT_FAIL
>+ fi
>
>- vm_warn_cnt_after=$(vm_ssh -- dmesg --level=warn | wc -l)
>- if [[ ${vm_warn_cnt_after} -gt ${vm_warn_cnt_before} ]]; then
>- echo "FAIL: kernel warning detected on vm" | log_host "${name}"
>- rc=$KSFT_FAIL
>+ host_warn_cnt_after=$(dmesg --level=warn | wc -l)
>+ if [[ ${host_warn_cnt_after} -gt ${host_warn_cnt_before} ]]; then
>+ echo "FAIL: kernel warning detected on host" | log_host "${name}"
>+ rc=$KSFT_FAIL
>+ fi
>+
>+ vm_oops_cnt_after=$(vm_ssh none -- dmesg | grep -i 'Oops' | wc -l)
>+ if [[ ${vm_oops_cnt_after} -gt ${vm_oops_cnt_before} ]]; then
>+ echo "FAIL: kernel oops detected on vm" | log_host "${name}"
>+ rc=$KSFT_FAIL
>+ fi
>+
>+ vm_warn_cnt_after=$(vm_ssh none -- dmesg --level=warn | wc -l)
>+ if [[ ${vm_warn_cnt_after} -gt ${vm_warn_cnt_before} ]]; then
>+ echo "FAIL: kernel warning detected on vm" | log_host "${name}"
>+ rc=$KSFT_FAIL
>+ fi
>+
>+ check_result "${rc}"
>+ done
>+
>+ if [[ -n "${pidfile}" ]]; then
>+ log_host "VM terminate"
>+ terminate_pidfiles "${pidfile}"
> fi
>+}
>+
>+run_isolated_vm_tests() {
>+ for arg in "${ARGS[@]}"; do
>+ if shared_vm_test "${arg}"; then
>+ continue
>+ fi
>+
>+ add_namespaces
>+ if init_netns_test "${arg}"; then
>+ init_namespaces
>+ fi
>
>- return "${rc}"
>+ name=$(echo "${arg}" | awk '{ print $1 }')
>+ log_host "Executing test_${name}"
>+ eval test_"${name}"
>+ check_result $?
>+
>+ del_namespaces
>+ done
> }
>
>+BUILD=0
Is this a fix for an existing issue?
Another patch in that case?
> QEMU="qemu-system-$(uname -m)"
>
> while getopts :hvsq:b o
>@@ -543,34 +1308,13 @@ fi
> check_args "${ARGS[@]}"
> check_deps
> check_vng
>+check_socat
> handle_build
>
> echo "1..${#ARGS[@]}"
>
>-log_host "Booting up VM"
>-vm_start
>-vm_wait_for_ssh
>-log_host "VM booted up"
>-
>-cnt_pass=0
>-cnt_fail=0
>-cnt_skip=0
>-cnt_total=0
>-for arg in "${ARGS[@]}"; do
>- run_test "${arg}"
>- rc=$?
>- if [[ ${rc} -eq $KSFT_PASS ]]; then
>- cnt_pass=$(( cnt_pass + 1 ))
>- echo "ok ${cnt_total} ${arg}"
>- elif [[ ${rc} -eq $KSFT_SKIP ]]; then
>- cnt_skip=$(( cnt_skip + 1 ))
>- echo "ok ${cnt_total} ${arg} # SKIP"
>- elif [[ ${rc} -eq $KSFT_FAIL ]]; then
>- cnt_fail=$(( cnt_fail + 1 ))
>- echo "not ok ${cnt_total} ${arg} # exit=$rc"
>- fi
>- cnt_total=$(( cnt_total + 1 ))
>-done
>+run_shared_vm_tests
>+run_isolated_vm_tests
Sorry, there are too many changes and reviewing it is complicated. Can
you at least divide it into patches to fix pre-existing bugs, patches to
support namespaces (and use init_ns for the ones we already have), and
patches to add tests?
Thanks,
Stefano
>
> echo "SUMMARY: PASS=${cnt_pass} SKIP=${cnt_skip} FAIL=${cnt_fail}"
> echo "Log: ${LOG}"
>
>--
>2.47.3
>
^ permalink raw reply
* Re: [PATCH v3 0/4] drm: Add vblank timers for devices without interrupts
From: Thomas Zimmermann @ 2025-09-30 15:03 UTC (permalink / raw)
To: Michael Kelley, louis.chauvet@bootlin.com, drawat.floss@gmail.com,
hamohammed.sa@gmail.com, melissa.srw@gmail.com, simona@ffwll.ch,
airlied@gmail.com, maarten.lankhorst@linux.intel.com,
ville.syrjala@linux.intel.com, lyude@redhat.com,
javierm@redhat.com
Cc: dri-devel@lists.freedesktop.org, linux-hyperv@vger.kernel.org
In-Reply-To: <SN6PR02MB41575149CA466B89283B920DD414A@SN6PR02MB4157.namprd02.prod.outlook.com>
Hi
Am 16.09.25 um 17:00 schrieb Michael Kelley:
> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Tuesday, September 16, 2025 1:31 AM
>> Hi
>>
>> Am 09.09.25 um 05:29 schrieb Michael Kelley:
>>> From: Michael Kelley Sent: Thursday, September 4, 2025 10:36 PM
>>>> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Thursday, September 4, 2025 7:56 AM
>>>>> Compositors often depend on vblanks to limit their display-update
>>>>> rate. Without, they see vblank events ASAP, which breaks the rate-
>>>>> limit feature. This creates high CPU overhead. It is especially a
>>>>> problem with virtual devices with fast framebuffer access.
>>>>>
>>>>> The series moves vkms' vblank timer to DRM and converts the hyperv
>>>>> DRM driver. An earlier version of this series contains examples of
>>>>> other updated drivers. In principle, any DRM driver without vblank
>>>>> hardware can use the timer.
>>>> I've tested this patch set in a Hyper-V guest against the linux-next20250829
>>>> kernel. All looks good. Results and perf are the same as reported here [4].
>>>> So far I haven't seen the "vblank timer overrun" error, which is consistent
>>>> with the changes you made since my earlier testing. I'll keep running this
>>>> test kernel for a while to see if anything anomalous occurs.
>>> As I continued to run with this patch set, I got a single occurrence of this
>>> WARN_ON. I can't associate it with any particular action as I didn't notice
>>> it until well after it occurred.
>> I've investigated. The stack trace comes from the kernel console's
>> display update. It runs concurrently to the vblank timeout. What likely
>> happens here is that the update code reads two values and in between,
>> the vblank timeout updates them. So the update then compares an old and
>> a new value; leading to an incorrect result with triggers the warning.
>>
>> I'll include a fix in the series' next iteration. But I also think that
>> it's not critical. DRM's vblank helpers can usually deal with such problems.
> Thanks! I'm giving your v4 series a try now. Good that the underlying
> problem is not critical. But I was seeing the WARN_ON() output in
> dmesg every few days (a total of 4 times now), and that's not really
> acceptable even if everything continues to work correctly.
So it's probably a good sign that I haven't heard from you recently. :)
If you haven't seen any warnings with v4, I'd like to merge the series soon.
Best regards
Thomas
>
> Michael
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply
* RE: [PATCH v3 0/4] drm: Add vblank timers for devices without interrupts
From: Michael Kelley @ 2025-09-30 15:18 UTC (permalink / raw)
To: Thomas Zimmermann, louis.chauvet@bootlin.com,
drawat.floss@gmail.com, hamohammed.sa@gmail.com,
melissa.srw@gmail.com, simona@ffwll.ch, airlied@gmail.com,
maarten.lankhorst@linux.intel.com, ville.syrjala@linux.intel.com,
lyude@redhat.com, javierm@redhat.com
Cc: dri-devel@lists.freedesktop.org, linux-hyperv@vger.kernel.org
In-Reply-To: <b2a15b41-7f20-46ac-9f62-d5e48c597760@suse.de>
From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Tuesday, September 30, 2025 8:04 AM
>
> Hi
>
> Am 16.09.25 um 17:00 schrieb Michael Kelley:
> > From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Tuesday, September 16, 2025 1:31 AM
> >> Hi
> >>
> >> Am 09.09.25 um 05:29 schrieb Michael Kelley:
> >>> From: Michael Kelley Sent: Thursday, September 4, 2025 10:36 PM
> >>>> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Thursday, September 4, 2025 7:56 AM
> >>>>> Compositors often depend on vblanks to limit their display-update
> >>>>> rate. Without, they see vblank events ASAP, which breaks the rate-
> >>>>> limit feature. This creates high CPU overhead. It is especially a
> >>>>> problem with virtual devices with fast framebuffer access.
> >>>>>
> >>>>> The series moves vkms' vblank timer to DRM and converts the hyperv
> >>>>> DRM driver. An earlier version of this series contains examples of
> >>>>> other updated drivers. In principle, any DRM driver without vblank
> >>>>> hardware can use the timer.
> >>>> I've tested this patch set in a Hyper-V guest against the linux-next20250829
> >>>> kernel. All looks good. Results and perf are the same as reported here [4].
> >>>> So far I haven't seen the "vblank timer overrun" error, which is consistent
> >>>> with the changes you made since my earlier testing. I'll keep running this
> >>>> test kernel for a while to see if anything anomalous occurs.
> >>> As I continued to run with this patch set, I got a single occurrence of this
> >>> WARN_ON. I can't associate it with any particular action as I didn't notice
> >>> it until well after it occurred.
> >> I've investigated. The stack trace comes from the kernel console's
> >> display update. It runs concurrently to the vblank timeout. What likely
> >> happens here is that the update code reads two values and in between,
> >> the vblank timeout updates them. So the update then compares an old and
> >> a new value; leading to an incorrect result with triggers the warning.
> >>
> >> I'll include a fix in the series' next iteration. But I also think that
> >> it's not critical. DRM's vblank helpers can usually deal with such problems.
> > Thanks! I'm giving your v4 series a try now. Good that the underlying
> > problem is not critical. But I was seeing the WARN_ON() output in
> > dmesg every few days (a total of 4 times now), and that's not really
> > acceptable even if everything continues to work correctly.
>
> So it's probably a good sign that I haven't heard from you recently. :)
> If you haven't seen any warnings with v4, I'd like to merge the series soon.
>
> Best regards
> Thomas
>
Yes, all is good. I was delayed a bit due to some travel, but the test
system has been running for a week now with no warnings or other
issues. From my standpoint, the patch series is good to merge.
Michael
^ permalink raw reply
* Re: [PATCH v2 00/12] x86/msr: Inline rdmsr/wrmsr instructions
From: H. Peter Anvin @ 2025-09-30 19:19 UTC (permalink / raw)
To: Juergen Gross, linux-kernel, x86, linux-coco, kvm, linux-hyperv,
virtualization, llvm
Cc: xin, Kirill A. Shutemov, Dave Hansen, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Sean Christopherson, Paolo Bonzini,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Vitaly Kuznetsov, Boris Ostrovsky, xen-devel, Ajay Kaher,
Alexey Makhalov, Broadcom internal kernel review list,
Andy Lutomirski, Peter Zijlstra, Nathan Chancellor,
Nick Desaulniers, Bill Wendling, Justin Stitt
In-Reply-To: <20250930070356.30695-1-jgross@suse.com>
On 2025-09-30 00:03, Juergen Gross wrote:
> When building a kernel with CONFIG_PARAVIRT_XXL the paravirt
> infrastructure will always use functions for reading or writing MSRs,
> even when running on bare metal.
>
> Switch to inline RDMSR/WRMSR instructions in this case, reducing the
> paravirt overhead.
>
> In order to make this less intrusive, some further reorganization of
> the MSR access helpers is done in the first 5 patches.
>
> The next 5 patches are converting the non-paravirt case to use direct
> inlining of the MSR access instructions, including the WRMSRNS
> instruction and the immediate variants of RDMSR and WRMSR if possible.
>
> Patch 11 removes the PV hooks for MSR accesses and implements the
> Xen PV cases via calls depending on X86_FEATURE_XENPV, which results
> in runtime patching those calls away for the non-XenPV case.
>
> Patch 12 is a final little cleanup patch.
>
> This series has been tested to work with Xen PV and on bare metal.
>
> This series is inspired by Xin Li, who used a similar approach, but
> (in my opinion) with some flaws. Originally I thought it should be
> possible to use the paravirt infrastructure, but this turned out to be
> rather complicated, especially for the Xen PV case in the *_safe()
> variants of the MSR access functions.
>
Looks good to me.
(I'm not at all surprised that paravirt_ops didn't do the job. Both I and Xin
had come to the same conclusion.)
Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com>
^ permalink raw reply
* Re: [PATCH 1/2] fbdev/hyperv_fb: deprecate this in favor of Hyper-V DRM driver
From: Helge Deller @ 2025-09-30 19:26 UTC (permalink / raw)
To: Michael Kelley, Prasanna Kumar T S M,
dri-devel@lists.freedesktop.org, linux-hyperv@vger.kernel.org,
linux-fbdev@vger.kernel.org
In-Reply-To: <SN6PR02MB4157B55FBE271DB1B75F8FBCD416A@SN6PR02MB4157.namprd02.prod.outlook.com>
On 9/18/25 06:01, Michael Kelley wrote:
> From: Prasanna Kumar T S M <ptsm@linux.microsoft.com> Sent: Wednesday, September 17, 2025 7:03 AM
>>
>> The Hyper-V DRM driver is available since kernel version 5.14 and it
>> provides full KMS support and fbdev emulation via the DRM fbdev helpers.
>> Deprecate this driver in favor of Hyper-V DRM driver.
>>
>> Signed-off-by: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
>> ---
>> drivers/video/fbdev/Kconfig | 5 ++++-
>> drivers/video/fbdev/hyperv_fb.c | 2 ++
>> 2 files changed, 6 insertions(+), 1 deletion(-)
Series applied to fbdev git tree.
Thanks!
Helge
^ permalink raw reply
* Re: [PATCH v5 06/10] x86/realmode: Make the location of the trampoline configurable
From: Wei Liu @ 2025-09-30 21:08 UTC (permalink / raw)
To: Ricardo Neri
Cc: x86, Krzysztof Kozlowski, Conor Dooley, Rob Herring,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Michael Kelley, Rafael J. Wysocki, Saurabh Sengar, Chris Oo,
Kirill A. Shutemov, linux-hyperv, devicetree, linux-acpi,
linux-kernel, Ricardo Neri, Yunhong Jiang, Thomas Gleixner
In-Reply-To: <20250627-rneri-wakeup-mailbox-v5-6-df547b1d196e@linux.intel.com>
On Fri, Jun 27, 2025 at 08:35:12PM -0700, Ricardo Neri wrote:
> From: Yunhong Jiang <yunhong.jiang@linux.intel.com>
>
> x86 CPUs boot in real mode. This mode uses 20-bit memory addresses (16-bit
> registers plus 4-bit segment selectors). This implies that the trampoline
> must reside under the 1MB memory boundary.
>
> There are platforms in which the firmware boots the secondary CPUs,
> switches them to long mode and transfers control to the kernel. An example
> of such mechanism is the ACPI Multiprocessor Wakeup Structure.
>
> In this scenario there is no restriction to locate the trampoline under 1MB
> memory. Moreover, certain platforms (for example, Hyper-V VTL guests) may
> not have memory available for allocation under 1MB.
>
> Add a new member to struct x86_init_resources to specify the upper bound
> for the location of the trampoline memory. Keep the default upper bound of
> 1MB to conserve the current behavior.
>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
> Originally-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Yunhong Jiang <yunhong.jiang@linux.intel.com>
> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Thomas, this is originally your idea. I take it you will be fine this
patch. I can pick this up in the Hyper-V tree.
Let me know otherwise.
Thanks,
Wei
> ---
> Changes since v4:
> - None
>
> Changes since v3:
> - Added Reviewed-by tag from Michael. Thanks!
>
> Changes since v2:
> - Edited the commit message for clarity.
> - Minor tweaks to comments.
> - Removed the option to not reserve the first 1MB of memory as it is
> not needed.
>
> Changes since v1:
> - Added this patch using code that Thomas suggested:
> https://lore.kernel.org/lkml/87a5ho2q6x.ffs@tglx/
> ---
> arch/x86/include/asm/x86_init.h | 3 +++
> arch/x86/kernel/x86_init.c | 3 +++
> arch/x86/realmode/init.c | 7 +++----
> 3 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
> index 36698cc9fb44..e770ce507a87 100644
> --- a/arch/x86/include/asm/x86_init.h
> +++ b/arch/x86/include/asm/x86_init.h
> @@ -31,12 +31,15 @@ struct x86_init_mpparse {
> * platform
> * @memory_setup: platform specific memory setup
> * @dmi_setup: platform specific DMI setup
> + * @realmode_limit: platform specific address limit for the real mode trampoline
> + * (default 1M)
> */
> struct x86_init_resources {
> void (*probe_roms)(void);
> void (*reserve_resources)(void);
> char *(*memory_setup)(void);
> void (*dmi_setup)(void);
> + unsigned long realmode_limit;
> };
>
> /**
> diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
> index 0a2bbd674a6d..a25fd7282811 100644
> --- a/arch/x86/kernel/x86_init.c
> +++ b/arch/x86/kernel/x86_init.c
> @@ -9,6 +9,7 @@
> #include <linux/export.h>
> #include <linux/pci.h>
> #include <linux/acpi.h>
> +#include <linux/sizes.h>
>
> #include <asm/acpi.h>
> #include <asm/bios_ebda.h>
> @@ -69,6 +70,8 @@ struct x86_init_ops x86_init __initdata = {
> .reserve_resources = reserve_standard_io_resources,
> .memory_setup = e820__memory_setup_default,
> .dmi_setup = dmi_setup,
> + /* Has to be under 1M so we can execute real-mode AP code. */
> + .realmode_limit = SZ_1M,
> },
>
> .mpparse = {
> diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
> index 88be32026768..694d80a5c68e 100644
> --- a/arch/x86/realmode/init.c
> +++ b/arch/x86/realmode/init.c
> @@ -46,7 +46,7 @@ void load_trampoline_pgtable(void)
>
> void __init reserve_real_mode(void)
> {
> - phys_addr_t mem;
> + phys_addr_t mem, limit = x86_init.resources.realmode_limit;
> size_t size = real_mode_size_needed();
>
> if (!size)
> @@ -54,10 +54,9 @@ void __init reserve_real_mode(void)
>
> WARN_ON(slab_is_available());
>
> - /* Has to be under 1M so we can execute real-mode AP code. */
> - mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
> + mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, limit);
> if (!mem)
> - pr_info("No sub-1M memory is available for the trampoline\n");
> + pr_info("No memory below %pa for the real-mode trampoline\n", &limit);
> else
> set_real_mode_mem(mem);
>
>
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH hyperv-next v5 04/16] arch/x86: mshyperv: Trap on access for some synthetic MSRs
From: Wei Liu @ 2025-09-30 21:59 UTC (permalink / raw)
To: Michael Kelley
Cc: Roman Kisel, arnd@arndb.de, bp@alien8.de, corbet@lwn.net,
dave.hansen@linux.intel.com, decui@microsoft.com,
haiyangz@microsoft.com, hpa@zytor.com, kys@microsoft.com,
mikelley@microsoft.com, mingo@redhat.com, tglx@linutronix.de,
Tianyu.Lan@microsoft.com, wei.liu@kernel.org, x86@kernel.org,
linux-hyperv@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
benhill@microsoft.com, bperkins@microsoft.com,
sunilmut@microsoft.com
In-Reply-To: <BN7PR02MB414878837D34F40D23DB9506D40FA@BN7PR02MB4148.namprd02.prod.outlook.com>
On Tue, Sep 09, 2025 at 03:11:47AM +0000, Michael Kelley wrote:
> From: Roman Kisel <romank@linux.microsoft.com> Sent: Wednesday, August 27, 2025 6:06 PM
> >
> > hv_set_non_nested_msr() has special handling for SINT MSRs
> > when a paravisor is present. In addition to updating the MSR on the
> > host, the mirror MSR in the paravisor is updated, including with the
> > proxy bit. But with Confidential VMBus, the proxy bit must not be
> > used, so add a special case to skip it.
> >
> > Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> > Reviewed-by: Alok Tiwari <alok.a.tiwari@oracle.com>
> > Reviewed-by: Tianyu Lan <tiala@microsoft.com>
> > ---
[...]
> > diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
> > index a619b661275b..5e2c6fd637d2 100644
> > --- a/arch/x86/kernel/cpu/mshyperv.c
> > +++ b/arch/x86/kernel/cpu/mshyperv.c
> > @@ -28,6 +28,7 @@
> > #include <asm/apic.h>
> > #include <asm/timer.h>
> > #include <asm/reboot.h>
> > +#include <asm/msr.h>
> > #include <asm/nmi.h>
> > #include <clocksource/hyperv_timer.h>
> > #include <asm/msr.h>
> > @@ -38,6 +39,16 @@
> > bool hv_nested;
> > struct ms_hyperv_info ms_hyperv;
> >
> > +#define HYPERV_SINT_PROXY_ENABLE BIT(20)
> > +#define HYPERV_SINT_PROXY_DISABLE 0
>
> Seems like these definitions belong in hvgdk_mini.h together with
> the definition of "union hv_synic_sint". Since that union already
> defines the "proxy" field, the definitions really should be in terms
> of that field (though I'd have to fiddle with the code to figure out
> if there's a reasonable way to do that).
>
If we use sint.proxy (or sint->proxy) then we don't even need this
definition. I think this is only needed because the code writes u64
directly to the MSR without reinterpreting it as hv_synic_sint.
Wei
^ permalink raw reply
* Re: [PATCH v1 2/2] Drivers: hv: Make CONFIG_HYPERV bool
From: Wei Liu @ 2025-09-30 22:05 UTC (permalink / raw)
To: Mukesh R
Cc: Greg KH, dri-devel, linux-kernel, linux-input, linux-hyperv,
netdev, linux-pci, linux-scsi, linux-fbdev, linux-arch,
virtualization, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, jikos, bentiss, kys, haiyangz, wei.liu, decui,
dmitry.torokhov, andrew+netdev, davem, edumazet, kuba, pabeni,
bhelgaas, James.Bottomley, martin.petersen, deller, arnd,
sgarzare, horms
In-Reply-To: <a8c8305c-b518-c840-fc64-50bcba302725@linux.microsoft.com>
On Fri, Sep 12, 2025 at 11:10:00AM -0700, Mukesh R wrote:
[...]
> > What was it made against?
> >
>
> Sorry to hear that. It was built against hyper-next, but perhaps I
> accidentally used our internal mirror. Let me rebase and send V2
> right away.
Sorry for the late reply -- I was away for two weeks. I can pick this
series up.
Greg, feel free to ignore this series.
Wei
>
> Thanks,
> -Mukesh
>
>
>
^ permalink raw reply
* Re: [PATCH v4] x86/hyperv: Fix kdump on Azure CVMs
From: Wei Liu @ 2025-09-30 22:48 UTC (permalink / raw)
To: Michael Kelley
Cc: Vitaly Kuznetsov, Wei Liu, linux-hyperv@vger.kernel.org,
K. Y. Srinivasan, Haiyang Zhang, Dexuan Cui, x86@kernel.org,
linux-kernel@vger.kernel.org, Nuno Das Neves, Tianyu Lan, Li Tian,
Philipp Rudo
In-Reply-To: <SN6PR02MB4157B42CCDC571AA07A34E82D403A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Fri, Sep 05, 2025 at 03:57:03PM +0000, Michael Kelley wrote:
> From: Vitaly Kuznetsov <vkuznets@redhat.com> Sent: Friday, September 5, 2025 12:48 AM
> >
> > Wei Liu <wei.liu@kernel.org> writes:
> >
> > > On Thu, Aug 28, 2025 at 12:16:18PM +0300, Vitaly Kuznetsov wrote:
> > >> Azure CVM instance types featuring a paravisor hang upon kdump. The
> > >> investigation shows that makedumpfile causes a hang when it steps on a page
> > >> which was previously share with the host
> > >> (HVCALL_MODIFY_SPARSE_GPA_PAGE_HOST_VISIBILITY). The new kernel has no
> > >> knowledge of these 'special' regions (which are Vmbus connection pages,
> > >> GPADL buffers, ...). There are several ways to approach the issue:
> > >> - Convey the knowledge about these regions to the new kernel somehow.
> > >> - Unshare these regions before accessing in the new kernel (it is unclear
> > >> if there's a way to query the status for a given GPA range).
> > >> - Unshare these regions before jumping to the new kernel (which this patch
> > >> implements).
> > >>
> > >> To make the procedure as robust as possible, store PFN ranges of shared
> > >> regions in a linked list instead of storing GVAs and re-using
> > >> hv_vtom_set_host_visibility(). This also allows to avoid memory allocation
> > >> on the kdump/kexec path.
> > >>
> > >> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
> > >
> > > No fixes tag for this one?
> > >
> >
> > Personally, I don't see this as a 'bug', it's rather a missing
> > feature. In theory, we can add something like
> >
> > Fixes: 810a52126502 ("x86/hyperv: Add new hvcall guest address host visibility
> > support")
> >
> > but I'm on the fence whether this is accurate or not.
> >
> > > Should it be marked as a stable backport?
> >
> > I think it may make sense even without an explicit 'Fixes:': kdump is the
> > user's last resort when it comes to kernel crashes and doubly so on
> > CVMs. Pure kexec may also come handy.
> >
>
> I agree -- think of this as adding a feature instead of fixing a bug. Prior
> to now, there hasn't been any attempt to make kexec/kdump work
> for Azure CVMs.
>
> Instead of using the word "Fix", maybe the patch "Subject:" should be
> changed to "x86/hyperv: Add kexec/kdump support on Azure CVMs".
I have fixed that in the hyperv-next tree. Thanks for the discussion.
Wei
>
> Michael
^ permalink raw reply
* Re: [PATCH 0/5] x86/Hyper-V: Add AMD Secure AVIC for Hyper-V platform
From: Wei Liu @ 2025-09-30 23:05 UTC (permalink / raw)
To: Tianyu Lan
Cc: kys, haiyangz, wei.liu, decui, tglx, mingo, bp, dave.hansen, x86,
hpa, arnd, Neeraj.Upadhyay, tiala, kvijayab, romank, linux-arch,
linux-hyperv
In-Reply-To: <20250918150023.474021-1-tiala@microsoft.com>
On Thu, Sep 18, 2025 at 11:00:18AM -0400, Tianyu Lan wrote:
> Secure AVIC is a new hardware feature in the AMD64
> architecture to allow SEV-SNP guests to prevent the
> hypervisor from generating unexpected interrupts to
> a vCPU or otherwise violate architectural assumptions
> around APIC behavior.
>
> Each vCPU has a guest-allocated APIC backing page of
> size 4K, which maintains APIC state for that vCPU.
> APIC backing page's ALLOWED_IRR field indicates the
> interrupt vectors which the guest allows the hypervisor
> to send.
>
> This patchset is to enable the feature for Hyper-V
> platform. Patch "Drivers: hv: Allow vmbus message
> synic interrupt injected from Hyper-V" is to expose
> new fucntion hv_enable_coco_interrupt() and device
> driver and arch code may update AVIC backing page
> ALLOWED_IRR field to allow Hyper-V inject associated
> vector.
>
> The patchset is based on the tip tree commit 27a17e02418e
> (x86/sev: Indicate the SEV-SNP guest supports Secure AVIC)
>
> Tianyu Lan (5):
> x86/hyperv: Don't use hv apic driver when Secure AVIC is available
> drivers: hv: Allow vmbus message synic interrupt injected from Hyper-V
> x86/hyperv: Don't use auto-eoi when Secure AVIC is available
> x86/hyperv: Allow Hyper-V to inject STIMER0 interrupts
These look good to me.
> x86/Hyper-V: Add Hyper-V specific hvcall to set backing page
Please address Borislav's comment on this patch.
Thanks,
Wei
>
> arch/x86/hyperv/hv_apic.c | 8 ++++++
> arch/x86/hyperv/hv_init.c | 31 ++++++++++++++++++++++-
> arch/x86/hyperv/ivm.c | 38 ++++++++++++++++++++++++++++
> arch/x86/include/asm/mshyperv.h | 2 ++
> arch/x86/kernel/apic/x2apic_savic.c | 9 ++++++-
> arch/x86/kernel/cpu/mshyperv.c | 3 +++
> drivers/hv/hv.c | 2 ++
> drivers/hv/hv_common.c | 5 ++++
> include/asm-generic/mshyperv.h | 1 +
> include/hyperv/hvgdk_mini.h | 39 +++++++++++++++++++++++++++++
> 10 files changed, 136 insertions(+), 2 deletions(-)
>
> --
> 2.25.1
>
>
^ permalink raw reply
* Re: [PATCH v4 0/5] mshv: Fixes for stats and vp state page mappings
From: Wei Liu @ 2025-09-30 23:14 UTC (permalink / raw)
To: Nuno Das Neves
Cc: Stanislav Kinsburskii, linux-hyperv, linux-kernel, prapal,
easwar.hariharan, tiala, anirudh, paekkaladevi, kys, haiyangz,
wei.liu, decui
In-Reply-To: <96009fb8-0ad6-4e5b-8656-af78874a5605@linux.microsoft.com>
On Mon, Sep 29, 2025 at 11:19:51AM -0700, Nuno Das Neves wrote:
> On 9/26/2025 4:12 PM, Stanislav Kinsburskii wrote:
> > On Fri, Sep 26, 2025 at 09:23:10AM -0700, Nuno Das Neves wrote:
> >> There are some differences in how L1VH partitions must map stats and vp
> >> state pages, some of which are due to differences across hypervisor
> >> versions. Detect and handle these cases.
> >>
> >
> > I'm not sure that support for older and actully broken versions on
> > hypervisor need to be usptreamed, as these versions will go away sooner
> > or later and this support will become dead weight.
> >
> As far as I know, these changes are relevant for shipped versions of the
> hypervisor - they are not 'broken' except in some very specific cases
> (live migration on L1VH, I think?)
>
Right, they are not broken, just have more limitations.
> The hypervisor team added a feature bit for these changes so that both old
> and new versions of these APIs can be supported.
>
> > I think we should upstrem only the changes needed for the new versiong
> > of hypervisors instead and carry legacy support out of tree until it
> > becomes obsoleted.
> >
> Which version do you suggest to be the cutoff?
>
> I'd prefer to support as many versions of the hypervisor as we can, as
> long as they are at all relevant. We can remove the support later.
> Removing prematurely just creates friction. Inevitably some users will
> find themselves running on an older hypervisor and then it just fails
> with a cryptic error. This includes myself, since I test L1VH on Azure
> which typically has older hypervisor versions.
This. It takes a long time to saturate the fleet with a new hypervisor.
Realistically I am looking at 2+ years before we can drop the
compatibility code, if ever.
Another reason to upstream the compatibility code is because partners
will want to pick up our code, so hiding this code from them makes both
our and their life harder.
Wei
>
> Nuno
^ permalink raw reply
* Re: [PATCH v2] drivers: hv: vmbus: Clean up sscanf format specifier in target_cpu_store()
From: Wei Liu @ 2025-09-30 23:28 UTC (permalink / raw)
To: Michael Kelley
Cc: Alok Tiwari, kys@microsoft.com, haiyangz@microsoft.com,
wei.liu@kernel.org, decui@microsoft.com,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <SN6PR02MB4157E58381C62CCC2681A20BD416A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Thu, Sep 18, 2025 at 03:51:00AM +0000, Michael Kelley wrote:
> From: Alok Tiwari <alok.a.tiwari@oracle.com> Sent: Wednesday, September 17, 2025 2:00 AM
> >
> > The target_cpu_store() function parses the target CPU from the sysfs
> > buffer using sscanf(). The format string currently uses "%uu", which
> > is redundant. The compiler ignores the extra "u", so there is no
> > incorrect parsing at runtime.
> >
> > Update the format string to use "%u" for clarity and consistency.
> >
> > Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
> > ---
> > v1 -> v2
> > Rephrase commit message and subject to clarify
> > that there is no incorrect parsing at runtime.
> > ---
> > drivers/hv/vmbus_drv.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> > index 5b4f8d009ca5..69591dc7bad2 100644
> > --- a/drivers/hv/vmbus_drv.c
> > +++ b/drivers/hv/vmbus_drv.c
> > @@ -1742,7 +1742,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel,
> > u32 target_cpu;
> > ssize_t ret;
> >
> > - if (sscanf(buf, "%uu", &target_cpu) != 1)
> > + if (sscanf(buf, "%u", &target_cpu) != 1)
> > return -EIO;
> >
> > cpus_read_lock();
> > --
> > 2.50.1
>
> Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Applied. Thanks.
^ permalink raw reply
* Re: [PATCH 1/3] drivers: hv: vmbus: Fix sysfs output format for ring buffer index
From: Wei Liu @ 2025-09-30 23:32 UTC (permalink / raw)
To: Alok Tiwari; +Cc: kys, haiyangz, wei.liu, decui, linux-hyperv, linux-kernel
In-Reply-To: <20250913192450.4134957-1-alok.a.tiwari@oracle.com>
On Sat, Sep 13, 2025 at 12:24:42PM -0700, Alok Tiwari wrote:
> The sysfs attributes out_read_index and out_write_index in
> vmbus_drv.c currently use %d to print outbound.current_read_index
> and outbound.current_write_index.
>
> These fields are u32 values, so printing them with %d (signed) is
> not logically correct. Update the format specifier to %u to
> correctly match their type.
>
> No functional change, only fixes the sysfs output format.
>
> Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com>
Applied this and patch 3. The second patch is dropped in favor of the v2
you sent out later.
Wei
^ permalink raw reply
* Re: [PATCH v1 0/2] Fix CONFIG_HYPERV and vmbus related anamoly
From: Wei Liu @ 2025-09-30 23:57 UTC (permalink / raw)
To: Mukesh Rathor
Cc: dri-devel, linux-kernel, linux-input, linux-hyperv, netdev,
linux-pci, linux-scsi, linux-fbdev, linux-arch, virtualization,
maarten.lankhorst, mripard, tzimmermann, airlied, simona, jikos,
bentiss, kys, haiyangz, wei.liu, decui, dmitry.torokhov,
andrew+netdev, davem, edumazet, kuba, pabeni, bhelgaas,
James.Bottomley, martin.petersen, gregkh, deller, arnd, sgarzare,
horms
In-Reply-To: <20250906010952.2145389-1-mrathor@linux.microsoft.com>
On Fri, Sep 05, 2025 at 06:09:50PM -0700, Mukesh Rathor wrote:
> At present, drivers/Makefile will subst =m to =y for CONFIG_HYPERV
> for hv subdir. Also, drivers/hv/Makefile replaces =m to =y to build in
> hv_common.c that is needed for the drivers. Moreover, vmbus driver is
> built if CONFIG_HYPER is set, either loadable or builtin.
>
> This is not a good approach. CONFIG_HYPERV is really an umbrella
> config that encompasses builtin code and various other things and not
> a dedicated config option for VMBus. VMBus should really have a config
> option just like CONFIG_HYPERV_BALLOON etc. This small series introduces
> CONFIG_HYPERV_VMBUS to build VMBus driver and make that distinction
> explicit. With that CONFIG_HYPERV could be changed to bool.
>
> For now, hv_common.c is left as is to reduce conflicts for upcoming
> patches, but once merges are mostly done, that and some others should
> be moved to virt/hyperv directory.
>
> V1:
> o Change subject from hyper-v to "Drivers: hv:"
> o Rewrite commit messages paying attention to VMBus and not vmbus
> o Change some wordings in Kconfig
> o Make new VMBUS config option default to HYPERV option for a smoother
> transition
>
> Mukesh Rathor (2):
> Driver: hv: Add CONFIG_HYPERV_VMBUS option
> Drivers: hv: Make CONFIG_HYPERV bool
>
Applied. Thanks.
^ permalink raw reply
* Re: [PATCH v1 0/2] Fix CONFIG_HYPERV and vmbus related anamoly
From: Wei Liu @ 2025-09-30 23:59 UTC (permalink / raw)
To: Mukesh Rathor
Cc: dri-devel, linux-kernel, linux-input, linux-hyperv, netdev,
linux-pci, linux-scsi, linux-fbdev, linux-arch, virtualization,
maarten.lankhorst, mripard, tzimmermann, airlied, simona, jikos,
bentiss, kys, haiyangz, wei.liu, decui, dmitry.torokhov,
andrew+netdev, davem, edumazet, kuba, pabeni, bhelgaas,
James.Bottomley, martin.petersen, gregkh, deller, arnd, sgarzare,
horms
In-Reply-To: <aNxuU6VI3dQVPYF7@liuwe-devbox-ubuntu-v2.lamzopl0uupeniq2etz1fddiyg.xx.internal.cloudapp.net>
On Tue, Sep 30, 2025 at 11:57:07PM +0000, Wei Liu wrote:
> On Fri, Sep 05, 2025 at 06:09:50PM -0700, Mukesh Rathor wrote:
> > At present, drivers/Makefile will subst =m to =y for CONFIG_HYPERV
> > for hv subdir. Also, drivers/hv/Makefile replaces =m to =y to build in
> > hv_common.c that is needed for the drivers. Moreover, vmbus driver is
> > built if CONFIG_HYPER is set, either loadable or builtin.
> >
> > This is not a good approach. CONFIG_HYPERV is really an umbrella
> > config that encompasses builtin code and various other things and not
> > a dedicated config option for VMBus. VMBus should really have a config
> > option just like CONFIG_HYPERV_BALLOON etc. This small series introduces
> > CONFIG_HYPERV_VMBUS to build VMBus driver and make that distinction
> > explicit. With that CONFIG_HYPERV could be changed to bool.
> >
> > For now, hv_common.c is left as is to reduce conflicts for upcoming
> > patches, but once merges are mostly done, that and some others should
> > be moved to virt/hyperv directory.
> >
> > V1:
> > o Change subject from hyper-v to "Drivers: hv:"
> > o Rewrite commit messages paying attention to VMBus and not vmbus
> > o Change some wordings in Kconfig
> > o Make new VMBUS config option default to HYPERV option for a smoother
> > transition
> >
> > Mukesh Rathor (2):
> > Driver: hv: Add CONFIG_HYPERV_VMBUS option
> > Drivers: hv: Make CONFIG_HYPERV bool
> >
>
> Applied. Thanks.
I meant to apply v2 of this series. This is sent to the wrong version.
Please ignore.
^ permalink raw reply
* Re: [PATCH v2 0/2] Fix CONFIG_HYPERV and vmbus related anamoly
From: Wei Liu @ 2025-10-01 0:01 UTC (permalink / raw)
To: Mukesh Rathor
Cc: dri-devel, linux-kernel, linux-input, linux-hyperv, netdev,
linux-pci, linux-scsi, linux-fbdev, linux-arch, virtualization,
maarten.lankhorst, mripard, tzimmermann, airlied, simona, jikos,
bentiss, kys, haiyangz, wei.liu, decui, dmitry.torokhov,
andrew+netdev, davem, edumazet, kuba, pabeni, bhelgaas,
James.Bottomley, martin.petersen, gregkh, deller, arnd, sgarzare,
horms
In-Reply-To: <20250915234604.3256611-1-mrathor@linux.microsoft.com>
On Mon, Sep 15, 2025 at 04:46:02PM -0700, Mukesh Rathor wrote:
> At present, drivers/Makefile will subst =m to =y for CONFIG_HYPERV
> for hv subdir. Also, drivers/hv/Makefile replaces =m to =y to build in
> hv_common.c that is needed for the drivers. Moreover, vmbus driver is
> built if CONFIG_HYPER is set, either loadable or builtin.
>
> This is not a good approach. CONFIG_HYPERV is really an umbrella
> config that encompasses builtin code and various other things and not
> a dedicated config option for VMBus. VMBus should really have a config
> option just like CONFIG_HYPERV_BALLOON etc. This small series introduces
> CONFIG_HYPERV_VMBUS to build VMBus driver and make that distinction
> explicit. With that CONFIG_HYPERV could be changed to bool.
>
> For now, hv_common.c is left as is to reduce conflicts for upcoming
> patches, but once merges are mostly done, that and some others should
> be moved to virt/hyperv directory.
>
> V2:
> o rebased on hyper-next: commit 553d825fb2f0
> ("x86/hyperv: Switch to msi_create_parent_irq_domain()")
>
> V1:
> o Change subject from hyper-v to "Drivers: hv:"
> o Rewrite commit messages paying attention to VMBus and not vmbus
> o Change some wordings in Kconfig
> o Make new VMBUS config option default to HYPERV option for a smoother
> transition
>
> Mukesh Rathor (2):
> Driver: hv: Add CONFIG_HYPERV_VMBUS option
I changed Driver to Drivers and applied both patches. Thanks.
^ permalink raw reply
* Re: [PATCH v2 0/4] Introduce movable pages for Hyper-V guests
From: Wei Liu @ 2025-10-01 4:03 UTC (permalink / raw)
To: Stanislav Kinsburskii
Cc: kys, haiyangz, wei.liu, decui, linux-hyperv, linux-kernel
In-Reply-To: <175916156212.55038.16727147489322393965.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>
On Mon, Sep 29, 2025 at 04:02:59PM +0000, Stanislav Kinsburskii wrote:
> From the start, the root-partition driver allocates, pins, and maps all
> guest memory into the hypervisor at guest creation. This is simple: Linux
> cannot move the pages, so the guest’s view in Linux and in Microsoft
> Hypervisor never diverges.
>
> However, this approach has major drawbacks:
> - NUMA: affinity can’t be changed at runtime, so you can’t migrate guest memory closer to the CPUs running it → performance hit.
> - Memory management: unused guest memory can’t be swapped out, compacted, or merged.
> - Provisioning time: upfront allocation/pinning slows guest create/destroy.
> - Overcommit: no memory overcommit on hosts with pinned-guest memory.
>
> This series adds movable memory pages for Hyper-V child partitions. Guest
> pages are no longer allocated upfront; they’re allocated and mapped into
> the hypervisor on demand (i.e., when the guest touches a GFN that isn’t yet
> backed by a host PFN).
> When a page is moved, Linux no longer holds it and it is unmapped from the hypervisor.
> As a result, Hyper-V guests behave like regular Linux processes, enabling standard Linux memory features to apply to guests.
>
> Exceptions (still pinned):
> 1. Encrypted guests (explicit).
> 2 Guests with passthrough devices (implicitly pinned by the VFIO framework).
>
> v2:
> - Split unmap batching into a separate patch.
> - Fixed commit messages from v1 review.
> - Renamed a few functions for clarity.
>
> ---
>
> Stanislav Kinsburskii (4):
> Drivers: hv: Refactor and rename memory region handling functions
> Drivers: hv: Centralize guest memory region destruction
> Drivers: hv: Batch GPA unmap operations to improve large region performance
> Drivers: hv: Add support for movable memory regions
>
Our internal test discovered an issue which caused a kernel panic. Has
that been fixed in this series?
Without fixing that bug or ruling out problems in the code I don't think
I can merge this. Once this feature goes into other people's systems it
will be extremely difficult to debug.
Wei
>
> drivers/hv/Kconfig | 1
> drivers/hv/mshv_root.h | 10 +
> drivers/hv/mshv_root_hv_call.c | 2
> drivers/hv/mshv_root_main.c | 472 +++++++++++++++++++++++++++++++++-------
> 4 files changed, 403 insertions(+), 82 deletions(-)
>
^ permalink raw reply
* Re: [PATCH 0/3] Introduce movable pages for Hyper-V guests
From: Wei Liu @ 2025-10-01 4:18 UTC (permalink / raw)
To: Mukesh R, Mike Rapoport
Cc: Stanislav Kinsburskii, kys, haiyangz, wei.liu, decui,
linux-hyperv, linux-kernel
In-Reply-To: <0ef4d844-a0af-9fa6-2163-b83f80bc74b1@linux.microsoft.com>
+Mike Rapoport, our resident memory management expert.
On Fri, Sep 26, 2025 at 07:02:02PM -0700, Mukesh R wrote:
> On 9/24/25 14:30, Stanislav Kinsburskii wrote:
> >>From the start, the root-partition driver allocates, pins, and maps all
> > guest memory into the hypervisor at guest creation. This is simple: Linux
> > cannot move the pages, so the guest?s view in Linux and in Microsoft
> > Hypervisor never diverges.
> >
> > However, this approach has major drawbacks:
> > - NUMA: affinity can?t be changed at runtime, so you can?t migrate guest memory closer to the CPUs running it ? performance hit.
> > - Memory management: unused guest memory can?t be swapped out, compacted, or merged.
> > - Provisioning time: upfront allocation/pinning slows guest create/destroy.
> > - Overcommit: no memory overcommit on hosts with pinned-guest memory.
> >
> > This series adds movable memory pages for Hyper-V child partitions. Guest
> > pages are no longer allocated upfront; they?re allocated and mapped into
> > the hypervisor on demand (i.e., when the guest touches a GFN that isn?t yet
> > backed by a host PFN).
> > When a page is moved, Linux no longer holds it and it is unmapped from the hypervisor.
> > As a result, Hyper-V guests behave like regular Linux processes, enabling standard Linux memory features to apply to guests.
> >
> > Exceptions (still pinned):
> > 1. Encrypted guests (explicit).
> > 2 Guests with passthrough devices (implicitly pinned by the VFIO framework).
>
>
> As I had commented internally, I am not fully comfortable about the
> approach here, specially around use of HMM, and the correctness of
> locking for shared memory regions, but my knowledge is from 4.15 and
> maybe outdated, and don't have time right now. So I won't object to it
> if other hard core mmu developers think there are no issues.
>
Mike, I seem to remember you had a discussion with Stanislav about this?
Can you confirm that this is a reasonable approach?
Better yet, if you have time to review the code, that would be great.
Note that there is a v2 on linux-hyperv. But I would like to close
Mukesh's question first.
Thanks,
Wei
> However, we won't be using this for minkernel, so would like a driver
> boot option to disable it upon boot that we can just set in minkernel
> init path. This option can also be used to disable it if problems are
> observed on the field. Minkernel design is still being worked on, so I
> cannot provide much details on it yet.
>
> Thanks,
> -Mukesh
>
>
> > ---
> >
> > Stanislav Kinsburskii (3):
> > Drivers: hv: Rename a few memory region related functions for clarity
> > Drivers: hv: Centralize guest memory region destruction in helper
> > Drivers: hv: Add support for movable memory regions
> >
> >
> > drivers/hv/Kconfig | 1
> > drivers/hv/mshv_root.h | 8 +
> > drivers/hv/mshv_root_main.c | 448 +++++++++++++++++++++++++++++++++++++------
> > 3 files changed, 397 insertions(+), 60 deletions(-)
> >
>
^ permalink raw reply
* Re: [PATCH v2 4/6] x86/hyperv: Add trampoline asm code to transition from hypervisor
From: Wei Liu @ 2025-10-01 6:00 UTC (permalink / raw)
To: Mukesh Rathor
Cc: linux-hyperv, linux-kernel, linux-arch, kys, haiyangz, wei.liu,
decui, tglx, mingo, bp, dave.hansen, x86, hpa, arnd
In-Reply-To: <20250923214609.4101554-5-mrathor@linux.microsoft.com>
On Tue, Sep 23, 2025 at 02:46:07PM -0700, Mukesh Rathor wrote:
> Introduce a small asm stub to transition from the hypervisor to Linux
> after devirtualization. Devirtualization means disabling hypervisor on
> the fly, so after it is done, the code is running on physical processor
> instead of virtual, and hypervisor is gone. This can be done by a
> root/dom0 vm only.
I want to scrub "dom0" from comments and commit messages. We drew
parallels to Xen when we first wrote this code, but it's not a useful
term externally. "root" or "root partition" should be sufficient.
>
> At a high level, during panic of either the hypervisor or the dom0 (aka
> root), the NMI handler asks hypervisor to devirtualize. As part of that,
> the arguments include an entry point to return back to Linux. This asm
> stub implements that entry point.
>
> The stub is entered in protected mode, uses temporary gdt and page table
> to enable long mode and get to kernel entry point which then restores full
> kernel context to resume execution to kexec.
>
> Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
> ---
> arch/x86/hyperv/hv_trampoline.S | 101 ++++++++++++++++++++++++++++++++
> 1 file changed, 101 insertions(+)
> create mode 100644 arch/x86/hyperv/hv_trampoline.S
>
> diff --git a/arch/x86/hyperv/hv_trampoline.S b/arch/x86/hyperv/hv_trampoline.S
> new file mode 100644
> index 000000000000..25f02ff12286
> --- /dev/null
> +++ b/arch/x86/hyperv/hv_trampoline.S
> @@ -0,0 +1,101 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * X86 specific Hyper-V kdump/crash related code.
> + *
> + * Copyright (C) 2025, Microsoft, Inc.
> + *
> + */
> +#include <linux/linkage.h>
> +#include <asm/alternative.h>
> +#include <asm/msr.h>
> +#include <asm/processor-flags.h>
> +#include <asm/nospec-branch.h>
> +
> +/*
> + * void noreturn hv_crash_asm32(arg1)
> + * arg1 == edi == 32bit PA of struct hv_crash_tramp_data
> + *
> + * The hypervisor jumps here upon devirtualization in protected mode. This
> + * code gets copied to a page in the low 4G ie, 32bit space so it can run
> + * in the protected mode. Hence we cannot use any compile/link time offsets or
> + * addresses. It restores long mode via temporary gdt and page tables and
> + * eventually jumps to kernel code entry at HV_CRASHDATA_OFFS_C_entry.
> + *
> + * PreCondition (ie, Hypervisor call back ABI):
> + * o CR0 is set to 0x0021: PE(prot mode) and NE are set, paging is disabled
> + * o CR4 is set to 0x0
> + * o IA32_EFER is set to 0x901 (SCE and NXE are set)
> + * o EDI is set to the Arg passed to HVCALL_DISABLE_HYP_EX.
> + * o CS, DS, ES, FS, GS are all initialized with a base of 0 and limit 0xFFFF
> + * o IDTR, TR and GDTR are initialized with a base of 0 and limit of 0xFFFF
> + * o LDTR is initialized as invalid (limit of 0)
> + * o MSR PAT is power on default.
> + * o Other state/registers are cleared. All TLBs flushed.
> + */
> +
> +#define HV_CRASHDATA_OFFS_TRAMPCR3 0x0 /* 0 */
> +#define HV_CRASHDATA_OFFS_KERNCR3 0x8 /* 8 */
> +#define HV_CRASHDATA_OFFS_GDTRLIMIT 0x12 /* 18 */
> +#define HV_CRASHDATA_OFFS_CS_JMPTGT 0x28 /* 40 */
> +#define HV_CRASHDATA_OFFS_C_entry 0x30 /* 48 */
> +
> + .text
> + .code32
> +
I recently learned that instrumentation may be problematic for context
switching code. I have not studied this code and noinstr usage in tree
extensively so cannot make a judgement here.
It is worth checking out the recent discussion on the VTL transition
code.
https://lore.kernel.org/linux-hyperv/27e50bb7-7f0e-48fb-bdbc-6c6d606e7113@redhat.com/
And check out the in-tree document Documentation/core-api/entry.rst.
Wei
> +SYM_CODE_START(hv_crash_asm32)
> + UNWIND_HINT_UNDEFINED
> + ENDBR
> + movl $X86_CR4_PAE, %ecx
> + movl %ecx, %cr4
> +
> + movl %edi, %ebx
> + add $HV_CRASHDATA_OFFS_TRAMPCR3, %ebx
> + movl %cs:(%ebx), %eax
> + movl %eax, %cr3
> +
> + /* Setup EFER for long mode now */
> + movl $MSR_EFER, %ecx
> + rdmsr
> + btsl $_EFER_LME, %eax
> + wrmsr
> +
> + /* Turn paging on using the temp 32bit trampoline page table */
> + movl %cr0, %eax
> + orl $(X86_CR0_PG), %eax
> + movl %eax, %cr0
> +
> + /* since kernel cr3 could be above 4G, we need to be in the long mode
> + * before we can load 64bits of the kernel cr3. We use a temp gdt for
> + * that with CS.L=1 and CS.D=0 */
> + mov %edi, %eax
> + add $HV_CRASHDATA_OFFS_GDTRLIMIT, %eax
> + lgdtl %cs:(%eax)
> +
> + /* not done yet, restore CS now to switch to CS.L=1 */
> + mov %edi, %eax
> + add $HV_CRASHDATA_OFFS_CS_JMPTGT, %eax
> + ljmp %cs:*(%eax)
> +SYM_CODE_END(hv_crash_asm32)
> +
> + /* we now run in full 64bit IA32-e long mode, CS.L=1 and CS.D=0 */
> + .code64
> + .balign 8
> +SYM_CODE_START(hv_crash_asm64)
> + UNWIND_HINT_UNDEFINED
> + ENDBR
> + /* restore kernel page tables so we can jump to kernel code */
> + mov %edi, %eax
> + add $HV_CRASHDATA_OFFS_KERNCR3, %eax
> + movq %cs:(%eax), %rbx
> + movq %rbx, %cr3
> +
> + mov %edi, %eax
> + add $HV_CRASHDATA_OFFS_C_entry, %eax
> + movq %cs:(%eax), %rbx
> + ANNOTATE_RETPOLINE_SAFE
> + jmp *%rbx
> +
> + int $3
> +
> +SYM_INNER_LABEL(hv_crash_asm_end, SYM_L_GLOBAL)
> +SYM_CODE_END(hv_crash_asm64)
> --
> 2.36.1.vfs.0.0
>
>
^ permalink raw reply
* Re: [PATCH v3 0/4] drm: Add vblank timers for devices without interrupts
From: Thomas Zimmermann @ 2025-10-01 7:06 UTC (permalink / raw)
To: Michael Kelley, louis.chauvet@bootlin.com, drawat.floss@gmail.com,
hamohammed.sa@gmail.com, melissa.srw@gmail.com, simona@ffwll.ch,
airlied@gmail.com, maarten.lankhorst@linux.intel.com,
ville.syrjala@linux.intel.com, lyude@redhat.com,
javierm@redhat.com
Cc: dri-devel@lists.freedesktop.org, linux-hyperv@vger.kernel.org
In-Reply-To: <SN6PR02MB415712C780B051175BCD8B32D41AA@SN6PR02MB4157.namprd02.prod.outlook.com>
Hi
Am 30.09.25 um 17:18 schrieb Michael Kelley:
> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Tuesday, September 30, 2025 8:04 AM
>> Hi
>>
>> Am 16.09.25 um 17:00 schrieb Michael Kelley:
>>> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Tuesday, September 16, 2025 1:31 AM
>>>> Hi
>>>>
>>>> Am 09.09.25 um 05:29 schrieb Michael Kelley:
>>>>> From: Michael Kelley Sent: Thursday, September 4, 2025 10:36 PM
>>>>>> From: Thomas Zimmermann <tzimmermann@suse.de> Sent: Thursday, September 4, 2025 7:56 AM
>>>>>>> Compositors often depend on vblanks to limit their display-update
>>>>>>> rate. Without, they see vblank events ASAP, which breaks the rate-
>>>>>>> limit feature. This creates high CPU overhead. It is especially a
>>>>>>> problem with virtual devices with fast framebuffer access.
>>>>>>>
>>>>>>> The series moves vkms' vblank timer to DRM and converts the hyperv
>>>>>>> DRM driver. An earlier version of this series contains examples of
>>>>>>> other updated drivers. In principle, any DRM driver without vblank
>>>>>>> hardware can use the timer.
>>>>>> I've tested this patch set in a Hyper-V guest against the linux-next20250829
>>>>>> kernel. All looks good. Results and perf are the same as reported here [4].
>>>>>> So far I haven't seen the "vblank timer overrun" error, which is consistent
>>>>>> with the changes you made since my earlier testing. I'll keep running this
>>>>>> test kernel for a while to see if anything anomalous occurs.
>>>>> As I continued to run with this patch set, I got a single occurrence of this
>>>>> WARN_ON. I can't associate it with any particular action as I didn't notice
>>>>> it until well after it occurred.
>>>> I've investigated. The stack trace comes from the kernel console's
>>>> display update. It runs concurrently to the vblank timeout. What likely
>>>> happens here is that the update code reads two values and in between,
>>>> the vblank timeout updates them. So the update then compares an old and
>>>> a new value; leading to an incorrect result with triggers the warning.
>>>>
>>>> I'll include a fix in the series' next iteration. But I also think that
>>>> it's not critical. DRM's vblank helpers can usually deal with such problems.
>>> Thanks! I'm giving your v4 series a try now. Good that the underlying
>>> problem is not critical. But I was seeing the WARN_ON() output in
>>> dmesg every few days (a total of 4 times now), and that's not really
>>> acceptable even if everything continues to work correctly.
>> So it's probably a good sign that I haven't heard from you recently. :)
>> If you haven't seen any warnings with v4, I'd like to merge the series soon.
>>
>> Best regards
>> Thomas
>>
> Yes, all is good. I was delayed a bit due to some travel, but the test
> system has been running for a week now with no warnings or other
> issues. From my standpoint, the patch series is good to merge.
That's great news. I've now added the series to our drm-misc-next branch
and it should reach upstream in v6.19.
Best regards
Thomas
>
> Michael
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply
* Re: [PATCH 0/3] Introduce movable pages for Hyper-V guests
From: Mike Rapoport @ 2025-10-01 16:39 UTC (permalink / raw)
To: Wei Liu
Cc: Mukesh R, Stanislav Kinsburskii, kys, haiyangz, decui,
linux-hyperv, linux-kernel
In-Reply-To: <aNyrlijDzaosdWxa@liuwe-devbox-ubuntu-v2.lamzopl0uupeniq2etz1fddiyg.xx.internal.cloudapp.net>
On Wed, Oct 01, 2025 at 04:18:30AM +0000, Wei Liu wrote:
> +Mike Rapoport, our resident memory management expert.
>
> On Fri, Sep 26, 2025 at 07:02:02PM -0700, Mukesh R wrote:
> > On 9/24/25 14:30, Stanislav Kinsburskii wrote:
> > >>From the start, the root-partition driver allocates, pins, and maps all
> > > guest memory into the hypervisor at guest creation. This is simple: Linux
> > > cannot move the pages, so the guest?s view in Linux and in Microsoft
> > > Hypervisor never diverges.
> > >
> > > However, this approach has major drawbacks:
> > > - NUMA: affinity can?t be changed at runtime, so you can?t migrate guest memory closer to the CPUs running it ? performance hit.
> > > - Memory management: unused guest memory can?t be swapped out, compacted, or merged.
> > > - Provisioning time: upfront allocation/pinning slows guest create/destroy.
> > > - Overcommit: no memory overcommit on hosts with pinned-guest memory.
> > >
> > > This series adds movable memory pages for Hyper-V child partitions. Guest
> > > pages are no longer allocated upfront; they?re allocated and mapped into
> > > the hypervisor on demand (i.e., when the guest touches a GFN that isn?t yet
> > > backed by a host PFN).
> > > When a page is moved, Linux no longer holds it and it is unmapped from the hypervisor.
> > > As a result, Hyper-V guests behave like regular Linux processes, enabling standard Linux memory features to apply to guests.
> > >
> > > Exceptions (still pinned):
> > > 1. Encrypted guests (explicit).
> > > 2 Guests with passthrough devices (implicitly pinned by the VFIO framework).
> >
> >
> > As I had commented internally, I am not fully comfortable about the
> > approach here, specially around use of HMM, and the correctness of
> > locking for shared memory regions, but my knowledge is from 4.15 and
> > maybe outdated, and don't have time right now. So I won't object to it
> > if other hard core mmu developers think there are no issues.
> >
>
> Mike, I seem to remember you had a discussion with Stanislav about this?
> Can you confirm that this is a reasonable approach?
>
> Better yet, if you have time to review the code, that would be great.
> Note that there is a v2 on linux-hyperv. But I would like to close
> Mukesh's question first.
I only had time to skip through the patches and yes, this is a reasonable
approach. I also confirmed privately with HMM maintainer a while ago that
the use of HMM and MMU notifiers is correct.
I don't know enough about mshv to see if there are corner cases that these
patches don't cover, but conceptually they make memory model follow KVM
best practices.
> > However, we won't be using this for minkernel, so would like a driver
> > boot option to disable it upon boot that we can just set in minkernel
> > init path. This option can also be used to disable it if problems are
> > observed on the field. Minkernel design is still being worked on, so I
> > cannot provide much details on it yet.
The usual way we do things in the kernel is to add functionality when it
has users, so a boot option can be added later when minkernel design will
be more mature and ready for upstream.
--
Sincerely yours,
Mike.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox