From patchwork Fri Jan 10 15:13:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 11327645 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 78E876C1 for ; Fri, 10 Jan 2020 15:15:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 143822077C for ; Fri, 10 Jan 2020 15:15:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 143822077C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.ibm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47436 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipw0W-0003LM-BW for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 10:15:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49487) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipvz6-0001L3-Pa for qemu-devel@nongnu.org; Fri, 10 Jan 2020 10:14:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ipvz2-0000qI-E4 for qemu-devel@nongnu.org; Fri, 10 Jan 2020 10:14:00 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:39564) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ipvz2-0000k7-4z; Fri, 10 Jan 2020 10:13:56 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00AFC3sS054415; Fri, 10 Jan 2020 10:13:51 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xe6ywpawx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 10:13:51 -0500 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00AFCAW0055331; Fri, 10 Jan 2020 10:13:51 -0500 Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xe6ywpawg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 10:13:51 -0500 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00AFCaAv015445; Fri, 10 Jan 2020 15:13:50 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma03dal.us.ibm.com with ESMTP id 2xajb8dhxs-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 15:13:50 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00AFDnk557541046 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jan 2020 15:13:49 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 37042C605B; Fri, 10 Jan 2020 15:13:49 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DA3DFC6059; Fri, 10 Jan 2020 15:13:47 +0000 (GMT) Received: from farosas.linux.ibm.com.br.ibm.com (unknown [9.86.27.174]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Fri, 10 Jan 2020 15:13:47 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH v6 1/3] target/ppc: Clarify the meaning of return values in kvm_handle_debug Date: Fri, 10 Jan 2020 12:13:42 -0300 Message-Id: <20200110151344.278471-2-farosas@linux.ibm.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200110151344.278471-1-farosas@linux.ibm.com> References: <20200110151344.278471-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-10_01:2020-01-10, 2020-01-09 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 mlxlogscore=985 priorityscore=1501 impostorscore=0 suspectscore=1 bulkscore=0 mlxscore=0 malwarescore=0 lowpriorityscore=0 phishscore=0 spamscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001100129 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini , qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The kvm_handle_debug function can return 0 to go back into the guest or return 1 to notify the gdbstub thread and pass control to GDB. Signed-off-by: Fabiano Rosas --- target/ppc/kvm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index d1c334f0e3..0bd4a8d399 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -53,6 +53,9 @@ #define PROC_DEVTREE_CPU "/proc/device-tree/cpus/" +#define DEBUG_RETURN_GUEST 0 +#define DEBUG_RETURN_GDB 1 + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -1570,7 +1573,7 @@ void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) static int kvm_handle_hw_breakpoint(CPUState *cs, struct kvm_debug_exit_arch *arch_info) { - int handle = 0; + int handle = DEBUG_RETURN_GUEST; int n; int flag = 0; @@ -1578,13 +1581,13 @@ static int kvm_handle_hw_breakpoint(CPUState *cs, if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) { n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW); if (n >= 0) { - handle = 1; + handle = DEBUG_RETURN_GDB; } } else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ | KVMPPC_DEBUG_WATCH_WRITE)) { n = find_hw_watchpoint(arch_info->address, &flag); if (n >= 0) { - handle = 1; + handle = DEBUG_RETURN_GDB; cs->watchpoint_hit = &hw_watchpoint; hw_watchpoint.vaddr = hw_debug_points[n].addr; hw_watchpoint.flags = flag; @@ -1596,12 +1599,12 @@ static int kvm_handle_hw_breakpoint(CPUState *cs, static int kvm_handle_singlestep(void) { - return 1; + return DEBUG_RETURN_GDB; } static int kvm_handle_sw_breakpoint(void) { - return 1; + return DEBUG_RETURN_GDB; } static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run) @@ -1653,7 +1656,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run) env->error_code = POWERPC_EXCP_INVAL; ppc_cpu_do_interrupt(cs); - return 0; + return DEBUG_RETURN_GUEST; } int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) From patchwork Fri Jan 10 15:13:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 11327649 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0D0E16C1 for ; Fri, 10 Jan 2020 15:15:37 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E075C2077C for ; Fri, 10 Jan 2020 15:15:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E075C2077C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.ibm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47444 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipw0c-0003US-H9 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 10:15:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49628) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipvz8-0001M5-Mb for qemu-devel@nongnu.org; Fri, 10 Jan 2020 10:14:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ipvz6-0000tc-SE for qemu-devel@nongnu.org; Fri, 10 Jan 2020 10:14:02 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:61804) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ipvz6-0000rB-Jr; Fri, 10 Jan 2020 10:14:00 -0500 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00AFC6Bo074903; Fri, 10 Jan 2020 10:13:54 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xeregxn62-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 10:13:53 -0500 Received: from m0098396.ppops.net (m0098396.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00AFD4Cx078093; Fri, 10 Jan 2020 10:13:53 -0500 Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xeregxn5q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 10:13:53 -0500 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00AFCaAx015445; Fri, 10 Jan 2020 15:13:52 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma03dal.us.ibm.com with ESMTP id 2xajb8dhy6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 15:13:52 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00AFDpef59048350 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jan 2020 15:13:51 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0D203C605B; Fri, 10 Jan 2020 15:13:51 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B1FBAC6055; Fri, 10 Jan 2020 15:13:49 +0000 (GMT) Received: from farosas.linux.ibm.com.br.ibm.com (unknown [9.86.27.174]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Fri, 10 Jan 2020 15:13:49 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH v6 2/3] kvm-all: Introduce kvm_set_singlestep Date: Fri, 10 Jan 2020 12:13:43 -0300 Message-Id: <20200110151344.278471-3-farosas@linux.ibm.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200110151344.278471-1-farosas@linux.ibm.com> References: <20200110151344.278471-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-10_01:2020-01-10, 2020-01-09 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 priorityscore=1501 impostorscore=0 clxscore=1015 adultscore=0 mlxlogscore=999 bulkscore=0 phishscore=0 suspectscore=1 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001100129 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.156.1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini , qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" For single stepping (via KVM) of a guest vcpu to work, KVM needs not only to support the SET_GUEST_DEBUG ioctl but to also recognize the KVM_GUESTDBG_SINGLESTEP bit in the control field of the kvm_guest_debug struct. This patch adds support for querying the single step capability so that QEMU can decide what to do for the platforms that do not have such support. This will allow architecture-specific implementations of a fallback mechanism for single stepping in cases where KVM does not support it. Signed-off-by: Fabiano Rosas Reviewed-by: David Gibson Acked-by: David Gibson --- accel/kvm/kvm-all.c | 9 +++++++++ accel/stubs/kvm-stub.c | 5 +++++ exec.c | 2 +- include/sysemu/kvm.h | 3 +++ stubs/Makefile.objs | 1 + stubs/kvm-arch-singlestep.c | 14 ++++++++++++++ target/ppc/kvm.c | 15 +++++++++++++++ 7 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 stubs/kvm-arch-singlestep.c diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index b2f1a5bcb5..a1ea8f9641 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2668,6 +2668,15 @@ int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap) return data.err; } +void kvm_set_singlestep(CPUState *cs, int enabled) +{ + if (kvm_arch_can_singlestep(cs)) { + kvm_update_guest_debug(cs, 0); + } else { + kvm_arch_emulate_singlestep(cs, enabled); + } +} + int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 82f118d2df..8773c15713 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -78,6 +78,11 @@ int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap) return -ENOSYS; } +void kvm_set_singlestep(CPUState *cs, int enabled) +{ + g_assert_not_reached(); +} + int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { diff --git a/exec.c b/exec.c index d4b769d0d4..10b61fccb8 100644 --- a/exec.c +++ b/exec.c @@ -1204,7 +1204,7 @@ void cpu_single_step(CPUState *cpu, int enabled) if (cpu->singlestep_enabled != enabled) { cpu->singlestep_enabled = enabled; if (kvm_enabled()) { - kvm_update_guest_debug(cpu, 0); + kvm_set_singlestep(cpu, enabled); } else { /* must flush all the translated code to avoid inconsistencies */ /* XXX: only flush what is necessary */ diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 141342de98..43abdb8430 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -247,6 +247,8 @@ bool kvm_memcrypt_enabled(void); */ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len); +bool kvm_arch_can_singlestep(CPUState *cs); +void kvm_arch_emulate_singlestep(CPUState *cpu, int enabled); #ifdef NEED_CPU_H #include "cpu.h" @@ -259,6 +261,7 @@ int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type); void kvm_remove_all_breakpoints(CPUState *cpu); int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap); +void kvm_set_singlestep(CPUState *cs, int enabled); int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr); int kvm_on_sigbus(int code, void *addr); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 8b0ff25508..e6310b878c 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -12,6 +12,7 @@ stub-obj-y += get-vm-name.o stub-obj-y += iothread.o stub-obj-y += iothread-lock.o stub-obj-y += is-daemonized.o +stub-obj-y += kvm-arch-singlestep.o stub-obj-$(CONFIG_LINUX_AIO) += linux-aio.o stub-obj-y += machine-init-done.o stub-obj-y += migr-blocker.o diff --git a/stubs/kvm-arch-singlestep.c b/stubs/kvm-arch-singlestep.c new file mode 100644 index 0000000000..30ee278ba4 --- /dev/null +++ b/stubs/kvm-arch-singlestep.c @@ -0,0 +1,14 @@ +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "sysemu/kvm.h" + +bool kvm_arch_can_singlestep(CPUState *cs) +{ + /* for backwards compatibility assume the feature is present */ + return true; +} + +void kvm_arch_emulate_singlestep(CPUState *cpu, int enabled) +{ + warn_report("KVM does not support single stepping"); +} diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 0bd4a8d399..6fb8687126 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -88,6 +88,7 @@ static int cap_ppc_safe_indirect_branch; static int cap_ppc_count_cache_flush_assist; static int cap_ppc_nested_kvm_hv; static int cap_large_decr; +static int cap_ppc_singlestep; static uint32_t debug_inst_opcode; @@ -136,6 +137,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) kvmppc_get_cpu_characteristics(s); cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); cap_large_decr = kvmppc_get_dec_bits(); + cap_ppc_singlestep = kvm_vm_check_extension(s, KVM_CAP_PPC_GUEST_DEBUG_SSTEP); /* * Note: setting it to false because there is not such capability * in KVM at this moment. @@ -1383,6 +1385,19 @@ static int kvmppc_handle_dcr_write(CPUPPCState *env, return 0; } +bool kvm_arch_can_singlestep(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (cap_ppc_singlestep) { + return true; + } + + /* Fallback for when the capability is not available */ + return env->excp_model == POWERPC_EXCP_BOOKE || kvmppc_is_pr(kvm_state); +} + int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { /* Mixed endian case is not handled */ From patchwork Fri Jan 10 15:13:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 11327651 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AC91B6C1 for ; Fri, 10 Jan 2020 15:15:42 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7CF692077C for ; Fri, 10 Jan 2020 15:15:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7CF692077C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.ibm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47446 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipw0i-0003XR-VY for patchwork-qemu-devel@patchwork.kernel.org; Fri, 10 Jan 2020 10:15:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49668) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ipvz9-0001MA-78 for qemu-devel@nongnu.org; Fri, 10 Jan 2020 10:14:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ipvz6-0000tO-RT for qemu-devel@nongnu.org; Fri, 10 Jan 2020 10:14:03 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:14024 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ipvz6-0000rr-LF; Fri, 10 Jan 2020 10:14:00 -0500 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 00AFC6Gb040959; Fri, 10 Jan 2020 10:13:56 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xereh6f7u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 10:13:55 -0500 Received: from m0098417.ppops.net (m0098417.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 00AFCGh3041791; Fri, 10 Jan 2020 10:13:55 -0500 Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 2xereh6f7j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 10:13:55 -0500 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 00AFC0lb005683; Fri, 10 Jan 2020 15:13:54 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma04dal.us.ibm.com with ESMTP id 2xajb7nh0y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2020 15:13:54 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 00AFDqBu51184060 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jan 2020 15:13:53 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DAB54C605A; Fri, 10 Jan 2020 15:13:52 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 855D9C605D; Fri, 10 Jan 2020 15:13:51 +0000 (GMT) Received: from farosas.linux.ibm.com.br.ibm.com (unknown [9.86.27.174]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Fri, 10 Jan 2020 15:13:51 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH v6 3/3] target/ppc: support single stepping with KVM HV Date: Fri, 10 Jan 2020 12:13:44 -0300 Message-Id: <20200110151344.278471-4-farosas@linux.ibm.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200110151344.278471-1-farosas@linux.ibm.com> References: <20200110151344.278471-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572 definitions=2020-01-10_01:2020-01-10, 2020-01-09 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 spamscore=0 impostorscore=0 malwarescore=0 suspectscore=1 phishscore=0 lowpriorityscore=0 clxscore=1015 priorityscore=1501 adultscore=0 mlxlogscore=946 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1910280000 definitions=main-2001100129 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] [fuzzy] X-Received-From: 148.163.158.5 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , Paolo Bonzini , qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" The hardware singlestep mechanism in POWER works via a Trace Interrupt (0xd00) that happens after any instruction executes, whenever MSR_SE = 1 (PowerISA Section 6.5.15 - Trace Interrupt). However, with kvm_hv, the Trace Interrupt happens inside the guest and KVM has no visibility of it. Therefore, when the gdbstub uses the KVM_SET_GUEST_DEBUG ioctl to enable singlestep, KVM simply ignores it. This patch takes advantage of the Trace Interrupt to perform the step inside the guest, but uses a breakpoint at the Trace Interrupt handler to return control to KVM. The exit is treated by KVM as a regular breakpoint and it returns to the host (and QEMU eventually). Before signalling GDB, QEMU sets the Next Instruction Pointer to the instruction following the one being stepped and restores the MSR, SRR0, SRR1 values from before the step, effectively skipping the interrupt handler execution and hiding the trace interrupt breakpoint from GDB. This approach works with both of GDB's 'scheduler-locking' options (off, step). Note: - kvm_arch_emulate_singlestep happens after GDB asks for a single step, while the vcpus are stopped. - kvm_handle_singlestep executes after the step, during the handling of the Emulation Assist Interrupt (breakpoint). Signed-off-by: Fabiano Rosas --- hw/ppc/spapr_hcall.c | 5 + target/ppc/cpu.h | 21 +++ target/ppc/excp_helper.c | 15 ++ target/ppc/kvm.c | 330 ++++++++++++++++++++++++++++++++++++++- target/ppc/kvm_ppc.h | 6 +- 5 files changed, 369 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index f1799b1b70..194b68ed22 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1382,6 +1382,7 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, target_ulong value1, target_ulong value2) { + CPUState *cs = CPU(cpu); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); if (!(pcc->insns_flags2 & PPC2_ISA207S)) { @@ -1400,6 +1401,10 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, spapr_set_all_lpcrs(mflags << LPCR_AIL_SHIFT, LPCR_AIL); + if (cs->singlestep_enabled && kvm_enabled()) { + kvm_singlestep_ail_change(cs); + } + return H_SUCCESS; } diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 103bfe9dc2..b69f8565aa 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -440,6 +440,10 @@ typedef struct ppc_v3_pate_t { #define msr_ts ((env->msr >> MSR_TS1) & 3) #define msr_tm ((env->msr >> MSR_TM) & 1) +#define srr1_ir ((env->spr[SPR_SRR1] >> MSR_IR) & 1) +#define srr1_dr ((env->spr[SPR_SRR1] >> MSR_DR) & 1) +#define srr1_se ((env->spr[SPR_SRR1] >> MSR_SE) & 1) + #define DBCR0_ICMP (1 << 27) #define DBCR0_BRT (1 << 26) #define DBSR_ICMP (1 << 27) @@ -1158,6 +1162,16 @@ struct CPUPPCState { uint32_t tm_vscr; uint64_t tm_dscr; uint64_t tm_tar; + + /* Used for software single step */ + target_ulong sstep_srr0; + target_ulong sstep_srr1; + target_ulong sstep_insn; + target_ulong trace_handler_addr; + int sstep_kind; +#define SSTEP_REGULAR 0 +#define SSTEP_PENDING 1 +#define SSTEP_GUEST 2 }; #define SET_FIT_PERIOD(a_, b_, c_, d_) \ @@ -1251,6 +1265,7 @@ struct PPCVirtualHypervisorClass { OBJECT_GET_CLASS(PPCVirtualHypervisorClass, (obj), \ TYPE_PPC_VIRTUAL_HYPERVISOR) +target_ulong ppc_get_trace_int_handler_addr(CPUState *cs, bool mmu_on); void ppc_cpu_do_interrupt(CPUState *cpu); bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req); void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); @@ -2220,6 +2235,12 @@ enum { PPC2_ISA300) }; +#define OP_RFID 19 +#define XOP_RFID 18 +#define OP_MOV 31 +#define XOP_MFMSR 83 +#define XOP_MTSPR 467 + /*****************************************************************************/ /* * Memory access type : diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 5752ed4a4d..87230f871a 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -784,6 +784,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) check_tlb_flush(env, false); } +target_ulong ppc_get_trace_int_handler_addr(CPUState *cs, bool mmu_on) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + int ail = AIL_NONE; + + /* AIL is only used if translation is enabled */ + if (mmu_on) { + ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; + } + + return env->excp_vectors[POWERPC_EXCP_TRACE] | + ppc_excp_vector_offset(cs, ail); +} + void ppc_cpu_do_interrupt(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 6fb8687126..2b6cba59c8 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1546,6 +1546,202 @@ void kvm_arch_remove_all_hw_breakpoints(void) nb_hw_breakpoint = nb_hw_watchpoint = 0; } +static uint32_t ppc_gdb_read_insn(CPUState *cs, target_ulong addr) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + uint32_t insn; + + cpu_memory_rw_debug(cs, addr, (uint8_t *)&insn, sizeof(insn), 0); + + if (msr_le) { + return ldl_le_p(&insn); + } else { + return ldl_be_p(&insn); + } +} + +static uint32_t ppc_gdb_get_op(uint32_t insn) +{ + return extract32(insn, 26, 6); +} + +static uint32_t ppc_gdb_get_xop(uint32_t insn) +{ + return extract32(insn, 1, 10); +} + +static uint32_t ppc_gdb_get_spr(uint32_t insn) +{ + return extract32(insn, 11, 5) << 5 | extract32(insn, 16, 5); +} + +static uint32_t ppc_gdb_get_rt(uint32_t insn) +{ + return extract32(insn, 21, 5); +} + +static void kvm_insert_singlestep_breakpoint(CPUState *cs, bool mmu_on) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + target_ulong bp_addr; + target_ulong saved_msr = env->msr; + + bp_addr = ppc_get_trace_int_handler_addr(cs, mmu_on); + if (env->nip == bp_addr) { + /* + * We are trying to step the interrupt handler address itself; + * move the breakpoint to the next instruction. + */ + bp_addr += 4; + } + + /* + * The actual access by the guest might be made in a mode + * different than we are now (due to rfid) so temporarily set the + * MSR to reflect that during the breakpoint placement. + * + * Note: we need this because breakpoints currently use + * cpu_memory_rw_debug, which does the memory accesses from the + * guest point of view. + */ + if ((msr_ir & msr_dr) != mmu_on) { + if (mmu_on) { + env->msr |= (1ULL << MSR_IR | 1ULL << MSR_DR); + } else { + env->msr &= ~(1ULL << MSR_IR | 1ULL << MSR_DR); + } + } + + kvm_insert_breakpoint(cs, bp_addr, 4, GDB_BREAKPOINT_SW); + env->trace_handler_addr = bp_addr; + env->msr = saved_msr; +} + +/* + * The emulated singlestep works by forcing a Trace Interrupt inside + * the guest by setting its MSR_SE bit. When the guest executes the + * instruction, the Trace Interrupt triggers and the step is done. We + * then need to hide the fact that the interrupt ever happened before + * returning into the guest. + * + * Since the Trace Interrupt does not set MSR_HV (the whole point of + * having to emulate the step), we set a breakpoint at the interrupt + * handler address (0xd00) so that it reaches KVM (this is treated by + * KVM like an ordinary breakpoint) and control is returned to QEMU. + * + * There are things to consider before the step (this function): + * + * - The breakpoint location depends on where the interrupt vectors are, + * which in turn depends on the LPCR_AIL and MSR_IR|DR bits; + * + * - If the stepped instruction changes the LPCR_AIL, the breakpoint + * location needs to be updated mid-step; + * + * - If the stepped instruction is rfid, the MSR bits after the step + * will come from SRR1. + * + * + * There are some fixups needed after the step, before returning to + * the guest (kvm_handle_singlestep): + * + * - The interrupt will set SRR0 and SRR1, so we need to restore them + * to what they were before the interrupt; + * + * - If the stepped instruction wrote to the SRRs, we need to avoid + * undoing that; + * + * - We set the MSR_SE bit, so it needs to be cleared. + * + */ +void kvm_arch_emulate_singlestep(CPUState *cs, int enabled) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + uint32_t insn; + bool rfid, mmu_on; + + if (!enabled) { + return; + } + + if (env->sstep_kind != SSTEP_PENDING) { + env->sstep_kind = SSTEP_REGULAR; + } + + cpu_synchronize_state(cs); + insn = ppc_gdb_read_insn(cs, env->nip); + + /* + * rfid needs special handling because it: + * - overwrites NIP with SRR0; + * - overwrites MSR with SRR1; + * - cannot be single stepped. + */ + rfid = ppc_gdb_get_op(insn) == OP_RFID && ppc_gdb_get_xop(insn) == XOP_RFID; + + if (rfid && (kvm_find_sw_breakpoint(cs, env->spr[SPR_SRR0]) || + env->sstep_kind == SSTEP_PENDING)) { + /* + * There is a breakpoint at the next instruction address or a + * pending step. It will already cause the vm exit we need for + * the single step, so there's nothing to be done. + */ + env->sstep_kind = SSTEP_REGULAR; + return; + } + + /* + * Save the registers that will be affected by the single step + * mechanism. These will be used after the step. + */ + env->sstep_srr0 = env->spr[SPR_SRR0]; + env->sstep_srr1 = env->spr[SPR_SRR1]; + env->sstep_insn = insn; + + /* + * MSR_SE = 1 will cause a Trace Interrupt in the guest after the + * next instruction executes. If this is a rfid, use SRR1 instead + * of MSR. + */ + if (rfid) { + if ((env->spr[SPR_SRR1] >> MSR_SE) & 1) { + /* + * The guest is doing a single step itself. Make sure we + * restore it later. + */ + env->sstep_kind = SSTEP_GUEST; + } + + env->spr[SPR_SRR1] |= (1ULL << MSR_SE); + mmu_on = srr1_ir & srr1_dr; + } else { + env->msr |= (1ULL << MSR_SE); + mmu_on = msr_ir & msr_dr; + } + + kvm_insert_singlestep_breakpoint(cs, mmu_on); +} + +void kvm_singlestep_ail_change(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (kvm_arch_can_singlestep(cs)) { + return; + } + + /* + * The instruction being stepped altered the interrupt vectors + * location (AIL). Re-insert the single step breakpoint at the new + * location + */ + kvm_remove_breakpoint(cs, env->trace_handler_addr, 4, GDB_BREAKPOINT_SW); + kvm_insert_singlestep_breakpoint(cs, (msr_ir & msr_dr)); +} + void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) { int n; @@ -1585,6 +1781,98 @@ void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) } } +/* Revert any side-effects caused during single step */ +static void restore_singlestep_env(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + uint32_t insn = env->sstep_insn; + int reg; + int spr; + + env->spr[SPR_SRR0] = env->sstep_srr0; + env->spr[SPR_SRR1] = env->sstep_srr1; + + if (ppc_gdb_get_op(insn) != OP_MOV) { + return; + } + + reg = ppc_gdb_get_rt(insn); + + switch (ppc_gdb_get_xop(insn)) { + case XOP_MTSPR: + /* + * mtspr: the guest altered the SRR, so do not use the + * pre-step value. + */ + spr = ppc_gdb_get_spr(insn); + if (spr == SPR_SRR0 || spr == SPR_SRR1) { + env->spr[spr] = env->gpr[reg]; + } + break; + case XOP_MFMSR: + /* + * mfmsr: clear MSR_SE bit to avoid the guest knowing + * that it is being single-stepped. + */ + env->gpr[reg] &= ~(1ULL << MSR_SE); + break; + } +} + +static int kvm_handle_singlestep(CPUState *cs, target_ulong address) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (kvm_arch_can_singlestep(cs)) { + return DEBUG_RETURN_GDB; + } + + cpu_synchronize_state(cs); + + if (address == env->trace_handler_addr) { + kvm_remove_breakpoint(cs, env->trace_handler_addr, 4, + GDB_BREAKPOINT_SW); + + if (env->sstep_kind == SSTEP_GUEST) { + /* + * The guest expects the last instruction to have caused a + * single step, go back into the interrupt handler. + */ + env->sstep_kind = SSTEP_REGULAR; + return DEBUG_RETURN_GDB; + } + + env->nip = env->spr[SPR_SRR0]; + /* Bits 33-36, 43-47 are set by the interrupt */ + env->msr = env->spr[SPR_SRR1] & ~(1ULL << MSR_SE | + PPC_BITMASK(33, 36) | + PPC_BITMASK(43, 47)); + restore_singlestep_env(cs); + + } else if (address == env->trace_handler_addr + 4) { + /* + * A step at trace_handler_addr would interfere with the + * single step mechanism itself, so we have previously + * displaced the breakpoint to the next instruction. + */ + kvm_remove_breakpoint(cs, env->trace_handler_addr + 4, 4, + GDB_BREAKPOINT_SW); + restore_singlestep_env(cs); + } else { + /* + * Another interrupt (e.g. system call, program interrupt) + * took us somewhere else in the code and we hit a breakpoint + * there. Mark the step as pending. + */ + env->sstep_kind = SSTEP_PENDING; + } + + cs->singlestep_enabled = false; + return DEBUG_RETURN_GDB; +} + static int kvm_handle_hw_breakpoint(CPUState *cs, struct kvm_debug_exit_arch *arch_info) { @@ -1612,13 +1900,41 @@ static int kvm_handle_hw_breakpoint(CPUState *cs, return handle; } -static int kvm_handle_singlestep(void) +static int kvm_handle_sw_breakpoint(CPUState *cs, target_ulong address) { - return DEBUG_RETURN_GDB; -} + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (kvm_arch_can_singlestep(cs)) { + return DEBUG_RETURN_GDB; + } + + cpu_synchronize_state(cs); + + if (address == env->trace_handler_addr) { + if (env->sstep_kind == SSTEP_PENDING) { + /* + * Although we have singlestep_enabled == false by now, + * the original step still wasn't handled (is pending). + */ + cs->singlestep_enabled = true; + env->sstep_kind = SSTEP_REGULAR; + + return kvm_handle_singlestep(cs, address); + } + + CPU_FOREACH(cs) { + if (cs->singlestep_enabled) { + /* + * We hit this breakpoint while another cpu is doing a + * software single step. Go back into the guest to + * give chance for the single step to finish. + */ + return DEBUG_RETURN_GUEST; + } + } + } -static int kvm_handle_sw_breakpoint(void) -{ return DEBUG_RETURN_GDB; } @@ -1629,7 +1945,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run) struct kvm_debug_exit_arch *arch_info = &run->debug.arch; if (cs->singlestep_enabled) { - return kvm_handle_singlestep(); + return kvm_handle_singlestep(cs, arch_info->address); } if (arch_info->status) { @@ -1637,7 +1953,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run) } if (kvm_find_sw_breakpoint(cs, arch_info->address)) { - return kvm_handle_sw_breakpoint(); + return kvm_handle_sw_breakpoint(cs, arch_info->address); } /* diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index f22daabf51..dc1b6df422 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -81,7 +81,7 @@ bool kvmppc_hpt_needs_host_contiguous_pages(void); void kvm_check_mmu(PowerPCCPU *cpu, Error **errp); void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online); void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset); - +void kvm_singlestep_ail_change(CPUState *cs); #else static inline uint32_t kvmppc_get_tbfreq(void) @@ -211,6 +211,10 @@ static inline void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset) { } +static inline void kvm_singlestep_ail_change(CPUState *cs) +{ +} + #ifndef CONFIG_USER_ONLY static inline bool kvmppc_spapr_use_multitce(void) {