From patchwork Mon Jan 7 16:30:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 154910 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp3674026ljp; Mon, 7 Jan 2019 08:38:23 -0800 (PST) X-Google-Smtp-Source: ALg8bN6WtJXQKyUCAnAMsCb+wiS+viIttyNgmIE/bgdn5GpXZ3DkXY1LDxm7G7YqOD9PJI3g5EPn X-Received: by 2002:adf:ee89:: with SMTP id b9mr54413318wro.246.1546879103702; Mon, 07 Jan 2019 08:38:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546879103; cv=none; d=google.com; s=arc-20160816; b=BtHonriAihXbpo9rH63FW093vp8T0D9rKfbnWAio2cX6zVfXgDGA/Sg/yxwsxAB57u iocfIE3qqa72X/FheWsNqmyjkfEVOBn9kbEwSxAVqstaSpc02PXop90WL4IMr287x3/Q IUVta3ww/bVbjWA6VJyOGly51rQ1mnPJNvh2t7TED5U8w5oE7WUzJkQPJ39DDxzO8uQZ 50WK+V6ffIojrj2IHInfS4pAqHc6I6wx3Ks2cxjDi42hHeAzjlxiqc9L/CJBDPDbaS3d r/pBuSeiwbPfVMLeuio0sra4DrpgGsiTyuDar7TfQ2Mg7cO4vMdXtVXBDILuRrogWU71 aAUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=vMh6xY1GMYIdM+kfMAqkwNArXmtcSl7a//C6INwAbMg=; b=gQRzfyOtSLz83HflpZEL0Tb7mZ5Zpy2mwlMIgrsnEi/OrNQQTD56QRGaNOOZ+PR58n /a9OpT+D6J7o4hFGZwh9KMu7BdnQt0NajvT8ZSAHCqq1A+w0TytBjJ+PENAJt5tD/AIN GAtPkUQ/5ggeO/ScpOrzP1xhKOylHOsz7+pVXyn3JYwVPhfCsolPyN7osnxDsFr67m0h feD+OI2FCXPkcceiUSUJJVgyRRPXz2v7Tr2pqmF68fIig+PXXJMit/99mQ7JUSE09EjP vUSDKeuzjaKdpy75l1bfqr8RD0ggHKsS+sJA2v2Cm1l9wwIBGBmkSsZXEGtlYJJOc/NY kwrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Ih4zsYxf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id b19si38068556wrf.44.2019.01.07.08.38.23 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 07 Jan 2019 08:38:23 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Ih4zsYxf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:43948 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ggXuw-0001Vm-IJ for patch@linaro.org; Mon, 07 Jan 2019 11:38:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46027) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ggXoI-0004nw-AW for qemu-devel@nongnu.org; Mon, 07 Jan 2019 11:31:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ggXoG-0001dy-DN for qemu-devel@nongnu.org; Mon, 07 Jan 2019 11:31:30 -0500 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]:52182) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ggXoF-0001bi-Rl for qemu-devel@nongnu.org; Mon, 07 Jan 2019 11:31:28 -0500 Received: by mail-wm1-x332.google.com with SMTP id b11so1465566wmj.1 for ; Mon, 07 Jan 2019 08:31:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=vMh6xY1GMYIdM+kfMAqkwNArXmtcSl7a//C6INwAbMg=; b=Ih4zsYxfRe5gaXs5f6pLlb8USSLIsBEWtIWtBCmaBWAn9jG4C2bP8S6Ae9qly9dyxe X+PJ3Om4GEKLTocjwwTuv+A8VN1wsv/UMgd64YBX+Roo/rnycTIikOAd9cgpk294ch2b /PFpH94n0yTqOwldoAhjzk5rhVsIjNsFNIIZ8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vMh6xY1GMYIdM+kfMAqkwNArXmtcSl7a//C6INwAbMg=; b=GWszZD8cXS8nN2d+woGfHjYTFItWwmI8zJX+l4DYOauxbVVXgiC42sm/wfKTe962qd dAaTCBPlDgIBKGeBFrujJGEundqmSIAE50UKfqLOu+rYT8xTu0BWnscb4muF6F2Ndsur jX/7V6BiWSNzTtptSktQ2fzhu4aVWnk2WROtV6I/1B3bLQkxq9IJZxl3q7DjytS564DR aqf4IRJGRrxVSe2fRTlaoyrPo3Jetve5mV+9Szq0ciinG2pr6L9M5TmObe083Z+vSaoY k/zm1gsobpa9HKDx62OxbQ9IGs13oxfCND1/y3sqAM8LN9e5vcrgZd29NLE2GEkRAO0o XWzw== X-Gm-Message-State: AJcUukfqc5eEpCLBuNIwZtkK0xhmT3kfcZJHzZLr4F22ccNg6JLShNRx 7UtwoVgDnMY//OVZFUnmWHBo1osenHBQew== X-Received: by 2002:a1c:13d1:: with SMTP id 200mr9078593wmt.4.1546878686243; Mon, 07 Jan 2019 08:31:26 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j14sm46039759wrv.96.2019.01.07.08.31.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 07 Jan 2019 08:31:25 -0800 (PST) From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 7 Jan 2019 16:30:44 +0000 Message-Id: <20190107163117.16269-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190107163117.16269-1-peter.maydell@linaro.org> References: <20190107163117.16269-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::332 Subject: [Qemu-devel] [PULL 04/37] gdbstub: introduce GDB processes 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: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Luc Michel Add a structure GDBProcess that represents processes from the GDB semantic point of view. CPUs can be split into different processes, by grouping them under different cpu-cluster objects. Each occurrence of a cpu-cluster object implies the existence of the corresponding process in the GDB stub. The GDB process ID is derived from the corresponding cluster ID as follows: GDB PID = cluster ID + 1 This is because PIDs -1 and 0 are reserved in GDB and cannot be used by processes. A default process is created to handle CPUs that are not in a cluster. This process gets the PID of the last process PID + 1. Signed-off-by: Luc Michel Acked-by: Alistair Francis Reviewed-by: Edgar E. Iglesias Reviewed-by: Philippe Mathieu-Daudé Message-id: 20181207090135.7651-3-luc.michel@greensocs.com [PMM: fixed checkpatch nit about block comment style] Signed-off-by: Peter Maydell --- gdbstub.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) -- 2.19.2 diff --git a/gdbstub.c b/gdbstub.c index c4e4f9f0821..9ac6f19a186 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -29,6 +29,7 @@ #include "chardev/char-fe.h" #include "sysemu/sysemu.h" #include "exec/gdbstub.h" +#include "hw/cpu/cluster.h" #endif #define MAX_PACKET_LENGTH 4096 @@ -296,6 +297,11 @@ typedef struct GDBRegisterState { struct GDBRegisterState *next; } GDBRegisterState; +typedef struct GDBProcess { + uint32_t pid; + bool attached; +} GDBProcess; + enum RSState { RS_INACTIVE, RS_IDLE, @@ -324,6 +330,9 @@ typedef struct GDBState { CharBackend chr; Chardev *mon_chr; #endif + bool multiprocess; + GDBProcess *processes; + int process_num; char syscall_buf[256]; gdb_syscall_complete_cb current_syscall_cb; } GDBState; @@ -1751,6 +1760,30 @@ void gdb_exit(CPUArchState *env, int code) #endif } +/* + * Create the process that will contain all the "orphan" CPUs (that are not + * part of a CPU cluster). Note that if this process contains no CPUs, it won't + * be attachable and thus will be invisible to the user. + */ +static void create_default_process(GDBState *s) +{ + GDBProcess *process; + int max_pid = 0; + + if (s->process_num) { + max_pid = s->processes[s->process_num - 1].pid; + } + + s->processes = g_renew(GDBProcess, s->processes, ++s->process_num); + process = &s->processes[s->process_num - 1]; + + /* We need an available PID slot for this process */ + assert(max_pid < UINT32_MAX); + + process->pid = max_pid + 1; + process->attached = false; +} + #ifdef CONFIG_USER_ONLY int gdb_handlesig(CPUState *cpu, int sig) @@ -1848,6 +1881,7 @@ static bool gdb_accept(void) s = g_malloc0(sizeof(GDBState)); s->c_cpu = first_cpu; s->g_cpu = first_cpu; + create_default_process(s); s->fd = fd; gdb_has_xml = false; @@ -2004,6 +2038,65 @@ static const TypeInfo char_gdb_type_info = { .class_init = char_gdb_class_init, }; +static int find_cpu_clusters(Object *child, void *opaque) +{ + if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) { + GDBState *s = (GDBState *) opaque; + CPUClusterState *cluster = CPU_CLUSTER(child); + GDBProcess *process; + + s->processes = g_renew(GDBProcess, s->processes, ++s->process_num); + + process = &s->processes[s->process_num - 1]; + + /* + * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at + * runtime, we enforce here that the machine does not use a cluster ID + * that would lead to PID 0. + */ + assert(cluster->cluster_id != UINT32_MAX); + process->pid = cluster->cluster_id + 1; + process->attached = false; + + return 0; + } + + return object_child_foreach(child, find_cpu_clusters, opaque); +} + +static int pid_order(const void *a, const void *b) +{ + GDBProcess *pa = (GDBProcess *) a; + GDBProcess *pb = (GDBProcess *) b; + + if (pa->pid < pb->pid) { + return -1; + } else if (pa->pid > pb->pid) { + return 1; + } else { + return 0; + } +} + +static void create_processes(GDBState *s) +{ + object_child_foreach(object_get_root(), find_cpu_clusters, s); + + if (s->processes) { + /* Sort by PID */ + qsort(s->processes, s->process_num, sizeof(s->processes[0]), pid_order); + } + + create_default_process(s); +} + +static void cleanup_processes(GDBState *s) +{ + g_free(s->processes); + s->process_num = 0; + s->processes = NULL; +} + int gdbserver_start(const char *device) { trace_gdbstub_op_start(device); @@ -2060,11 +2153,15 @@ int gdbserver_start(const char *device) } else { qemu_chr_fe_deinit(&s->chr, true); mon_chr = s->mon_chr; + cleanup_processes(s); memset(s, 0, sizeof(GDBState)); s->mon_chr = mon_chr; } s->c_cpu = first_cpu; s->g_cpu = first_cpu; + + create_processes(s); + if (chr) { qemu_chr_fe_init(&s->chr, chr, &error_abort); qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,