From nobody Wed Nov 5 22:43:06 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1537520537671114.59355074955863; Fri, 21 Sep 2018 02:02:17 -0700 (PDT) Received: from localhost ([::1]:54627 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g3HKK-0003AW-41 for importer@patchew.org; Fri, 21 Sep 2018 05:02:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49116) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g3Gi3-0006rF-ER for qemu-devel@nongnu.org; Fri, 21 Sep 2018 04:22:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g3Gi0-00029l-4B for qemu-devel@nongnu.org; Fri, 21 Sep 2018 04:22:43 -0400 Received: from mail-eopbgr70091.outbound.protection.outlook.com ([40.107.7.91]:35048 helo=EUR04-HE1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g3Ghz-00027r-Je for qemu-devel@nongnu.org; Fri, 21 Sep 2018 04:22:40 -0400 Received: from rkaganb.sw.ru (185.231.240.5) by AM0PR08MB3588.eurprd08.prod.outlook.com (2603:10a6:208:e1::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1143.18; Fri, 21 Sep 2018 08:22:36 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=h1TF3puJSDhV4pijmNyVfa1Qzqz5IWEO/QCphaTlqic=; b=iQKE+zrDm/fUwuPZXKxYAA++TxJ+9Y3YyJL0eXK5zFeAI0S6tiJMOF99PHNoULB90AY3ehNXf7qpjIuh8ZM3AjRpzuz9YHuN5lIc4cgOLANwwgEY6LnAh48zkZuy5Djlzx03ARvFPMBn0II5zaEOiB03is5vIg1VCWSBeOiWH9U= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=rkagan@virtuozzo.com; From: Roman Kagan To: qemu-devel@nongnu.org Date: Fri, 21 Sep 2018 11:22:12 +0300 Message-Id: <20180921082217.29481-6-rkagan@virtuozzo.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180921082217.29481-1-rkagan@virtuozzo.com> References: <20180921082217.29481-1-rkagan@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [185.231.240.5] X-ClientProxiedBy: VI1P193CA0003.EURP193.PROD.OUTLOOK.COM (2603:10a6:800:bd::13) To AM0PR08MB3588.eurprd08.prod.outlook.com (2603:10a6:208:e1::30) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 3a02a6a1-074b-4c23-3f59-08d61f9b63b4 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:AM0PR08MB3588; X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3588; 3:GcISga/XmIBueht9pv3lQhoVfY4sY8CNrFtEe4L0xmTPdWLfPJnu8+xEaK4MIitEZOnfhCKBygftXR+tT+fBTHFk9wCy+VMfZqtLeQaSunmSieqFMMWx/hFmkpEe4bEXc0fm8lrnxDmIvuvNOlTSbVl5mdv9frPp21EmkKYEU6DBJlYbnBzeL+788I3C3MZGKyjrGyFF4R6n8nBVxEzrr4UN5v/7eVjadCFD4lvaxITqLAgfGgdMYnxqsI1pe+gQ; 25:0wFBoz1mX+EIXyEmgw8ZI7vHzsDZcCBU0XhNOxkf7pUdMzXhnppsZe/mJCYqVSLY5Tdp/AqwEH+omLfyy/XmtayQZSMcKFs8bECw1R2SiaxHp//fRNFpYFaFtGQmeFci5mjDglZeBSAZ3HExXl/VdjgVrXnzoyKmI0ym5fCYzF8hibaCwr0xuiSEUJiEqh6MsOumk0qnrLNSo1hmUakeH3mFd9mLpR+Rndscbaf87hyZ6u8bk4V9RdiMijk+N86x4W1MCctISvrwPAGr+zSniiJJnSsHpo+NAbDA/P4+wgi1fa15mH50N+/HaWVPY2WMhsmwIHf1BJBWWjb3ZOcgPg==; 31:96kQDGZy0nrmMz8tuoPdApXR7qv8Ln0CY1kPoVsfQvBFoTCE/cnoLI9xJ0ffBBp8PgQ7q2PcfH7Y37Wcf2oE/BU/CfBzhPFAWt9mSZV3qJt124jPCc32/j9Q6+cwz+1BBZ/tRW17LZC/MuG8eSd9UW1xK1d6bhN7lDXwL5Lomg/ZKc7o8nkbhxYxMEzwe3Z4EncH9QdaLThoHDExeWo7gsuuH0uobY3LIm9eMzWqwbA= X-MS-TrafficTypeDiagnostic: AM0PR08MB3588: X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3588; 20:rFI6jqVzfCzDBvLfEEhne/tCGQ+bp2YwVwAMrE/lxkMCUFJnU8ZdCs2lUGL4sHNxBQaTBnZDAWSKdcgjB3gZ+Yoo0pWj3I/2KGDn4k3Mf2fmQALhx615mZPo6UbJRzg6g7Du6xUBI2VPHPGYUz00s+dPVUDPNHrQ9rOEI14KIceENYTnOAHceuZ5JjsVPnJl1TsRtfBgOg4CFmgDhfVHOJsGEMxDiHHhSO6uDAY2Og0ASZlJB4tjmqLJLTT3Vv3aUx9ODKHzgHyutCNyEUfMY/V4zdl7X7hv/6RXI+Q5lkM/k5wkIsiFfVGLZeUOd7rLVq35bw9nLMxjprCCDu+0cd21BPRhb6P+iN13ZJck6YlTpT+Ohs4H2XO6XchNwcgPhVyVqvcEs2uqWKqWB+o/kDqwPRbG3OjQvA4kKIvB2oBYNshhtuGUYcj+vlgSF5QMMHcYwArYqM2eV7/H9gm6wZqw8DcqQTOxLhbc2+HjqWe4gfA/PiaNQ7c6aJuUFJmR; 4:2iGG3Eump7ysLIjxLL7yV/FemuyeklXqEeKKsprtmTkTxclkvzitJ4cjVW9Y6Pd4NnJNdQnuBHyVTzC07CSmYk14p/rAZjivrR7YC0Dgb+AioC1XOX9Z0PL9GK//LWofGTV3yO8s5AgJP7PvmSOzARIFYnyLudC7IadCZ4EJFwJvVmJQKkIu3Og3fwdt9lGVCqzhC+3cPebA9He3UYyFO4YftDhOoOLdXvBR91ou+xqqN6MRxcPpICPSG+FvjJNCN4SxYyun62d9LCfPBJ9blg== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3231355)(944501410)(52105095)(10201501046)(3002001)(149027)(150027)(6041310)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123560045)(20161123564045)(201708071742011)(7699051); SRVR:AM0PR08MB3588; BCL:0; PCL:0; RULEID:; SRVR:AM0PR08MB3588; X-Forefront-PRVS: 0802ADD973 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(136003)(396003)(39850400004)(366004)(376002)(189003)(199004)(6916009)(16526019)(5660300001)(36756003)(3846002)(54906003)(48376002)(6506007)(476003)(486006)(14444005)(52116002)(446003)(1076002)(76176011)(386003)(51416003)(186003)(6116002)(16586007)(15650500001)(2906002)(66066001)(6512007)(7416002)(50226002)(53936002)(25786009)(106356001)(53416004)(81166006)(47776003)(316002)(956004)(11346002)(2616005)(7736002)(8936002)(305945005)(8676002)(2351001)(105586002)(97736004)(4326008)(86362001)(6666003)(68736007)(478600001)(6486002)(2361001)(50466002)(26005)(69596002)(81156014); DIR:OUT; SFP:1102; SCL:1; SRVR:AM0PR08MB3588; H:rkaganb.sw.ru; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR08MB3588; 23:g0nYmrljPNIj88b4QMEMFfBZkSO5FMfhQds5CDTWW?= =?us-ascii?Q?myWp0Uajfe0BTrfJGDyBmlxwZ9GR7fVpdlLuRLhYRWEil9mcY3jnEebS43Ug?= =?us-ascii?Q?POWaujLqBuOFdgA3gOeINUI9+AwRcuLALi1EfYqgk9bH0YlSfNdtJQ2mllrt?= =?us-ascii?Q?L1SNiaBjHyoDokqMZq4I8ZN0OLidqG8/IFDQEhATAxn1st7iaKjOz6Z4hTBs?= =?us-ascii?Q?pLKu8n3Rx+fJItxXb2Xyyu8vJPBs2Y2ptSO7AU1EKLp/2obRVjXbRBKAPO8U?= =?us-ascii?Q?67gNIjP/UqcApZsNnHAEtrxaAMRYUSL9i7ggxlfjS1n0FcM66YSIN9At6bAg?= =?us-ascii?Q?dTioB2jGYjZD7aKS5MQqUL76e5UD5RUsVFNQpZ/aleI/uwaLi3Vnwtu6aAPp?= =?us-ascii?Q?9DjJ2dk5GW56it7ZE4g3BLgwKtEQN2bv1OZTd1B2r3eLoEbWkMzr5WdLusxz?= =?us-ascii?Q?pcyT91WyaVpoqjnBsqsS5rnSPQj9Y/f7i4MFNk/SYrlM29mibZ76vvL8Q3x0?= =?us-ascii?Q?yxq6OOHJITAMKiMd0Nngsjd/nz4xm57qW22fnMB5eMAQwUAMDmrVHOh4crUQ?= =?us-ascii?Q?uTXdzyMcPfDm+o691jg/bR26LmbDOFp1taUd46bJVrjqOUzZcstPOlC1r05b?= =?us-ascii?Q?Y7Tlpt3mVoHPPBMhP7pdK7hSeoG1VyeUMUDz7FjzyHpYWrs/QB6+c96uuCsg?= =?us-ascii?Q?BS8bELqpRj0ElNf7tT7NVl8+CNsduxRqlZIb4NG1d92JneV5PRVfLUbPcQnt?= =?us-ascii?Q?9ulOwTsiRw/yW6j65CpXkbiacpR67DzAlfpCuHXBEmVB8qpAVo34F57HfS1v?= =?us-ascii?Q?zQ1BzJfbj2koNWMGX2xRH+u8zd0M2Kdtp/fNQKvFDXuhN6VFOJiux0QMTZK9?= =?us-ascii?Q?aM7lU4zIieqUtsiRdiR8uh82mX+DLzGo5lKBP0QZcN1bkQCy+Rej706KBh2y?= =?us-ascii?Q?jBa0sU/zw0TV/+UW01MLTUtffA+R3EPASxAgHVjVbYDGR7L4BYWSM/NPIDZX?= =?us-ascii?Q?+O/CEWZtDgoN9a+h5sGiuS+BV6ba59CfS6OnhhOfMtYVGLs0PXbhOaseHx8e?= =?us-ascii?Q?aS+4+MI6CH2USn0SNnx+psTD6lghEGfeJIcwOEsuTqaOtF26GwiDnR/hckbU?= =?us-ascii?Q?0+9/GStsFE1axMppAPEuLb/MTcv8kynG+Lgk4bYZxjx3X0PT5H7cnk+R07/a?= =?us-ascii?Q?wT3ofzXNKqWbEJ4OPJW3UCJITQFVZhm7HeRRWfjY9HwvPP58qIz9T1yX/A46?= =?us-ascii?Q?/0b/8kqGxUp5za9VZRf+ZCC+uTJ7ET26TIZuo1BazhbtD4jSYrfYeeJJoGw7?= =?us-ascii?Q?UU+2gGlIvkPZyHUxG5lcyyIhLSHH57gBgEDS3u7MGVGBpFNgR0fgtaLWWeJR?= =?us-ascii?Q?EZRpg=3D=3D?= X-Microsoft-Antispam-Message-Info: e8R9F/OQOUMomL/MtLZ+r45jpgF8lnqGb+q7bHJwBqe1/lHrCgkTQVSV0AEbIL2c5v1iwGcEyDBscbn4ZD36v4mK9vvLCaEE7xm3B/jjLpmkM4l2cEjie9e0WAq7OPv6UxZFe2NXi1fs0PCBbrqhOjRMfrWKbTdyXEjNbqNK3BCM8/X1o0HkLrxmk+T3nUvpx7EhAb7rAf7yEAdm9T8r+uqhnFnwfd4rZ3/bj1GxTCnnpfCyWP91N+4PuTmlFLFFwe43Rgq5eYswLtEkoEMYR35AjhsW95fOgNhz/BI+aPkJuQFrFHHpeQpLJkZv03DBJWwDOko8ppJxQMK6tYG/ab0mJUSa5A2UypzBKmshxQw= X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3588; 6:caqV4X7bfnCA5MNDBEgvX4QtCqqTD5bjexW0ZFFHB4F/F9VqfEX4iqL06TOpfciEwDoYzr+Dc39YfKP4Pk6u80DVgRvTJA+3lkHDTjko5qkwTnR+J3kJw8FF82WrPI/8BPBLcKuc31QzgvXo002OgyuvmcZvGfn8oP5oZlqD3kpQGWQ1/o9e5gxjtgLbT60t1flgQBztO7TfcPRa8aydFcTrSPIN1akuZyNUeZYG4Tiubel3NxuILvesfrxXDgJKVZXO5ZZRN0J7GPOLixtHIivJtsEUxm4iCvhWSMMj7ehgdmxjMdao0WEL+z20VayXB1H2B/wgzE8ZanfMCush77lupkT5dSwqs45oxkpq8DIdV30MI21MQr9RgNjjAzRu/6Z7nd5RY/taefmMYu9ROok+0CzAQO8uGzpwXs0fw6IBAhJsr/7VVlUydph6IEsxwquZzoqOQsjgm3tLyr2LDA==; 5:viSTLAOQ3mmbrMfkUzbIzmqdX8RTITKsZraxMmlT3vh7tZzKMP9jwS50BqRjNyDjnztB0pkhskP2hwviCAfHmjtnojjnnmw25QPy0nDz88ZXILCBRqiEPQ6Agi2A+4uWcwKumjAR79+248Hrl23l5eicI5B7PEJuFI3aGBgQP6c=; 7:BqEubzjP2c9YhSJ37mx1mfRP6Hp00C8b+HrtOiwy0dAH+CLizr2rLXGGmlmDUVJ+KqVbYZu5TKtpdQsF0CBkwiRKV6oek5Yi+jb7m9W4waCrX/GwDXVKY89QZIgOaueUDD9/0rGZPSOilu44nfg6gXI00h0j3TjB/V6o/naA6D34SR9Iap38c72D7eeu/DjWt/7MNpQNoLRYwHNyMtin3KaPGSaSdyNr8f7adhvCDsCXAwYDnJ12ldJeCP7UBeVo SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3588; 20:8nSftaQ6AjNqfLEgrU6T+QtVDVNw6xncmLWm57rFVciyCs6DfCCykvqbyeQtwTgA5SdoL8NMABXHthbgDxQ4jZ+MbZe4QUkxc/6RF75QpcghNr1105ioUyL0wyMkHtcOm1eQ3SehPBi3COnWXSBkOGSPlg/CB6vegrcchIMX+Is= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2018 08:22:36.1563 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3a02a6a1-074b-4c23-3f59-08d61f9b63b4 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR08MB3588 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 40.107.7.91 Subject: [Qemu-devel] [PATCH 05/10] hyperv: add synic message delivery X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vijayabhaskar Balakrishna , Eduardo Habkost , Konrad Rzeszutek Wilk , "Michael S. Tsirkin" , Venu Busireddy , Liran Alon , Paolo Bonzini , Si-Wei Liu , Igor Mammedov , Boris Ostrovsky , Karl Heubaum Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add infrastructure to deliver SynIC messages to the SynIC message page. Note that KVM may also want to deliver (SynIC timer) messages to the same message slot. The problem is that the access to a SynIC message slot is controlled by the value of its .msg_type field which indicates if the slot is being owned by the hypervisor (zero) or by the guest (non-zero). This leaves no room for synchronizing multiple concurrent producers. The simplest way to deal with this for both KVM and QEMU is to only deliver messages in the vcpu thread. KVM already does this; this patch makes it for QEMU, too. Specifically, - add a function for posting messages, which only copies the message into the staging buffer if its free, and schedules a work on the corresponding vcpu to actually deliver it to the guest slot; - instead of a sint ack callback, set up the sint route with a message status callback. This function is called in a bh whenever there are updates to the message slot status: either the vcpu made definitive progress delivering the message from the staging buffer (succeeded or failed) or the guest issued EOM; the status is passed as an argument to the callback. Signed-off-by: Roman Kagan --- include/hw/hyperv/hyperv.h | 18 ++++- hw/hyperv/hyperv.c | 162 ++++++++++++++++++++++++++++++++++--- 2 files changed, 166 insertions(+), 14 deletions(-) diff --git a/include/hw/hyperv/hyperv.h b/include/hw/hyperv/hyperv.h index 6fba4762c8..82d561fc88 100644 --- a/include/hw/hyperv/hyperv.h +++ b/include/hw/hyperv/hyperv.h @@ -11,18 +11,30 @@ #define HW_HYPERV_HYPERV_H =20 #include "cpu-qom.h" +#include "hw/hyperv/hyperv-proto.h" =20 typedef struct HvSintRoute HvSintRoute; -typedef void (*HvSintAckClb)(void *data); + +/* + * Callback executed in a bottom-half when the status of posting the messa= ge + * becomes known, before unblocking the connection for further messages + */ +typedef void (*HvSintMsgCb)(void *data, int status); =20 HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint, - HvSintAckClb sint_ack_clb, - void *sint_ack_clb_data); + HvSintMsgCb cb, void *cb_data); void hyperv_sint_route_ref(HvSintRoute *sint_route); void hyperv_sint_route_unref(HvSintRoute *sint_route); =20 int hyperv_sint_route_set_sint(HvSintRoute *sint_route); =20 +/* + * Submit a message to be posted in vcpu context. If the submission succe= eds, + * the status of posting the message is reported via the callback associat= ed + * with the @sint_route; until then no more messages are accepted. + */ +int hyperv_post_msg(HvSintRoute *sint_route, struct hyperv_message *msg); + static inline uint32_t hyperv_vp_index(CPUState *cs) { return cs->cpu_index; diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c index 70cf129d04..21217631dc 100644 --- a/hw/hyperv/hyperv.c +++ b/hw/hyperv/hyperv.c @@ -148,14 +148,51 @@ static void synic_register_types(void) =20 type_init(synic_register_types) =20 +/* + * KVM has its own message producers (SynIC timers). To guarantee + * serialization with both KVM vcpu and the guest cpu, the messages are fi= rst + * staged in an intermediate area and then posted to the SynIC message pag= e in + * the vcpu thread. + */ +typedef struct HvSintStagedMesage { + /* message content staged by hyperv_post_msg */ + struct hyperv_message msg; + /* callback + data (r/o) to complete the processing in a BH */ + HvSintMsgCb cb; + void *cb_data; + /* message posting status filled by cpu_post_msg */ + int status; + /* passing the buck: */ + enum { + /* initial state */ + HV_STAGED_MSG_FREE, + /* + * hyperv_post_msg (e.g. in main loop) grabs the staged area (FREE= -> + * BUSY), copies msg, and schedules cpu_post_msg on the assigned c= pu + */ + HV_STAGED_MSG_BUSY, + /* + * cpu_post_msg (vcpu thread) tries to copy staged msg to msg slot, + * notify the guest, records the status, marks the posting done (B= USY + * -> POSTED), and schedules sint_msg_bh BH + */ + HV_STAGED_MSG_POSTED, + /* + * sint_msg_bh (BH) verifies that the posting is done, runs the + * callback, and starts over (POSTED -> FREE) + */ + } state; +} HvSintStagedMesage; + struct HvSintRoute { uint32_t sint; SynICState *synic; int gsi; EventNotifier sint_set_notifier; EventNotifier sint_ack_notifier; - HvSintAckClb sint_ack_clb; - void *sint_ack_clb_data; + + HvSintStagedMesage *staged_msg; + unsigned refcount; }; =20 @@ -166,17 +203,115 @@ static CPUState *hyperv_find_vcpu(uint32_t vp_index) return cs; } =20 -static void kvm_hv_sint_ack_handler(EventNotifier *notifier) +/* + * BH to complete the processing of a staged message. + */ +static void sint_msg_bh(void *opaque) +{ + HvSintRoute *sint_route =3D opaque; + HvSintStagedMesage *staged_msg =3D sint_route->staged_msg; + + if (atomic_read(&staged_msg->state) !=3D HV_STAGED_MSG_POSTED) { + /* status nor ready yet (spurious ack from guest?), ignore */ + return; + } + + staged_msg->cb(staged_msg->cb_data, staged_msg->status); + staged_msg->status =3D 0; + + /* staged message processing finished, ready to start over */ + atomic_set(&staged_msg->state, HV_STAGED_MSG_FREE); + /* drop the reference taken in hyperv_post_msg */ + hyperv_sint_route_unref(sint_route); +} + +/* + * Worker to transfer the message from the staging area into the SynIC mes= sage + * page in vcpu context. + */ +static void cpu_post_msg(CPUState *cs, run_on_cpu_data data) +{ + HvSintRoute *sint_route =3D data.host_ptr; + HvSintStagedMesage *staged_msg =3D sint_route->staged_msg; + SynICState *synic =3D sint_route->synic; + struct hyperv_message *dst_msg; + bool wait_for_sint_ack =3D false; + + assert(staged_msg->state =3D=3D HV_STAGED_MSG_BUSY); + + if (!synic->enabled || !synic->msg_page_addr) { + staged_msg->status =3D -ENXIO; + goto posted; + } + + dst_msg =3D &synic->msg_page->slot[sint_route->sint]; + + if (dst_msg->header.message_type !=3D HV_MESSAGE_NONE) { + dst_msg->header.message_flags |=3D HV_MESSAGE_FLAG_PENDING; + staged_msg->status =3D -EAGAIN; + wait_for_sint_ack =3D true; + } else { + memcpy(dst_msg, &staged_msg->msg, sizeof(*dst_msg)); + staged_msg->status =3D hyperv_sint_route_set_sint(sint_route); + } + + memory_region_set_dirty(&synic->msg_page_mr, 0, sizeof(*synic->msg_pag= e)); + +posted: + atomic_set(&staged_msg->state, HV_STAGED_MSG_POSTED); + /* + * Notify the msg originator of the progress made; if the slot was bus= y we + * set msg_pending flag in it so it will be the guest who will do EOM = and + * trigger the notification from KVM via sint_ack_notifier + */ + if (!wait_for_sint_ack) { + aio_bh_schedule_oneshot(qemu_get_aio_context(), sint_msg_bh, + sint_route); + } +} + +/* + * Post a Hyper-V message to the staging area, for delivery to guest in the + * vcpu thread. + */ +int hyperv_post_msg(HvSintRoute *sint_route, struct hyperv_message *src_ms= g) +{ + HvSintStagedMesage *staged_msg =3D sint_route->staged_msg; + + assert(staged_msg); + + /* grab the staging area */ + if (atomic_cmpxchg(&staged_msg->state, HV_STAGED_MSG_FREE, + HV_STAGED_MSG_BUSY) !=3D HV_STAGED_MSG_FREE) { + return -EAGAIN; + } + + memcpy(&staged_msg->msg, src_msg, sizeof(*src_msg)); + + /* hold a reference on sint_route until the callback is finished */ + hyperv_sint_route_ref(sint_route); + + /* schedule message posting attempt in vcpu thread */ + async_run_on_cpu(sint_route->synic->cs, cpu_post_msg, + RUN_ON_CPU_HOST_PTR(sint_route)); + return 0; +} + +static void sint_ack_handler(EventNotifier *notifier) { HvSintRoute *sint_route =3D container_of(notifier, HvSintRoute, sint_ack_notifier); event_notifier_test_and_clear(notifier); - sint_route->sint_ack_clb(sint_route->sint_ack_clb_data); + + /* + * the guest consumed the previous message so complete the current one= with + * -EAGAIN and let the msg originator retry + */ + aio_bh_schedule_oneshot(qemu_get_aio_context(), sint_msg_bh, sint_rout= e); } =20 HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, uint32_t sint, - HvSintAckClb sint_ack_clb, - void *sint_ack_clb_data) + HvSintMsgCb cb, void *cb_data) { HvSintRoute *sint_route; EventNotifier *ack_notifier; @@ -200,14 +335,19 @@ HvSintRoute *hyperv_sint_route_new(uint32_t vp_index,= uint32_t sint, goto err; } =20 - ack_notifier =3D sint_ack_clb ? &sint_route->sint_ack_notifier : NULL; + + ack_notifier =3D cb ? &sint_route->sint_ack_notifier : NULL; if (ack_notifier) { + sint_route->staged_msg =3D g_new0(HvSintStagedMesage, 1); + sint_route->staged_msg->cb =3D cb; + sint_route->staged_msg->cb_data =3D cb_data; + r =3D event_notifier_init(ack_notifier, false); if (r) { goto err_sint_set_notifier; } =20 - event_notifier_set_handler(ack_notifier, kvm_hv_sint_ack_handler); + event_notifier_set_handler(ack_notifier, sint_ack_handler); } =20 gsi =3D kvm_irqchip_add_hv_sint_route(kvm_state, vp_index, sint); @@ -222,8 +362,6 @@ HvSintRoute *hyperv_sint_route_new(uint32_t vp_index, u= int32_t sint, goto err_irqfd; } sint_route->gsi =3D gsi; - sint_route->sint_ack_clb =3D sint_ack_clb; - sint_route->sint_ack_clb_data =3D sint_ack_clb_data; sint_route->synic =3D synic; sint_route->sint =3D sint; sint_route->refcount =3D 1; @@ -236,6 +374,7 @@ err_gsi: if (ack_notifier) { event_notifier_set_handler(ack_notifier, NULL); event_notifier_cleanup(ack_notifier); + g_free(sint_route->staged_msg); } err_sint_set_notifier: event_notifier_cleanup(&sint_route->sint_set_notifier); @@ -266,9 +405,10 @@ void hyperv_sint_route_unref(HvSintRoute *sint_route) &sint_route->sint_set_notifier, sint_route->gsi); kvm_irqchip_release_virq(kvm_state, sint_route->gsi); - if (sint_route->sint_ack_clb) { + if (sint_route->staged_msg) { event_notifier_set_handler(&sint_route->sint_ack_notifier, NULL); event_notifier_cleanup(&sint_route->sint_ack_notifier); + g_free(sint_route->staged_msg); } event_notifier_cleanup(&sint_route->sint_set_notifier); g_free(sint_route); --=20 2.17.1