From patchwork Tue Sep 6 07:46:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 9315929 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E5ACB60752 for ; Tue, 6 Sep 2016 08:12:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E4A9F28BB0 for ; Tue, 6 Sep 2016 08:12:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D84E128BDC; Tue, 6 Sep 2016 08:12:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4A07428BB0 for ; Tue, 6 Sep 2016 08:12:43 +0000 (UTC) Received: from localhost ([::1]:59778 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bhBUo-0006Bl-B7 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 06 Sep 2016 04:12:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38934) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bhB6P-0001KV-Et for qemu-devel@nongnu.org; Tue, 06 Sep 2016 03:47:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bhB6G-0002CT-1J for qemu-devel@nongnu.org; Tue, 06 Sep 2016 03:47:28 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:46601 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bhB6F-0002CK-SW for qemu-devel@nongnu.org; Tue, 06 Sep 2016 03:47:19 -0400 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u867gax9014495 for ; Tue, 6 Sep 2016 03:47:19 -0400 Received: from e06smtp06.uk.ibm.com (e06smtp06.uk.ibm.com [195.75.94.102]) by mx0a-001b2d01.pphosted.com with ESMTP id 259rhk37dg-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 06 Sep 2016 03:47:19 -0400 Received: from localhost by e06smtp06.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 6 Sep 2016 08:47:17 +0100 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp06.uk.ibm.com (192.168.101.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 6 Sep 2016 08:47:16 +0100 X-IBM-Helo: d06dlp03.portsmouth.uk.ibm.com X-IBM-MailFrom: cornelia.huck@de.ibm.com X-IBM-RcptTo: qemu-devel@nongnu.org Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id B2B731B08074 for ; Tue, 6 Sep 2016 08:49:00 +0100 (BST) Received: from d06av06.portsmouth.uk.ibm.com (d06av06.portsmouth.uk.ibm.com [9.149.37.217]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u867lFq963045784 for ; Tue, 6 Sep 2016 07:47:15 GMT Received: from d06av06.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u867lFR7013462 for ; Tue, 6 Sep 2016 03:47:15 -0400 Received: from gondolin.boeblingen.de.ibm.com (dyn-9-152-224-137.boeblingen.de.ibm.com [9.152.224.137]) by d06av06.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u867lCmW013216 (version=TLSv1/SSLv3 cipher=AES256-SHA256 bits=256 verify=NO); Tue, 6 Sep 2016 03:47:14 -0400 From: Cornelia Huck To: peter.maydell@linaro.org Date: Tue, 6 Sep 2016 09:46:41 +0200 X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160906074710.13495-1-cornelia.huck@de.ibm.com> References: <20160906074710.13495-1-cornelia.huck@de.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16090607-0024-0000-0000-0000021219D4 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16090607-0025-0000-0000-00002042705B Message-Id: <20160906074710.13495-10-cornelia.huck@de.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-09-06_03:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1609060120 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PULL 09/38] s390x/kvm: 2 byte software breakpoint support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: borntraeger@de.ibm.com, agraf@suse.de, qemu-devel@nongnu.org, David Hildenbrand , jfrei@linux.vnet.ibm.com, Cornelia Huck Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: David Hildenbrand Diag 501 (4 bytes) was used until now for software breakpoints on s390. As instructions on s390 might be 2 bytes long, temporarily overwriting them with 4 bytes is evil and can result in very strange guest behaviour. We make use of invalid instruction 0x0000 as new sw breakpoint instruction. We have to enable interception of that instruction in KVM using a capability. If no software breakpoint has been inserted at the reported position, an operation exception has to be injected into the guest. Otherwise a breakpoint has been hit and the pc has to be rewound. If KVM doesn't yet support interception of instruction 0x0000 the existing mechanism exploiting diag 501 is used. To keep overhead low, interception of instruction 0x0000 will only be enabled if sw breakpoints are really used. Reviewed-by: Christian Borntraeger Signed-off-by: David Hildenbrand Signed-off-by: Cornelia Huck --- target-s390x/cpu.h | 2 ++ target-s390x/kvm.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index c216bda..eeff1b0 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -394,6 +394,8 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc, ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0); } +#define MAX_ILEN 6 + /* While the PoO talks about ILC (a number between 1-3) what is actually stored in LowCore is shifted left one bit (an even between 2-6). As this is the actual length of the insn and therefore more useful, that diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 80ac621..4341d54 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -109,6 +109,7 @@ #define ICPT_WAITPSW 0x1c #define ICPT_SOFT_INTERCEPT 0x24 #define ICPT_CPU_STOP 0x28 +#define ICPT_OPEREXC 0x2c #define ICPT_IO 0x40 #define NR_LOCAL_IRQS 32 @@ -665,16 +666,37 @@ static void *legacy_s390_alloc(size_t size, uint64_t *align) return mem == MAP_FAILED ? NULL : mem; } -/* DIAG 501 is used for sw breakpoints */ -static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01}; +static uint8_t const *sw_bp_inst; +static uint8_t sw_bp_ilen; + +static void determine_sw_breakpoint_instr(void) +{ + /* DIAG 501 is used for sw breakpoints with old kernels */ + static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01}; + /* Instruction 0x0000 is used for sw breakpoints with recent kernels */ + static const uint8_t instr_0x0000[] = {0x00, 0x00}; + + if (sw_bp_inst) { + return; + } + if (kvm_vm_enable_cap(kvm_state, KVM_CAP_S390_USER_INSTR0, 0)) { + sw_bp_inst = diag_501; + sw_bp_ilen = sizeof(diag_501); + DPRINTF("KVM: will use 4-byte sw breakpoints.\n"); + } else { + sw_bp_inst = instr_0x0000; + sw_bp_ilen = sizeof(instr_0x0000); + DPRINTF("KVM: will use 2-byte sw breakpoints.\n"); + } +} int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { + determine_sw_breakpoint_instr(); if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, - sizeof(diag_501), 0) || - cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)diag_501, - sizeof(diag_501), 1)) { + sw_bp_ilen, 0) || + cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)sw_bp_inst, sw_bp_ilen, 1)) { return -EINVAL; } return 0; @@ -682,14 +704,14 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) { - uint8_t t[sizeof(diag_501)]; + uint8_t t[MAX_ILEN]; - if (cpu_memory_rw_debug(cs, bp->pc, t, sizeof(diag_501), 0)) { + if (cpu_memory_rw_debug(cs, bp->pc, t, sw_bp_ilen, 0)) { return -EINVAL; - } else if (memcmp(t, diag_501, sizeof(diag_501))) { + } else if (memcmp(t, sw_bp_inst, sw_bp_ilen)) { return -EINVAL; } else if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, - sizeof(diag_501), 1)) { + sw_bp_ilen, 1)) { return -EINVAL; } @@ -1310,7 +1332,7 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct kvm_run *run) cpu_synchronize_state(CPU(cpu)); - pc = env->psw.addr - 4; + pc = env->psw.addr - sw_bp_ilen; if (kvm_find_sw_breakpoint(CPU(cpu), pc)) { env->psw.addr = pc; return EXCP_DEBUG; @@ -1864,6 +1886,14 @@ static int handle_intercept(S390CPU *cpu) cpu->env.sigp_order = 0; r = EXCP_HALTED; break; + case ICPT_OPEREXC: + /* currently only instr 0x0000 after enabled via capability */ + r = handle_sw_breakpoint(cpu, run); + if (r == -ENOENT) { + enter_pgmcheck(cpu, PGM_OPERATION); + r = 0; + } + break; case ICPT_SOFT_INTERCEPT: fprintf(stderr, "KVM unimplemented icpt SOFT\n"); exit(1);