From nobody Wed May 1 08:33:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1678205202; cv=none; d=zohomail.com; s=zohoarc; b=ULFrJHxUOPGG6TPC1uUyf74p7BzUihXvvJtoMOOdYxLiM6rALRUIzdApt4UnikcEZ3GbRJV5o3ud2EJsh+sbWeNuBaGhyjdyHmU1dUu0ybJglc5LqxxE6C/dlptAmXoJHgZo8hTBEO3FVUgY9thOv2dl9QdcspEaWrMebD8Pwt0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1678205202; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9iQwB6p2IbDsuTo7h2CcmdpXMTGTs8SrDPWPSs9O2Rs=; b=REDScidFciHw+NGZ8m4oObOSp9VmoFdmPfLSeyx/LwZ9kRuDTGefOnzgNDIg08GifOu7QQuSshYqF5oi/r+tn2OShVkDw7YcbuI6r1G1ikoRLyP6/Q3VScmhrFoRB+IAVPxZEUYwI+sS7jWyLNzqFmzk78/vgG6rx9qMLmtDbYE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1678205202262190.97200958620886; Tue, 7 Mar 2023 08:06:42 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZZpB-0005RX-UZ; Tue, 07 Mar 2023 11:06:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZp8-0005QY-Sa for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:05:58 -0500 Received: from forwardcorp1c.mail.yandex.net ([178.154.239.200]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZp6-0002Sd-Dv for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:05:58 -0500 Received: from mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net [IPv6:2a02:6b8:c12:5da4:0:640:ef2d:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id 64D545E6F0; Tue, 7 Mar 2023 19:05:49 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:1223::1:36]) by mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id d5eRk00OeKo0-LmDxUi1q; Tue, 07 Mar 2023 19:05:48 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1678205148; bh=9iQwB6p2IbDsuTo7h2CcmdpXMTGTs8SrDPWPSs9O2Rs=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=TiovxLva4MACCepU+GkKOZwHh4TJytWdbA7YqzGvMGrTXo6UgMnP0TbWJ49OXbFH7 X1PKFcsYBL/vX4V3XHRdlBwY55QHM9OlJyNxiUg2fToVd96z7wZRylGj3lh8hwxpIv uei40+xEufqJKru6sRNgyr2GYFObhLPuTHdymvhg= Authentication-Results: mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net; dkim=pass header.i=@yandex-team.ru From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Cc: armbru@redhat.com, eblake@redhat.com, eduardo@habkost.net, berrange@redhat.com, pbonzini@redhat.com, marcel.apfelbaum@gmail.com, mst@redhat.com, den-plotnikov@yandex-team.ru, antonkuchin@yandex-team.ru, vsementsov@yandex-team.ru, philmd@linaro.org Subject: [PATCH v6 1/4] qapi/qdev.json: unite DEVICE_* event data into single structure Date: Tue, 7 Mar 2023 19:05:34 +0300 Message-Id: <20230307160537.2261803-2-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230307160537.2261803-1-vsementsov@yandex-team.ru> References: <20230307160537.2261803-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=178.154.239.200; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1c.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1678205206040100004 Content-Type: text/plain; charset="utf-8" DEVICE_DELETED and DEVICE_UNPLUG_GUEST_ERROR has equal data, let's refactor it to one structure. That also helps to add new events consistently. Signed-off-by: Vladimir Sementsov-Ogievskiy --- qapi/qdev.json | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/qapi/qdev.json b/qapi/qdev.json index 2708fb4e99..135cd81586 100644 --- a/qapi/qdev.json +++ b/qapi/qdev.json @@ -114,16 +114,37 @@ { 'command': 'device_del', 'data': {'id': 'str'} } =20 ## -# @DEVICE_DELETED: +# @DeviceAndPath: # -# Emitted whenever the device removal completion is acknowledged by the gu= est. -# At this point, it's safe to reuse the specified device ID. Device remova= l can -# be initiated by the guest or by HMP/QMP commands. +# In events we designate devices by both their ID (if the device has one) +# and QOM path. +# +# Why we need ID? User specify ID in device_add command and in command line +# and expects same identifier in the event data. +# +# Why we need QOM path? Some devices don't have ID and we still want to em= it +# events for them. +# +# So, we have a bit of redundancy, as QOM path for device that has ID is +# always /machine/peripheral/ID. But that's hard to change keeping both +# simple interface for most users and universality for the generic case. # # @device: the device's ID if it has one # # @path: the device's QOM path # +# Since: 8.0 +## +{ 'struct': 'DeviceAndPath', + 'data': { '*device': 'str', 'path': 'str' } } + +## +# @DEVICE_DELETED: +# +# Emitted whenever the device removal completion is acknowledged by the gu= est. +# At this point, it's safe to reuse the specified device ID. Device remova= l can +# be initiated by the guest or by HMP/QMP commands. +# # Since: 1.5 # # Example: @@ -134,18 +155,13 @@ # "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } # ## -{ 'event': 'DEVICE_DELETED', - 'data': { '*device': 'str', 'path': 'str' } } +{ 'event': 'DEVICE_DELETED', 'data': 'DeviceAndPath' } =20 ## # @DEVICE_UNPLUG_GUEST_ERROR: # # Emitted when a device hot unplug fails due to a guest reported error. # -# @device: the device's ID if it has one -# -# @path: the device's QOM path -# # Since: 6.2 # # Example: @@ -156,5 +172,4 @@ # "timestamp": { "seconds": 1615570772, "microseconds": 202844 } } # ## -{ 'event': 'DEVICE_UNPLUG_GUEST_ERROR', - 'data': { '*device': 'str', 'path': 'str' } } +{ 'event': 'DEVICE_UNPLUG_GUEST_ERROR', 'data': 'DeviceAndPath' } --=20 2.34.1 From nobody Wed May 1 08:33:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1678205225; cv=none; d=zohomail.com; s=zohoarc; b=A0GPAi+G+hgJcZIktKVHnXj+b+lSxYY86/JO/0nxNlAPEPYciKZS7+vAkkgYS7zGhs+OnvlNqtSTa4jUMVOIdnwPqXLrD1hUCbIPZ4q5dcJLxOAR69NHJz+o4AIHIx4VlerZ4/NFWg+SOGLaAk2PHKnkjKIHjPOLeGh8jJRuRDk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1678205225; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=imMF1bPfQoH0wNGQMIIAc5Z45ST3KT1vMXdJ36fPlTo=; b=gRNGIdNBqHLpLqFoP24yYOSatUg9AzHAAc7Aq3nfaz6L8G+OfBr2BBDGqXvSNj3/Pgjd+ZgMkYbDKlMndFOjeMUjlAviUeovo7iK5UdHhxQtB+pQVxXaTuO7b5EWXMaLcJ/UsREB+w+Fti7x7e525Jas9S+sFxvp12KDIGf6crw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1678205225225579.6132785322404; Tue, 7 Mar 2023 08:07:05 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZZpE-0005ST-Rm; Tue, 07 Mar 2023 11:06:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZpA-0005Qt-Ks for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:06:01 -0500 Received: from forwardcorp1b.mail.yandex.net ([2a02:6b8:c02:900:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZp7-0002Sm-By for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:06:00 -0500 Received: from mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net [IPv6:2a02:6b8:c12:5da4:0:640:ef2d:0]) by forwardcorp1b.mail.yandex.net (Yandex) with ESMTP id 8B8C9608D0; Tue, 7 Mar 2023 19:05:50 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:1223::1:36]) by mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id d5eRk00OeKo0-2wYM5OQC; Tue, 07 Mar 2023 19:05:49 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1678205149; bh=imMF1bPfQoH0wNGQMIIAc5Z45ST3KT1vMXdJ36fPlTo=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=y2vYzKlfu0bfrleLh0FFsI4A4L7VqwVudpdvTp7NqVQWuVLHdLjMd9FEaEm5WuiqK 997KdjNr/5kOntLhkmWqw4ZUSZx4zIp//QQyDYwJnd9ylub1TWeowQIE85eSZDDOh8 OzCisJoN2epLb2kgoyloHKGBTnLgDpa/tmrpFGQc= Authentication-Results: mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net; dkim=pass header.i=@yandex-team.ru From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Cc: armbru@redhat.com, eblake@redhat.com, eduardo@habkost.net, berrange@redhat.com, pbonzini@redhat.com, marcel.apfelbaum@gmail.com, mst@redhat.com, den-plotnikov@yandex-team.ru, antonkuchin@yandex-team.ru, vsementsov@yandex-team.ru, philmd@linaro.org Subject: [PATCH v6 2/4] qapi: add DEVICE_ON and query-hotplug infrastructure Date: Tue, 7 Mar 2023 19:05:35 +0300 Message-Id: <20230307160537.2261803-3-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230307160537.2261803-1-vsementsov@yandex-team.ru> References: <20230307160537.2261803-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a02:6b8:c02:900:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1b.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1678205226813100005 Content-Type: text/plain; charset="utf-8" We have DEVICE_DELETED event, that signals that device_del command is actually completed. But we don't have a counter-part for device_add. Still it's sensible for SHPC and PCIe-native hotplug, as there are time when the device in some intermediate state. Let's add an event that say that the device is finally powered on, power indicator is on and everything is OK for next manipulation on that device. Motivations: 1. To be sure that device is "accepted" by guest. Guest may ignore hotplugged device for some reason (for example during OS booting). Management wants to catch this and handle the problem, instead of silent assume that everything is OK. So, if we don't get the event by some timeout, we can report an error, try to unplug/plug the disk again or do some other things to handle the problem. 2. The device can't be removed (by blockdev-del) while power indicator of hotplug controller is blinking (QEMU reports "guest is busy (power indicator blinking)"). So, management should avoid removing the device until it gets the DEVICE_ON event. (Probably, better solution for this point is to automatically postpone deletion until power indicator stops blinking) 3. Also, management tool may make a GUI visualization of power indicator with help of this event. As a counter-part add query-hotplug command, that shows "device-on" state as well as some addtional information. Signed-off-by: Vladimir Sementsov-Ogievskiy --- qapi/qdev.json | 144 +++++++++++++++++++++++++++++++++++++++++ include/hw/hotplug.h | 12 ++++ include/hw/qdev-core.h | 1 + include/monitor/qdev.h | 2 + hw/core/hotplug.c | 13 ++++ softmmu/qdev-monitor.c | 41 ++++++++++++ 6 files changed, 213 insertions(+) diff --git a/qapi/qdev.json b/qapi/qdev.json index 135cd81586..e37286da78 100644 --- a/qapi/qdev.json +++ b/qapi/qdev.json @@ -173,3 +173,147 @@ # ## { 'event': 'DEVICE_UNPLUG_GUEST_ERROR', 'data': 'DeviceAndPath' } + +## +# @LedActivity: +# +# Three-state led indicator state. +# +# @on: Indicator is on. +# +# @blink: Indicator is blinking. +# +# @off: Indicator is off. +# +# Since: 8.0 +## +{ 'enum': 'LedActivity', + 'data': [ 'on', 'blink', 'off' ] } + +## +# @HotplugSHPCSlotState: +# +# Standard Hot-Plug Controller slot state. +# +# @power-only: Slot is powered on but neither clock nor bus are connected. +# +# @enabled: Slot is powered on, clock and bus are connected, the card is +# fully functional from a hardware standpoint. +# +# @disabled: Slot is disabled, card is safe to be removed. +# +# Since: 8.0 +## +{ 'enum': 'HotplugSHPCSlotState', + 'data': [ 'power-only', 'enabled', 'disabled' ] } + +## +# @HotplugBaseState: +# +# Base structure for SHPC and PCIe-native hotplug. +# +# @power-led: Power indicator. When power indicator is on the device is +# ready and accepted by guest. Off status means that device +# is safe to remove and blinking is an intermediate state of +# hot-plug or hot-unplug. +# +# @attention-led: Attention indicator. Off status means normal operation, +# On signals about operational problem, Blinking is for +# locating the slot. +# +# Since: 8.0 +## +{ 'struct': 'HotplugBaseState', + 'data': { '*power-led': 'LedActivity', + '*attention-led': 'LedActivity' } } + +## +# @HotplugSHPCState: +# +# Standard Hot Plug Controller state. +# +# @slot-state: The slot state field of Slot Status. +# +# Since: 8.0 +## +{ 'struct': 'HotplugSHPCState', + 'base': 'HotplugBaseState', + 'data': { '*slot-state': 'HotplugSHPCSlotState' } } + +## +# @HotplugPCIeNativeState: +# +# PCIe Native hotplug slot state. +# +# @power-on: PCIe Power Controller Control of Slot Control Register. +# True means Power On (Power Controller Control bit is 0), +# False means Power Off (Power Controller Control bit is 1). +# +# Since: 8.0 +## +{ 'struct': 'HotplugPCIeNativeState', + 'base': 'HotplugBaseState', + 'data': { '*power-on': 'bool' } } + +## +# @HotplugType: +# +# Type of hotplug controller / provider. +# +# @shpc: Standard Hot Plug Controller +# +# @pcie-native: PCIe Native hotplug +# +# Since: 8.0 +## +{ 'enum': 'HotplugType', + 'data': ['shpc', 'pcie-native'] } + +## +# @HotplugInfo: +# +# Generic hotplug slot state. +# +# @type: type of the hotplug (shpc or pcie-native) +# +# @bus: The QOM path of the parent bus where device is hotplugged. +# +# @addr: The bus address for hotplugged device if applicable. +# +# @child: the hotplugged device +# +# @device-on: Device is powered-on by guest. This state changes at most +# once for the device and corresponds to DEVICE_ON event. +# +# Single: 8.0 +## +{ 'union': 'HotplugInfo', + 'base': { 'type': 'HotplugType', + 'bus': 'DeviceAndPath', + '*addr': 'str', + 'child': 'DeviceAndPath', + 'device-on': 'bool' }, + 'discriminator': 'type', + 'data': { 'shpc': 'HotplugSHPCState', + 'pcie-native': 'HotplugPCIeNativeState' } } + +## +# @query-hotplug: +# +# Query the state of hotplug controller. +# +# Since: 8.0 +## +{ 'command': 'query-hotplug', + 'data': { 'id': 'str' }, + 'returns': 'HotplugInfo' } + +## +# @DEVICE_ON: +# +# Emitted whenever the device insertion completion is acknowledged by the = guest. +# For now only emitted for SHPC and PCIe-native hotplug. +# +# Since: 8.0 +## +{ 'event': 'DEVICE_ON', 'data': 'DeviceAndPath' } diff --git a/include/hw/hotplug.h b/include/hw/hotplug.h index e15f59c8b3..b82261d91e 100644 --- a/include/hw/hotplug.h +++ b/include/hw/hotplug.h @@ -13,6 +13,7 @@ #define HOTPLUG_H =20 #include "qom/object.h" +#include "qapi/qapi-types-qdev.h" =20 #define TYPE_HOTPLUG_HANDLER "hotplug-handler" =20 @@ -58,6 +59,8 @@ struct HotplugHandlerClass { hotplug_fn plug; hotplug_fn unplug_request; hotplug_fn unplug; + HotplugInfo *(*get_hotplug_state)(HotplugHandler *plug_handler, + DeviceState *plugged_dev, Error **er= rp); }; =20 /** @@ -94,4 +97,13 @@ void hotplug_handler_unplug_request(HotplugHandler *plug= _handler, void hotplug_handler_unplug(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp); + +/** + * hotplug_handler_get_hotplug_state: + * + * Calls #HotplugHandlerClass.get_hotplug_state callback of @plug_handler. + */ +HotplugInfo *hotplug_handler_get_hotplug_state(HotplugHandler *plug_handle= r, + DeviceState *plugged_dev, + Error **errp); #endif diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index f5b3b2f89a..dc2f91a2e2 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -180,6 +180,7 @@ struct DeviceState { char *id; char *canonical_path; bool realized; + bool device_on_sent; /* set once by SHPC or PCIE-hotplug */ bool pending_deleted_event; int64_t pending_deleted_expires_ms; QDict *opts; diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h index 1d57bf6577..c1c8798e89 100644 --- a/include/monitor/qdev.h +++ b/include/monitor/qdev.h @@ -36,4 +36,6 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, */ const char *qdev_set_id(DeviceState *dev, char *id, Error **errp); =20 +void qdev_hotplug_device_on_event(DeviceState *dev); + #endif diff --git a/hw/core/hotplug.c b/hw/core/hotplug.c index 17ac986685..08d6d03760 100644 --- a/hw/core/hotplug.c +++ b/hw/core/hotplug.c @@ -57,6 +57,19 @@ void hotplug_handler_unplug(HotplugHandler *plug_handler, } } =20 +HotplugInfo *hotplug_handler_get_hotplug_state(HotplugHandler *plug_handle= r, + DeviceState *plugged_dev, + Error **errp) +{ + HotplugHandlerClass *hdc =3D HOTPLUG_HANDLER_GET_CLASS(plug_handler); + + if (hdc->get_hotplug_state) { + return hdc->get_hotplug_state(plug_handler, plugged_dev, errp); + } + + return NULL; +} + static const TypeInfo hotplug_handler_info =3D { .name =3D TYPE_HOTPLUG_HANDLER, .parent =3D TYPE_INTERFACE, diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c index b8d2c4dadd..e4956bbd94 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -25,6 +25,7 @@ #include "sysemu/arch_init.h" #include "qapi/error.h" #include "qapi/qapi-commands-qdev.h" +#include "qapi/qapi-events-qdev.h" #include "qapi/qmp/dispatch.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" @@ -956,6 +957,36 @@ void qmp_device_del(const char *id, Error **errp) } } =20 +HotplugInfo *qmp_query_hotplug(const char *id, Error **errp) +{ + DeviceState *dev =3D find_device_state(id, errp); + HotplugHandler *hotplug_ctrl; + + if (!dev) { + return NULL; + } + + if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) { + error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name); + return NULL; + } + + if (!DEVICE_GET_CLASS(dev)->hotpluggable) { + error_setg(errp, QERR_DEVICE_NO_HOTPLUG, + object_get_typename(OBJECT(dev))); + return NULL; + } + + hotplug_ctrl =3D qdev_get_hotplug_handler(dev); + /* + * hotpluggable device MUST have HotplugHandler, if it doesn't + * then something is very wrong with it. + */ + g_assert(hotplug_ctrl); + + return hotplug_handler_get_hotplug_state(hotplug_ctrl, dev, errp); +} + void hmp_device_add(Monitor *mon, const QDict *qdict) { Error *err =3D NULL; @@ -1146,3 +1177,13 @@ bool qmp_command_available(const QmpCommand *cmd, Er= ror **errp) } return true; } + +void qdev_hotplug_device_on_event(DeviceState *dev) +{ + if (dev->device_on_sent) { + return; + } + + dev->device_on_sent =3D true; + qapi_event_send_device_on(dev->id, dev->canonical_path); +} --=20 2.34.1 From nobody Wed May 1 08:33:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1678205224; cv=none; d=zohomail.com; s=zohoarc; b=eWlz4TB6iMhnDeWEkGYb8ZE7OoAfxqS8mGLMJLjzS0F9/qgQCK5qzN3zqN8UWEvz6/7/SyKrusSWOO567ZkDHeKzJBYK8FJ/2cgRDVP6zlVdLvI7UIegOKZekHeTukCM1OCOxvxQqOCKygKAqWzwbAD5syjvtq6I+gKqJIwGFQ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1678205224; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=fQc6gN4E+qeVrWzTwe7IJtiBptlNfbeb2giYA6kstIg=; b=lhvlhpFMSKPaVA0/5cx2MCe61J77/08YIV164+yaJopiWLpO0Kv6B1bEJibdGoWcoHHlBZMTcBEz/YEMdyNyWbmysJ3IbVXSK9USye7XJ7Uz56Sjr5jKVhhE+lNmlakzRQZ7JIuARs/JWOxPZaHDRA+4rHUOoeHrnRNJJzp3xP0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1678205224034681.3316450004032; Tue, 7 Mar 2023 08:07:04 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZZpC-0005Rr-GT; Tue, 07 Mar 2023 11:06:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZpA-0005Qr-Jb for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:06:01 -0500 Received: from forwardcorp1b.mail.yandex.net ([2a02:6b8:c02:900:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZp7-0002UF-6a for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:06:00 -0500 Received: from mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net [IPv6:2a02:6b8:c12:5da4:0:640:ef2d:0]) by forwardcorp1b.mail.yandex.net (Yandex) with ESMTP id D2B2E5FBF6; Tue, 7 Mar 2023 19:05:51 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:1223::1:36]) by mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id d5eRk00OeKo0-k0D133I1; Tue, 07 Mar 2023 19:05:50 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1678205150; bh=fQc6gN4E+qeVrWzTwe7IJtiBptlNfbeb2giYA6kstIg=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=Ec7UNSVcXv0wM/otp4IOOoXgIKFeQ+hg6FFONZeXkRstlb9myw8pqrVq8xiMetmCG mvyWPepCSQsFtf9mKiH3x2aDecaKIaHeCJnQ9rzrrJGN5jjJP75FO/aIaH65HzVBEC YzzqAiv0ettBC1xVtQAf5ofL2XjLMgDzPi328RtU= Authentication-Results: mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net; dkim=pass header.i=@yandex-team.ru From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Cc: armbru@redhat.com, eblake@redhat.com, eduardo@habkost.net, berrange@redhat.com, pbonzini@redhat.com, marcel.apfelbaum@gmail.com, mst@redhat.com, den-plotnikov@yandex-team.ru, antonkuchin@yandex-team.ru, vsementsov@yandex-team.ru, philmd@linaro.org Subject: [PATCH v6 3/4] shpc: implement DEVICE_ON event and query-hotplug Date: Tue, 7 Mar 2023 19:05:36 +0300 Message-Id: <20230307160537.2261803-4-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230307160537.2261803-1-vsementsov@yandex-team.ru> References: <20230307160537.2261803-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a02:6b8:c02:900:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1b.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1678205225731100002 Content-Type: text/plain; charset="utf-8" For PCIe and SHPC hotplug it's important to track led indicators and "device-on" status. At this step, implement the prepared infrastructure in SHPC. Signed-off-by: Vladimir Sementsov-Ogievskiy --- include/hw/pci/pci_bridge.h | 2 + include/hw/pci/shpc.h | 2 + include/monitor/qdev.h | 4 ++ hw/pci-bridge/pci_bridge_dev.c | 14 ++++++ hw/pci-bridge/pcie_pci_bridge.c | 1 + hw/pci/shpc.c | 86 +++++++++++++++++++++++++++++++++ softmmu/qdev-monitor.c | 17 +++++++ 7 files changed, 126 insertions(+) diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h index 63a7521567..b8cb86a6f7 100644 --- a/include/hw/pci/pci_bridge.h +++ b/include/hw/pci/pci_bridge.h @@ -126,6 +126,8 @@ void pci_bridge_dev_unplug_cb(HotplugHandler *hotplug_d= ev, DeviceState *dev, Error **errp); void pci_bridge_dev_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); +HotplugInfo *pci_bridge_dev_get_hotplug_state(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **er= rp); =20 /* * before qdev initialization(qdev_init()), this function sets bus_name and diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h index 89c7a3b7fa..bf722ce65d 100644 --- a/include/hw/pci/shpc.h +++ b/include/hw/pci/shpc.h @@ -51,6 +51,8 @@ void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, D= eviceState *dev, Error **errp); void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); +HotplugInfo *shpc_get_hotplug_state(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp); =20 extern VMStateInfo shpc_vmstate_info; #define SHPC_VMSTATE(_field, _type, _test) \ diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h index c1c8798e89..949a3672cb 100644 --- a/include/monitor/qdev.h +++ b/include/monitor/qdev.h @@ -1,6 +1,8 @@ #ifndef MONITOR_QDEV_H #define MONITOR_QDEV_H =20 +#include "qapi/qapi-types-qdev.h" + /*** monitor commands ***/ =20 void hmp_info_qtree(Monitor *mon, const QDict *qdict); @@ -38,4 +40,6 @@ const char *qdev_set_id(DeviceState *dev, char *id, Error= **errp); =20 void qdev_hotplug_device_on_event(DeviceState *dev); =20 +DeviceAndPath *qdev_new_device_and_path(DeviceState *dev); + #endif diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 4b2696ea7f..69ffe93e2a 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -241,6 +241,19 @@ void pci_bridge_dev_unplug_request_cb(HotplugHandler *= hotplug_dev, shpc_device_unplug_request_cb(hotplug_dev, dev, errp); } =20 +HotplugInfo *pci_bridge_dev_get_hotplug_state(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **er= rp) +{ + PCIDevice *pci_hotplug_dev =3D PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled fo= r " + "this %s", object_get_typename(OBJECT(hotplug_dev))); + return NULL; + } + return shpc_get_hotplug_state(hotplug_dev, dev, errp); +} + static void pci_bridge_dev_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -261,6 +274,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klas= s, void *data) hc->plug =3D pci_bridge_dev_plug_cb; hc->unplug =3D pci_bridge_dev_unplug_cb; hc->unplug_request =3D pci_bridge_dev_unplug_request_cb; + hc->get_hotplug_state =3D pci_bridge_dev_get_hotplug_state; } =20 static const TypeInfo pci_bridge_dev_info =3D { diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridg= e.c index 2301b2ca0b..959b536303 100644 --- a/hw/pci-bridge/pcie_pci_bridge.c +++ b/hw/pci-bridge/pcie_pci_bridge.c @@ -157,6 +157,7 @@ static void pcie_pci_bridge_class_init(ObjectClass *kla= ss, void *data) hc->plug =3D pci_bridge_dev_plug_cb; hc->unplug =3D pci_bridge_dev_unplug_cb; hc->unplug_request =3D pci_bridge_dev_unplug_request_cb; + hc->get_hotplug_state =3D pci_bridge_dev_get_hotplug_state; } =20 static const TypeInfo pcie_pci_bridge_info =3D { diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index e7bc7192f1..af2c49ee44 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -8,6 +8,9 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" #include "hw/pci/msi.h" +#include "qapi/qapi-types-qdev.h" +#include "qapi/qapi-events-qdev.h" +#include "monitor/qdev.h" =20 /* TODO: model power only and disabled slot states. */ /* TODO: handle SERR and wakeups */ @@ -123,6 +126,39 @@ #define SHPC_PCI_TO_IDX(pci_slot) ((pci_slot) - 1) #define SHPC_IDX_TO_PHYSICAL(slot) ((slot) + 1) =20 +static char *shpc_idx_to_pci_addr(int slot) +{ + return g_strdup_printf("%d", SHPC_IDX_TO_PCI(slot)); +} + +static LedActivity shpc_led_state_to_qapi(uint8_t value) +{ + switch (value) { + case SHPC_LED_ON: + return LED_ACTIVITY_ON; + case SHPC_LED_BLINK: + return LED_ACTIVITY_BLINK; + case SHPC_LED_OFF: + return LED_ACTIVITY_OFF; + default: + abort(); + } +} + +static HotplugSHPCSlotState shpc_slot_state_to_qapi(uint8_t value) +{ + switch (value) { + case SHPC_STATE_PWRONLY: + return HOTPLUGSHPC_SLOT_STATE_POWER_ONLY; + case SHPC_STATE_ENABLED: + return HOTPLUGSHPC_SLOT_STATE_ENABLED; + case SHPC_STATE_DISABLED: + return HOTPLUGSHPC_SLOT_STATE_DISABLED; + default: + abort(); + } +} + static uint8_t shpc_get_status(SHPCDevice *shpc, int slot, uint16_t msk) { uint8_t *status =3D shpc->config + SHPC_SLOT_STATUS(slot); @@ -263,14 +299,23 @@ static bool shpc_slot_is_off(uint8_t state, uint8_t p= ower, uint8_t attn) return state =3D=3D SHPC_STATE_DISABLED && power =3D=3D SHPC_LED_OFF; } =20 +static bool shpc_slot_is_on(uint8_t state, uint8_t power, uint8_t attn) +{ + return state =3D=3D SHPC_STATE_ENABLED && power =3D=3D SHPC_LED_ON && + attn =3D=3D SHPC_LED_OFF; +} + static void shpc_slot_command(PCIDevice *d, uint8_t target, uint8_t state, uint8_t power, uint8_t attn) { SHPCDevice *shpc =3D d->shpc; int slot =3D SHPC_LOGICAL_TO_IDX(target); + int pci_slot =3D SHPC_IDX_TO_PCI(slot); uint8_t old_state =3D shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK= ); uint8_t old_power =3D shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MA= SK); uint8_t old_attn =3D shpc_get_status(shpc, slot, SHPC_SLOT_ATTN_LED_MA= SK); + DeviceState *child_dev =3D + DEVICE(shpc->sec_bus->devices[PCI_DEVFN(pci_slot, 0)]); =20 if (target < SHPC_CMD_TRGT_MIN || slot >=3D shpc->nslots) { shpc_invalid_command(shpc); @@ -313,6 +358,12 @@ static void shpc_slot_command(PCIDevice *d, uint8_t ta= rget, SHPC_SLOT_EVENT_MRL | SHPC_SLOT_EVENT_PRESENCE; } + + if (!shpc_slot_is_on(old_state, old_power, old_attn) && + shpc_slot_is_on(state, power, attn) && child_dev) + { + qdev_hotplug_device_on_event(child_dev); + } } =20 static void shpc_command(PCIDevice *d) @@ -713,6 +764,41 @@ void shpc_cap_write_config(PCIDevice *d, uint32_t addr= , uint32_t val, int l) shpc_cap_update_dword(d); } =20 +HotplugInfo *shpc_get_hotplug_state(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + PCIDevice *pci_hotplug_dev =3D PCI_DEVICE(hotplug_dev); + SHPCDevice *shpc =3D pci_hotplug_dev->shpc; + int slot; + uint8_t state, power, attn; + HotplugInfo *res; + + if (!shpc_device_get_slot(PCI_DEVICE(dev), &slot, shpc, errp)) { + return NULL; + } + + state =3D shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK); + power =3D shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK); + attn =3D shpc_get_status(shpc, slot, SHPC_SLOT_ATTN_LED_MASK); + + res =3D g_new(HotplugInfo, 1); + *res =3D (HotplugInfo) { + .bus =3D qdev_new_device_and_path(DEVICE(pci_hotplug_dev)), + .addr =3D shpc_idx_to_pci_addr(slot), + .child =3D qdev_new_device_and_path(dev), + .type =3D HOTPLUG_TYPE_SHPC, + .device_on =3D dev->device_on_sent, + .u.shpc.has_power_led =3D true, + .u.shpc.power_led =3D shpc_led_state_to_qapi(power), + .u.shpc.has_attention_led =3D true, + .u.shpc.attention_led =3D shpc_led_state_to_qapi(attn), + .u.shpc.has_slot_state =3D true, + .u.shpc.slot_state =3D shpc_slot_state_to_qapi(state), + }; + + return res; +} + static int shpc_save(QEMUFile *f, void *pv, size_t size, const VMStateField *field, JSONWriter *vmdesc) { diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c index e4956bbd94..814d8260d7 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -1178,6 +1178,23 @@ bool qmp_command_available(const QmpCommand *cmd, Er= ror **errp) return true; } =20 +DeviceAndPath *qdev_new_device_and_path(DeviceState *dev) +{ + DeviceAndPath *res; + + if (!dev) { + return NULL; + } + + res =3D g_new(DeviceAndPath, 1); + *res =3D (DeviceAndPath) { + .device =3D g_strdup(dev->id), + .path =3D g_strdup(dev->canonical_path), + }; + + return res; +} + void qdev_hotplug_device_on_event(DeviceState *dev) { if (dev->device_on_sent) { --=20 2.34.1 From nobody Wed May 1 08:33:32 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=yandex-team.ru ARC-Seal: i=1; a=rsa-sha256; t=1678205203; cv=none; d=zohomail.com; s=zohoarc; b=IcEREHUy7uXB/+2bBbSq5Eev52zp29eo7Wxeegn9TSFYt2HoBsrZ/XZH7LneMKzm7OXewclV36CT2LDWP5nqro5xVjDgHoTUKc+yjyGnVJVgoaHEspF5lTQVBJkzykbyTa7fk7D3rEzf5zGYo53PzwAvYjTSMOmTYqlPFxn+itc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1678205203; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=gW/0JMJLXFZEHFqHTlYTalR4SChAVsIvTrcNaeJnXVU=; b=i9h1h2f1xVZzqKfs47+CEhPo3I/BZLrto1uYgfA98GGH8rdk+dBRwSZKiRMgn0TWvLfm5VuNDOMmsWzfxLQ9tIy7eYjbPDJyq5KE9WRn+Z4GhStWmWLK1dDRWxVkP/K2zwqnCg7e6HlDUzgjbLKfYwrfrM05mPnqF5fA1nY3H4g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1678205203520564.6554018481113; Tue, 7 Mar 2023 08:06:43 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pZZpB-0005RY-W5; Tue, 07 Mar 2023 11:06:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZpA-0005Qs-Jj for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:06:01 -0500 Received: from forwardcorp1c.mail.yandex.net ([2a02:6b8:c03:500:1:45:d181:df01]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pZZp8-0002UK-G3 for qemu-devel@nongnu.org; Tue, 07 Mar 2023 11:06:00 -0500 Received: from mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net [IPv6:2a02:6b8:c12:5da4:0:640:ef2d:0]) by forwardcorp1c.mail.yandex.net (Yandex) with ESMTP id 143C55E5C0; Tue, 7 Mar 2023 19:05:53 +0300 (MSK) Received: from vsementsov-win.yandex-team.ru (unknown [2a02:6b8:b081:1223::1:36]) by mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id d5eRk00OeKo0-VB7GE4BT; Tue, 07 Mar 2023 19:05:52 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1678205152; bh=gW/0JMJLXFZEHFqHTlYTalR4SChAVsIvTrcNaeJnXVU=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=Qc8c84BKY/7OnIj1upI5uZNl98UEkW/NzcEIqdW5H+FaprlrR8Eix9l6OSow3PNhZ oXD2EdbmoUduYr5WR+4Tff6JDqsiFleZQ6AFxDxI764ZHxN3r5VzkuHhx05cI5rCnu cu7xkhy9W9UQ0ZL6P4FZ5sTEmYUX6AjRWuNpxDeE= Authentication-Results: mail-nwsmtp-smtp-corp-main-26.myt.yp-c.yandex.net; dkim=pass header.i=@yandex-team.ru From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org Cc: armbru@redhat.com, eblake@redhat.com, eduardo@habkost.net, berrange@redhat.com, pbonzini@redhat.com, marcel.apfelbaum@gmail.com, mst@redhat.com, den-plotnikov@yandex-team.ru, antonkuchin@yandex-team.ru, vsementsov@yandex-team.ru, philmd@linaro.org Subject: [PATCH v6 4/4] pcie: implement DEVICE_ON event and query-hotplug Date: Tue, 7 Mar 2023 19:05:37 +0300 Message-Id: <20230307160537.2261803-5-vsementsov@yandex-team.ru> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230307160537.2261803-1-vsementsov@yandex-team.ru> References: <20230307160537.2261803-1-vsementsov@yandex-team.ru> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a02:6b8:c03:500:1:45:d181:df01; envelope-from=vsementsov@yandex-team.ru; helo=forwardcorp1c.mail.yandex.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yandex-team.ru) X-ZM-MESSAGEID: 1678205205817100001 Content-Type: text/plain; charset="utf-8" For PCIe and SHPC hotplug it's important to track led indicators and "device-on" status. At this step implement the prepared infrastructure in PCIe. Signed-off-by: Vladimir Sementsov-Ogievskiy --- include/hw/pci/pcie.h | 2 ++ hw/pci/pcie.c | 83 +++++++++++++++++++++++++++++++++++++++++++ hw/pci/pcie_port.c | 1 + 3 files changed, 86 insertions(+) diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index 3cc2b15957..f755a7cacb 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -146,4 +146,6 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_de= v, DeviceState *dev, Error **errp); void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); +HotplugInfo *pcie_cap_slot_get_hotplug_state(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **err= p); #endif /* QEMU_PCIE_H */ diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index b8c24cf45f..a47c95e4b2 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -19,7 +19,10 @@ */ =20 #include "qemu/osdep.h" + +#include "monitor/qdev.h" #include "qapi/error.h" +#include "qapi/qapi-events-qdev.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pcie.h" #include "hw/pci/msix.h" @@ -45,6 +48,30 @@ static bool pcie_sltctl_powered_off(uint16_t sltctl) && (sltctl & PCI_EXP_SLTCTL_PIC) =3D=3D PCI_EXP_SLTCTL_PWR_IND_OFF; } =20 +static bool pcie_sltctl_powered_on(uint16_t sltctl) +{ + return (sltctl & PCI_EXP_SLTCTL_PCC) =3D=3D PCI_EXP_SLTCTL_PWR_ON && + (sltctl & PCI_EXP_SLTCTL_PIC) =3D=3D PCI_EXP_SLTCTL_PWR_IND_ON && + (sltctl & PCI_EXP_SLTCTL_AIC) =3D=3D PCI_EXP_SLTCTL_ATTN_IND_OFF; +} + +static LedActivity pcie_led_state_to_qapi(uint16_t value) +{ + switch (value) { + case PCI_EXP_SLTCTL_PWR_IND_ON: + case PCI_EXP_SLTCTL_ATTN_IND_ON: + return LED_ACTIVITY_ON; + case PCI_EXP_SLTCTL_PWR_IND_BLINK: + case PCI_EXP_SLTCTL_ATTN_IND_BLINK: + return LED_ACTIVITY_BLINK; + case PCI_EXP_SLTCTL_PWR_IND_OFF: + case PCI_EXP_SLTCTL_ATTN_IND_OFF: + return LED_ACTIVITY_OFF; + default: + abort(); + } +} + /*************************************************************************= ** * pci express capability helper functions */ @@ -724,6 +751,28 @@ void pcie_cap_slot_get(PCIDevice *dev, uint16_t *slt_c= tl, uint16_t *slt_sta) *slt_sta =3D pci_get_word(exp_cap + PCI_EXP_SLTSTA); } =20 +static void find_child_fn(PCIBus *bus, PCIDevice *dev, void *opaque) +{ + PCIDevice **child =3D opaque; + + if (!*child) { + *child =3D dev; + } +} + +/* + * Returns the plugged device or first function of multifunction plugged d= evice + */ +static PCIDevice *pcie_cap_slot_find_child(PCIDevice *dev) +{ + PCIBus *sec_bus =3D pci_bridge_get_sec_bus(PCI_BRIDGE(dev)); + PCIDevice *child =3D NULL; + + pci_for_each_device(sec_bus, pci_bus_num(sec_bus), find_child_fn, &chi= ld); + + return child; +} + void pcie_cap_slot_write_config(PCIDevice *dev, uint16_t old_slt_ctl, uint16_t old_slt_sta, uint32_t addr, uint32_t val, int len) @@ -731,6 +780,7 @@ void pcie_cap_slot_write_config(PCIDevice *dev, uint32_t pos =3D dev->exp.exp_cap; uint8_t *exp_cap =3D dev->config + pos; uint16_t sltsta =3D pci_get_word(exp_cap + PCI_EXP_SLTSTA); + DeviceState *child_dev =3D DEVICE(pcie_cap_slot_find_child(dev)); =20 if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) { /* @@ -768,6 +818,12 @@ void pcie_cap_slot_write_config(PCIDevice *dev, sltsta); } =20 + if ((sltsta & PCI_EXP_SLTSTA_PDS) && pcie_sltctl_powered_on(val) && + !pcie_sltctl_powered_on(old_slt_ctl) && child_dev) + { + qdev_hotplug_device_on_event(child_dev); + } + /* * If the slot is populated, power indicator is off and power * controller is off, it is safe to detach the devices. @@ -1100,3 +1156,30 @@ void pcie_acs_reset(PCIDevice *dev) pci_set_word(dev->config + dev->exp.acs_cap + PCI_ACS_CTRL, 0); } } + +HotplugInfo *pcie_cap_slot_get_hotplug_state(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **err= p) +{ + PCIDevice *hotplug_pdev =3D PCI_DEVICE(hotplug_dev); + uint8_t *exp_cap =3D hotplug_pdev->config + hotplug_pdev->exp.exp_cap; + uint16_t sltctl =3D pci_get_word(exp_cap + PCI_EXP_SLTCTL); + uint16_t power_led =3D sltctl & PCI_EXP_SLTCTL_PIC; + uint16_t attn_led =3D sltctl & PCI_EXP_SLTCTL_AIC; + uint16_t pcc =3D sltctl & PCI_EXP_SLTCTL_PCC; + HotplugInfo *res =3D g_new(HotplugInfo, 1); + + *res =3D (HotplugInfo) { + .type =3D HOTPLUG_TYPE_PCIE_NATIVE, + .bus =3D qdev_new_device_and_path(DEVICE(hotplug_pdev)), + .child =3D qdev_new_device_and_path(dev), + .device_on =3D dev->device_on_sent, + .u.pcie_native.has_power_led =3D true, + .u.pcie_native.power_led =3D pcie_led_state_to_qapi(power_led), + .u.pcie_native.has_attention_led =3D true, + .u.pcie_native.attention_led =3D pcie_led_state_to_qapi(attn_led), + .u.pcie_native.has_power_on =3D true, + .u.pcie_native.power_on =3D pcc =3D=3D PCI_EXP_SLTCTL_PWR_ON, + }; + + return res; +} diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c index 65a397ad23..8b28efc52d 100644 --- a/hw/pci/pcie_port.c +++ b/hw/pci/pcie_port.c @@ -188,6 +188,7 @@ static void pcie_slot_class_init(ObjectClass *oc, void = *data) hc->plug =3D pcie_cap_slot_plug_cb; hc->unplug =3D pcie_cap_slot_unplug_cb; hc->unplug_request =3D pcie_cap_slot_unplug_request_cb; + hc->get_hotplug_state =3D pcie_cap_slot_get_hotplug_state; } =20 static const TypeInfo pcie_slot_type_info =3D { --=20 2.34.1