From nobody Sat May 11 23:29:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=fail Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561727575026678.2180758802676; Fri, 28 Jun 2019 06:12:55 -0700 (PDT) Received: from localhost ([::1]:59674 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqgL-0004wI-46 for importer@patchew.org; Fri, 28 Jun 2019 09:12:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41488) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqGN-0008Pd-E9 for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgqGK-0001Zn-TH for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:45:59 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:36920) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hgqGK-0001Qz-4T for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:45:56 -0400 Received: from kouign-amann.bar.greensocs.com (unknown [172.16.11.117]) by beetle.greensocs.com (Postfix) with ESMTPS id 88A5896F53; Fri, 28 Jun 2019 12:45:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725939; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+jjwPWtFxt7ePzzf+2PHr+LueKDt8+NJ5t9Cx/GeY1g=; b=e/sRlyVQVWtXqYF9JyV7LTN79hDrgnuk6Elgp+LmPncFLOqHJBobew+d2F9rKf6s2fMreE 4DpQG1LAPjjp1XkbNaTnFe+VIxgtALZABtqEqG7xm+G5iQ2c++MCRnXhcbVHrEIksXdI6j rJOnGTi4bqowopS5ii+oHp1pm67xDCI= From: Damien Hedde To: qemu-devel@nongnu.org Date: Fri, 28 Jun 2019 14:45:30 +0200 Message-Id: <20190628124534.10679-2-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190628124534.10679-1-damien.hedde@greensocs.com> References: <20190628124534.10679-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725939; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+jjwPWtFxt7ePzzf+2PHr+LueKDt8+NJ5t9Cx/GeY1g=; b=0zcU5pI5cjVhFy+XhOW3HpjuJKTSTXZ4Jrpeugqq+GW4jV0Ag0Rv2ODte3WAD7P4Mr4ktH m3ss7b2LHYoLQ7XjHLdYZzA/ZrCy2xP6cWfuXLtu3FxZPFIdzZ9nT3/7zj9sV7Qh8fUsDw EAE9ISsdzi5WNnsAdj7ywGgsZhePTQM= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1561725939; a=rsa-sha256; cv=none; b=gQ/hhAG9GgqSEOf2ts5c+5FvRqJvHZdfi/W2vjDVqcRDMX50zmnA2tylROQcJI8zoTbIvj yAQHRbD8xN09wOYyOLNjQP+uCqW8FiaAdqpywjUVFNXm1jIMWMnk0IGs80WZXq4gD097Iy t79rcMY1N9E9SPYNvtzxCe6P80YZl7A= ARC-Authentication-Results: i=1; beetle.greensocs.com; none Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [RFC PATCH 1/5] introduce [p]mem(read|write) qmp commands 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: Damien Hedde , ehabkost@redhat.com, mark.burton@greensocs.com, armbru@redhat.com, sakisp@xilinx.com, edgari@xilinx.com, crosa@redhat.com, pbonzini@redhat.com, luc.michel@greensocs.com, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This introduces memread, memwrite, pmemread and pmemwrite qmp commands. The memread and memwrite read virtual memory from a given cpu point of view. If no cpu index is specified, the cpu-id 0 is used. The pmemread and pmemwrite directly read physical memory. The data is passed/returned in a list of bytes. The maximum length is set t= o 8, they can be used to 64bits. This is based on the work of Frederic Konrad. Signed-off-by: Damien Hedde --- cpus.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ qapi/misc.json | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+) diff --git a/cpus.c b/cpus.c index 1af51b73dd..7aae35c098 100644 --- a/cpus.c +++ b/cpus.c @@ -2484,3 +2484,129 @@ void dump_drift_info(void) qemu_printf("Max guest advance NA\n"); } } + +static Bytes *memread(int64_t addr, int64_t size, CPUState *cpu, Error **e= rrp) +{ + uint32_t l =3D 0; + uint8List *prev =3D NULL; + Bytes *res; + uint8_t buf[8]; + + if (size <=3D 0 || size > sizeof(buf)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", + "out of range"); + return NULL; + } + + if (cpu) { + if (cpu_memory_rw_debug(cpu, addr, buf, size, 0) !=3D 0) { + error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64 + " specified", addr, size); + return NULL; + } + } else { + MemTxResult r =3D address_space_read(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, buf, l); + if (r !=3D MEMTX_OK) { + error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64 + " specified", addr, size); + return NULL; + } + } + + res =3D g_new0(Bytes, 1); + while (l < size) { + uint8List *cur =3D g_new0(uint8List, 1); + cur->value =3D buf[l++]; + if (!prev) { + res->bytes =3D cur; + } else { + prev->next =3D cur; + } + prev =3D cur; + } + + return res; + +} + +Bytes *qmp_memread(int64_t addr, int64_t size, + bool has_cpu, int64_t cpu_index, Error **errp) +{ + CPUState *cpu; + + if (!has_cpu) { + cpu_index =3D 0; + } + + cpu =3D qemu_get_cpu(cpu_index); + if (cpu =3D=3D NULL) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", + "a CPU number"); + return NULL; + } + + return memread(addr, size, cpu, errp); +} + +Bytes *qmp_pmemread(int64_t addr, int64_t size, Error **errp) +{ + return memread(addr, size, NULL, errp); +} + +static void memwrite(int64_t addr, uint8List *bytes, CPUState *cpu, + Error **errp) +{ + uint32_t l =3D 0; + uint8_t buf[8]; + + while (bytes !=3D NULL) { + if (l >=3D sizeof(buf)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "bytes", + "too long"); + return; + } + buf[l++] =3D bytes->value; + bytes =3D bytes->next; + } + + if (cpu) { + if (cpu_memory_rw_debug(cpu, addr, buf, l, 1) !=3D 0) { + error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRIu32 + " specified", addr, l); + return; + } + } else { + MemTxResult r =3D address_space_write(&address_space_memory, addr, + MEMTXATTRS_UNSPECIFIED, buf, l= ); + if (r !=3D MEMTX_OK) { + error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64 + " specified", addr, size); + return; + } + } +} + +void qmp_memwrite(int64_t addr, uint8List *bytes, + bool has_cpu, int64_t cpu_index, Error **errp) +{ + CPUState *cpu; + + if (!has_cpu) { + cpu_index =3D 0; + } + + cpu =3D qemu_get_cpu(cpu_index); + if (cpu =3D=3D NULL) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", + "a CPU number"); + return; + } + + memwrite(addr, bytes, cpu, errp); +} + +void qmp_pmemwrite(int64_t addr, uint8List *bytes, Error **errp) +{ + memwrite(addr, bytes, NULL, errp); +} diff --git a/qapi/misc.json b/qapi/misc.json index dc4cf9da20..3aca91b4ac 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3047,3 +3047,122 @@ 'data': 'NumaOptions', 'allow-preconfig': true } + +## +# @Bytes: +# +# An array of bytes. +# +# @bytes: the list of bytes +# +# Since: 4.1 +## +{ 'struct': 'Bytes', 'data': {'bytes': ['uint8'] } } + +## +# @memread: +# +# Read a portion of guest memory. +# +# @addr: the virtual address of the guest to read from +# +# @size: the size of memory region to read (max is 8) +# +# @cpu-index: the index of the virtual CPU to use for translating the +# virtual address (defaults to CPU 0) +# +# Returns: The read bytes +# +# Since: 4.1 +# +# Example: +# +# -> { "execute": "memread", +# "arguments": { "addr": 10, +# "size": 4 } } +# <- { "return": { 'bytes' : [10, 78, 231, 7] } } +# +## +{ 'command': 'memread', + 'data': {'addr': 'int', 'size': 'int', '*cpu-index': 'int'}, + 'returns' : 'Bytes' +} + +## +# @memwrite: +# +# Write a portion of guest memory. +# +# @addr: the virtual address of the guest to write to +# +# @bytes: the bytes to write into memory region (max length is 8) +# +# @cpu-index: the index of the virtual CPU to use for translating the +# virtual address (defaults to CPU 0) +# +# Since: 4.1 +# +# Returns: nothing on success. +# +# Example: +# +# -> { "execute": "memread", +# "arguments": { "addr": 10, +# "bytes": [10, 78, 231, 7] } } +# <- { "return": {} } +# +## +{ 'command': 'memwrite', + 'data': {'addr': 'int', 'bytes': ['uint8'], '*cpu-index': 'int'} +} + +## +# @pmemread: +# +# Read a portion of guest memory. +# +# @addr: the physical address of the guest to read from +# +# @size: the size of memory region to read (max is 8) +# +# Returns: The read bytes +# +# Since: 4.1 +# +# Example: +# +# -> { "execute": "memread", +# "arguments": { "addr": 10, +# "size": 4 } } +# <- { "return": { 'bytes' : [10, 78, 231, 7] } } +# +## +{ 'command': 'pmemread', + 'data': {'addr': 'int', 'size': 'int'}, + 'returns' : 'Bytes' +} + +## +# @pmemwrite: +# +# Write a portion of guest memory. +# +# @addr: the physical address of the guest to write to +# +# @bytes: the bytes to write into memory region (max length is 8) +# +# Since: 4.1 +# +# Returns: nothing on success. +# +# Example: +# +# -> { "execute": "memread", +# "arguments": { "addr": 10, +# "bytes": [10, 78, 231, 7] } } +# <- { "return": {} } +# +## +{ 'command': 'pmemwrite', + 'data': {'addr': 'int', 'bytes': ['uint8']} +} --=20 2.22.0 From nobody Sat May 11 23:29:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=fail Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561727772724678.3402463845403; Fri, 28 Jun 2019 06:16:12 -0700 (PDT) Received: from localhost ([::1]:59720 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqjP-0000n6-Pz for importer@patchew.org; Fri, 28 Jun 2019 09:15:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41569) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqGP-0008U4-Ln for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgqGM-0001b9-2o for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:01 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:36948) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hgqGL-0001RD-7U for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:45:57 -0400 Received: from kouign-amann.bar.greensocs.com (unknown [172.16.11.117]) by beetle.greensocs.com (Postfix) with ESMTPS id 3A1BC96F54; Fri, 28 Jun 2019 12:45:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725939; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DjS6MgiRGaWDm6aO6owVkrbeZw4PYZfjBhtjtiuXYAo=; b=Qv6OJOL1ZmQuhg6sxOZ4Cs8tJ5FTvI9Ji/IptnJsj0wAfn6fbiE7pDIMcPXWTcA4nrSgA0 WfjBG6S/xJw6gGv2gFc+UOzKl1shAFpaLWVmWIn/zznRSus5AglUw1TUKQN9T7+RQlYhKr QmQuSgYFuBCZ8o4ik95Ac5AEz+UoQL4= From: Damien Hedde To: qemu-devel@nongnu.org Date: Fri, 28 Jun 2019 14:45:31 +0200 Message-Id: <20190628124534.10679-3-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190628124534.10679-1-damien.hedde@greensocs.com> References: <20190628124534.10679-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725939; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DjS6MgiRGaWDm6aO6owVkrbeZw4PYZfjBhtjtiuXYAo=; b=Zx5pyHhttz+CESwoTP2Lh/gJmkVr00bA25Tc568k4Ymcah3p+V3k9UAxkY997tXSPBke27 uGSz9cHKdf0NeDn+FF/80dxv6DV5ogzVniPXsiM8lHli9/A/rqonqEZm+cyAYyQnTtj51l b4p9SMGoOUI5bxA58R+NfW8dW/OrO3Y= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1561725939; a=rsa-sha256; cv=none; b=3zlVFfDvjF+mdOoWoT9p1DdR/pgONbMiTE8aP+ROUV+TwEsG5w4gWdZNhtfYZTXJJhr1M5 FEUq0FgmClIXPcpSoHxoB+PQ43F0OrvZRjERWlTbQ5g/H/naraURcA+5MRTcmZ53lGMIIm LK3x/VPGEkZHChXRxjx2Fj0q1dtuIuU= ARC-Authentication-Results: i=1; beetle.greensocs.com; none Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [RFC PATCH 2/5] introduce a qmp command to set gpios 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: Damien Hedde , ehabkost@redhat.com, mark.burton@greensocs.com, armbru@redhat.com, sakisp@xilinx.com, edgari@xilinx.com, crosa@redhat.com, pbonzini@redhat.com, luc.michel@greensocs.com, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This adds the "gpio-set" qmp command. Taking the device path, the gpio name and number, the command set the value (true or false) of the gpio. It works only on gpio input line. This is based on Frederic Konrad's work. Signed-off-by: Damien Hedde --- cpus.c | 4 ++-- monitor/qmp-cmds.c | 30 ++++++++++++++++++++++++++++++ qapi/misc.json | 29 +++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/cpus.c b/cpus.c index 7aae35c098..3688550c55 100644 --- a/cpus.c +++ b/cpus.c @@ -2580,8 +2580,8 @@ static void memwrite(int64_t addr, uint8List *bytes, = CPUState *cpu, MemTxResult r =3D address_space_write(&address_space_memory, addr, MEMTXATTRS_UNSPECIFIED, buf, l= ); if (r !=3D MEMTX_OK) { - error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64 - " specified", addr, size); + error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRIu32 + " specified", addr, l); return; } } diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 01ce77e129..6bf0204edd 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -726,3 +726,33 @@ MemoryInfo *qmp_query_memory_size_summary(Error **errp) =20 return mem_info; } + +void qmp_gpio_set(const char *path, bool has_gpio, const char *gpio, + bool has_number, int64_t number, bool value, Error **err= p) +{ + DeviceState *dev; + qemu_irq irq; + + dev =3D DEVICE(object_resolve_path(path, NULL)); + if (!dev) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, + "Cannot find device '%s'", path); + return; + } + + if (!has_gpio) { + gpio =3D NULL; + } + if (!has_number) { + number =3D 0; + } + irq =3D qdev_get_gpio_in_named(dev, gpio, number); + if (!irq) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "GPIO input '%s[%"PRId64"]' does not exists", + has_gpio ? gpio : "unnamed", number); + return; + } + + qemu_set_irq(irq, value); +} diff --git a/qapi/misc.json b/qapi/misc.json index 3aca91b4ac..255236b96f 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3166,3 +3166,32 @@ { 'command': 'pmemwrite', 'data': {'addr': 'int', 'bytes': ['uint8']} } + +## +# @gpio-set: +# +# @path: Path to the device. +# +# @gpio: Name of the GPIO will be unnamed-gpio if omitted. +# +# @number: Number of the GPIO line, 0 if omitted. +# +# @value: Value (boolean) to be set for the GPIO. +# +# Returns: nothing in case of success +# +# Since 4.1 +# +# Example: +# +# -> { "execute": "gpio-set", +# "arguments": { "path": "/machine/unattached/device[5]", +# "gpio": "ssi-gpio-cs", +# "number": 0, +# "value": true } } +# <- { "return": {} } +# +## +{ 'command': 'gpio-set', + 'data': { 'path': 'str', '*gpio': 'str', '*number': 'int', 'value': 'boo= l' } +} --=20 2.22.0 From nobody Sat May 11 23:29:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=fail Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561728283377406.2337981938574; Fri, 28 Jun 2019 06:24:43 -0700 (PDT) Received: from localhost ([::1]:59846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqrn-0000fJ-FF for importer@patchew.org; Fri, 28 Jun 2019 09:24:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41648) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqGU-0000Ce-HA for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgqGM-0001cW-P6 for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:05 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:36960) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hgqGM-0001RW-Af for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:45:58 -0400 Received: from kouign-amann.bar.greensocs.com (unknown [172.16.11.117]) by beetle.greensocs.com (Postfix) with ESMTPS id DB90596F56; Fri, 28 Jun 2019 12:45:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725940; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=52GqakeBEYFuvvGGQuIdSqZ3Pd2SaMwkpCLAurtIDyg=; b=7SkZLZ7XEke4O7AOVq6ydDJvywXeJk21MVckEuIUo9UyHE7CxYoqQtR7anet/Z+d8NRMxH XPj3/QDGts+0akfBL3wM8HhmIwZzDLRIXZyoZnvqyVUQ83mCJJpA0J52kZ1tHQ3ZOg4TwA 6430zKi5d7vd8Wsp9JbZzUfRI7SpeKM= From: Damien Hedde To: qemu-devel@nongnu.org Date: Fri, 28 Jun 2019 14:45:32 +0200 Message-Id: <20190628124534.10679-4-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190628124534.10679-1-damien.hedde@greensocs.com> References: <20190628124534.10679-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725940; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=52GqakeBEYFuvvGGQuIdSqZ3Pd2SaMwkpCLAurtIDyg=; b=ykKUVV1gK/kbs7YSwkkom+VSz6gJJj0xjK1aUiUlxFduHTPem34+XQCXe7v2j7itLMurD3 ohwRM7l9mG4mIATddPZGjPvdT36jBvuXXwOtQiw7nVPwjliTqqJO0xWoJzRJU2P0ZlHhau F/2+KXU2XOI6BHGFbbhXRbV5we7EBsc= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1561725940; a=rsa-sha256; cv=none; b=qvW0Rfe6Z6xbscss3SxZT9uzqT1+cH5Hu+dz5nZVqW0I9xeIaV8lSX1ycUA4gO+kTtc7oY U+B18rch+XLrufL4965dnzMqyWAiSk9r4x3kIXVNvTyrVmfmODpYlPVbujEdaRGKMoZ4+B 2fOEiRN1+66MJlLUXxXdEn3JE6ZC4Zk= ARC-Authentication-Results: i=1; beetle.greensocs.com; none Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [RFC PATCH 3/5] add qmp time-notify event triggering system 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: Damien Hedde , ehabkost@redhat.com, mark.burton@greensocs.com, armbru@redhat.com, sakisp@xilinx.com, edgari@xilinx.com, crosa@redhat.com, pbonzini@redhat.com, luc.michel@greensocs.com, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This adds an event triggering mechanism composed of: + an event that is catchable by qmp clients + a command to create such events When triggered the event TIME_NOTIFICATION is signaled. Optionnaly the virtual machine is also paused (put in debug state). The virtual machine can then be restarted by the _cont_ command. To create an event, an id and the deadline in virtual clock nanoseconds should be given to the "time-notify" qmp command. The event will be triggered at the given time which may be absolute or relative to the current virtual clock time. This allows to write qmp clients that can pause the vm, do some actions then restart the vm. This is based on the work of Frederic Konrad. Signed-off-by: Damien Hedde --- monitor/Makefile.objs | 1 + monitor/qmp-cmd-time-notify.c | 116 ++++++++++++++++++++++++++++++++++ monitor/trace-events | 4 ++ qapi/misc.json | 48 ++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 monitor/qmp-cmd-time-notify.c diff --git a/monitor/Makefile.objs b/monitor/Makefile.objs index e91a8581cd..f4c7293460 100644 --- a/monitor/Makefile.objs +++ b/monitor/Makefile.objs @@ -1,3 +1,4 @@ obj-y +=3D misc.o common-obj-y +=3D monitor.o qmp.o hmp.o common-obj-y +=3D qmp-cmds.o hmp-cmds.o +common-obj-y +=3D qmp-cmd-time-notify.o diff --git a/monitor/qmp-cmd-time-notify.c b/monitor/qmp-cmd-time-notify.c new file mode 100644 index 0000000000..de13b2d3a1 --- /dev/null +++ b/monitor/qmp-cmd-time-notify.c @@ -0,0 +1,116 @@ +/* + * qmp-cmd-time-notify.c + * + * Copyright (c) 2016,2019 GreenSocs SAS + * + * Authors: + * Fred Konrad + * Damien Hedde + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qapi/qmp/qerror.h" +#include "qapi/qmp/qjson.h" +#include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-events-misc.h" +#include "qemu/timer.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "sysemu/sysemu.h" +#include "sysemu/cpus.h" +#include "trace.h" + +typedef struct TimeNotifEntry TimeNotifEntry; +static QLIST_HEAD(, TimeNotifEntry) events =3D QLIST_HEAD_INITIALIZER(even= ts); +static QEMUTimer *timer; + +struct TimeNotifEntry { + uint64_t time_ns; + int64_t id; + bool pause; + QLIST_ENTRY(TimeNotifEntry) node; +}; + +static void mod_next_event_timer(void) +{ + if (QLIST_EMPTY(&events)) { + return; + } + + timer_mod(timer, QLIST_FIRST(&events)->time_ns); +} + +static void trigger_notif(void *opaque) +{ + TimeNotifEntry *entry; + uint64_t current_time =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + bool do_stop; + + entry =3D QLIST_FIRST(&events); + assert(entry && entry->time_ns <=3D current_time); + do_stop =3D entry->pause; + + QLIST_REMOVE(entry, node); + qapi_event_send_time_notification(entry->id, current_time); + trace_qmp_time_notify_trigger(entry->id, current_time, entry->pause); + g_free(entry); + + mod_next_event_timer(); + + if (do_stop) { + qemu_system_vmstop_request_prepare(); + qemu_system_vmstop_request(RUN_STATE_DEBUG); + /* + * FIXME: should not return to device code in case + * vm_stop() has been requested. + */ + cpu_stop_current(); + } +} + +void qmp_time_notify(int64_t event_id, int64_t time_ns, + bool has_relative, bool relative, + bool has_pause, bool pause, + Error **errp) +{ + TimeNotifEntry *new_entry, *entry, *prev =3D NULL; + + if (!timer) { + timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, trigger_notif, NULL); + } + + if (time_ns < 0) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "time_ns", + "must be positive"); + } + + new_entry =3D g_new0(TimeNotifEntry, 1); + new_entry->id =3D event_id; + new_entry->time_ns =3D time_ns; + new_entry->pause =3D has_pause && pause; + if (has_relative && relative) { + new_entry->time_ns +=3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + } + trace_qmp_time_notify_schedule(new_entry->id, new_entry->time_ns, + new_entry->pause); + + /* find the event just before the new one */ + QLIST_FOREACH(entry, &events, node) { + if (entry->time_ns > new_entry->time_ns) { + break; + } + prev =3D entry; + } + + /* then insert the new entry */ + if (prev) { + QLIST_INSERT_AFTER(prev, new_entry, node); + } else { + QLIST_INSERT_HEAD(&events, new_entry, node); + mod_next_event_timer(); + } +} diff --git a/monitor/trace-events b/monitor/trace-events index 0365ac4d99..73f375db68 100644 --- a/monitor/trace-events +++ b/monitor/trace-events @@ -13,3 +13,7 @@ monitor_suspend(void *ptr, int cnt) "mon %p: %d" monitor_qmp_cmd_in_band(const char *id) "%s" monitor_qmp_cmd_out_of_band(const char *id) "%s" handle_qmp_command(void *mon, const char *req) "mon %p req: %s" + +# qmp-cmd-time-notify.c +qmp_time_notify_trigger(int64_t id, uint64_t time, int pause) "event #%"PR= Id64" at %"PRIu64" ns pause %d" +qmp_time_notify_schedule(int64_t id, uint64_t time, int pause) "event #%"P= RId64" at %"PRIu64" ns pause %d" diff --git a/qapi/misc.json b/qapi/misc.json index 255236b96f..8e84f4d4d3 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -3195,3 +3195,51 @@ { 'command': 'gpio-set', 'data': { 'path': 'str', '*gpio': 'str', '*number': 'int', 'value': 'boo= l' } } + +## +# @time-notify: +# +# Schedule a TIME_NOTIFICATION which will optionally stop qemu when trigge= red. +# +# @time_ns: The virtual guest clock at which do the notification. +# +# @relative: Optional boolean telling if time_ns is relative to current ti= me. +# Defaults to False. +# +# @event_id: An ID, to track the notification. +# +# @pause: Optional boolean telling whether to pause qemu when notification= is +# hit. Defaults to False. +# +# Returns: nothing in case of success +# +# Since 4.1 +# +# Example: +# +# -> { "execute": "time-notify", +# "arguments": { "event_id": 5, +# "time_ns": 10000000, +# "pause": true} } +# <- { "return": {} } +# +## +{ 'command': 'time-notify', + 'data': {'event_id': 'int', 'time_ns': 'int', '*relative': 'bool', + '*pause': 'bool'} +} + +## +# @TIME_NOTIFICATION: +# +# Emitted when notification deadline is hit +# +# @time_ns: The current virtual guest clock time. +# +# @event_id: The id given when setting up the notification. +# +# Since: 4.1 +# +## +{ 'event': 'TIME_NOTIFICATION', + 'data': { 'event_id': 'int', 'time_ns': 'int'} } --=20 2.22.0 From nobody Sat May 11 23:29:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=fail Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561727480423292.65087872928063; Fri, 28 Jun 2019 06:11:20 -0700 (PDT) Received: from localhost ([::1]:59640 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqeq-0002H2-I1 for importer@patchew.org; Fri, 28 Jun 2019 09:11:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41650) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqGU-0000Ch-HB for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgqGL-0001aO-9H for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:05 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:36982) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hgqGK-0001Rl-Pt for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:45:57 -0400 Received: from kouign-amann.bar.greensocs.com (unknown [172.16.11.117]) by beetle.greensocs.com (Postfix) with ESMTPS id 89F6696F57; Fri, 28 Jun 2019 12:45:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ong44x20Rm5gt6iEZYBnbtQRmzo27WdaVQNGYbfZANU=; b=xdhD0JqG4sX39UDxDDrU6GJdw+AyoOhZnyHVL2P5diI2K8ZUuaqAnZgdqEY926Xx7u29eg tSJLpew9zXYlOn3UI0tSxQLFokmYLKj66wGKL0VGCj5Blu4bnLy2vSz+QbQSwJuV7gWVrs ZEZkH/cnRS8dGK9/RfS0x1hur7DR9G0= From: Damien Hedde To: qemu-devel@nongnu.org Date: Fri, 28 Jun 2019 14:45:33 +0200 Message-Id: <20190628124534.10679-5-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190628124534.10679-1-damien.hedde@greensocs.com> References: <20190628124534.10679-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ong44x20Rm5gt6iEZYBnbtQRmzo27WdaVQNGYbfZANU=; b=kEIaNtXQTQGW31G4bX0llfuF/1zTSd99+QsZFKVycIKGP+vg4I1BPaeQMg+dMklMYsbAF/ EFJ+0MiXKfhT7GoxA2Iji1locG5nT/2l6pYI2LbaSmg/d2m0I+nvPUHEQXvX0uH7Lhg1cJ 03CLJSdb/RlUiMTDnpMiqqGAQRp5J80= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1561725941; a=rsa-sha256; cv=none; b=UOHYaG6Qe4PK8Rx2zVozTMkIiKBrpiIUqBapzGToQYaNop/W0kYhrtAv/xK8nD9zytbto3 g3gtbyp1bqhhtBvUyIZ726b4tj8L4yWvFuleWe/oGipAY5BOslqvJXEqa737rOzLNHGgfW zjKNuDcHLdVSQR1eDK0uq38TuFfmPwQ= ARC-Authentication-Results: i=1; beetle.greensocs.com; none Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [RFC PATCH 4/5] fault_injection: introduce Python scripting framework 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: Damien Hedde , ehabkost@redhat.com, mark.burton@greensocs.com, armbru@redhat.com, sakisp@xilinx.com, edgari@xilinx.com, crosa@redhat.com, pbonzini@redhat.com, luc.michel@greensocs.com, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This is the actual Python framework. It provides some wrappers: * which allow to notify a callback in a given qemu time. * read or write some memory location * read/write qom properties. * set a GPIO. This is based on the work of Frederic Konrad Signed-off-by: Damien Hedde --- scripts/qmp/fault_injection.py | 278 +++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 scripts/qmp/fault_injection.py diff --git a/scripts/qmp/fault_injection.py b/scripts/qmp/fault_injection.py new file mode 100644 index 0000000000..2d23e69d47 --- /dev/null +++ b/scripts/qmp/fault_injection.py @@ -0,0 +1,278 @@ +# Fault injection helper script based on top of QMP. +# +# Copyright (C) 2016,2019 GreenSocs SAS +# +# Authors: +# Frederic Konrad +# Damien Hedde +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. +# + +import json +import ast +import readline +import sys +import struct +import os +sys.path.append(os.path.join(os.path.dirname(__file__), + '..', '..', 'python', 'qemu')) +import qmp + +def die(cause): + print(sys.stderr.write('error: %s\n' % cause)) + sys.exit(1) + +class FaultInjectionQMPError(Exception): + def __init__(self, rsp): + self.args =3D (rsp,) + +class FaultInjectionFramework(qmp.QEMUMonitorProtocol): + qemu_time =3D 0 + verbose =3D 0 + callback =3D {} + endianness =3D None + + def print_v(self, msg, level): + if level <=3D self.verbose: + print(msg) + + def print_qemu_version(self): + version =3D self._greeting['QMP']['version']['qemu'] + print('Connected to QEMU %d.%d.%d' % (version['major'], + version['minor'], + version['micro'])) + + def __init__(self, address, verbose =3D 0): + self.verbose =3D verbose + qmp.QEMUMonitorProtocol.__init__(self, self.__get_address(address)) + + try: + self._greeting =3D qmp.QEMUMonitorProtocol.connect(self) + except qmp.QMPConnectError: + die('Didn\'t get QMP greeting message') + except qmp.QMPCapabilitiesError: + die('Could not negotiate capabilities') + except self.error: + die('Could not connect to %s' % address) + + self.print_qemu_version() + self._completer =3D None + self._pretty =3D False + self._transmode =3D False + self._actions =3D list() + + def set_endian_big(self): + self.endianness =3D 'big' + + def set_endian_little(self): + self.endianness =3D 'little' + + def time_print(self, arg): + self.print_v('%sns: %s' % (self.qemu_time, arg), 1) + + def send(self, qmpcmd): + self.print_v(qmpcmd, 2) + resp =3D self.cmd_obj(qmpcmd) + if resp is None: + die('Disconnected') + self.print_v(resp, 2) + if 'error' in resp: + raise FaultInjectionQMPError(resp) + return resp + + def cont(self): + qmpcmd =3D {'execute': 'cont', 'arguments': {}} + self.send(qmpcmd) + + def run_once(self): + # RUN the simulation until one event is received + self.cont() + # Wait for an event to appear + done =3D False + while done =3D=3D False: + for ev in self.get_events(True): + self.print_v(ev, 2) + if ev['event'] =3D=3D 'TIME_NOTIFICATION': + data =3D ev['data'] + self.qemu_time =3D data['time_ns']; + self.callback[data['event_id']]() + self.cont() + done =3D True + elif ev['event'] =3D=3D 'SHUTDOWN': + self.clear_events() + return True + self.clear_events() + return False + + def run(self): + # RUN the simulation. + self.time_print('Simulation is now running') + # Wait for an event to appear + shutdown_evt =3D False + while shutdown_evt =3D=3D False: + shutdown_evt =3D self.run_once() + self.close() + + def notify(self, time_ns, cb, relative =3D False): + # Notify a callback at qemu time time_ns + next_index =3D len(self.callback) + elt =3D 0 + for elt in range(0, next_index + 1): + if elt =3D=3D next_index: + break + if self.callback[elt] =3D=3D cb: + break + + self.callback[elt] =3D cb + if relative: + self.time_print('Notify %s in %sns' % (cb, time_ns)) + else: + self.time_print('Notify %s at %sns' % (cb, time_ns)) + qmpcmd =3D {'execute': 'time-notify', + 'arguments': {'event_id': elt, + 'time_ns': time_ns, + 'pause' : True}} + if relative: + qmpcmd['arguments']['relative'] =3D True + self.send(qmpcmd) + + def _pvmemwrite(self, virtual, address, value, cpu =3D None): + # write a value to a virtual or physical address + if type(value) is not list: + value =3D list(value) + + self.time_print('write: @%s0x%08x size %d values [' + % ('V' if virtual else 'P', address, len(value)) + + ','.join('%d' % i for i in value) + + '] from cpu %s' % (cpu)) + qmpcmd =3D {'execute': 'memwrite' if virtual else 'pmemwrite', + 'arguments': {'addr': address, 'bytes': value}} + if cpu is not None: + qmpcmd['arguments']['cpu'] =3D cpu; + rsp =3D self.send(qmpcmd) + + def _pvmemread(self, virtual, address, size, cpu =3D None): + # read a value to a virtual or physical address + + self.time_print('read: @%s0x%08x size %d values from cpu %s' + % ('V' if virtual else 'P', address, size, cpu)) + qmpcmd =3D {'execute': 'memread' if virtual else 'pmemread', + 'arguments': {'addr': address, 'size': size}} + if cpu is not None: + qmpcmd['arguments']['cpu'] =3D cpu; + rsp =3D self.send(qmpcmd) + value =3D bytearray(rsp['return']['bytes']) + return value + + def _memstructformat(self, size): + if self.endianness =3D=3D 'little': + s =3D '<' + elif self.endianness =3D=3D 'big': + s =3D '>' + else: + #defaults to native + s =3D '=3D' + s +=3D {1:'B', 2:'H', 4:'I', 8:'Q'}[size] + return s + + def read_mem(self, address, size, cpu =3D None): + fmt =3D self._memstructformat(size) + value =3D self._pvmemread(True, address, size, cpu) + return struct.unpack(fmt, value)[0] + + def write_mem(self, address, size, value, cpu =3D None): + fmt =3D self._memstructformat(size) + value =3D bytearray(struct.pack(fmt, value)) + self._pvmemwrite(True, address, value, cpu) + + def read_pmem(self, address, size): + fmt =3D self._memstructformat(size) + value =3D self._pvmemread(False, address, size) + return struct.unpack(fmt, value)[0] + + def write_pmem(self, address, size, value): + fmt =3D self._memstructformat(size) + value =3D bytearray(struct.pack(fmt, value)) + self._pvmemwrite(False, address, value) + + def get_qom_property(self, path, property): + # Get a QOM property + qmpcmd =3D {'execute': 'qom-get', + 'arguments': {'path': path, + 'property': property}} + value =3D self.send(qmpcmd)['return'] + return value + + def set_qom_property(self, path, property, value): + # Set a QOM property + qmpcmd =3D {'execute': 'qom-set', + 'arguments': {'path': path, + 'property': property, + 'value': value}} + self.send(qmpcmd) + + def set_gpio(self, path, gpio, num, value): + # Set a GPIO + qmpcmd =3D {'execute': 'gpio-set', + 'arguments': {'path': path, 'value': value}} + if gpio is not None: + qmpcmd['arguments']['gpio'] =3D gpio + if num is not None: + qmpcmd['arguments']['number'] =3D num + self.send(qmpcmd) + + def help(self): + msg =3D [ + "Fault Injection Framework Commands", + "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n", + "cont()", + " * Resume the simulation when the Virtual Machine is stopped.= \n", + "run()", + " * Start the simulation when the notify are set.\n", + "notify(delta_ns, cb)", + " * Notify the callback cb in guest time delta_ns.\n", + "write_mem(address, size, value, cpu)", + " * write @value of size @size at virtual @address from @cpu.", + " * @size is in bytes, supported values are 1, 2, 4 and 8.", + " * @cpu is the cpu id.\n", + "read_mem(address, size, cpu)", + " * read a value of size @size at virtual @address from @cpu.", + " * @size is in bytes, supported values are 1, 2, 4 and 8.", + " * @cpu is the cpu id.", + " * returns the value.\n", + "write_pmem(address, size, value)", + " * write @value of size @size at physical @address.", + " * @size is in bytes, supported values are 1, 2, 4 and 8.\n", + "read_pmem(address, size)", + " * read a value of size @size at physical @address.", + " * @size is in bytes, supported values are 1, 2, 4 and 8.", + " * returns the value.\n", + "get_qom_property(path, property)", + " * Get a qom property.", + " * Returns the qom property named @property in @path.\n", + "set_qom_property(path, property, value)", + " * Set the property named @property in @path with @value.\n", + "set_gpio(path, gpio, num, value)", + " * Set the gpio named @gpio number @num in @path with the @va= l.", + " * @val is a boolean.\n" + ] + for m in msg: + print(m) + + def __get_address(self, arg): + """ + Figure out if the argument is in the port:host form, if it's not i= t's + probably a file path. + """ + addr =3D arg.split(':') + if len(addr) =3D=3D 2: + try: + port =3D int(addr[1]) + except ValueError: + raise QMPShellBadPort + return ( addr[0], port ) + # socket path + return arg + --=20 2.22.0 From nobody Sat May 11 23:29:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; arc=fail Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561727937338147.2517157801658; Fri, 28 Jun 2019 06:18:57 -0700 (PDT) Received: from localhost ([::1]:59746 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqmB-0003Mq-G4 for importer@patchew.org; Fri, 28 Jun 2019 09:18:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41649) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hgqGU-0000Cg-HA for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hgqGM-0001cE-L0 for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:46:05 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:37004) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hgqGM-0001Zt-63 for qemu-devel@nongnu.org; Fri, 28 Jun 2019 08:45:58 -0400 Received: from kouign-amann.bar.greensocs.com (unknown [172.16.11.117]) by beetle.greensocs.com (Postfix) with ESMTPS id 3A9D596F58; Fri, 28 Jun 2019 12:45:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GIhpl/DttkLLK7DJX0z6TNYXgE+dPetO02X9ZhbQxV8=; b=h7jF2T0fsXdKZL4y5iwn88gt8VIk8dkDRJC8l0isl2aiiP28gS5sdgv2n6IaX/dU2pdGu3 agWnqfH3Mo/uQ48nCzhLfkopfFFDqndUk+TgyqyhsRGm3r5YZ/c4oh2THlpX66ZSTdVTJv 2TPN0JquvAtbKhsB6Sl8Q+NTOmeJ3Jc= From: Damien Hedde To: qemu-devel@nongnu.org Date: Fri, 28 Jun 2019 14:45:34 +0200 Message-Id: <20190628124534.10679-6-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190628124534.10679-1-damien.hedde@greensocs.com> References: <20190628124534.10679-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1561725941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GIhpl/DttkLLK7DJX0z6TNYXgE+dPetO02X9ZhbQxV8=; b=mS6j+2pPCfSd1JvGpPHYEbGTeAkmLCZejEUuI/oqKEwg6n1kU2uKsEXXmesZ2yyWfE1+GI A6tx4aVqYpxmjPDYU1boYt6lOZq7jTVQyaYeCJd3mtSPaneZf768Fqr8fGMT8qTIj5zCWr jcDJvgy081q+5IV0gALPfIcZOBy/E8I= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1561725941; a=rsa-sha256; cv=none; b=6QG9edmInuNkDFiiOSf7gN6KYVCUcyZuP8hzanDh5uEZAFC7vBLO8sOpZtMPvmKZ28sT8y ValY/+l2xllUv9/amCRrHAHFgXse2rceDd+6NncqhQc/MD10NdKxgV69z2VZFyk4MvMeYt lIpvHaDKd8t1lO+ecClpfmb/RHz+SPk= ARC-Authentication-Results: i=1; beetle.greensocs.com; none Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [RFC PATCH 5/5] docs: add fault injection framework documentation 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: Damien Hedde , ehabkost@redhat.com, mark.burton@greensocs.com, armbru@redhat.com, sakisp@xilinx.com, edgari@xilinx.com, crosa@redhat.com, pbonzini@redhat.com, luc.michel@greensocs.com, rth@twiddle.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" This adds some hints about how to use the fault injection framework. This is based on Frederic Konrad's work. Signed-off-by: Damien Hedde --- docs/fault_injection.txt | 149 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 docs/fault_injection.txt diff --git a/docs/fault_injection.txt b/docs/fault_injection.txt new file mode 100644 index 0000000000..3cb1c1fd1a --- /dev/null +++ b/docs/fault_injection.txt @@ -0,0 +1,149 @@ + Fault Injection Framework + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Introduction +------------ + +The fault injection framework allows users to write python scripts to inje= ct +faults through the QMP (QEMU Machine Protocol) during execution. + +Basically it's composed of a Python API which makes some QMP commands easy= to +send to the machine: + * read/write a virtual/memory memory location. + * set a GPIO line. + * get/set a QOM property. + +In addition it allows the Python script to be notified back by QEMU so it = can +do any of the previous commands at a given virtual clock time. + +Today the available function in the API are the following: + * notify(time_ns, cb, do_halt) + * write_mem(address, value, size, cpu) + * read_mem(address, size, cpu) + * write_pmem(address, value, size) + * read_pmem(address, size) + * get_qom_property(path, property) + * set_qom_property(path, property, value) + * set_gpio(path, gpio, num, value) + +Empty Example +------------- + +This is an empty example to begin: + +import fault_injection +import sys + +framework =3D None + +def main(): + # The injection framework will parse the command line automatically + # (eg: the qmp socket/port.. etc) + sys.stdout.write('Fault Injection Example\n') + global framework + framework =3D fault_injection.FaultInjectionFramework(sys.argv[1]) + + framework.run() + sys.exit(1) + +if __name__ =3D=3D '__main__': + main() + +To run the example just save the example in `script/qmp/example_scenario` +Run qemu with the additional arguments: `-S -qmp unix:/path/to/qmp-sock,se= rver` +in order to wait for a qmp connection and stop the QEMU machine. +Run the example with: `./example_scenario /path/to/qmp-sock` + +It will start the simulation inside QEMU and do nothing else. + +Adding a callback at a given time +--------------------------------- + +As described above a callback can be added in the python scenario. +For example we can create the following callback which write 0xDEADBEEF @0= with +a size of 4 from cpu 0 and then reads it back: + +def write_mem_callback(): + print 'write_mem_callback()' + framework.write_mem(0x0, 0xDEADBEEF, 4, 0) + val =3D framework.read_mem(0x0, 4, 0) + print 'value read: 0x%8.8X' %val + +Then we can notify it in the main function before framework.run(): +`framework.notify(1000000000, write_mem_callback)` + +The script works as expected: + +write_mem_callback() +value read: 0xDEADBEEF + +Using the python interpreter +---------------------------- + +The Python interpreter can be used to send the command above: +For example to set the vinithi bit to 1 for the /rpu_cpu@0 the following +commands can be done in the script/qmp directory: + +$ python +>>> import fault_injection +>>> inj=3Dfault_injection.FaultInjectionFramework("../../qmp-sock", 0) +Connected to QEMU 2.2.50 + +>>> inj.help() + +Fault Injection Framework Commands +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +cont() + * Resume the simulation when the Virtual Machine is stopped. + +notify(time_ns, cb, do_pause) + * Notify the callback cb in guest time time_ns. Simulation is stopped onl= y if + do_pause is set to True. + +run_once() + * Start the simulation and handle a callback set by notify. Return after + first callback is handled + +run() + * Start the simulation and handle the callbacks set by notify. Do not ret= urn + until the end of the simulation. + +write_mem(address, value, size, cpu) + * Write @value of size @size at virtual @address from @cpu. + * @cpu is the cpu id. + +write_pmem(address, value, size) + * Like write_mem, but on a physical @address. + +read_mem(address, size, cpu) + * Read a value of size @size at virtual @address from @cpu. + * @cpu is the cpu id. + * Returns the value. + +read_pmem(address, size) + * Like read_mem, but on a physical @address. + +get_qom_property(path, property) + * Get a qom property. + * Returns the qom property named @property in @path. + +set_qom_property(path, property, value) + * Set the property named @property in @path with @value. + +set_gpio(path, gpio, num, value) + * Set the gpio named @gpio number @num in @path with the @val. + * @val is a boolean. + +>>> inj.set_gpio('/rpu_cpu@0', 'vinithi', 0, 1) + +Notes +----- + +The user can turn debug information on by passing a level to the framework +constructor eg: +"framework =3D fault_injection.FaultInjectionFramework(1)" will print time= d traces +such as write or read. +"framework =3D fault_injection.FaultInjectionFramework(2)" will print the = QMP +commands as well. + --=20 2.22.0