From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746202988; cv=none; d=zohomail.com; s=zohoarc; b=bslqojDdHTRlsYYGVSjcJOUGBKEKVTTki8gXuJhTDU/noCT0zHuc9wGRyqwDne1So8BLOXOSoIUzHm7xBL5n7648Gw9+ofr+a6F8LWLJqWrW2hTjpewO0lp3jlXru+j+OLaX0SlzqYWT9BTKTGh3Eg0N6d0kdh/Do4dwoemVm7k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746202988; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=n/XI4d+aGEAu3W8N5OXyAiG/e9D9J/dXw/QpLzSeH60=; b=ZtbkiR8dPurM+d0urQBglqDx2TVt1tgrNy6kmWSHTOi26O1UN1Y7xrALpaIEJ1nQSpPMoOFlQsGleUH0I2+VdbUin88t0sWcv3ALy6kk/zd2F0S9wXtGuz0ArBqsbRKGSvIFS48VeVFxPGxnPNKzawVMRfSgRkunM+yOUi4Br7g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746202988102672.2269422442788; Fri, 2 May 2025 09:23:08 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974783.1362544 (Exim 4.92) (envelope-from ) id 1uAt9y-0005rm-3e; Fri, 02 May 2025 16:22:46 +0000 Received: by outflank-mailman (output) from mailman id 974783.1362544; Fri, 02 May 2025 16:22:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9y-0005rf-13; Fri, 02 May 2025 16:22:46 +0000 Received: by outflank-mailman (input) for mailman id 974783; Fri, 02 May 2025 16:22:45 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9x-0005rZ-0p for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:45 +0000 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [2a00:1450:4864:20::62b]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id ac7837b7-2771-11f0-9eb4-5ba50f476ded; Fri, 02 May 2025 18:22:42 +0200 (CEST) Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-aca99fc253bso347466866b.0 for ; Fri, 02 May 2025 09:22:42 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:41 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ac7837b7-2771-11f0-9eb4-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202962; x=1746807762; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=n/XI4d+aGEAu3W8N5OXyAiG/e9D9J/dXw/QpLzSeH60=; b=d2bPKH9joldNLChSA0Ien9N4z0aFxamZa4C14nbrfVfJdjPRRQcNyvwwKLn6mnliE3 xUemhwBapCxUMutZhobflthzmjWw6HY+9hQiluv7QGuE+Yol44wzUl9h1hocXjhgR13B 99zSVcmzOo+YUd7smVbiuLsyKgn82JdO3jGsim3mb/+Dp9RVqwWPaiiI16pHVw2JisX9 5c3HSRna5TFTyHXHtymU7etmSG4FoHkUy9ZiAL9pPX+k5IwJvsB58THk/gm6ksey9R12 SyFV90ZGN8d1TlKeFx0iMDvSQTNnNovGE93Im4yqajNjndVxKVeEWSKPwHd5/4LEUcoz cqsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202962; x=1746807762; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=n/XI4d+aGEAu3W8N5OXyAiG/e9D9J/dXw/QpLzSeH60=; b=lAV8iTQAsOQM+qcLuOZ9nsLxqoPsLV9LdSFHkXTo0W1usZBpgTK7YYauXaFgdOcRhg u+he+kcNx//6MuTzDHTOJE1jLSvWg0VGf8XWBHv6raOvtz9cuijQTe1xrOIaDZAr9L7h Af/y0WmffiI4pjzeX3xXZho76sHZ2oXzUw79pDo/XWbqlHTEjDCzihNHdBjx6rk39syI 4fNd0S3BfnxcU3npwXBvAx0Wys5llM7SCj1VwZJ4gWiHNSqSfe4YGOU0xBA/Ogq/eOwX YHaSeSfEPDW12Tz3W8Lpmu/2ulVlOZXyguVNZN601bKMOrmyGl1TjuZZxUQ0LoV+h/A5 +9AQ== X-Gm-Message-State: AOJu0Yw33NViZx9jTagSvheMpzjePsFNyfD7UXAgCc3IOAvC7s7weS10 i16ztoxZy8otPqo2IjNVt+NIoRY0uLIAuTF6xhFScbC6ebwoVtpO6XZ/IA== X-Gm-Gg: ASbGncv4+qJKpcC1K+DMimSGXdwMpETPiUkzJ6AOsmwo/J4fDZh873AzI1XmRcvZ5gd 3yXcURedxS0wK0DD8/2bztAQTbjOFswrqC56SdxAO34D8igmp39m/431xlFG5VZgdmy1BJNexLD kd9azmDsWFHYmWh1pCKDx0t2zFA+iudAAf2DdD/DQNLGXGh+m2AQMxFIUFnPFjDG1vaaCuylnZE zq8jR3Y0GrQ0p/rbrVinAJ3WGFdRiF3U3WBD1xU6/8xjK9BAlVD7x3CkONm/pPa+vTX2Rs+9vr9 AlX2Jc44a/xaysG2djXeQdrn/yGumxFbwBONp8SN7Y8QSuGZQbJV6y3ZMG9Yol3RQcQSmQL91X9 Rg4kS188Xyu+q2PIJoMu+ X-Google-Smtp-Source: AGHT+IHcEdh3kTSRS+zA/pHD951bZuVy/SgDsrgVZMtcEdqrJOEeMR8KgJ1YDXIUD8XLa13yuN4+xQ== X-Received: by 2002:a17:907:60cf:b0:acb:b5a4:ba35 with SMTP id a640c23a62f3a-ad17ad397d6mr372957566b.2.1746202961835; Fri, 02 May 2025 09:22:41 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v3 1/8] xen/arm: drop declaration of handle_device_interrupts() Date: Fri, 2 May 2025 18:22:31 +0200 Message-ID: <790c29f1e564190909e74433fee5a694a1d22551.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746202989355019000 Content-Type: text/plain; charset="utf-8" There is no definition of handle_device_interrupts() thereby it could be dropped. Signed-off-by: Oleksii Kurochko Reviewed-by: Michal Orzel --- Change in v3: - Update commit message - Add Reviewed-by: Michal Orzel . --- xen/arch/arm/include/asm/domain_build.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/xen/arch/arm/include/asm/domain_build.h b/xen/arch/arm/include= /asm/domain_build.h index 17619c875d..378c10cc98 100644 --- a/xen/arch/arm/include/asm/domain_build.h +++ b/xen/arch/arm/include/asm/domain_build.h @@ -28,17 +28,6 @@ void evtchn_allocate(struct domain *d); =20 unsigned int get_allocation_size(paddr_t size); =20 -/* - * handle_device_interrupts retrieves the interrupts configuration from - * a device tree node and maps those interrupts to the target domain. - * - * Returns: - * < 0 error - * 0 success - */ -int handle_device_interrupts(struct domain *d, struct dt_device_node *dev, - bool need_mapping); - /* * Helper to write an interrupts with the GIC format * This code is assuming the irq is an PPI. --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746202992; cv=none; d=zohomail.com; s=zohoarc; b=AtlH2ixaV2j2yFKudzcQRAKOg282jbBAiuDTgeERi579C8MJ8PeYb2FSUf9VcZxh/MefJDhA23xk5yzc6bXUv68n+7lDkP+EGIOWT3eCygSSNKR8eA2yUp52e/JxqQStTQnRd3YixuXZeSjBJZA9nWJ/ONmXT9//CujXy5lux6I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746202992; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=u8nlrE1xOfFR3x/zATZSfmk84RnKUZVsA7gy/a2VH80=; b=F+pQtH9eo3TpQk5pXu30XbSBMV8C87ZW5EWQU76HDnIMdhHrJsIKkSE9UEqGv298MyeicaXAt+e4fZf69kH1SAEnESk1R9VLwnQ/OZQ30zRIIm6bctgYHePvXylE9QoDJwAU3zPsS9dAazagAZ9xgIn66PRrvRKOYqd0+h8LnXA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746202992160661.7899356422841; Fri, 2 May 2025 09:23:12 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974785.1362561 (Exim 4.92) (envelope-from ) id 1uAt9z-00069b-NH; Fri, 02 May 2025 16:22:47 +0000 Received: by outflank-mailman (output) from mailman id 974785.1362561; Fri, 02 May 2025 16:22:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9z-000692-Hn; Fri, 02 May 2025 16:22:47 +0000 Received: by outflank-mailman (input) for mailman id 974785; Fri, 02 May 2025 16:22:46 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9y-0005rY-Ey for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:46 +0000 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [2a00:1450:4864:20::636]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ad7f56c8-2771-11f0-9ffb-bf95429c2676; Fri, 02 May 2025 18:22:44 +0200 (CEST) Received: by mail-ej1-x636.google.com with SMTP id a640c23a62f3a-ac2a81e41e3so394102966b.1 for ; Fri, 02 May 2025 09:22:44 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:43 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ad7f56c8-2771-11f0-9ffb-bf95429c2676 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202964; x=1746807764; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=u8nlrE1xOfFR3x/zATZSfmk84RnKUZVsA7gy/a2VH80=; b=mdLPNWCI2Xn9lyjJT5bGSTkcJ7PDAHcVRWtHmRs6EJgHyd8NwqJm23C0nB/pku4OAM umF/2BqHhUIhl6Q20sr5jCfQ0NgyG3porEwm/GMgLxXcY0bbBaL4z7en143rEyuio+bL o04KMC14I5EsLf5KGvAWYjkx1O9iTIYiemJikdeeI9BJWkgHvu1rcs+hFZ/204B2okIL WDITby62BtBqaGbqw5ta6HpbGXp5MmXvfDCwuGHxfg7v3yN24ggxKA3ZDgXnI359W1uS c7BxHvLgNDbsUCEButyLLD1/JgAXdhvAB6U+VZ5mTxyfz1KlXMTcv1YsF+KqtiOV9+xJ G4AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202964; x=1746807764; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=u8nlrE1xOfFR3x/zATZSfmk84RnKUZVsA7gy/a2VH80=; b=OGkqIkBkh0V6BQ0z4z1x2Ip6SYFssPQ7BlUsoZmUh+VwUMTXnEZAL+D+pEzsWdNNL0 gUfWjsMjj9XdiTVrzDynK/wWcnHlOqBhN8ZWGZBINQAdWcPvw7ZDwfawdD7hliuVWoHC KdjacLHVHjP01SrMIdLgCT2WLblC2uVJ27BYBqJSglk//uA03OkYzK6JEu4OnMiJcHbr jXOtz931tg9KqYVT11iH+QTYzrN/fKUQkJiaUlt6fguwAx0aZg91eGgVG6iGJ/JK16FF VjzLdo2tGlpSxOhLauzbLeXp8ETeCgPtZ8JyVtouXB7Y1liv2tcAltRfoZHKcfQdDTAH dDsA== X-Gm-Message-State: AOJu0YzZk/VbX31Okv7NqbK0Z1VLVSRWc1kbt9GVrKK4HHATnxHWE78S 2vtMkrIdNTQAzYSkZ8KsELVvFzh1Agzjs3BFd07Y66f+RYlZU/DaE9mTXw== X-Gm-Gg: ASbGncsljhXWem6a2bWV/8YtzBO4liiWslSWtZhEHSkFLJzblUkstXYqvRLVeziT/Hy MvriqvknlshfB4mQxMKZvbSKsVJeEKoPfcOYwPUSmby3uRP0Fcx2EPYLwDv+t1cbP+vDhtcBqFT 6IW0of67lt8apkO2DbOdhxw1XAPYNkHhI7pO4svMQMZE8UUPCGlhJXP4B7lwwfXTM2BcCaB86eW 1vLvJMTSx+To8KBo6GYOE6SfucYvRwbZTEAfxi+7hFWqDBo8GC7RrhVfKpYmIYZZnh5QkgMe3mc RSTHPeNOgH1En55CsggODtTfJX+OHfQJW7jpTONIsIuLXMNLFNOu6JHfe8xdeyI63gMIt0sNmYN 4xyKtibkYLw== X-Google-Smtp-Source: AGHT+IEJ7hvV5q+nkxkUGh611s55rUyl6E9LU57qUyEPjnLtQ4i6XHxWf1qoYOBdtkLf1bqZLmib7g== X-Received: by 2002:a17:907:97d6:b0:ace:9d90:c49c with SMTP id a640c23a62f3a-ad17ad1a4famr335823766b.8.1746202963300; Fri, 02 May 2025 09:22:43 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 2/8] xen/common: dom0less: make some parts of Arm's CONFIG_DOM0LESS common Date: Fri, 2 May 2025 18:22:32 +0200 Message-ID: <82f0c1d4fe25b4a52d76f3c8004e107b183af56c.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746202993235019000 Content-Type: text/plain; charset="utf-8" Move some parts of Arm's Dom0Less code to be reused by other architectures. At the moment, RISC-V is going to reuse these parts. Move dom0less-build.h from the Arm-specific directory to asm-generic as these header is expected to be the same across acrhictectures with some updates: add the following declaration of construct_domU(), and arch_create_domUs() as there are some parts which are still architecture-specific. Introduce HAS_DOM0LESS to provide ability to enable generic Dom0less code for an architecture. Relocate the CONFIG_DOM0LESS configuration to the common with adding "depends on HAS_DOM0LESS" to not break builds for architectures which don't support CONFIG_DOM0LESS config, especically it would be useful to not provide stubs for construct_domU(), arch_create_domUs() in case of *-randconfig which may set CONFIG_DOM0LESS=3Dy. Move is_dom0less_mode() function to the common code, as it depends on boot modules that are already part of the common code. Move create_domUs() function to the common code with some updates: - Add arch_create_domUs() to cover parsing of arch-specific features, for example, SVE (Scalar Vector Extension ) exists only in Arm. Signed-off-by: Oleksii Kurochko Reviewed-by: Stefano Stabellini --- It was suggested to change dom0less to predefined domus or similar (https://lore.kernel.org/xen-devel/cd2a3644-c9c6-4e77-9491-2988703906c0@gma= il.com/T/#m1d5e81e5f1faca98a3c51efe4f35af25010edbf0): I decided to go with dom0less name for now as it will require a lot of plac= es to change, including CI's test, and IMO we could do in a separate patch. If it is necessry to do now, I'll be happy to do that in next version of th= e current patch series. --- Changes in v3: - Move changes connected to the patch "xen/arm: dom0less delay xenstore in= itialization" to common. Also, some necessary parts for the mentioned patches were moved to common (such as alloc_xenstore_evtchn(), ... ). Not all changes are moved, changes connected to alloc_xenstore_params() = and construct_domu() will be moved in the following patches of this patch se= ries. - Move parsing of capabilities property to common code. - Align parsing of "passthrough", "multiboot,device-tree" properties with = staging. - Drop arch_xen_domctl_createdomain(). - Add 'select HAS_DEVICE_TREE' for config HAS_DOM0LESS. - Add empty lines after license in the top of newly added files. - s/arch_create_domus/arch_create_domUs. - Add footer below commit message regarding the naming of dom0less. --- Changes in v2: - Convert 'depends on Arm' to 'depends on HAS_DOM0LESS' for CONFIG_DOM0LESS_BOOT. - Change 'default Arm' to 'default y' for CONFIG_DOM0LESS_BOOT as there is dependency on HAS_DOM0LESS. - Introduce HAS_DOM0LESS and enable it for Arm. - Update the commit message. --- xen/arch/arm/Kconfig | 9 +- xen/arch/arm/dom0less-build.c | 371 ++++------------------ xen/arch/arm/include/asm/Makefile | 1 + xen/arch/arm/include/asm/dom0less-build.h | 34 -- xen/common/Kconfig | 13 + xen/common/device-tree/Makefile | 1 + xen/common/device-tree/dom0less-build.c | 283 +++++++++++++++++ xen/include/asm-generic/dom0less-build.h | 49 +++ 8 files changed, 404 insertions(+), 357 deletions(-) delete mode 100644 xen/arch/arm/include/asm/dom0less-build.h create mode 100644 xen/common/device-tree/dom0less-build.c create mode 100644 xen/include/asm-generic/dom0less-build.h diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index da8a406f5a..d0e0a7753c 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -15,6 +15,7 @@ config ARM select GENERIC_UART_INIT select HAS_ALTERNATIVE if HAS_VMAP select HAS_DEVICE_TREE + select HAS_DOM0LESS select HAS_STACK_PROTECTOR select HAS_UBSAN =20 @@ -120,14 +121,6 @@ config GICV2 Driver for the ARM Generic Interrupt Controller v2. If unsure, say Y =20 -config DOM0LESS_BOOT - bool "Dom0less boot support" if EXPERT - default y - help - Dom0less boot support enables Xen to create and start domU guests during - Xen boot without the need of a control domain (Dom0), which could be - present anyway. - config GICV3 bool "GICv3 driver" depends on !NEW_VGIC diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index a356fc94fc..ef49495d4f 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -22,48 +22,7 @@ #include #include =20 -#define XENSTORE_PFN_LATE_ALLOC UINT64_MAX - -static domid_t __initdata xs_domid =3D DOMID_INVALID; -static bool __initdata need_xenstore; - -void __init set_xs_domain(struct domain *d) -{ - xs_domid =3D d->domain_id; - set_global_virq_handler(d, VIRQ_DOM_EXC); -} - -bool __init is_dom0less_mode(void) -{ - struct bootmodules *mods =3D &bootinfo.modules; - struct bootmodule *mod; - unsigned int i; - bool dom0found =3D false; - bool domUfound =3D false; - - /* Look into the bootmodules */ - for ( i =3D 0 ; i < mods->nr_mods ; i++ ) - { - mod =3D &mods->module[i]; - /* Find if dom0 and domU kernels are present */ - if ( mod->kind =3D=3D BOOTMOD_KERNEL ) - { - if ( mod->domU =3D=3D false ) - { - dom0found =3D true; - break; - } - else - domUfound =3D true; - } - } - - /* - * If there is no dom0 kernel but at least one domU, then we are in - * dom0less mode - */ - return ( !dom0found && domUfound ); -} +bool __initdata need_xenstore; =20 #ifdef CONFIG_VGICV2 static int __init make_gicv2_domU_node(struct kernel_info *kinfo) @@ -686,25 +645,6 @@ static int __init prepare_dtb_domU(struct domain *d, s= truct kernel_info *kinfo) return -EINVAL; } =20 -static int __init alloc_xenstore_evtchn(struct domain *d) -{ - evtchn_alloc_unbound_t alloc; - int rc; - - alloc.dom =3D d->domain_id; - alloc.remote_dom =3D xs_domid; - rc =3D evtchn_alloc_unbound(&alloc, 0); - if ( rc ) - { - printk("Failed allocating event channel for domain\n"); - return rc; - } - - d->arch.hvm.params[HVM_PARAM_STORE_EVTCHN] =3D alloc.port; - - return 0; -} - #define XENSTORE_PFN_OFFSET 1 static int __init alloc_xenstore_page(struct domain *d) { @@ -771,36 +711,6 @@ static int __init alloc_xenstore_params(struct kernel_= info *kinfo) return rc; } =20 -static void __init initialize_domU_xenstore(void) -{ - struct domain *d; - - if ( xs_domid =3D=3D DOMID_INVALID ) - return; - - for_each_domain( d ) - { - uint64_t gfn =3D d->arch.hvm.params[HVM_PARAM_STORE_PFN]; - int rc; - - if ( gfn =3D=3D 0 ) - continue; - - if ( is_xenstore_domain(d) ) - continue; - - rc =3D alloc_xenstore_evtchn(d); - if ( rc < 0 ) - panic("%pd: Failed to allocate xenstore_evtchn\n", d); - - if ( gfn !=3D XENSTORE_PFN_LATE_ALLOC && IS_ENABLED(CONFIG_GRANT_T= ABLE) ) - { - ASSERT(gfn < UINT32_MAX); - gnttab_seed_entry(d, GNTTAB_RESERVED_XENSTORE, xs_domid, gfn); - } - } -} - static void __init domain_vcpu_affinity(struct domain *d, const struct dt_device_node *node) { @@ -906,8 +816,8 @@ static inline int domain_p2m_set_allocation(struct doma= in *d, uint64_t mem, } #endif /* CONFIG_ARCH_PAGING_MEMPOOL */ =20 -static int __init construct_domU(struct domain *d, - const struct dt_device_node *node) +int __init construct_domU(struct domain *d, + const struct dt_device_node *node) { struct kernel_info kinfo =3D KERNEL_INFO_INIT; const char *dom0less_enhanced; @@ -1009,246 +919,77 @@ static int __init construct_domU(struct domain *d, return alloc_xenstore_params(&kinfo); } =20 -void __init create_domUs(void) +void __init arch_create_domUs(struct dt_device_node *node, + struct xen_domctl_createdomain *d_cfg, + unsigned int flags) { - struct dt_device_node *node; - const char *dom0less_iommu; - bool iommu =3D false; - const struct dt_device_node *cpupool_node, - *chosen =3D dt_find_node_by_path("/chosen"= ); - const char *llc_colors_str =3D NULL; - - BUG_ON(chosen =3D=3D NULL); - dt_for_each_child_node(chosen, node) - { - struct domain *d; - struct xen_domctl_createdomain d_cfg =3D { - .arch.gic_version =3D XEN_DOMCTL_CONFIG_GIC_NATIVE, - .flags =3D XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap, - /* - * The default of 1023 should be sufficient for guests because - * on ARM we don't bind physical interrupts to event channels. - * The only use of the evtchn port is inter-domain communicati= ons. - * 1023 is also the default value used in libxl. - */ - .max_evtchn_port =3D 1023, - .max_grant_frames =3D -1, - .max_maptrack_frames =3D -1, - .grant_opts =3D XEN_DOMCTL_GRANT_version(opt_gnttab_max_versio= n), - }; - unsigned int flags =3D 0U; - bool has_dtb =3D false; - uint32_t val; - int rc; - - if ( !dt_device_is_compatible(node, "xen,domain") ) - continue; - - if ( (max_init_domid + 1) >=3D DOMID_FIRST_RESERVED ) - panic("No more domain IDs available\n"); + uint32_t val; =20 - if ( dt_property_read_u32(node, "capabilities", &val) ) - { - if ( val & ~DOMAIN_CAPS_MASK ) - panic("Invalid capabilities (%"PRIx32")\n", val); - - if ( val & DOMAIN_CAPS_CONTROL ) - flags |=3D CDF_privileged; - - if ( val & DOMAIN_CAPS_HARDWARE ) - { - if ( hardware_domain ) - panic("Only 1 hardware domain can be specified! (%pd)\= n", - hardware_domain); - - d_cfg.max_grant_frames =3D gnttab_dom0_frames(); - d_cfg.max_evtchn_port =3D -1; - flags |=3D CDF_hardware; - iommu =3D true; - } - - if ( val & DOMAIN_CAPS_XENSTORE ) - { - if ( xs_domid !=3D DOMID_INVALID ) - panic("Only 1 xenstore domain can be specified! (%u)\n= ", - xs_domid); + d_cfg->arch.gic_version =3D XEN_DOMCTL_CONFIG_GIC_NATIVE; + d_cfg->flags =3D XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap; =20 - d_cfg.flags |=3D XEN_DOMCTL_CDF_xs_domain; - d_cfg.max_evtchn_port =3D -1; - } - } - - if ( dt_find_property(node, "xen,static-mem", NULL) ) - { - if ( llc_coloring_enabled ) - panic("LLC coloring and static memory are incompatible\n"); - - flags |=3D CDF_staticmem; - } - - if ( dt_property_read_bool(node, "direct-map") ) - { - if ( !(flags & CDF_staticmem) ) - panic("direct-map is not valid for domain %s without stati= c allocation.\n", - dt_node_name(node)); - - flags |=3D CDF_directmap; - } - - if ( !dt_property_read_u32(node, "cpus", &d_cfg.max_vcpus) ) - panic("Missing property 'cpus' for domain %s\n", - dt_node_name(node)); - - if ( !dt_property_read_string(node, "passthrough", &dom0less_iommu= ) ) - { - if ( flags & CDF_hardware ) - panic("Don't specify passthrough for hardware domain\n"); - - if ( !strcmp(dom0less_iommu, "enabled") ) - iommu =3D true; - } - - if ( (flags & CDF_hardware) && !(flags & CDF_directmap) && - !iommu_enabled ) - panic("non-direct mapped hardware domain requires iommu\n"); - - if ( dt_find_compatible_node(node, NULL, "multiboot,device-tree") ) - { - if ( flags & CDF_hardware ) - panic("\"multiboot,device-tree\" incompatible with hardwar= e domain\n"); - - has_dtb =3D true; - } - - if ( iommu_enabled && (iommu || has_dtb) ) - d_cfg.flags |=3D XEN_DOMCTL_CDF_iommu; - - if ( !dt_property_read_u32(node, "nr_spis", &d_cfg.arch.nr_spis) ) - { - int vpl011_virq =3D GUEST_VPL011_SPI; - - d_cfg.arch.nr_spis =3D VGIC_DEF_NR_SPIS; - - /* - * The VPL011 virq is GUEST_VPL011_SPI, unless direct-map is - * set, in which case it'll match the hardware. - * - * Since the domain is not yet created, we can't use - * d->arch.vpl011.irq. So the logic to find the vIRQ has to - * be hardcoded. - * The logic here shall be consistent with the one in - * domain_vpl011_init(). - */ - if ( flags & CDF_directmap ) - { - vpl011_virq =3D serial_irq(SERHND_DTUART); - if ( vpl011_virq < 0 ) - panic("Error getting IRQ number for this serial port %= d\n", - SERHND_DTUART); - } + if ( !dt_property_read_u32(node, "nr_spis", &d_cfg->arch.nr_spis) ) + { + int vpl011_virq =3D GUEST_VPL011_SPI; =20 - /* - * vpl011 uses one emulated SPI. If vpl011 is requested, make - * sure that we allocate enough SPIs for it. - */ - if ( dt_property_read_bool(node, "vpl011") ) - d_cfg.arch.nr_spis =3D MAX(d_cfg.arch.nr_spis, - vpl011_virq - 32 + 1); - } - else if ( flags & CDF_hardware ) - panic("nr_spis cannot be specified for hardware domain\n"); + d_cfg->arch.nr_spis =3D VGIC_DEF_NR_SPIS; =20 - /* Get the optional property domain-cpupool */ - cpupool_node =3D dt_parse_phandle(node, "domain-cpupool", 0); - if ( cpupool_node ) + /* + * The VPL011 virq is GUEST_VPL011_SPI, unless direct-map is + * set, in which case it'll match the hardware. + * + * Since the domain is not yet created, we can't use + * d->arch.vpl011.irq. So the logic to find the vIRQ has to + * be hardcoded. + * The logic here shall be consistent with the one in + * domain_vpl011_init(). + */ + if ( flags & CDF_directmap ) { - int pool_id =3D btcpupools_get_domain_pool_id(cpupool_node); - if ( pool_id < 0 ) - panic("Error getting cpupool id from domain-cpupool (%d)\n= ", - pool_id); - d_cfg.cpupool_id =3D pool_id; + vpl011_virq =3D serial_irq(SERHND_DTUART); + if ( vpl011_virq < 0 ) + panic("Error getting IRQ number for this serial port %d\n", + SERHND_DTUART); } =20 - if ( dt_property_read_u32(node, "max_grant_version", &val) ) - d_cfg.grant_opts =3D XEN_DOMCTL_GRANT_version(val); + /* + * vpl011 uses one emulated SPI. If vpl011 is requested, make + * sure that we allocate enough SPIs for it. + */ + if ( dt_property_read_bool(node, "vpl011") ) + d_cfg->arch.nr_spis =3D MAX(d_cfg->arch.nr_spis, + vpl011_virq - 32 + 1); + } + else if ( flags & CDF_hardware ) + panic("nr_spis cannot be specified for hardware domain\n"); =20 - if ( dt_property_read_u32(node, "max_grant_frames", &val) ) - { - if ( val > INT32_MAX ) - panic("max_grant_frames (%"PRIu32") overflow\n", val); - d_cfg.max_grant_frames =3D val; - } + if ( dt_get_property(node, "sve", &val) ) + { +#ifdef CONFIG_ARM64_SVE + unsigned int sve_vl_bits; + bool ret =3D false; =20 - if ( dt_property_read_u32(node, "max_maptrack_frames", &val) ) + if ( !val ) { - if ( val > INT32_MAX ) - panic("max_maptrack_frames (%"PRIu32") overflow\n", val); - d_cfg.max_maptrack_frames =3D val; + /* Property found with no value, means max HW VL supported */ + ret =3D sve_domctl_vl_param(-1, &sve_vl_bits); } - - if ( dt_get_property(node, "sve", &val) ) + else { -#ifdef CONFIG_ARM64_SVE - unsigned int sve_vl_bits; - bool ret =3D false; - - if ( !val ) - { - /* Property found with no value, means max HW VL supported= */ - ret =3D sve_domctl_vl_param(-1, &sve_vl_bits); - } + if ( dt_property_read_u32(node, "sve", &val) ) + ret =3D sve_domctl_vl_param(val, &sve_vl_bits); else - { - if ( dt_property_read_u32(node, "sve", &val) ) - ret =3D sve_domctl_vl_param(val, &sve_vl_bits); - else - panic("Error reading 'sve' property\n"); - } + panic("Error reading 'sve' property\n"); + } =20 - if ( ret ) - d_cfg.arch.sve_vl =3D sve_encode_vl(sve_vl_bits); - else - panic("SVE vector length error\n"); + if ( ret ) + d_cfg->arch.sve_vl =3D sve_encode_vl(sve_vl_bits); + else + panic("SVE vector length error\n"); #else - panic("'sve' property found, but CONFIG_ARM64_SVE not selected= \n"); + panic("'sve' property found, but CONFIG_ARM64_SVE not selected\n"); #endif - } - - dt_property_read_string(node, "llc-colors", &llc_colors_str); - if ( !llc_coloring_enabled && llc_colors_str ) - panic("'llc-colors' found, but LLC coloring is disabled\n"); - - /* - * The variable max_init_domid is initialized with zero, so here i= t's - * very important to use the pre-increment operator to call - * domain_create() with a domid > 0. (domid =3D=3D 0 is reserved f= or Dom0) - */ - d =3D domain_create(++max_init_domid, &d_cfg, flags); - if ( IS_ERR(d) ) - panic("Error creating domain %s (rc =3D %ld)\n", - dt_node_name(node), PTR_ERR(d)); - - if ( llc_coloring_enabled && - (rc =3D domain_set_llc_colors_from_str(d, llc_colors_str)) ) - panic("Error initializing LLC coloring for domain %s (rc =3D %= d)\n", - dt_node_name(node), rc); - - d->is_console =3D true; - dt_device_set_used_by(node, d->domain_id); - - rc =3D construct_domU(d, node); - if ( rc ) - panic("Could not set up domain %s (rc =3D %d)\n", - dt_node_name(node), rc); - - if ( d_cfg.flags & XEN_DOMCTL_CDF_xs_domain ) - set_xs_domain(d); } - - if ( need_xenstore && xs_domid =3D=3D DOMID_INVALID ) - panic("xenstore requested, but xenstore domain not present\n"); - - initialize_domU_xenstore(); } =20 /* diff --git a/xen/arch/arm/include/asm/Makefile b/xen/arch/arm/include/asm/M= akefile index 4a4036c951..831c914cce 100644 --- a/xen/arch/arm/include/asm/Makefile +++ b/xen/arch/arm/include/asm/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only generic-y +=3D altp2m.h generic-y +=3D device.h +generic-y +=3D dom0less-build.h generic-y +=3D hardirq.h generic-y +=3D iocap.h generic-y +=3D paging.h diff --git a/xen/arch/arm/include/asm/dom0less-build.h b/xen/arch/arm/inclu= de/asm/dom0less-build.h deleted file mode 100644 index b0e41a1954..0000000000 --- a/xen/arch/arm/include/asm/dom0less-build.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __ASM_DOM0LESS_BUILD_H_ -#define __ASM_DOM0LESS_BUILD_H_ - -#include - -#ifdef CONFIG_DOM0LESS_BOOT - -void create_domUs(void); -bool is_dom0less_mode(void); -void set_xs_domain(struct domain *d); - -#else /* !CONFIG_DOM0LESS_BOOT */ - -static inline void create_domUs(void) {} -static inline bool is_dom0less_mode(void) -{ - return false; -} -static inline void set_xs_domain(struct domain *d) {} - -#endif /* CONFIG_DOM0LESS_BOOT */ - -#endif /* __ASM_DOM0LESS_BUILD_H_ */ - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/common/Kconfig b/xen/common/Kconfig index be28060716..be38abf9e1 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -12,6 +12,15 @@ config CORE_PARKING bool depends on NR_CPUS > 1 =20 +config DOM0LESS_BOOT + bool "Dom0less boot support" if EXPERT + depends on HAS_DOM0LESS + default y + help + Dom0less boot support enables Xen to create and start domU guests during + Xen boot without the need of a control domain (Dom0), which could be + present anyway. + config GRANT_TABLE bool "Grant table support" if EXPERT default y @@ -74,6 +83,10 @@ config HAS_DEVICE_TREE bool select LIBFDT =20 +config HAS_DOM0LESS + bool + select HAS_DEVICE_TREE + config HAS_DIT # Data Independent Timing bool =20 diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makef= ile index 7c549be38a..f3dafc9b81 100644 --- a/xen/common/device-tree/Makefile +++ b/xen/common/device-tree/Makefile @@ -1,5 +1,6 @@ obj-y +=3D bootfdt.init.o obj-y +=3D bootinfo.init.o obj-y +=3D device-tree.o +obj-$(CONFIG_DOM0LESS_BOOT) +=3D dom0less-build.o obj-$(CONFIG_OVERLAY_DTB) +=3D dt-overlay.o obj-y +=3D intc.o diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tr= ee/dom0less-build.c new file mode 100644 index 0000000000..a01a8b6b1a --- /dev/null +++ b/xen/common/device-tree/dom0less-build.c @@ -0,0 +1,283 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static domid_t __initdata xs_domid =3D DOMID_INVALID; + +void __init set_xs_domain(struct domain *d) +{ + xs_domid =3D d->domain_id; + set_global_virq_handler(d, VIRQ_DOM_EXC); +} + +bool __init is_dom0less_mode(void) +{ + struct bootmodules *mods =3D &bootinfo.modules; + struct bootmodule *mod; + unsigned int i; + bool dom0found =3D false; + bool domUfound =3D false; + + /* Look into the bootmodules */ + for ( i =3D 0 ; i < mods->nr_mods ; i++ ) + { + mod =3D &mods->module[i]; + /* Find if dom0 and domU kernels are present */ + if ( mod->kind =3D=3D BOOTMOD_KERNEL ) + { + if ( mod->domU =3D=3D false ) + { + dom0found =3D true; + break; + } + else + domUfound =3D true; + } + } + + /* + * If there is no dom0 kernel but at least one domU, then we are in + * dom0less mode + */ + return ( !dom0found && domUfound ); +} + +static int __init alloc_xenstore_evtchn(struct domain *d) +{ + evtchn_alloc_unbound_t alloc; + int rc; + + alloc.dom =3D d->domain_id; + alloc.remote_dom =3D xs_domid; + rc =3D evtchn_alloc_unbound(&alloc, 0); + if ( rc ) + { + printk("Failed allocating event channel for domain\n"); + return rc; + } + + d->arch.hvm.params[HVM_PARAM_STORE_EVTCHN] =3D alloc.port; + + return 0; +} + +static void __init initialize_domU_xenstore(void) +{ + struct domain *d; + + if ( xs_domid =3D=3D DOMID_INVALID ) + return; + + for_each_domain( d ) + { + uint64_t gfn =3D d->arch.hvm.params[HVM_PARAM_STORE_PFN]; + int rc; + + if ( gfn =3D=3D 0 ) + continue; + + if ( is_xenstore_domain(d) ) + continue; + + rc =3D alloc_xenstore_evtchn(d); + if ( rc < 0 ) + panic("%pd: Failed to allocate xenstore_evtchn\n", d); + + if ( gfn !=3D XENSTORE_PFN_LATE_ALLOC && IS_ENABLED(CONFIG_GRANT_T= ABLE) ) + { + ASSERT(gfn < UINT32_MAX); + gnttab_seed_entry(d, GNTTAB_RESERVED_XENSTORE, xs_domid, gfn); + } + } +} + +void __init create_domUs(void) +{ + struct dt_device_node *node; + const char *dom0less_iommu; + bool iommu =3D false; + const struct dt_device_node *cpupool_node, + *chosen =3D dt_find_node_by_path("/chosen"= ); + const char *llc_colors_str =3D NULL; + + BUG_ON(chosen =3D=3D NULL); + dt_for_each_child_node(chosen, node) + { + struct domain *d; + struct xen_domctl_createdomain d_cfg =3D {0}; + unsigned int flags =3D 0U; + bool has_dtb =3D false; + uint32_t val; + int rc; + + if ( !dt_device_is_compatible(node, "xen,domain") ) + continue; + + if ( (max_init_domid + 1) >=3D DOMID_FIRST_RESERVED ) + panic("No more domain IDs available\n"); + + d_cfg.max_evtchn_port =3D 1023; + d_cfg.max_grant_frames =3D -1; + d_cfg.max_maptrack_frames =3D -1; + d_cfg.grant_opts =3D XEN_DOMCTL_GRANT_version(opt_gnttab_max_versi= on); + + if ( dt_property_read_u32(node, "capabilities", &val) ) + { + if ( val & ~DOMAIN_CAPS_MASK ) + panic("Invalid capabilities (%"PRIx32")\n", val); + + if ( val & DOMAIN_CAPS_CONTROL ) + flags |=3D CDF_privileged; + + if ( val & DOMAIN_CAPS_HARDWARE ) + { + if ( hardware_domain ) + panic("Only 1 hardware domain can be specified! (%pd)\= n", + hardware_domain); + + d_cfg.max_grant_frames =3D gnttab_dom0_frames(); + d_cfg.max_evtchn_port =3D -1; + flags |=3D CDF_hardware; + iommu =3D true; + } + + if ( val & DOMAIN_CAPS_XENSTORE ) + { + if ( xs_domid !=3D DOMID_INVALID ) + panic("Only 1 xenstore domain can be specified! (%u)\n= ", + xs_domid); + + d_cfg.flags |=3D XEN_DOMCTL_CDF_xs_domain; + d_cfg.max_evtchn_port =3D -1; + } + } + + if ( dt_find_property(node, "xen,static-mem", NULL) ) + { + if ( llc_coloring_enabled ) + panic("LLC coloring and static memory are incompatible\n"); + + flags |=3D CDF_staticmem; + } + + if ( dt_property_read_bool(node, "direct-map") ) + { + if ( !(flags & CDF_staticmem) ) + panic("direct-map is not valid for domain %s without stati= c allocation.\n", + dt_node_name(node)); + + flags |=3D CDF_directmap; + } + + if ( !dt_property_read_u32(node, "cpus", &d_cfg.max_vcpus) ) + panic("Missing property 'cpus' for domain %s\n", + dt_node_name(node)); + + if ( !dt_property_read_string(node, "passthrough", &dom0less_iommu= ) ) + { + if ( flags & CDF_hardware ) + panic("Don't specify passthrough for hardware domain\n"); + + if ( !strcmp(dom0less_iommu, "enabled") ) + iommu =3D true; + } + + if ( (flags & CDF_hardware) && !(flags & CDF_directmap) && + !iommu_enabled ) + panic("non-direct mapped hardware domain requires iommu\n"); + + if ( dt_find_compatible_node(node, NULL, "multiboot,device-tree") ) + { + if ( flags & CDF_hardware ) + panic("\"multiboot,device-tree\" incompatible with hardwar= e domain\n"); + + has_dtb =3D true; + } + + if ( iommu_enabled && (iommu || has_dtb) ) + d_cfg.flags |=3D XEN_DOMCTL_CDF_iommu; + + /* Get the optional property domain-cpupool */ + cpupool_node =3D dt_parse_phandle(node, "domain-cpupool", 0); + if ( cpupool_node ) + { + int pool_id =3D btcpupools_get_domain_pool_id(cpupool_node); + if ( pool_id < 0 ) + panic("Error getting cpupool id from domain-cpupool (%d)\n= ", + pool_id); + d_cfg.cpupool_id =3D pool_id; + } + + if ( dt_property_read_u32(node, "max_grant_version", &val) ) + d_cfg.grant_opts =3D XEN_DOMCTL_GRANT_version(val); + + if ( dt_property_read_u32(node, "max_grant_frames", &val) ) + { + if ( val > INT32_MAX ) + panic("max_grant_frames (%"PRIu32") overflow\n", val); + d_cfg.max_grant_frames =3D val; + } + + if ( dt_property_read_u32(node, "max_maptrack_frames", &val) ) + { + if ( val > INT32_MAX ) + panic("max_maptrack_frames (%"PRIu32") overflow\n", val); + d_cfg.max_maptrack_frames =3D val; + } + + dt_property_read_string(node, "llc-colors", &llc_colors_str); + if ( !llc_coloring_enabled && llc_colors_str ) + panic("'llc-colors' found, but LLC coloring is disabled\n"); + + arch_create_domUs(node, &d_cfg, flags); + + /* + * The variable max_init_domid is initialized with zero, so here i= t's + * very important to use the pre-increment operator to call + * domain_create() with a domid > 0. (domid =3D=3D 0 is reserved f= or Dom0) + */ + d =3D domain_create(++max_init_domid, &d_cfg, flags); + if ( IS_ERR(d) ) + panic("Error creating domain %s (rc =3D %ld)\n", + dt_node_name(node), PTR_ERR(d)); + + if ( llc_coloring_enabled && + (rc =3D domain_set_llc_colors_from_str(d, llc_colors_str)) ) + panic("Error initializing LLC coloring for domain %s (rc =3D %= d)\n", + dt_node_name(node), rc); + + d->is_console =3D true; + dt_device_set_used_by(node, d->domain_id); + + rc =3D construct_domU(d, node); + if ( rc ) + panic("Could not set up domain %s (rc =3D %d)\n", + dt_node_name(node), rc); + + if ( d_cfg.flags & XEN_DOMCTL_CDF_xs_domain ) + set_xs_domain(d); + } + + if ( need_xenstore && xs_domid =3D=3D DOMID_INVALID ) + panic("xenstore requested, but xenstore domain not present\n"); + + initialize_domU_xenstore(); +} diff --git a/xen/include/asm-generic/dom0less-build.h b/xen/include/asm-gen= eric/dom0less-build.h new file mode 100644 index 0000000000..5655571a66 --- /dev/null +++ b/xen/include/asm-generic/dom0less-build.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_GENERIC_DOM0LESS_BUILD_H__ +#define __ASM_GENERIC_DOM0LESS_BUILD_H__ + +#include + +#ifdef CONFIG_DOM0LESS_BOOT + +#include + +struct domain; +struct dt_device_node; + +/* TODO: remove both when construct_domU() will be moved to common. */ +#define XENSTORE_PFN_LATE_ALLOC UINT64_MAX +extern bool need_xenstore; + +void create_domUs(void); +bool is_dom0less_mode(void); +void set_xs_domain(struct domain *d); + +int construct_domU(struct domain *d, const struct dt_device_node *node); + +void arch_create_domUs(struct dt_device_node *node, + struct xen_domctl_createdomain *d_cfg, + unsigned int flags); + +#else /* !CONFIG_DOM0LESS_BOOT */ + +static inline void create_domUs(void) {} +static inline bool is_dom0less_mode(void) +{ + return false; +} +static inline void set_xs_domain(struct domain *d) {} + +#endif /* CONFIG_DOM0LESS_BOOT */ + +#endif /* __ASM_GENERIC_DOM0LESS_BUILD_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746202998; cv=none; d=zohomail.com; s=zohoarc; b=J9iSMMd7gWRjSjnmRzgtSlU+efKaWUnzbDsqUQGncwGoIh9Iwpz6TwAJnD50uh5de8POSil2pPV5zsG2t9tF+0Nj5TPGkIjCRxvGc9H0UjZS+x6bx4B4yXzGqdOp/pCaUUF9negrwdlJqeQQfeImKagKwvhVR/pFPkEeGdFuSsE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746202998; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=EFAs5QpEMZiGVQnaEa+bU01BSHSsYQBC71P0gj1yZJI=; b=YX/NRehf4oPpi6xlFr7ZkBydbLZCcZXLlaSbx1hg4O2qxWDzi5mz7+JxNSL4DWYaQENeDVUhlxXYxemqonkCbu8tzmdLGwgUxfZWDb7hdn+eEzCOdDMkaTowHdc1taXDfnD5Gg1UIWmZvi+xDzZ2ZvIswKtuG9KLwL1ssUi8yrQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746202998810868.8385430782324; Fri, 2 May 2025 09:23:18 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974786.1362567 (Exim 4.92) (envelope-from ) id 1uAtA0-0006Ep-2i; Fri, 02 May 2025 16:22:48 +0000 Received: by outflank-mailman (output) from mailman id 974786.1362567; Fri, 02 May 2025 16:22:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9z-0006Cs-Rc; Fri, 02 May 2025 16:22:47 +0000 Received: by outflank-mailman (input) for mailman id 974786; Fri, 02 May 2025 16:22:46 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9y-0005rZ-ET for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:46 +0000 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [2a00:1450:4864:20::635]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id adf38485-2771-11f0-9eb4-5ba50f476ded; Fri, 02 May 2025 18:22:45 +0200 (CEST) Received: by mail-ej1-x635.google.com with SMTP id a640c23a62f3a-acb5ec407b1so350766266b.1 for ; Fri, 02 May 2025 09:22:45 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:43 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: adf38485-2771-11f0-9eb4-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202964; x=1746807764; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EFAs5QpEMZiGVQnaEa+bU01BSHSsYQBC71P0gj1yZJI=; b=IVqd0Cb5NtPyuEXPh+Sv4UQZCA+naZDqWajGaAeDxfplL2fNIAIWf+aeuv5wSIi9bK wXRBQ6zuqnXJYt6TD41mijoNcrw6kJWPeNgyMSBafeXkqbP7y1mc2WKit9kCiTlYOrIm 2fpuER+Eu7Ynl8XE6m4SRZrRsIVWi/oNwbiZ3iRXgv+Lc81XTRX4O4GL7apai1vV4Js3 WbIWq7UFR/SXnxg7My9TuDM4LFBzWiTf6MKv84L5dG3ezcS1c2r+J7vVfdE6PACjETdg e35uVeQqz04nyiBk1xVYdDL4LB98JdYTcx2Vr6Q3zL9IwwNwEq6ymeyuiooQZdzbQa9v sTpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202964; x=1746807764; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EFAs5QpEMZiGVQnaEa+bU01BSHSsYQBC71P0gj1yZJI=; b=PxqxpJeQf0X1eAFvG98aJuSWCWEYPXtNZRL3zkCUHWI3A3vxtzx9tSaG1qbMRZRpJc wYXs2iUxfPbAnYeZhOO7suJH2gwKHM5MofWKSjALramI2McNN1nOESDjlIIWiLnikB2w Hp+69kP8+HG071JPQxHy6IXE5Z89Ojp11pjeuL6+FFiKq4A444ooYQOo23fkaZIMSv7g 5qLiEXfnpIvcN3dtDsYisVok4WuU6QoAN2D8WiacDLWquY/Md9TGElFOw4tRLqteKlF5 mwbm4oai5NoAxn8BWuAVNKMSzOneMRFVxL6h9dxYsxVxUXCpiBh/gRm4LGtCz2bUYxAl hflA== X-Gm-Message-State: AOJu0Yy6TLcUD+kcn8ihxT10YHsADUU/ivL0WOoddFOHu6k4evl1ZVEF HfP/pTiv4sj7b6NkBvGey18YeMz10CchNuVUehjmSUhIaX0yJXI8pCzNXg== X-Gm-Gg: ASbGncvK+LaaH8LWuUCySPtYr1TZorLfz1BcmIRY4qh/7FhMzpHf1qpCoxaRg5fhnkw GKKXMy9eakRqy8AowrZXQcZYyTRJo1wGYZ8BUlDZwDMGjy5PDG0q2Vt/EtOnqyLSKf5QW02Cl0K +DuQ/c8HBQgorhXfBAXb4EsH7XhXJZ9p527EwFnskoCLhmaGJcyqqoJ/EilRZCqVWnwQoVVWmgF Uwo7/bn/do9YFtf0BDJ5jgiR7LSTOJhCrnb3uBsZNa/cesQGWoy0mrgJNvfQ5ev/0bkiAADxSJB APkHMxK2XoDx1lLLE7T6PNuo6Me1tcy/QUyRUe0OHnhqyWTgMZrzXzV+cElegybikrJiq/bQkzw J3RmnK6gHRg== X-Google-Smtp-Source: AGHT+IG41K40YYS4kZTEzP/j/FNULhrVewtRhe65Dr55/B8N+pjqrBt0RnFpsySUUXw8H+l8zwZLPw== X-Received: by 2002:a17:907:94d0:b0:ac7:95ae:747f with SMTP id a640c23a62f3a-ad17af8f52cmr311730866b.45.1746202964218; Fri, 02 May 2025 09:22:44 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 3/8] asm-generic: move parts of Arm's asm/kernel.h to common code Date: Fri, 2 May 2025 18:22:33 +0200 Message-ID: <0c16f8fb2702db5fd6751c7da347a97caa431002.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746202999296019000 Content-Type: text/plain; charset="utf-8" Move the following parts to common with the following changes: - struct kernel_info: - Create arch_kernel_info for arch specific kernel information. At the moment, it contains domain_type for Arm. - Rename vpl011 to vuart to have more generic name suitable for other arc= hs. - s/phandle_gic/phandle_intc to have more generic name suitable for other archs. - Make text_offset of zimage structure available for RISCV_64. - Wrap by `#ifdef KERNEL_INFO_SHM_MEM_INIT` definition of KERNEL_SHM_MEM_IN= IT and wrap by `#ifndef KERNEL_INFO_INIT` definition of KERNEL_INFO_INIT to = have ability to override KERNEL_INFO_SHM_MEM_INIT for arch in case it doesn't want to use generic one. - Move DOM0LESS_* macros to dom0less-build.h. - Move all others parts of Arm's kernel.h to xen/fdt-kernel.h. Because of the changes in struct kernel_info the correspondent parts of Arm= 's code are updated. As part of this patch the following clean up happens: - Drop asm/setup.h from asm/kernel.h as nothing depends from it. Add inclusion of asm/setup.h for a code which uses device_tree_get_reg() = to avoid compilation issues for CONFIG_STATIC_MEMORY and CONFIG_STATIC_SHM. - Drop inclusion of asm/kernel.h everywhere except xen/fdt-kernel.h. Signed-off-by: Oleksii Kurochko --- Changes in v3: - Only resolving of merge conflicts. --- Changes in v2: - Introduce xen/fdt-kernel.h. - Move DOM0LESS_* macros to dom0less-build.h. - Move the rest in asm-generic/kernel.h to xen/fdt-kernel.h. - Drop inclusion of asm/kernel.h everywhere except xen/fdt-kernel.h. - Wrap by #if __has_include(....) the member of kernel_info structure: struct arch_kernel_info arch. - Update the commit message. --- xen/arch/arm/acpi/domain_build.c | 2 +- xen/arch/arm/dom0less-build.c | 31 +++--- xen/arch/arm/domain_build.c | 12 +- xen/arch/arm/include/asm/domain_build.h | 2 +- xen/arch/arm/include/asm/kernel.h | 126 +-------------------- xen/arch/arm/include/asm/static-memory.h | 2 +- xen/arch/arm/include/asm/static-shmem.h | 2 +- xen/arch/arm/kernel.c | 12 +- xen/arch/arm/static-memory.c | 1 + xen/arch/arm/static-shmem.c | 1 + xen/common/device-tree/dt-overlay.c | 2 +- xen/include/asm-generic/dom0less-build.h | 28 +++++ xen/include/xen/fdt-kernel.h | 133 +++++++++++++++++++++++ 13 files changed, 199 insertions(+), 155 deletions(-) create mode 100644 xen/include/xen/fdt-kernel.h diff --git a/xen/arch/arm/acpi/domain_build.c b/xen/arch/arm/acpi/domain_bu= ild.c index 2ce75543d0..f9ca8b47e5 100644 --- a/xen/arch/arm/acpi/domain_build.c +++ b/xen/arch/arm/acpi/domain_build.c @@ -10,6 +10,7 @@ */ =20 #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #include =20 /* Override macros from asm/page.h to make them work with mfn_t */ diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index ef49495d4f..c0634dd61e 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include #include +#include #include #include #include @@ -64,11 +65,11 @@ static int __init make_gicv2_domU_node(struct kernel_in= fo *kinfo) if (res) return res; =20 - res =3D fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_gic); + res =3D fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_intc); if (res) return res; =20 - res =3D fdt_property_cell(fdt, "phandle", kinfo->phandle_gic); + res =3D fdt_property_cell(fdt, "phandle", kinfo->phandle_intc); if (res) return res; =20 @@ -135,11 +136,11 @@ static int __init make_gicv3_domU_node(struct kernel_= info *kinfo) if (res) return res; =20 - res =3D fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_gic); + res =3D fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_intc); if (res) return res; =20 - res =3D fdt_property_cell(fdt, "phandle", kinfo->phandle_gic); + res =3D fdt_property_cell(fdt, "phandle", kinfo->phandle_intc); if (res) return res; =20 @@ -200,7 +201,7 @@ static int __init make_vpl011_uart_node(struct kernel_i= nfo *kinfo) return res; =20 res =3D fdt_property_cell(fdt, "interrupt-parent", - kinfo->phandle_gic); + kinfo->phandle_intc); if ( res ) return res; =20 @@ -486,10 +487,10 @@ static int __init domain_handle_dtb_bootmodule(struct= domain *d, */ if ( dt_node_cmp(name, "gic") =3D=3D 0 ) { - uint32_t phandle_gic =3D fdt_get_phandle(pfdt, node_next); + uint32_t phandle_intc =3D fdt_get_phandle(pfdt, node_next); =20 - if ( phandle_gic !=3D 0 ) - kinfo->phandle_gic =3D phandle_gic; + if ( phandle_intc !=3D 0 ) + kinfo->phandle_intc =3D phandle_intc; continue; } =20 @@ -532,7 +533,7 @@ static int __init prepare_dtb_domU(struct domain *d, st= ruct kernel_info *kinfo) int addrcells, sizecells; int ret, fdt_size =3D DOMU_DTB_SIZE; =20 - kinfo->phandle_gic =3D GUEST_PHANDLE_GIC; + kinfo->phandle_intc =3D GUEST_PHANDLE_GIC; kinfo->gnttab_start =3D GUEST_GNTTAB_BASE; kinfo->gnttab_size =3D GUEST_GNTTAB_SIZE; =20 @@ -594,7 +595,7 @@ static int __init prepare_dtb_domU(struct domain *d, st= ruct kernel_info *kinfo) /* * domain_handle_dtb_bootmodule has to be called before the rest of * the device tree is generated because it depends on the value of - * the field phandle_gic. + * the field phandle_intc. */ if ( kinfo->dtb_bootmodule ) { @@ -611,7 +612,7 @@ static int __init prepare_dtb_domU(struct domain *d, st= ruct kernel_info *kinfo) if ( ret ) goto err; =20 - if ( kinfo->vpl011 ) + if ( kinfo->vuart ) { ret =3D -EINVAL; #ifdef CONFIG_SBSA_VUART_CONSOLE @@ -839,8 +840,8 @@ int __init construct_domU(struct domain *d, printk("*** LOADING DOMU cpus=3D%u memory=3D%#"PRIx64"KB ***\n", d->max_vcpus, mem); =20 - kinfo.vpl011 =3D dt_property_read_bool(node, "vpl011"); - if ( kinfo.vpl011 && is_hardware_domain(d) ) + kinfo.vuart =3D dt_property_read_bool(node, "vpl011"); + if ( kinfo.vuart && is_hardware_domain(d) ) panic("hardware domain cannot specify vpl011\n"); =20 rc =3D dt_property_read_string(node, "xen,enhanced", &dom0less_enhance= d); @@ -872,7 +873,7 @@ int __init construct_domU(struct domain *d, =20 #ifdef CONFIG_ARM_64 /* type must be set before allocate memory */ - d->arch.type =3D kinfo.type; + d->arch.type =3D kinfo.arch.type; #endif if ( is_hardware_domain(d) ) { @@ -898,7 +899,7 @@ int __init construct_domU(struct domain *d, * tree node in prepare_dtb_domU, so initialization on related var= iables * shall be done first. */ - if ( kinfo.vpl011 ) + if ( kinfo.vuart ) { rc =3D domain_vpl011_init(d, NULL); if ( rc < 0 ) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 270a6b97e4..8c7a054718 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include #include +#include #include #include #include @@ -20,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -747,7 +747,7 @@ static int __init fdt_property_interrupts(const struct = kernel_info *kinfo, return res; =20 res =3D fdt_property_cell(kinfo->fdt, "interrupt-parent", - kinfo->phandle_gic); + kinfo->phandle_intc); =20 return res; } @@ -2026,7 +2026,7 @@ static int __init prepare_dtb_hwdom(struct domain *d,= struct kernel_info *kinfo) =20 ASSERT(dt_host && (dt_host->sibling =3D=3D NULL)); =20 - kinfo->phandle_gic =3D dt_interrupt_controller->phandle; + kinfo->phandle_intc =3D dt_interrupt_controller->phandle; fdt =3D device_tree_flattened; =20 new_size =3D fdt_totalsize(fdt) + DOM0_FDT_EXTRA_SIZE; @@ -2196,13 +2196,13 @@ int __init construct_domain(struct domain *d, struc= t kernel_info *kinfo) =20 #ifdef CONFIG_ARM_64 /* if aarch32 mode is not supported at EL1 do not allow 32-bit domain = */ - if ( !(cpu_has_el1_32) && kinfo->type =3D=3D DOMAIN_32BIT ) + if ( !(cpu_has_el1_32) && kinfo->arch.type =3D=3D DOMAIN_32BIT ) { printk("Platform does not support 32-bit domain\n"); return -EINVAL; } =20 - if ( is_sve_domain(d) && (kinfo->type =3D=3D DOMAIN_32BIT) ) + if ( is_sve_domain(d) && (kinfo->arch.type =3D=3D DOMAIN_32BIT) ) { printk("SVE is not available for 32-bit domain\n"); return -EINVAL; @@ -2318,7 +2318,7 @@ int __init construct_hwdom(struct kernel_info *kinfo, =20 #ifdef CONFIG_ARM_64 /* type must be set before allocate_memory */ - d->arch.type =3D kinfo->type; + d->arch.type =3D kinfo->arch.type; #endif find_gnttab_region(d, kinfo); if ( is_domain_direct_mapped(d) ) diff --git a/xen/arch/arm/include/asm/domain_build.h b/xen/arch/arm/include= /asm/domain_build.h index 378c10cc98..df1c0fe301 100644 --- a/xen/arch/arm/include/asm/domain_build.h +++ b/xen/arch/arm/include/asm/domain_build.h @@ -1,8 +1,8 @@ #ifndef __ASM_DOMAIN_BUILD_H__ #define __ASM_DOMAIN_BUILD_H__ =20 +#include #include -#include =20 typedef __be32 gic_interrupt_t[3]; typedef bool (*alloc_domheap_mem_cb)(struct domain *d, struct page_info *p= g, diff --git a/xen/arch/arm/include/asm/kernel.h b/xen/arch/arm/include/asm/k= ernel.h index bdc96f4c18..cfeab792c7 100644 --- a/xen/arch/arm/include/asm/kernel.h +++ b/xen/arch/arm/include/asm/kernel.h @@ -6,137 +6,15 @@ #ifndef __ARCH_ARM_KERNEL_H__ #define __ARCH_ARM_KERNEL_H__ =20 -#include #include -#include =20 -/* - * List of possible features for dom0less domUs - * - * DOM0LESS_ENHANCED_NO_XS: Notify the OS it is running on top of Xen. Al= l the - * default features (excluding Xenstore) will be - * available. Note that an OS *must* not rely on= the - * availability of Xen features if this is not s= et. - * DOM0LESS_XENSTORE: Xenstore will be enabled for the VM. The - * xenstore page allocation is done by Xen at - * domain creation. This feature can't be - * enabled without the DOM0LESS_ENHANCED_NO_XS. - * DOM0LESS_XS_LEGACY Xenstore will be enabled for the VM, the - * xenstore page allocation will happen in - * init-dom0less. This feature can't be enabled - * without the DOM0LESS_ENHANCED_NO_XS. - * DOM0LESS_ENHANCED: Notify the OS it is running on top of Xen. Al= l the - * default features (including Xenstore) will be - * available. Note that an OS *must* not rely on= the - * availability of Xen features if this is not s= et. - * DOM0LESS_ENHANCED_LEGACY: Same as before, but using DOM0LESS_XS_LEGACY. - */ -#define DOM0LESS_ENHANCED_NO_XS BIT(0, U) -#define DOM0LESS_XENSTORE BIT(1, U) -#define DOM0LESS_XS_LEGACY BIT(2, U) -#define DOM0LESS_ENHANCED_LEGACY (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XS_LE= GACY) -#define DOM0LESS_ENHANCED (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XENST= ORE) - -struct kernel_info { +struct arch_kernel_info +{ #ifdef CONFIG_ARM_64 enum domain_type type; #endif - - struct domain *d; - - void *fdt; /* flat device tree */ - paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */ - struct meminfo mem; -#ifdef CONFIG_STATIC_SHM - struct shared_meminfo shm_mem; -#endif - - /* kernel entry point */ - paddr_t entry; - - /* grant table region */ - paddr_t gnttab_start; - paddr_t gnttab_size; - - /* boot blob load addresses */ - const struct bootmodule *kernel_bootmodule, *initrd_bootmodule, *dtb_b= ootmodule; - const char* cmdline; - paddr_t dtb_paddr; - paddr_t initrd_paddr; - - /* Enable pl011 emulation */ - bool vpl011; - - /* Enable/Disable PV drivers interfaces */ - uint16_t dom0less_feature; - - /* GIC phandle */ - uint32_t phandle_gic; - - /* loader to use for this kernel */ - void (*load)(struct kernel_info *info); - /* loader specific state */ - union { - struct { - paddr_t kernel_addr; - paddr_t len; -#ifdef CONFIG_ARM_64 - paddr_t text_offset; /* 64-bit Image only */ -#endif - paddr_t start; /* Must be 0 for 64-bit Image */ - } zimage; - }; }; =20 -static inline struct membanks *kernel_info_get_mem(struct kernel_info *kin= fo) -{ - return container_of(&kinfo->mem.common, struct membanks, common); -} - -static inline const struct membanks * -kernel_info_get_mem_const(const struct kernel_info *kinfo) -{ - return container_of(&kinfo->mem.common, const struct membanks, common); -} - -#ifdef CONFIG_STATIC_SHM -#define KERNEL_INFO_SHM_MEM_INIT \ - .shm_mem.common.max_banks =3D NR_SHMEM_BANKS, \ - .shm_mem.common.type =3D STATIC_SHARED_MEMORY, -#else -#define KERNEL_INFO_SHM_MEM_INIT -#endif - -#define KERNEL_INFO_INIT \ -{ \ - .mem.common.max_banks =3D NR_MEM_BANKS, \ - .mem.common.type =3D MEMORY, \ - KERNEL_INFO_SHM_MEM_INIT \ -} - -/* - * Probe the kernel to detemine its type and select a loader. - * - * Sets in info: - * ->type - * ->load hook, and sets loader specific variables ->zimage - */ -int kernel_probe(struct kernel_info *info, const struct dt_device_node *do= main); - -/* - * Loads the kernel into guest RAM. - * - * Expects to be set in info when called: - * ->mem - * ->fdt - * - * Sets in info: - * ->entry - * ->dtb_paddr - * ->initrd_paddr - */ -void kernel_load(struct kernel_info *info); - #endif /* #ifdef __ARCH_ARM_KERNEL_H__ */ =20 /* diff --git a/xen/arch/arm/include/asm/static-memory.h b/xen/arch/arm/includ= e/asm/static-memory.h index 804166e541..a32a3c6553 100644 --- a/xen/arch/arm/include/asm/static-memory.h +++ b/xen/arch/arm/include/asm/static-memory.h @@ -3,8 +3,8 @@ #ifndef __ASM_STATIC_MEMORY_H_ #define __ASM_STATIC_MEMORY_H_ =20 +#include #include -#include =20 #ifdef CONFIG_STATIC_MEMORY =20 diff --git a/xen/arch/arm/include/asm/static-shmem.h b/xen/arch/arm/include= /asm/static-shmem.h index 94eaa9d500..a4f853805a 100644 --- a/xen/arch/arm/include/asm/static-shmem.h +++ b/xen/arch/arm/include/asm/static-shmem.h @@ -3,8 +3,8 @@ #ifndef __ASM_STATIC_SHMEM_H_ #define __ASM_STATIC_SHMEM_H_ =20 +#include #include -#include #include =20 #ifdef CONFIG_STATIC_SHM diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index 2647812e8e..f00fc388db 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ #include #include =20 +#include #include #include =20 @@ -101,7 +103,7 @@ static paddr_t __init kernel_zimage_place(struct kernel= _info *info) paddr_t load_addr; =20 #ifdef CONFIG_ARM_64 - if ( (info->type =3D=3D DOMAIN_64BIT) && (info->zimage.start =3D=3D 0)= ) + if ( (info->arch.type =3D=3D DOMAIN_64BIT) && (info->zimage.start =3D= =3D 0) ) return mem->bank[0].start + info->zimage.text_offset; #endif =20 @@ -371,10 +373,10 @@ static int __init kernel_uimage_probe(struct kernel_i= nfo *info, switch ( uimage.arch ) { case IH_ARCH_ARM: - info->type =3D DOMAIN_32BIT; + info->arch.type =3D DOMAIN_32BIT; break; case IH_ARCH_ARM64: - info->type =3D DOMAIN_64BIT; + info->arch.type =3D DOMAIN_64BIT; break; default: printk(XENLOG_ERR "Unsupported uImage arch type %d\n", uimage.arch= ); @@ -444,7 +446,7 @@ static int __init kernel_zimage64_probe(struct kernel_i= nfo *info, =20 info->load =3D kernel_zimage_load; =20 - info->type =3D DOMAIN_64BIT; + info->arch.type =3D DOMAIN_64BIT; =20 return 0; } @@ -496,7 +498,7 @@ static int __init kernel_zimage32_probe(struct kernel_i= nfo *info, info->load =3D kernel_zimage_load; =20 #ifdef CONFIG_ARM_64 - info->type =3D DOMAIN_32BIT; + info->arch.type =3D DOMAIN_32BIT; #endif =20 return 0; diff --git a/xen/arch/arm/static-memory.c b/xen/arch/arm/static-memory.c index d4585c5a06..e0f76afcd8 100644 --- a/xen/arch/arm/static-memory.c +++ b/xen/arch/arm/static-memory.c @@ -2,6 +2,7 @@ =20 #include =20 +#include #include =20 static bool __init append_static_memory_to_bank(struct domain *d, diff --git a/xen/arch/arm/static-shmem.c b/xen/arch/arm/static-shmem.c index e8d4ca3ba3..14ae48fb1e 100644 --- a/xen/arch/arm/static-shmem.c +++ b/xen/arch/arm/static-shmem.c @@ -6,6 +6,7 @@ #include =20 #include +#include #include #include =20 diff --git a/xen/common/device-tree/dt-overlay.c b/xen/common/device-tree/d= t-overlay.c index 97fb99eaaa..81107cb48d 100644 --- a/xen/common/device-tree/dt-overlay.c +++ b/xen/common/device-tree/dt-overlay.c @@ -6,8 +6,8 @@ * Written by Vikram Garhwal * */ -#include #include +#include #include #include #include diff --git a/xen/include/asm-generic/dom0less-build.h b/xen/include/asm-gen= eric/dom0less-build.h index 5655571a66..f095135caa 100644 --- a/xen/include/asm-generic/dom0less-build.h +++ b/xen/include/asm-generic/dom0less-build.h @@ -16,6 +16,34 @@ struct dt_device_node; #define XENSTORE_PFN_LATE_ALLOC UINT64_MAX extern bool need_xenstore; =20 +/* + * List of possible features for dom0less domUs + * + * DOM0LESS_ENHANCED_NO_XS: Notify the OS it is running on top of Xen. Al= l the + * default features (excluding Xenstore) will be + * available. Note that an OS *must* not rely on= the + * availability of Xen features if this is not s= et. + * DOM0LESS_XENSTORE: Xenstore will be enabled for the VM. The + * xenstore page allocation is done by Xen at + * domain creation. This feature can't be + * enabled without the DOM0LESS_ENHANCED_NO_XS. + * DOM0LESS_XS_LEGACY Xenstore will be enabled for the VM, the + * xenstore page allocation will happen in + * init-dom0less. This feature can't be enabled + * without the DOM0LESS_ENHANCED_NO_XS. + * DOM0LESS_ENHANCED: Notify the OS it is running on top of Xen. Al= l the + * default features (including Xenstore) will be + * available. Note that an OS *must* not rely on= the + * availability of Xen features if this is not s= et. + * DOM0LESS_ENHANCED_LEGACY: Same as before, but using DOM0LESS_XS_LEGACY. + + */ +#define DOM0LESS_ENHANCED_NO_XS BIT(0, U) +#define DOM0LESS_XENSTORE BIT(1, U) +#define DOM0LESS_XS_LEGACY BIT(2, U) +#define DOM0LESS_ENHANCED_LEGACY (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XS_LE= GACY) +#define DOM0LESS_ENHANCED (DOM0LESS_ENHANCED_NO_XS | DOM0LESS_XENST= ORE) + void create_domUs(void); bool is_dom0less_mode(void); void set_xs_domain(struct domain *d); diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h new file mode 100644 index 0000000000..c81e759423 --- /dev/null +++ b/xen/include/xen/fdt-kernel.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * For Kernel image loading. + * + * Copyright (C) 2011 Citrix Systems, Inc. + */ +#ifndef __XEN_FDT_KERNEL_H__ +#define __XEN_FDT_KERNEL_H__ + +#include +#include +#include + +#if __has_include() +# include +#endif + +struct kernel_info { + struct domain *d; + + void *fdt; /* flat device tree */ + paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */ + struct meminfo mem; +#ifdef CONFIG_STATIC_SHM + struct shared_meminfo shm_mem; +#endif + + /* kernel entry point */ + paddr_t entry; + + /* grant table region */ + paddr_t gnttab_start; + paddr_t gnttab_size; + + /* boot blob load addresses */ + const struct bootmodule *kernel_bootmodule, *initrd_bootmodule, *dtb_b= ootmodule; + const char* cmdline; + paddr_t dtb_paddr; + paddr_t initrd_paddr; + + /* Enable uart emulation */ + bool vuart; + + /* Enable/Disable PV drivers interfaces */ + uint16_t dom0less_feature; + + /* Interrupt controller phandle */ + uint32_t phandle_intc; + + /* loader to use for this kernel */ + void (*load)(struct kernel_info *info); + + /* loader specific state */ + union { + struct { + paddr_t kernel_addr; + paddr_t len; +#if defined(CONFIG_ARM_64) || defined(CONFIG_RISCV_64) + paddr_t text_offset; /* 64-bit Image only */ +#endif + paddr_t start; /* Must be 0 for 64-bit Image */ + } zimage; + }; + +#if __has_include() + struct arch_kernel_info arch; +#endif +}; + +static inline struct membanks *kernel_info_get_mem(struct kernel_info *kin= fo) +{ + return container_of(&kinfo->mem.common, struct membanks, common); +} + +static inline const struct membanks * +kernel_info_get_mem_const(const struct kernel_info *kinfo) +{ + return container_of(&kinfo->mem.common, const struct membanks, common); +} + +#ifndef KERNEL_INFO_SHM_MEM_INIT + +#ifdef CONFIG_STATIC_SHM +#define KERNEL_INFO_SHM_MEM_INIT .shm_mem.common.max_banks =3D NR_SHMEM_BA= NKS, +#else +#define KERNEL_INFO_SHM_MEM_INIT +#endif + +#endif /* KERNEL_INFO_SHM_MEM_INIT */ + +#ifndef KERNEL_INFO_INIT + +#define KERNEL_INFO_INIT \ +{ \ + .mem.common.max_banks =3D NR_MEM_BANKS, \ + KERNEL_INFO_SHM_MEM_INIT \ +} + +#endif /* KERNEL_INFO_INIT */ + +/* + * Probe the kernel to detemine its type and select a loader. + * + * Sets in info: + * ->type + * ->load hook, and sets loader specific variables ->zimage + */ +int kernel_probe(struct kernel_info *info, const struct dt_device_node *do= main); + +/* + * Loads the kernel into guest RAM. + * + * Expects to be set in info when called: + * ->mem + * ->fdt + * + * Sets in info: + * ->entry + * ->dtb_paddr + * ->initrd_paddr + */ +void kernel_load(struct kernel_info *info); + +#endif /* __XEN_FDT_KERNEL_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746202994; cv=none; d=zohomail.com; s=zohoarc; b=JtZzhIFnnhwv5VOLhEIhjdkYqYsO9yA7m314C0QqkuxWYp+epexSvHIFn68nXU+1374DvEfHtV/lhJxy3aAOwEKnm1V93Bsa9A65c8mCXnGaQGTaAEZ1iCzVQ08+QxrHDRAJfdV1tawu5LF/zGXIxiImNZcBvsB7VwpWdb1qw9Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746202994; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GUnfT2l87qKF2diopszkoUIkPb5NuR2WPUZYnC7hfok=; b=F98U8ia+8e8zsG1De3SklqB1YMGpV4/3BmnmwH2ie4/5cU/Uto9Jzr9p+wF5jCrDbQMwv0QTx3TKYKyJaMaXbn+nrKqzUHRsJuEUCaBAVudZ58zcNrScVYrbVXd5L30dn8wTYRa5dqvnDzKzkq8p9n7AgzGtli5EZQYvf5d+8f0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746202994560227.5927443647248; Fri, 2 May 2025 09:23:14 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974787.1362584 (Exim 4.92) (envelope-from ) id 1uAtA1-0006lP-FM; Fri, 02 May 2025 16:22:49 +0000 Received: by outflank-mailman (output) from mailman id 974787.1362584; Fri, 02 May 2025 16:22:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtA1-0006kl-Ap; Fri, 02 May 2025 16:22:49 +0000 Received: by outflank-mailman (input) for mailman id 974787; Fri, 02 May 2025 16:22:47 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9z-0005rY-Lg for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:47 +0000 Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [2a00:1450:4864:20::630]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ae782e10-2771-11f0-9ffb-bf95429c2676; Fri, 02 May 2025 18:22:46 +0200 (CEST) Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-ace3b03c043so324833566b.2 for ; Fri, 02 May 2025 09:22:46 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:45 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ae782e10-2771-11f0-9ffb-bf95429c2676 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202965; x=1746807765; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GUnfT2l87qKF2diopszkoUIkPb5NuR2WPUZYnC7hfok=; b=UqivhO8hk9oL+PFMO3RH8AC5oPzvK4i6e94TB8Bs4u94VVuJhQiFREHSlbekRYTteS 8qDKAvG6aaFzpmChPvcLWaeEkU9TC6IZbSDPtxQdojpRhQcXVpD9bQ3rIjrpKy/hpjx+ h0oLBeSmswgWx8NrkXlH7ZneVSzpucNpVsCSa/BP4EA4Xzkx75EthcIznD2+iP7H/TVH ce5SrHFK/rJGLp8q3sC28e4cxU7833F51xWiOneGWy6y3jl52AuQGy8qUt+bnjc9fk0a +7h6SnG5ZMy0TZNb/Zxfz2fElUvXHRxhNNRThiGCGTZihQTARS80Nv6MBS6bCG2PBark tq0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202965; x=1746807765; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GUnfT2l87qKF2diopszkoUIkPb5NuR2WPUZYnC7hfok=; b=Bu6WLeICisOBxdF+li+fUpZJHkxqW1ddmL6QZya0JSwvHByOoOcEtC5+K7o61C/1Ht f097k8thUI8VH5D9fzktmp/GjgkSvyJ+uLDuHzxbEv1TH/VmRJ3OSH4jlfUA6gkS0UBt JbSB64DpcOA5qq1ZMkrEsce+OcmeJb9OZuKq4XlDYjRg9+OXDKtciJNsoKIBIyBylQkh Bczj9ZeM9WVA/b0v+2MFdT3QPK22jYP6DIPShZ2ke4BATdjfjNaR3sJRr9GVz7nfDE8G JJFGUENtuqI9c5j3CIU/5RxcAshpRM5wWe6xsT32c9Rjw1eqIhP9r+K8YgYwGCtPr/+y 8ncg== X-Gm-Message-State: AOJu0YzYWTyxYa2xPAqLktu33/hgusSDXeo04SIUHJYfKvls0CnsvYn3 cI2+7PqjZBrIZH/Q38NUR5hGY5vJ4+poguePFnlf1DBXlv0l3Z4kOZVC1w== X-Gm-Gg: ASbGncvaXF1fm+BUEKSDGhqy1DJzWMhy4cNarPy6h10O+g+LN6yE699N3kBdxXls4FB LjFwp+zndSh6mAuMjrsdGpK+JdkLIJ4R3V1zsxtklYFFsEo5nLICR77TsIzxuzFqLzRN6+prwHC j6DUNQ8JHsAMXkKKnGiZ2zJoTXtdQFE6LWKg14IqFfk3p+hK8GbxtjSN+XWaKctWHTbwQEMHPcw UGjPTm17Cc9xm8XJXEOVgULBa5axHFasWpAGmkhHcBz9eIR+4OitDQoA88Qgw6+bfqbylVb7Y7a 8+sk1A5v1Wh9nxBJyGzedHl+33kk09D6UUFnHEVP4HFz450yTNze+P3zI+qx8dA1gZkEWZTbGXS TheAcsM0Plg== X-Google-Smtp-Source: AGHT+IGtFzwT6D6y10u4kO1tm8gVNtyNHsF29taj/ekvV8Ee/bnhSAIr3w8QQ8ZXv7tca3xsqBx1mw== X-Received: by 2002:a17:907:60cf:b0:ac3:446d:142 with SMTP id a640c23a62f3a-ad17ad39ff9mr376934066b.2.1746202965316; Fri, 02 May 2025 09:22:45 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH v3 4/8] arm/static-shmem.h: drop inclusion of asm/setup.h Date: Fri, 2 May 2025 18:22:34 +0200 Message-ID: <5e02dc75f4f396d054e9b9206b9305889cadb1a5.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746202995503116600 Content-Type: text/plain; charset="utf-8" Nothing is dependent from asm/setup.h in asm/static-shmem.h so inclusion of asm/setup.h is droped. After this drop the following compilation error related to impicit declarat= ion of the following functions device_tree_get_reg and map_device_irqs_to_domai= n, device_tree_get_u32 occur during compilation of dom0less-build.c ( as they = are declared in asm/setup.h ). Add inclusion of in dt-overlay.c as it is using handle_device= () declared in . Signed-off-by: Oleksii Kurochko --- Changes in V2-3: - Nothing changed. Only rebase. --- xen/arch/arm/dom0less-build.c | 1 + xen/common/device-tree/dt-overlay.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index c0634dd61e..7eecd06d44 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include =20 diff --git a/xen/common/device-tree/dt-overlay.c b/xen/common/device-tree/d= t-overlay.c index 81107cb48d..d184186c01 100644 --- a/xen/common/device-tree/dt-overlay.c +++ b/xen/common/device-tree/dt-overlay.c @@ -13,6 +13,8 @@ #include #include =20 +#include + #define DT_OVERLAY_MAX_SIZE KB(500) =20 static LIST_HEAD(overlay_tracker); --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746202992; cv=none; d=zohomail.com; s=zohoarc; b=OfIMzOfBfYrH2F6lTCpcAImhdkz9nJsl4ipDu9ziNJOV0j4oMfHPQtIknMy2QU6kJztAJYLhBMiSlyzgE+54xYXRB3BR2Iv/mQIY5OEq4+TJAltm9sIdqrnLDydvSZEGd57tCPvfzpBTTiTvshDGvATqSr0wjcV9hYcNuDi8cTY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746202992; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+JrfvyxSkM64biX/am1b6/5d/FYxpOpOjwig6QZTZeo=; b=EOtqa+qroWqYwQrbZvQFGnTitZvgOY4nfx82HQA4i+OHBoBdqOCdKGDJa0rOhwGTi8PdqniCB0/VHT6ZK4ev5YLZP1gdFGTyRcpwPQp6fZUKA9bVqdxGg2zCIkV0l5Zzj8+ugCO5PxChRgss5ZLCN1d2QWMMSD0sjGbbSICJSNc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746202992872252.12216585558235; Fri, 2 May 2025 09:23:12 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974788.1362590 (Exim 4.92) (envelope-from ) id 1uAtA1-0006pn-Qk; Fri, 02 May 2025 16:22:49 +0000 Received: by outflank-mailman (output) from mailman id 974788.1362590; Fri, 02 May 2025 16:22:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtA1-0006oX-KB; Fri, 02 May 2025 16:22:49 +0000 Received: by outflank-mailman (input) for mailman id 974788; Fri, 02 May 2025 16:22:47 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAt9z-0005rZ-Lx for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:47 +0000 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [2a00:1450:4864:20::632]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id aefd9725-2771-11f0-9eb4-5ba50f476ded; Fri, 02 May 2025 18:22:47 +0200 (CEST) Received: by mail-ej1-x632.google.com with SMTP id a640c23a62f3a-ac2dfdf3c38so403589066b.3 for ; Fri, 02 May 2025 09:22:47 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:45 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: aefd9725-2771-11f0-9eb4-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202966; x=1746807766; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+JrfvyxSkM64biX/am1b6/5d/FYxpOpOjwig6QZTZeo=; b=Z/P/C2+vOld7vSi0p4IgWn/3sXZWR/82a+xIVcBzNyw24qA9v5INVpoX7m2hqvYYJh TTScRbNwk60qKwUF5PqRSrG4sYwJ+1mBQjFM6i+/gR0rx2MKss5dPx+0P6UJgdh3hHFd +Ubt4xqE8o4c8u7WOPJeQ/6eJebFQlAtDIwkddYdzbIyNP52Y9ivaqn6ElhfFgfTHGNG ZLnuSEbWP3OzLIpAmUxYJBO7LYicPzUq8lDG3kl+ZOsDpNXhbtZPm89oA+pYuNqO2l3Z ldZFJLHjCEbQO67Vx05qN7bEAAUM/q2DQ9lcu0hQdcJL22gXn5QggJsuNk2APTAE7n1t U1FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202966; x=1746807766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+JrfvyxSkM64biX/am1b6/5d/FYxpOpOjwig6QZTZeo=; b=nPBEQuNQbw+7WtU5os6OV69QeIvY+keOk5Rq4lkzCX6U6KQZplgEhJFXiXEde+tWf9 4Uxf/Jp+N1Rq14tvaoo1lnj7WV2xERW9D3Mz1VXNIC6aCV5VZfmlNDYnmhZvptVWPL+Q Uf3JyQbqXbAsokslDAFT/8KNDVDtuL03CXOizeOG4iA45Vw4ar0tg84mRA9aXkw40/Wp jjXmTNAdxFufYDTnvipOFxTXHJ7GLGzoMgfjBWLoBzkxbUZL64+W4LTmhGB4HL5TBQPU hxhBvTkjvP5pDZJvztRHdcDhJpZGIfX9fahUGZHVb+BFEHibRP0R4KeQRXudSoEH65cu tgCw== X-Gm-Message-State: AOJu0YzBni+OxOywrwdoUL3BJm7EbYHhD/4SbYkC4ki3g6voEGD4C8bl CBQ5JUvjAlrG43B41oP9WgdzJleplIkAjh516YVDaxko+sMoHcyz/W5Svw== X-Gm-Gg: ASbGncuXHdMSreGfk0/SSn2q4S4lddgvtVDl4A8r3mYUdv/xgkwOmVoN/rBX0ZGQMbx 2tMRoNK4yCu4m+WpX29p6I8ijX2TI3tUZ5oJKsBY8LOJQRZL7XSNnEbm+uicv8CPQaOY46AU/y0 fA/MDuDfM8eDJYJcEqzgw7kVOQzpc5OHbPm8S+z13h30DJgLkEcu55KedoS9HIPUeqkEfmx4DZa BRkI2XDNGEuyS5Hm+SFotUSQjg20o7M/i8Ojrsw8Av4iGQSWEBm8SmcQbQLo39l+3LreLOSxwRF BApaIai8qHyrFZ0Ky9o/8dmexTJ69o78cpIP0esY7yL4Ye2juNCFPa6AXJwvh6+E+mOrsLiuBIY IfMDAGi7g2A== X-Google-Smtp-Source: AGHT+IGpvTrTs4R9+cvgRyOaBz28ykGN+IVQHA9MrRTcQ2GDeRdCTzBEXuHwDhoQTH1aibTwzjquoA== X-Received: by 2002:a17:906:9c8c:b0:ac2:d0e6:2b99 with SMTP id a640c23a62f3a-ad17adc78d2mr327424366b.36.1746202966176; Fri, 02 May 2025 09:22:46 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 5/8] asm-generic: move some parts of Arm's domain_build.h to common Date: Fri, 2 May 2025 18:22:35 +0200 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746202993600116600 Content-Type: text/plain; charset="utf-8" Nothing changed. Only some functions declaration are moved to xen/include/ headers as they are expected to be used by common code of domain builing or dom0less. Signed-off-by: Oleksii Kurochko --- Chnages in v3: - Drop inclusion of from xen/fdt-domain-build.h. - Add empty line after license tag in xen/fdt-domain-build.h. --- Chnages in v2: - Add missed declaration of construct_hwdom(). - Drop unnessary blank line. - Introduce xen/fdt-domain-build.h and move parts of Arm's domain_build.h= to it. - Update the commit message. --- xen/arch/arm/acpi/domain_build.c | 1 + xen/arch/arm/dom0less-build.c | 1 + xen/arch/arm/domain_build.c | 1 + xen/arch/arm/include/asm/domain_build.h | 21 ++---------- xen/arch/arm/kernel.c | 1 + xen/arch/arm/static-shmem.c | 1 + xen/include/xen/fdt-domain-build.h | 43 +++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 xen/include/xen/fdt-domain-build.h diff --git a/xen/arch/arm/acpi/domain_build.c b/xen/arch/arm/acpi/domain_bu= ild.c index f9ca8b47e5..1c3555d814 100644 --- a/xen/arch/arm/acpi/domain_build.c +++ b/xen/arch/arm/acpi/domain_build.c @@ -10,6 +10,7 @@ */ =20 #include +#include #include #include #include diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index 7eecd06d44..0310579863 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include #include +#include #include #include #include diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 8c7a054718..9d649b06b3 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include #include +#include #include #include #include diff --git a/xen/arch/arm/include/asm/domain_build.h b/xen/arch/arm/include= /asm/domain_build.h index df1c0fe301..397e408a1f 100644 --- a/xen/arch/arm/include/asm/domain_build.h +++ b/xen/arch/arm/include/asm/domain_build.h @@ -5,28 +5,13 @@ #include =20 typedef __be32 gic_interrupt_t[3]; -typedef bool (*alloc_domheap_mem_cb)(struct domain *d, struct page_info *p= g, - unsigned int order, void *extra); -bool allocate_domheap_memory(struct domain *d, paddr_t tot_size, - alloc_domheap_mem_cb cb, void *extra); -bool allocate_bank_memory(struct kernel_info *kinfo, gfn_t sgfn, - paddr_t tot_size); -void allocate_memory(struct domain *d, struct kernel_info *kinfo); -int construct_domain(struct domain *d, struct kernel_info *kinfo); -int construct_hwdom(struct kernel_info *kinfo, - const struct dt_device_node *node); + int domain_fdt_begin_node(void *fdt, const char *name, uint64_t unit); -int make_chosen_node(const struct kernel_info *kinfo); -int make_cpus_node(const struct domain *d, void *fdt); -int make_hypervisor_node(struct domain *d, const struct kernel_info *kinfo, - int addrcells, int sizecells); -int make_memory_node(const struct kernel_info *kinfo, int addrcells, - int sizecells, const struct membanks *mem); int make_psci_node(void *fdt); -int make_timer_node(const struct kernel_info *kinfo); void evtchn_allocate(struct domain *d); =20 -unsigned int get_allocation_size(paddr_t size); +int construct_hwdom(struct kernel_info *kinfo, + const struct dt_device_node *node); =20 /* * Helper to write an interrupts with the GIC format diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index f00fc388db..5759a3470a 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/xen/arch/arm/static-shmem.c b/xen/arch/arm/static-shmem.c index 14ae48fb1e..1f8441d920 100644 --- a/xen/arch/arm/static-shmem.c +++ b/xen/arch/arm/static-shmem.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ =20 #include +#include #include #include #include diff --git a/xen/include/xen/fdt-domain-build.h b/xen/include/xen/fdt-domai= n-build.h new file mode 100644 index 0000000000..b79e9fabfe --- /dev/null +++ b/xen/include/xen/fdt-domain-build.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __XEN_FDT_DOMAIN_BUILD_H__ +#define __XEN_FDT_DOMAIN_BUILD_H__ + +#include +#include +#include +#include + +struct domain; +struct page_info; +struct membanks; + +typedef bool (*alloc_domheap_mem_cb)(struct domain *d, struct page_info *p= g, + unsigned int order, void *extra); +bool allocate_domheap_memory(struct domain *d, paddr_t tot_size, + alloc_domheap_mem_cb cb, void *extra); + +bool allocate_bank_memory(struct kernel_info *kinfo, gfn_t sgfn, + paddr_t tot_size); +void allocate_memory(struct domain *d, struct kernel_info *kinfo); +int construct_domain(struct domain *d, struct kernel_info *kinfo); +int make_chosen_node(const struct kernel_info *kinfo); +int make_cpus_node(const struct domain *d, void *fdt); +int make_hypervisor_node(struct domain *d, const struct kernel_info *kinfo, + int addrcells, int sizecells); +int make_memory_node(const struct kernel_info *kinfo, int addrcells, + int sizecells, const struct membanks *mem); +int make_timer_node(const struct kernel_info *kinfo); + +unsigned int get_allocation_size(paddr_t size); + +#endif /* __XEN_FDT_DOMAIN_BUILD_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746202991; cv=none; d=zohomail.com; s=zohoarc; b=b9OgCWHcjnM0ISC7iAjllRbhLkNVgWPoUyDXRNgQvOIqC4EwPb7XaEoUHMbL74GWjh/YBWApO5l0qGmsy5fQIO0ksAeyt4hD0iNYFxFVma3ExILnYFw68rtc86KcYr/ruDbe2rwAgAgu4dgjfTy+9C9IlTHGZSNCaTTstLrOTx8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746202991; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tEw+WJZfn43Csy9BpwvLETZuuvhLgTLz5jLGN2Akw+k=; b=N1RrIurXZHrVdL23B1G6wSsmUVUhkOxIiBJnXQvgiaPdrVLZpRrHxpy2Xum6i4TrnMISjqWfrlfwQQZJjFvuFtdSHLpvmR3XdF8MrbhS1/on9k4w0m67I824rl4ltNfa031IihwLpZoUE7hV9G7VJsO2pzE79kwJJ5KKqMNt33w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 174620299125147.65435744186573; Fri, 2 May 2025 09:23:11 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974790.1362605 (Exim 4.92) (envelope-from ) id 1uAtA8-0007Qu-7L; Fri, 02 May 2025 16:22:56 +0000 Received: by outflank-mailman (output) from mailman id 974790.1362605; Fri, 02 May 2025 16:22:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtA8-0007Qk-2z; Fri, 02 May 2025 16:22:56 +0000 Received: by outflank-mailman (input) for mailman id 974790; Fri, 02 May 2025 16:22:54 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtA6-0005rZ-QZ for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:54 +0000 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [2a00:1450:4864:20::636]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b24c8439-2771-11f0-9eb4-5ba50f476ded; Fri, 02 May 2025 18:22:52 +0200 (CEST) Received: by mail-ej1-x636.google.com with SMTP id a640c23a62f3a-ace333d5f7bso395823866b.3 for ; Fri, 02 May 2025 09:22:52 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:51 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b24c8439-2771-11f0-9eb4-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202972; x=1746807772; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tEw+WJZfn43Csy9BpwvLETZuuvhLgTLz5jLGN2Akw+k=; b=nPk68OEStxSeyJDyjxTN+BC629pLYpLUJsz9Bc1qmFTllwNwgUz2Hw1cxC6AnqYIA9 Wjw2h+C+W82ULEMf0VmQdfTk/lQ8jsQxcTu5RzN8ai6ydHuAYYz/sNnTOnzi2lZxApNd KPnrwY9Jtl3BgiGHy0VBG16Rqzlas69MaB0uGt2R3bRCMW0K44HGey9XRv4KqcwniGgg GgiXzh9uYVfUPafoDI5rz+ZXMC/RklkvBLMUvVPBANouyD50+VvJUViAG9K6kAzARM2I WUMWfTcbyV3HNSKgetd76I5M6+WKIxn9mwI1MdKeUhFY2K5be6pq9DQ6TAXVQMIgflKb RzPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202972; x=1746807772; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tEw+WJZfn43Csy9BpwvLETZuuvhLgTLz5jLGN2Akw+k=; b=P2Ru9VSrBiCuLkbVmgLI2H6I6+KlcWKrOL9YSwkasxL7giDhYLt8p2fiFXW8SpP3c6 b9kuYitMJGwS+n8Neb99oODiZvFcyqYa+ywEycd/6x7rArcESRvh+LpabYKyBM8yMf3W ddEg/sL9Q42reipe5GLYD0++Af7CVWtVvEyCIsfm0HemY4hWXD6rR8zY94ahlXvnJpdQ 8wrsaA4khRjTnrzUPZ4glA369prAQiJ1/l43KeR4SWeUhO+62AwHNzD2dGXRmGMNy55H 0rgrj7Fwbxr8oQY2iv9AdytKG0XTTcNfLWtQYhDdMqBib6WpTsGDffl06qsIjV1M2gDt nZYw== X-Gm-Message-State: AOJu0YzpJsZ+/2ITkNL26A+clB7JKLMsdZgVGP3Y6B67lj8YNtkEJlMP UqknpPQCI5rs96/2KdBCDj3lyCn50rZOqvLoiNxonSi3XVXZkoUFYY3iWA== X-Gm-Gg: ASbGncu3wAe1H2cznYk8KQdOTysJH7P2dAMBmyC5RY4XyYZGPbXEG6kFvcDe3K9LygY /5F/adyO2F0Kq3DBScIfwtOonuhwpF+E8g+sWk3yz5Kkl6/xh3NZJ2z381Ahe7USqCwzZXs7ZH4 Kp6RUMPk366i/ifiC4DYTOHvDzO554AnO8W2XVzn+d9Tm+ARGET4U7uSTCg7g+j5snn3CzKrzNO Tf9vICrV77E2ddGYPZBZ9i7eE7DYiB1KEMmqFUt8LqgIEfljcEJzz8ejd6tqQxovUnHVnWzOj52 /GIV4c+b3A44USPC+zEpmZQAQNuXpY9jETuZKUNuD+JwLPXRt48U7v0mMpFdvR6HWlU5Ku+gEYd L5dmfVdO0zw== X-Google-Smtp-Source: AGHT+IGJqeBBZEnnt2UBWN3+GsBE3xoUmV3md9Kfm2+aZUnIUtn30Itw7ZkCZoVpVY/HJr94Kio83Q== X-Received: by 2002:a17:907:72d6:b0:aca:a1c9:d155 with SMTP id a640c23a62f3a-ad17ad3b336mr305439966b.11.1746202971582; Fri, 02 May 2025 09:22:51 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 6/8] xen/common: dom0less: introduce common kernel.c Date: Fri, 2 May 2025 18:22:36 +0200 Message-ID: <4f178bd0e46adf3d4c7a91d6cdd4a0910dbef490.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746202991778116600 Content-Type: text/plain; charset="utf-8" The following functions don't have arch specific things so it is moved to common: - kernel_prboe() - kernel_load() - output_length() Functions necessary for dom0less are only moved. The following changes are done: - Swap __init and return type of kernel_decompress() function to be consistent with defintions of functions in other files. The same for output_length(). - Wrap by "ifdef CONFIG_ARM" the call of kernel_uimage_probe() in kernel_probe() as uImage isn't really used nowadays thereby leave kernel_uimage_probe() call here just for compatability with Arm code. - Introduce kernel_zimage_probe() to cover the case that arch can have different zimage header. - Add ASSERT() for kernel_load() to check that it argument isn't NULL. - Make kernel_uimage_probe() non-static in Arm's code as it is used in common/kernel.c. Introduce CONFIG_DOMAIN_BUILD_HELPERS to not provide stubs for archs which don't provide enough functionality to enable it. Select CONFIG_DOMAIN_BUILD_HELPERS for CONFIG_ARM as only Arm supports it, at the moment. Signed-off-by: Oleksii Kurochko --- Change in v3: - Empty line after license tag for newly introduced files. --- Change in v2: - Drop inclusion of asm/kernel.h in kernel.c as everything necessary has been moved to xen/fdt-kernel.h. --- xen/arch/arm/Kconfig | 1 + xen/arch/arm/kernel.c | 221 +--------------------------- xen/common/Kconfig | 9 +- xen/common/device-tree/Makefile | 1 + xen/common/device-tree/kernel.c | 242 +++++++++++++++++++++++++++++++ xen/include/asm-generic/kernel.h | 141 ++++++++++++++++++ xen/include/xen/fdt-kernel.h | 13 ++ 7 files changed, 412 insertions(+), 216 deletions(-) create mode 100644 xen/common/device-tree/kernel.c create mode 100644 xen/include/asm-generic/kernel.h diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index d0e0a7753c..3321d89068 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -11,6 +11,7 @@ config ARM_64 =20 config ARM def_bool y + select DOMAIN_BUILD_HELPERS select FUNCTION_ALIGNMENT_4B select GENERIC_UART_INIT select HAS_ALTERNATIVE if HAS_VMAP diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index 5759a3470a..1168c21e97 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -163,105 +163,6 @@ static void __init kernel_zimage_load(struct kernel_i= nfo *info) iounmap(kernel); } =20 -static __init uint32_t output_length(char *image, unsigned long image_len) -{ - return *(uint32_t *)&image[image_len - 4]; -} - -static __init int kernel_decompress(struct bootmodule *mod, uint32_t offse= t) -{ - char *output, *input; - char magic[2]; - int rc; - unsigned int kernel_order_out; - paddr_t output_size; - struct page_info *pages; - mfn_t mfn; - int i; - paddr_t addr =3D mod->start; - paddr_t size =3D mod->size; - - if ( size < offset ) - return -EINVAL; - - /* - * It might be that gzip header does not appear at the start address - * (e.g. in case of compressed uImage) so take into account offset to - * gzip header. - */ - addr +=3D offset; - size -=3D offset; - - if ( size < 2 ) - return -EINVAL; - - copy_from_paddr(magic, addr, sizeof(magic)); - - /* only gzip is supported */ - if ( !gzip_check(magic, size) ) - return -EINVAL; - - input =3D ioremap_cache(addr, size); - if ( input =3D=3D NULL ) - return -EFAULT; - - output_size =3D output_length(input, size); - kernel_order_out =3D get_order_from_bytes(output_size); - pages =3D alloc_domheap_pages(NULL, kernel_order_out, 0); - if ( pages =3D=3D NULL ) - { - iounmap(input); - return -ENOMEM; - } - mfn =3D page_to_mfn(pages); - output =3D vmap_contig(mfn, 1 << kernel_order_out); - - rc =3D perform_gunzip(output, input, size); - clean_dcache_va_range(output, output_size); - iounmap(input); - vunmap(output); - - if ( rc ) - { - free_domheap_pages(pages, kernel_order_out); - return rc; - } - - mod->start =3D page_to_maddr(pages); - mod->size =3D output_size; - - /* - * Need to free pages after output_size here because they won't be - * freed by discard_initial_modules - */ - i =3D PFN_UP(output_size); - for ( ; i < (1 << kernel_order_out); i++ ) - free_domheap_page(pages + i); - - /* - * When using static heap feature, don't give bootmodules memory back = to - * the heap allocator - */ - if ( using_static_heap ) - return 0; - - /* - * When freeing the kernel, we need to pass the module start address a= nd - * size as they were before taking an offset to gzip header into accou= nt, - * so that the entire region will be freed. - */ - addr -=3D offset; - size +=3D offset; - - /* - * Free the original kernel, update the pointers to the - * decompressed kernel - */ - fw_unreserved_regions(addr, addr + size, init_domheap_pages, 0); - - return 0; -} - /* * Uimage CPU Architecture Codes */ @@ -274,8 +175,8 @@ static __init int kernel_decompress(struct bootmodule *= mod, uint32_t offset) /* * Check if the image is a uImage and setup kernel_info */ -static int __init kernel_uimage_probe(struct kernel_info *info, - struct bootmodule *mod) +int __init kernel_uimage_probe(struct kernel_info *info, + struct bootmodule *mod) { struct { __be32 magic; /* Image Header Magic Number */ @@ -505,130 +406,20 @@ static int __init kernel_zimage32_probe(struct kerne= l_info *info, return 0; } =20 -int __init kernel_probe(struct kernel_info *info, - const struct dt_device_node *domain) +int __init kernel_zimage_probe(struct kernel_info *info, paddr_t addr, + paddr_t size) { - struct bootmodule *mod =3D NULL; - struct bootcmdline *cmd =3D NULL; - struct dt_device_node *node; - u64 kernel_addr, initrd_addr, dtb_addr, size; int rc; =20 - /* - * We need to initialize start to 0. This field may be populated during - * kernel_xxx_probe() if the image has a fixed entry point (for e.g. - * uimage.ep). - * We will use this to determine if the image has a fixed entry point = or - * the load address should be used as the start address. - */ - info->entry =3D 0; - - /* domain is NULL only for the hardware domain */ - if ( domain =3D=3D NULL ) - { - ASSERT(is_hardware_domain(info->d)); - - mod =3D boot_module_find_by_kind(BOOTMOD_KERNEL); - - info->kernel_bootmodule =3D mod; - info->initrd_bootmodule =3D boot_module_find_by_kind(BOOTMOD_RAMDI= SK); - - cmd =3D boot_cmdline_find_by_kind(BOOTMOD_KERNEL); - if ( cmd ) - info->cmdline =3D &cmd->cmdline[0]; - } - else - { - const char *name =3D NULL; - - dt_for_each_child_node(domain, node) - { - if ( dt_device_is_compatible(node, "multiboot,kernel") ) - { - u32 len; - const __be32 *val; - - val =3D dt_get_property(node, "reg", &len); - dt_get_range(&val, node, &kernel_addr, &size); - mod =3D boot_module_find_by_addr_and_kind( - BOOTMOD_KERNEL, kernel_addr); - info->kernel_bootmodule =3D mod; - } - else if ( dt_device_is_compatible(node, "multiboot,ramdisk") ) - { - u32 len; - const __be32 *val; - - val =3D dt_get_property(node, "reg", &len); - dt_get_range(&val, node, &initrd_addr, &size); - info->initrd_bootmodule =3D boot_module_find_by_addr_and_k= ind( - BOOTMOD_RAMDISK, initrd_addr); - } - else if ( dt_device_is_compatible(node, "multiboot,device-tree= ") ) - { - uint32_t len; - const __be32 *val; - - val =3D dt_get_property(node, "reg", &len); - if ( val =3D=3D NULL ) - continue; - dt_get_range(&val, node, &dtb_addr, &size); - info->dtb_bootmodule =3D boot_module_find_by_addr_and_kind( - BOOTMOD_GUEST_DTB, dtb_addr); - } - else - continue; - } - name =3D dt_node_name(domain); - cmd =3D boot_cmdline_find_by_name(name); - if ( cmd ) - info->cmdline =3D &cmd->cmdline[0]; - } - if ( !mod || !mod->size ) - { - printk(XENLOG_ERR "Missing kernel boot module?\n"); - return -ENOENT; - } - - printk("Loading %pd kernel from boot module @ %"PRIpaddr"\n", - info->d, info->kernel_bootmodule->start); - if ( info->initrd_bootmodule ) - printk("Loading ramdisk from boot module @ %"PRIpaddr"\n", - info->initrd_bootmodule->start); - - /* - * uImage header always appears at the top of the image (even compress= ed), - * so it needs to be probed first. Note that in case of compressed uIm= age, - * kernel_decompress is called from kernel_uimage_probe making the fun= ction - * self-containing (i.e. fall through only in case of a header not fou= nd). - */ - rc =3D kernel_uimage_probe(info, mod); - if ( rc !=3D -ENOENT ) - return rc; - - /* - * If it is a gzip'ed image, 32bit or 64bit, uncompress it. - * At this point, gzip header appears (if at all) at the top of the im= age, - * so pass 0 as an offset. - */ - rc =3D kernel_decompress(mod, 0); - if ( rc && rc !=3D -EINVAL ) - return rc; - #ifdef CONFIG_ARM_64 - rc =3D kernel_zimage64_probe(info, mod->start, mod->size); + rc =3D kernel_zimage64_probe(info, addr, size); if (rc < 0) #endif - rc =3D kernel_zimage32_probe(info, mod->start, mod->size); + rc =3D kernel_zimage32_probe(info, addr, size); =20 return rc; } =20 -void __init kernel_load(struct kernel_info *info) -{ - info->load(info); -} - /* * Local variables: * mode: C diff --git a/xen/common/Kconfig b/xen/common/Kconfig index be38abf9e1..38981f1d11 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -14,13 +14,20 @@ config CORE_PARKING =20 config DOM0LESS_BOOT bool "Dom0less boot support" if EXPERT - depends on HAS_DOM0LESS + depends on HAS_DOM0LESS && DOMAIN_BUILD_HELPERS default y help Dom0less boot support enables Xen to create and start domU guests during Xen boot without the need of a control domain (Dom0), which could be present anyway. =20 +config DOMAIN_BUILD_HELPERS + bool + help + Introduce functions necessary for working with domain creation, kernel, + etc. As an examples, these type of functions are going to be used by + CONFIG_DOM0LESS_BOOT. + config GRANT_TABLE bool "Grant table support" if EXPERT default y diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makef= ile index f3dafc9b81..e88a4d5799 100644 --- a/xen/common/device-tree/Makefile +++ b/xen/common/device-tree/Makefile @@ -4,3 +4,4 @@ obj-y +=3D device-tree.o obj-$(CONFIG_DOM0LESS_BOOT) +=3D dom0less-build.o obj-$(CONFIG_OVERLAY_DTB) +=3D dt-overlay.o obj-y +=3D intc.o +obj-$(CONFIG_DOMAIN_BUILD_HELPERS) +=3D kernel.o diff --git a/xen/common/device-tree/kernel.c b/xen/common/device-tree/kerne= l.c new file mode 100644 index 0000000000..1bf3bbf64e --- /dev/null +++ b/xen/common/device-tree/kernel.c @@ -0,0 +1,242 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static uint32_t __init output_length(char *image, unsigned long image_len) +{ + return *(uint32_t *)&image[image_len - 4]; +} + +int __init kernel_decompress(struct bootmodule *mod, uint32_t offset) +{ + char *output, *input; + char magic[2]; + int rc; + unsigned int kernel_order_out; + paddr_t output_size; + struct page_info *pages; + mfn_t mfn; + int i; + paddr_t addr =3D mod->start; + paddr_t size =3D mod->size; + + if ( size < offset ) + return -EINVAL; + + /* + * It might be that gzip header does not appear at the start address + * (e.g. in case of compressed uImage) so take into account offset to + * gzip header. + */ + addr +=3D offset; + size -=3D offset; + + if ( size < 2 ) + return -EINVAL; + + copy_from_paddr(magic, addr, sizeof(magic)); + + /* only gzip is supported */ + if ( !gzip_check(magic, size) ) + return -EINVAL; + + input =3D ioremap_cache(addr, size); + if ( input =3D=3D NULL ) + return -EFAULT; + + output_size =3D output_length(input, size); + kernel_order_out =3D get_order_from_bytes(output_size); + pages =3D alloc_domheap_pages(NULL, kernel_order_out, 0); + if ( pages =3D=3D NULL ) + { + iounmap(input); + return -ENOMEM; + } + mfn =3D page_to_mfn(pages); + output =3D vmap_contig(mfn, 1 << kernel_order_out); + + rc =3D perform_gunzip(output, input, size); + clean_dcache_va_range(output, output_size); + iounmap(input); + vunmap(output); + + if ( rc ) + { + free_domheap_pages(pages, kernel_order_out); + return rc; + } + + mod->start =3D page_to_maddr(pages); + mod->size =3D output_size; + + /* + * Need to free pages after output_size here because they won't be + * freed by discard_initial_modules + */ + i =3D PFN_UP(output_size); + for ( ; i < (1 << kernel_order_out); i++ ) + free_domheap_page(pages + i); + + /* + * When using static heap feature, don't give bootmodules memory back = to + * the heap allocator + */ + if ( using_static_heap ) + return 0; + + /* + * When freeing the kernel, we need to pass the module start address a= nd + * size as they were before taking an offset to gzip header into accou= nt, + * so that the entire region will be freed. + */ + addr -=3D offset; + size +=3D offset; + + /* + * Free the original kernel, update the pointers to the + * decompressed kernel + */ + fw_unreserved_regions(addr, addr + size, init_domheap_pages, 0); + + return 0; +} + +int __init kernel_probe(struct kernel_info *info, + const struct dt_device_node *domain) +{ + struct bootmodule *mod =3D NULL; + struct bootcmdline *cmd =3D NULL; + struct dt_device_node *node; + u64 kernel_addr, initrd_addr, dtb_addr, size; + int rc; + + /* + * We need to initialize start to 0. This field may be populated during + * kernel_xxx_probe() if the image has a fixed entry point (for e.g. + * uimage.ep). + * We will use this to determine if the image has a fixed entry point = or + * the load address should be used as the start address. + */ + info->entry =3D 0; + + /* domain is NULL only for the hardware domain */ + if ( domain =3D=3D NULL ) + { + ASSERT(is_hardware_domain(info->d)); + + mod =3D boot_module_find_by_kind(BOOTMOD_KERNEL); + + info->kernel_bootmodule =3D mod; + info->initrd_bootmodule =3D boot_module_find_by_kind(BOOTMOD_RAMDI= SK); + + cmd =3D boot_cmdline_find_by_kind(BOOTMOD_KERNEL); + if ( cmd ) + info->cmdline =3D &cmd->cmdline[0]; + } + else + { + const char *name =3D NULL; + + dt_for_each_child_node(domain, node) + { + if ( dt_device_is_compatible(node, "multiboot,kernel") ) + { + u32 len; + const __be32 *val; + + val =3D dt_get_property(node, "reg", &len); + dt_get_range(&val, node, &kernel_addr, &size); + mod =3D boot_module_find_by_addr_and_kind( + BOOTMOD_KERNEL, kernel_addr); + info->kernel_bootmodule =3D mod; + } + else if ( dt_device_is_compatible(node, "multiboot,ramdisk") ) + { + u32 len; + const __be32 *val; + + val =3D dt_get_property(node, "reg", &len); + dt_get_range(&val, node, &initrd_addr, &size); + info->initrd_bootmodule =3D boot_module_find_by_addr_and_k= ind( + BOOTMOD_RAMDISK, initrd_addr); + } + else if ( dt_device_is_compatible(node, "multiboot,device-tree= ") ) + { + uint32_t len; + const __be32 *val; + + val =3D dt_get_property(node, "reg", &len); + if ( val =3D=3D NULL ) + continue; + dt_get_range(&val, node, &dtb_addr, &size); + info->dtb_bootmodule =3D boot_module_find_by_addr_and_kind( + BOOTMOD_GUEST_DTB, dtb_addr); + } + else + continue; + } + name =3D dt_node_name(domain); + cmd =3D boot_cmdline_find_by_name(name); + if ( cmd ) + info->cmdline =3D &cmd->cmdline[0]; + } + if ( !mod || !mod->size ) + { + printk(XENLOG_ERR "Missing kernel boot module?\n"); + return -ENOENT; + } + + printk("Loading %pd kernel from boot module @ %"PRIpaddr"\n", + info->d, info->kernel_bootmodule->start); + if ( info->initrd_bootmodule ) + printk("Loading ramdisk from boot module @ %"PRIpaddr"\n", + info->initrd_bootmodule->start); + + /* + * uImage isn't really used nowadays thereby leave kernel_uimage_probe= () + * call here just for compatability with Arm code. + */ +#ifdef CONFIG_ARM + /* + * uImage header always appears at the top of the image (even compress= ed), + * so it needs to be probed first. Note that in case of compressed uIm= age, + * kernel_decompress is called from kernel_uimage_probe making the fun= ction + * self-containing (i.e. fall through only in case of a header not fou= nd). + */ + rc =3D kernel_uimage_probe(info, mod); + if ( rc !=3D -ENOENT ) + return rc; +#endif + + /* + * If it is a gzip'ed image, 32bit or 64bit, uncompress it. + * At this point, gzip header appears (if at all) at the top of the im= age, + * so pass 0 as an offset. + */ + rc =3D kernel_decompress(mod, 0); + if ( rc && rc !=3D -EINVAL ) + return rc; + + rc =3D kernel_zimage_probe(info, mod->start, mod->size); + + return rc; +} + +void __init kernel_load(struct kernel_info *info) +{ + ASSERT(info && info->load); + + info->load(info); +} diff --git a/xen/include/asm-generic/kernel.h b/xen/include/asm-generic/ker= nel.h new file mode 100644 index 0000000000..6857fabb34 --- /dev/null +++ b/xen/include/asm-generic/kernel.h @@ -0,0 +1,141 @@ +/* + * Kernel image loading. + * + * Copyright (C) 2011 Citrix Systems, Inc. + */ + +#ifndef __ASM_GENERIC_KERNEL_H__ +#define __ASM_GENERIC_KERNEL_H__ + +#include +#include +#include +#include + +struct kernel_info { + struct domain *d; + + void *fdt; /* flat device tree */ + paddr_t unassigned_mem; /* RAM not (yet) assigned to a bank */ + struct meminfo mem; +#ifdef CONFIG_STATIC_SHM + struct shared_meminfo shm_mem; +#endif + + /* kernel entry point */ + paddr_t entry; + + /* grant table region */ + paddr_t gnttab_start; + paddr_t gnttab_size; + + /* boot blob load addresses */ + const struct bootmodule *kernel_bootmodule, *initrd_bootmodule, *dtb_b= ootmodule; + const char* cmdline; + paddr_t dtb_paddr; + paddr_t initrd_paddr; + + /* Enable uart emulation */ + bool vuart; + + /* Enable/Disable PV drivers interfaces */ + uint16_t dom0less_feature; + + /* Interrupt controller phandle */ + uint32_t phandle_intc; + + /* loader to use for this kernel */ + void (*load)(struct kernel_info *info); + + /* loader specific state */ + union { + struct { + paddr_t kernel_addr; + paddr_t len; +#if defined(CONFIG_ARM_64) || defined(CONFIG_RISCV_64) + paddr_t text_offset; /* 64-bit Image only */ +#endif + paddr_t start; /* Must be 0 for 64-bit Image */ + } zimage; + }; + + struct arch_kernel_info arch; +}; + +static inline struct membanks *kernel_info_get_mem(struct kernel_info *kin= fo) +{ + return container_of(&kinfo->mem.common, struct membanks, common); +} + +static inline const struct membanks * +kernel_info_get_mem_const(const struct kernel_info *kinfo) +{ + return container_of(&kinfo->mem.common, const struct membanks, common); +} + +#ifndef KERNEL_INFO_SHM_MEM_INIT + +#ifdef CONFIG_STATIC_SHM +#define KERNEL_INFO_SHM_MEM_INIT .shm_mem.common.max_banks =3D NR_SHMEM_BA= NKS, +#else +#define KERNEL_INFO_SHM_MEM_INIT +#endif + +#endif /* KERNEL_INFO_SHM_MEM_INIT */ + +#ifndef KERNEL_INFO_INIT + +#define KERNEL_INFO_INIT \ +{ \ + .mem.common.max_banks =3D NR_MEM_BANKS, \ + KERNEL_INFO_SHM_MEM_INIT \ +} + +#endif /* KERNEL_INFO_INIT */ + +/* + * Probe the kernel to detemine its type and select a loader. + * + * Sets in info: + * ->type + * ->load hook, and sets loader specific variables ->zimage + */ +int kernel_probe(struct kernel_info *info, const struct dt_device_node *do= main); + +/* + * Loads the kernel into guest RAM. + * + * Expects to be set in info when called: + * ->mem + * ->fdt + * + * Sets in info: + * ->entry + * ->dtb_paddr + * ->initrd_paddr + */ +void kernel_load(struct kernel_info *info); + +int kernel_decompress(struct bootmodule *mod, uint32_t offset); + +int kernel_zimage_probe(struct kernel_info *info, paddr_t addr, paddr_t si= ze); + +/* + * uImage isn't really used nowadays thereby leave kernel_uimage_probe() + * call here just for compatability with Arm code. + */ +#ifdef CONFIG_ARM +struct bootmodule; +int kernel_uimage_probe(struct kernel_info *info, struct bootmodule *mod); +#endif + +#endif /*__ASM_GENERIC_KERNEL_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h index c81e759423..d85324c867 100644 --- a/xen/include/xen/fdt-kernel.h +++ b/xen/include/xen/fdt-kernel.h @@ -121,6 +121,19 @@ int kernel_probe(struct kernel_info *info, const struc= t dt_device_node *domain); */ void kernel_load(struct kernel_info *info); =20 +int kernel_decompress(struct bootmodule *mod, uint32_t offset); + +int kernel_zimage_probe(struct kernel_info *info, paddr_t addr, paddr_t si= ze); + +/* + * uImage isn't really used nowadays thereby leave kernel_uimage_probe() + * call here just for compatability with Arm code. + */ +#ifdef CONFIG_ARM +struct bootmodule; +int kernel_uimage_probe(struct kernel_info *info, struct bootmodule *mod); +#endif + #endif /* __XEN_FDT_KERNEL_H__ */ =20 /* --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746203004; cv=none; d=zohomail.com; s=zohoarc; b=mDRPbMr0euPClSZ8uCTKv/hUe07FNJuUiDGwcqg9pzH0avk+ESBDYEw7ILJPZAelhLZL3mEG0fbADE2gEXhqO+ifKr/mppiKTbQx7v89CtIGX3SUcF4jss+34d+vq1TYjYcUub4eHH2CY6exMtFmw2jz/yWSOLTAmopBJ3FF7QE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746203004; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=eDnnQd3pRZQgurScUoDNUVkdcI4ZQ5arFshUy2UUTRU=; b=X4JP/MV9ZxP7ji2FqsJCanYr5ZqyFxocK0MG7Yk00BztXpzeD4q3+HitajRfkB7j1iy6CQRoeSaKJW5xYfYKcZboyH+TNswA5+PApJ3FD3i/3QzCwWO1fxUlIuNejSN8EdarrU+3SYxJ+KYS3BjAmg1fDhmpDC2JKIMwoAgaEH8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746203004536526.3648014163338; Fri, 2 May 2025 09:23:24 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974793.1362615 (Exim 4.92) (envelope-from ) id 1uAtAB-0007nf-LI; Fri, 02 May 2025 16:22:59 +0000 Received: by outflank-mailman (output) from mailman id 974793.1362615; Fri, 02 May 2025 16:22:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtAB-0007nU-G0; Fri, 02 May 2025 16:22:59 +0000 Received: by outflank-mailman (input) for mailman id 974793; Fri, 02 May 2025 16:22:58 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtA9-0005rZ-RP for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:22:58 +0000 Received: from mail-ej1-x62f.google.com (mail-ej1-x62f.google.com [2a00:1450:4864:20::62f]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b38da72a-2771-11f0-9eb4-5ba50f476ded; Fri, 02 May 2025 18:22:54 +0200 (CEST) Received: by mail-ej1-x62f.google.com with SMTP id a640c23a62f3a-ac2aeada833so415876566b.0 for ; Fri, 02 May 2025 09:22:54 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:53 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b38da72a-2771-11f0-9eb4-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202974; x=1746807774; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=eDnnQd3pRZQgurScUoDNUVkdcI4ZQ5arFshUy2UUTRU=; b=Zypa2FZzZDidiLnPDtvtMw4N91QQAQSnLtD3axm0xxSc4ElMvlp8MY1BodAEkatPS9 cd6gmCmJ2xkc5dSyZpFu3/gMqVav9w4koDoN6BIfpjeeLRIMBOEmSFZzNarfTlhfLt2K VOvrtRpvVQMretEF2BzyMffysqi1uq/jlKJcaVzKPArKzYRPV3I1kTuZbiZOrcOqEgXW fGjoge6gzdHsffXz2V4dwM2pFLg7FcHOb86ZYmEoG+x50EtHQbtrXa+0h+5suiRlwZ3O 4FBTIexgQVfcorK9PMuVpUDVupsWvp997p39Spt1N33uNZwRvBvrAqzrrfOx7Rhkw6Lz YJxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202974; x=1746807774; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=eDnnQd3pRZQgurScUoDNUVkdcI4ZQ5arFshUy2UUTRU=; b=Z0sdiGE2aMATgloH5QZ0bCQZJyzl6Yrdz0tb0KaiMSiceWiRSeMRC6qvTRh70rNbpS KddbqSJSAvy2xMEySC9IN14DIEg9bFwirfjamEy6V/BnRWKmfnqk0dAWFweUIWFoUnWx 6tWlwcqq7fzl/kzoG67iJQg2EKDHqen832JmEhMfQ+IpLNrnDanPJ+1H+toa/1otJwmN hVrzQMjRM9a6A8G/VLKWVv/sqwdtpUcRWFFdy+cYDHe0cIBv+lOxtIDCloaPF74/DeB8 p56a2Y/mmWJhALng0gQe8GyfLrK232/1WQ2CgSaRaYxbp4macxylPhtPHtybBu6p8vHc 3WYQ== X-Gm-Message-State: AOJu0YzuKKMwVfHDVfs679fXmXxr3FESnZCfBjjhXbzhkLjhlH/J9L1Z 8I171wrHzoHvl7XbNln8Y4bB2EY+oraRws80kD8y0NF+D2z8EjDY/uNadw== X-Gm-Gg: ASbGncuHnulU9NK3v1+XRdBM4HW8zPbBOuM7T3fJryAqTqZ9EuKG1AiYRxl4fHb1mpI PX3TJMoGcIfmUlBloKq4LVJwuWH2FGKxYCQbSh+7Mcf5QZ2HdstI6iNQ/xWPtMMAMKE2r09/UXa u2+/WUb1jn3eltXaglV3/qjqAh2lbG33Grs/b1J0/VCz5KBbg+MiWo4rJW1miF1+k5zegoVuNr6 /3XFya/As9SH8b/1wyQ+uPb/SGXOt0yL0OfUM247erXvCAMJvHmn3Do7lIvaZhYcQsyCtfHwNZW DEn975UBd6OPoaBj5m9RzVc2KMLYdVlqsrU/P28NrQkevq55yNylOS8+bj5dihWFKK9erZ5ZZPb PzZGv7BeqHg== X-Google-Smtp-Source: AGHT+IFBYL8oC9QOxSaUJ6n0vLedCin6HK3FBCgmKEnu+ODVVJLploJQO8xtnwLidt8Tl3h+xoGWAQ== X-Received: by 2002:a17:907:869e:b0:ac7:3929:25f9 with SMTP id a640c23a62f3a-aceff04b0f4mr665444966b.29.1746202973551; Fri, 02 May 2025 09:22:53 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 7/8] xen/common: dom0less: introduce common domain-build.c Date: Fri, 2 May 2025 18:22:37 +0200 Message-ID: <291544ec45d69a3f0ff79eb6770266a0aa04e77d.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746203005396019000 Content-Type: text/plain; charset="utf-8" Some functions of Arm's domain_build.c could be reused by dom0less or other features connected to domain construction/build. The following functions are moved to common: - get_allocation_size(). - allocate_domheap_memory(). - guest_map_pages(). - allocate_bank_memory(). - add_hwdom_free_regions(). - find_unallocated_memory(). - allocate_memory(). - dtb_load(). - initrd_load(). Prototype of dtb_load() and initrd_load() is updated to recieve a pointer to copy_to_guest_phys() as some archs require copy_to_guest_phys_fluch_dcache(). Update arm/include/asm/Makefile to generate domain-build.h for Arm as it is used by domain-build.c. Signed-off-by: Oleksii Kurochko --- Change in v3: - Nothing changed. Only rebase. --- Change in v2: - Use xen/fdt-domain-build.h instead of asm/domain_build.h. --- xen/arch/arm/domain_build.c | 397 +------------------------ xen/common/device-tree/Makefile | 1 + xen/common/device-tree/domain-build.c | 404 ++++++++++++++++++++++++++ xen/include/xen/fdt-domain-build.h | 33 ++- 4 files changed, 439 insertions(+), 396 deletions(-) create mode 100644 xen/common/device-tree/domain-build.c diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 9d649b06b3..df29619c40 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -120,18 +120,6 @@ struct vcpu *__init alloc_dom0_vcpu0(struct domain *do= m0) return vcpu_create(dom0, 0); } =20 -unsigned int __init get_allocation_size(paddr_t size) -{ - /* - * get_order_from_bytes returns the order greater than or equal to - * the given size, but we need less than or equal. Adding one to - * the size pushes an evenly aligned size into the next order, so - * we can then unconditionally subtract 1 from the order which is - * returned. - */ - return get_order_from_bytes(size + 1) - 1; -} - /* * Insert the given pages into a memory bank, banks are ordered by address. * @@ -418,98 +406,6 @@ static void __init allocate_memory_11(struct domain *d, } } =20 -bool __init allocate_domheap_memory(struct domain *d, paddr_t tot_size, - alloc_domheap_mem_cb cb, void *extra) -{ - unsigned int max_order =3D UINT_MAX; - - while ( tot_size > 0 ) - { - unsigned int order =3D get_allocation_size(tot_size); - struct page_info *pg; - - order =3D min(max_order, order); - - pg =3D alloc_domheap_pages(d, order, 0); - if ( !pg ) - { - /* - * If we can't allocate one page, then it is unlikely to - * succeed in the next iteration. So bail out. - */ - if ( !order ) - return false; - - /* - * If we can't allocate memory with order, then it is - * unlikely to succeed in the next iteration. - * Record the order - 1 to avoid re-trying. - */ - max_order =3D order - 1; - continue; - } - - if ( !cb(d, pg, order, extra) ) - return false; - - tot_size -=3D (1ULL << (PAGE_SHIFT + order)); - } - - return true; -} - -static bool __init guest_map_pages(struct domain *d, struct page_info *pg, - unsigned int order, void *extra) -{ - gfn_t *sgfn =3D (gfn_t *)extra; - int res; - - BUG_ON(!sgfn); - res =3D guest_physmap_add_page(d, *sgfn, page_to_mfn(pg), order); - if ( res ) - { - dprintk(XENLOG_ERR, "Failed map pages to DOMU: %d", res); - return false; - } - - *sgfn =3D gfn_add(*sgfn, 1UL << order); - - return true; -} - -bool __init allocate_bank_memory(struct kernel_info *kinfo, gfn_t sgfn, - paddr_t tot_size) -{ - struct membanks *mem =3D kernel_info_get_mem(kinfo); - struct domain *d =3D kinfo->d; - struct membank *bank; - - /* - * allocate_bank_memory can be called with a tot_size of zero for - * the second memory bank. It is not an error and we can safely - * avoid creating a zero-size memory bank. - */ - if ( tot_size =3D=3D 0 ) - return true; - - bank =3D &mem->bank[mem->nr_banks]; - bank->start =3D gfn_to_gaddr(sgfn); - bank->size =3D tot_size; - - /* - * Allocate pages from the heap until tot_size is zero and map them to= the - * guest using guest_map_pages, passing the starting gfn as extra para= meter - * for the map operation. - */ - if ( !allocate_domheap_memory(d, tot_size, guest_map_pages, &sgfn) ) - return false; - - mem->nr_banks++; - kinfo->unassigned_mem -=3D bank->size; - - return true; -} - /* * When PCI passthrough is available we want to keep the * "linux,pci-domain" in sync for every host bridge. @@ -900,226 +796,6 @@ int __init add_ext_regions(unsigned long s_gfn, unsig= ned long e_gfn, return 0; } =20 -static int __init add_hwdom_free_regions(unsigned long s_gfn, - unsigned long e_gfn, void *data) -{ - struct membanks *free_regions =3D data; - paddr_t start, size; - paddr_t s =3D pfn_to_paddr(s_gfn); - paddr_t e =3D pfn_to_paddr(e_gfn); - unsigned int i, j; - - if ( free_regions->nr_banks >=3D free_regions->max_banks ) - return 0; - - /* - * Both start and size of the free region should be 2MB aligned to - * potentially allow superpage mapping. - */ - start =3D (s + SZ_2M - 1) & ~(SZ_2M - 1); - if ( start > e ) - return 0; - - /* - * e is actually "end-1" because it is called by rangeset functions - * which are inclusive of the last address. - */ - e +=3D 1; - size =3D (e - start) & ~(SZ_2M - 1); - - /* Find the insert position (descending order). */ - for ( i =3D 0; i < free_regions->nr_banks ; i++ ) - if ( size > free_regions->bank[i].size ) - break; - - /* Move the other banks to make space. */ - for ( j =3D free_regions->nr_banks; j > i ; j-- ) - { - free_regions->bank[j].start =3D free_regions->bank[j - 1].start; - free_regions->bank[j].size =3D free_regions->bank[j - 1].size; - } - - free_regions->bank[i].start =3D start; - free_regions->bank[i].size =3D size; - free_regions->nr_banks++; - - return 0; -} - -/* - * Find unused regions of Host address space which can be exposed to domain - * using the host memory layout. In order to calculate regions we exclude = every - * region passed in mem_banks from the Host RAM. - */ -static int __init find_unallocated_memory(const struct kernel_info *kinfo, - const struct membanks *mem_banks= [], - unsigned int nr_mem_banks, - struct membanks *free_regions, - int (*cb)(unsigned long s_gfn, - unsigned long e_gfn, - void *data)) -{ - const struct membanks *mem =3D bootinfo_get_mem(); - struct rangeset *unalloc_mem; - paddr_t start, end; - unsigned int i, j; - int res; - - ASSERT(domain_use_host_layout(kinfo->d)); - - unalloc_mem =3D rangeset_new(NULL, NULL, 0); - if ( !unalloc_mem ) - return -ENOMEM; - - /* Start with all available RAM */ - for ( i =3D 0; i < mem->nr_banks; i++ ) - { - start =3D mem->bank[i].start; - end =3D mem->bank[i].start + mem->bank[i].size; - res =3D rangeset_add_range(unalloc_mem, PFN_DOWN(start), - PFN_DOWN(end - 1)); - if ( res ) - { - printk(XENLOG_ERR "Failed to add: %#"PRIpaddr"->%#"PRIpaddr"\n= ", - start, end); - goto out; - } - } - - /* Remove all regions listed in mem_banks */ - for ( i =3D 0; i < nr_mem_banks; i++ ) - for ( j =3D 0; j < mem_banks[i]->nr_banks; j++ ) - { - start =3D mem_banks[i]->bank[j].start; - - /* Shared memory banks can contain INVALID_PADDR as start */ - if ( INVALID_PADDR =3D=3D start ) - continue; - - end =3D mem_banks[i]->bank[j].start + mem_banks[i]->bank[j].si= ze; - res =3D rangeset_remove_range(unalloc_mem, PFN_DOWN(start), - PFN_DOWN(end - 1)); - if ( res ) - { - printk(XENLOG_ERR - "Failed to add: %#"PRIpaddr"->%#"PRIpaddr", error %= d\n", - start, end, res); - goto out; - } - } - - start =3D 0; - end =3D (1ULL << p2m_ipa_bits) - 1; - res =3D rangeset_report_ranges(unalloc_mem, PFN_DOWN(start), PFN_DOWN(= end), - cb, free_regions); - if ( res ) - free_regions->nr_banks =3D 0; - else if ( !free_regions->nr_banks ) - res =3D -ENOENT; - -out: - rangeset_destroy(unalloc_mem); - - return res; -} - -void __init allocate_memory(struct domain *d, struct kernel_info *kinfo) -{ - struct membanks *mem =3D kernel_info_get_mem(kinfo); - unsigned int i, nr_banks =3D GUEST_RAM_BANKS; - struct membanks *hwdom_free_mem =3D NULL; - - printk(XENLOG_INFO "Allocating mappings totalling %ldMB for %pd:\n", - /* Don't want format this as PRIpaddr (16 digit hex) */ - (unsigned long)(kinfo->unassigned_mem >> 20), d); - - mem->nr_banks =3D 0; - /* - * Use host memory layout for hwdom. Only case for this is when LLC co= loring - * is enabled. - */ - if ( is_hardware_domain(d) ) - { - struct membanks *gnttab =3D membanks_xzalloc(1, MEMORY); - /* - * Exclude the following regions: - * 1) Remove reserved memory - * 2) Grant table assigned to hwdom - */ - const struct membanks *mem_banks[] =3D { - bootinfo_get_reserved_mem(), - gnttab, - }; - - if ( !gnttab ) - goto fail; - - gnttab->nr_banks =3D 1; - gnttab->bank[0].start =3D kinfo->gnttab_start; - gnttab->bank[0].size =3D kinfo->gnttab_size; - - hwdom_free_mem =3D membanks_xzalloc(NR_MEM_BANKS, MEMORY); - if ( !hwdom_free_mem ) - goto fail; - - if ( find_unallocated_memory(kinfo, mem_banks, ARRAY_SIZE(mem_bank= s), - hwdom_free_mem, add_hwdom_free_region= s) ) - goto fail; - - nr_banks =3D hwdom_free_mem->nr_banks; - xfree(gnttab); - } - - for ( i =3D 0; kinfo->unassigned_mem > 0 && nr_banks > 0; i++, nr_bank= s-- ) - { - paddr_t bank_start, bank_size; - - if ( is_hardware_domain(d) ) - { - bank_start =3D hwdom_free_mem->bank[i].start; - bank_size =3D hwdom_free_mem->bank[i].size; - } - else - { - const uint64_t bankbase[] =3D GUEST_RAM_BANK_BASES; - const uint64_t banksize[] =3D GUEST_RAM_BANK_SIZES; - - if ( i >=3D GUEST_RAM_BANKS ) - goto fail; - - bank_start =3D bankbase[i]; - bank_size =3D banksize[i]; - } - - bank_size =3D MIN(bank_size, kinfo->unassigned_mem); - if ( !allocate_bank_memory(kinfo, gaddr_to_gfn(bank_start), bank_s= ize) ) - goto fail; - } - - if ( kinfo->unassigned_mem ) - goto fail; - - for( i =3D 0; i < mem->nr_banks; i++ ) - { - printk(XENLOG_INFO "%pd BANK[%d] %#"PRIpaddr"-%#"PRIpaddr" (%ldMB)= \n", - d, - i, - mem->bank[i].start, - mem->bank[i].start + mem->bank[i].size, - /* Don't want format this as PRIpaddr (16 digit hex) */ - (unsigned long)(mem->bank[i].size >> 20)); - } - - xfree(hwdom_free_mem); - return; - - fail: - panic("Failed to allocate requested domain memory." - /* Don't want format this as PRIpaddr (16 digit hex) */ - " %ldKB unallocated. Fix the VMs configurations.\n", - (unsigned long)kinfo->unassigned_mem >> 10); -} - static int __init handle_pci_range(const struct dt_device_node *dev, uint64_t addr, uint64_t len, void *data) { @@ -2059,75 +1735,6 @@ static int __init prepare_dtb_hwdom(struct domain *d= , struct kernel_info *kinfo) return -EINVAL; } =20 -static void __init dtb_load(struct kernel_info *kinfo) -{ - unsigned long left; - - printk("Loading %pd DTB to 0x%"PRIpaddr"-0x%"PRIpaddr"\n", - kinfo->d, kinfo->dtb_paddr, - kinfo->dtb_paddr + fdt_totalsize(kinfo->fdt)); - - left =3D copy_to_guest_phys_flush_dcache(kinfo->d, kinfo->dtb_paddr, - kinfo->fdt, - fdt_totalsize(kinfo->fdt)); - - if ( left !=3D 0 ) - panic("Unable to copy the DTB to %pd memory (left =3D %lu bytes)\n= ", - kinfo->d, left); - xfree(kinfo->fdt); -} - -static void __init initrd_load(struct kernel_info *kinfo) -{ - const struct bootmodule *mod =3D kinfo->initrd_bootmodule; - paddr_t load_addr =3D kinfo->initrd_paddr; - paddr_t paddr, len; - int node; - int res; - __be32 val[2]; - __be32 *cellp; - void __iomem *initrd; - - if ( !mod || !mod->size ) - return; - - paddr =3D mod->start; - len =3D mod->size; - - printk("Loading %pd initrd from %"PRIpaddr" to 0x%"PRIpaddr"-0x%"PRIpa= ddr"\n", - kinfo->d, paddr, load_addr, load_addr + len); - - /* Fix up linux,initrd-start and linux,initrd-end in /chosen */ - node =3D fdt_path_offset(kinfo->fdt, "/chosen"); - if ( node < 0 ) - panic("Cannot find the /chosen node\n"); - - cellp =3D (__be32 *)val; - dt_set_cell(&cellp, ARRAY_SIZE(val), load_addr); - res =3D fdt_setprop_inplace(kinfo->fdt, node, "linux,initrd-start", - val, sizeof(val)); - if ( res ) - panic("Cannot fix up \"linux,initrd-start\" property\n"); - - cellp =3D (__be32 *)val; - dt_set_cell(&cellp, ARRAY_SIZE(val), load_addr + len); - res =3D fdt_setprop_inplace(kinfo->fdt, node, "linux,initrd-end", - val, sizeof(val)); - if ( res ) - panic("Cannot fix up \"linux,initrd-end\" property\n"); - - initrd =3D ioremap_wc(paddr, len); - if ( !initrd ) - panic("Unable to map the %pd initrd\n", kinfo->d); - - res =3D copy_to_guest_phys_flush_dcache(kinfo->d, load_addr, - initrd, len); - if ( res !=3D 0 ) - panic("Unable to copy the initrd in the %pd memory\n", kinfo->d); - - iounmap(initrd); -} - /* * Allocate the event channel PPIs and setup the HVM_PARAM_CALLBACK_IRQ. * The allocated IRQ will be found in d->arch.evtchn_irq. @@ -2220,8 +1827,8 @@ int __init construct_domain(struct domain *d, struct = kernel_info *kinfo) */ kernel_load(kinfo); /* initrd_load will fix up the fdt, so call it before dtb_load */ - initrd_load(kinfo); - dtb_load(kinfo); + initrd_load(kinfo, copy_to_guest_phys_flush_dcache); + dtb_load(kinfo, copy_to_guest_phys_flush_dcache); =20 memset(regs, 0, sizeof(*regs)); =20 diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makef= ile index e88a4d5799..831b91399b 100644 --- a/xen/common/device-tree/Makefile +++ b/xen/common/device-tree/Makefile @@ -1,6 +1,7 @@ obj-y +=3D bootfdt.init.o obj-y +=3D bootinfo.init.o obj-y +=3D device-tree.o +obj-$(CONFIG_DOMAIN_BUILD_HELPERS) +=3D domain-build.o obj-$(CONFIG_DOM0LESS_BOOT) +=3D dom0less-build.o obj-$(CONFIG_OVERLAY_DTB) +=3D dt-overlay.o obj-y +=3D intc.o diff --git a/xen/common/device-tree/domain-build.c b/xen/common/device-tree= /domain-build.c new file mode 100644 index 0000000000..69257a15ba --- /dev/null +++ b/xen/common/device-tree/domain-build.c @@ -0,0 +1,404 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +bool __init allocate_domheap_memory(struct domain *d, paddr_t tot_size, + alloc_domheap_mem_cb cb, void *extra) +{ + unsigned int max_order =3D UINT_MAX; + + while ( tot_size > 0 ) + { + unsigned int order =3D get_allocation_size(tot_size); + struct page_info *pg; + + order =3D min(max_order, order); + + pg =3D alloc_domheap_pages(d, order, 0); + if ( !pg ) + { + /* + * If we can't allocate one page, then it is unlikely to + * succeed in the next iteration. So bail out. + */ + if ( !order ) + return false; + + /* + * If we can't allocate memory with order, then it is + * unlikely to succeed in the next iteration. + * Record the order - 1 to avoid re-trying. + */ + max_order =3D order - 1; + continue; + } + + if ( !cb(d, pg, order, extra) ) + return false; + + tot_size -=3D (1ULL << (PAGE_SHIFT + order)); + } + + return true; +} + +static bool __init guest_map_pages(struct domain *d, struct page_info *pg, + unsigned int order, void *extra) +{ + gfn_t *sgfn =3D (gfn_t *)extra; + int res; + + BUG_ON(!sgfn); + res =3D guest_physmap_add_page(d, *sgfn, page_to_mfn(pg), order); + if ( res ) + { + dprintk(XENLOG_ERR, "Failed map pages to DOMU: %d", res); + return false; + } + + *sgfn =3D gfn_add(*sgfn, 1UL << order); + + return true; +} + +bool __init allocate_bank_memory(struct kernel_info *kinfo, gfn_t sgfn, + paddr_t tot_size) +{ + struct membanks *mem =3D kernel_info_get_mem(kinfo); + struct domain *d =3D kinfo->d; + struct membank *bank; + + /* + * allocate_bank_memory can be called with a tot_size of zero for + * the second memory bank. It is not an error and we can safely + * avoid creating a zero-size memory bank. + */ + if ( tot_size =3D=3D 0 ) + return true; + + bank =3D &mem->bank[mem->nr_banks]; + bank->start =3D gfn_to_gaddr(sgfn); + bank->size =3D tot_size; + + /* + * Allocate pages from the heap until tot_size is zero and map them to= the + * guest using guest_map_pages, passing the starting gfn as extra para= meter + * for the map operation. + */ + if ( !allocate_domheap_memory(d, tot_size, guest_map_pages, &sgfn) ) + return false; + + mem->nr_banks++; + kinfo->unassigned_mem -=3D bank->size; + + return true; +} + +static int __init add_hwdom_free_regions(unsigned long s_gfn, + unsigned long e_gfn, void *data) +{ + struct membanks *free_regions =3D data; + paddr_t start, size; + paddr_t s =3D pfn_to_paddr(s_gfn); + paddr_t e =3D pfn_to_paddr(e_gfn); + unsigned int i, j; + + if ( free_regions->nr_banks >=3D free_regions->max_banks ) + return 0; + + /* + * Both start and size of the free region should be 2MB aligned to + * potentially allow superpage mapping. + */ + start =3D (s + SZ_2M - 1) & ~(SZ_2M - 1); + if ( start > e ) + return 0; + + /* + * e is actually "end-1" because it is called by rangeset functions + * which are inclusive of the last address. + */ + e +=3D 1; + size =3D (e - start) & ~(SZ_2M - 1); + + /* Find the insert position (descending order). */ + for ( i =3D 0; i < free_regions->nr_banks ; i++ ) + if ( size > free_regions->bank[i].size ) + break; + + /* Move the other banks to make space. */ + for ( j =3D free_regions->nr_banks; j > i ; j-- ) + { + free_regions->bank[j].start =3D free_regions->bank[j - 1].start; + free_regions->bank[j].size =3D free_regions->bank[j - 1].size; + } + + free_regions->bank[i].start =3D start; + free_regions->bank[i].size =3D size; + free_regions->nr_banks++; + + return 0; +} + +/* + * Find unused regions of Host address space which can be exposed to domain + * using the host memory layout. In order to calculate regions we exclude = every + * region passed in mem_banks from the Host RAM. + */ +int __init find_unallocated_memory(const struct kernel_info *kinfo, + const struct membanks *mem_banks[], + unsigned int nr_mem_banks, + struct membanks *free_regions, + int (*cb)(unsigned long s_gfn, + unsigned long e_gfn, + void *data)) +{ + const struct membanks *mem =3D bootinfo_get_mem(); + struct rangeset *unalloc_mem; + paddr_t start, end; + unsigned int i, j; + int res; + + ASSERT(domain_use_host_layout(kinfo->d)); + + unalloc_mem =3D rangeset_new(NULL, NULL, 0); + if ( !unalloc_mem ) + return -ENOMEM; + + /* Start with all available RAM */ + for ( i =3D 0; i < mem->nr_banks; i++ ) + { + start =3D mem->bank[i].start; + end =3D mem->bank[i].start + mem->bank[i].size; + res =3D rangeset_add_range(unalloc_mem, PFN_DOWN(start), + PFN_DOWN(end - 1)); + if ( res ) + { + printk(XENLOG_ERR "Failed to add: %#"PRIpaddr"->%#"PRIpaddr"\n= ", + start, end); + goto out; + } + } + + /* Remove all regions listed in mem_banks */ + for ( i =3D 0; i < nr_mem_banks; i++ ) + for ( j =3D 0; j < mem_banks[i]->nr_banks; j++ ) + { + start =3D mem_banks[i]->bank[j].start; + + /* Shared memory banks can contain INVALID_PADDR as start */ + if ( INVALID_PADDR =3D=3D start ) + continue; + + end =3D mem_banks[i]->bank[j].start + mem_banks[i]->bank[j].si= ze; + res =3D rangeset_remove_range(unalloc_mem, PFN_DOWN(start), + PFN_DOWN(end - 1)); + if ( res ) + { + printk(XENLOG_ERR + "Failed to add: %#"PRIpaddr"->%#"PRIpaddr", error %= d\n", + start, end, res); + goto out; + } + } + + start =3D 0; + end =3D (1ULL << p2m_ipa_bits) - 1; + res =3D rangeset_report_ranges(unalloc_mem, PFN_DOWN(start), PFN_DOWN(= end), + cb, free_regions); + if ( res ) + free_regions->nr_banks =3D 0; + else if ( !free_regions->nr_banks ) + res =3D -ENOENT; + +out: + rangeset_destroy(unalloc_mem); + + return res; +} + +void __init allocate_memory(struct domain *d, struct kernel_info *kinfo) +{ + struct membanks *mem =3D kernel_info_get_mem(kinfo); + unsigned int i, nr_banks =3D GUEST_RAM_BANKS; + struct membanks *hwdom_free_mem =3D NULL; + + printk(XENLOG_INFO "Allocating mappings totalling %ldMB for %pd:\n", + /* Don't want format this as PRIpaddr (16 digit hex) */ + (unsigned long)(kinfo->unassigned_mem >> 20), d); + + mem->nr_banks =3D 0; + /* + * Use host memory layout for hwdom. Only case for this is when LLC co= loring + * is enabled. + */ + if ( is_hardware_domain(d) ) + { + struct membanks *gnttab =3D xzalloc_flex_struct(struct membanks, b= ank, 1); + /* + * Exclude the following regions: + * 1) Remove reserved memory + * 2) Grant table assigned to hwdom + */ + const struct membanks *mem_banks[] =3D { + bootinfo_get_reserved_mem(), + gnttab, + }; + + if ( !gnttab ) + goto fail; + + gnttab->nr_banks =3D 1; + gnttab->bank[0].start =3D kinfo->gnttab_start; + gnttab->bank[0].size =3D kinfo->gnttab_size; + + hwdom_free_mem =3D xzalloc_flex_struct(struct membanks, bank, + NR_MEM_BANKS); + if ( !hwdom_free_mem ) + goto fail; + + hwdom_free_mem->max_banks =3D NR_MEM_BANKS; + + if ( find_unallocated_memory(kinfo, mem_banks, ARRAY_SIZE(mem_bank= s), + hwdom_free_mem, add_hwdom_free_region= s) ) + goto fail; + + nr_banks =3D hwdom_free_mem->nr_banks; + xfree(gnttab); + } + + for ( i =3D 0; kinfo->unassigned_mem > 0 && nr_banks > 0; i++, nr_bank= s-- ) + { + paddr_t bank_start, bank_size; + + if ( is_hardware_domain(d) ) + { + bank_start =3D hwdom_free_mem->bank[i].start; + bank_size =3D hwdom_free_mem->bank[i].size; + } + else + { + const uint64_t bankbase[] =3D GUEST_RAM_BANK_BASES; + const uint64_t banksize[] =3D GUEST_RAM_BANK_SIZES; + + if ( i >=3D GUEST_RAM_BANKS ) + goto fail; + + bank_start =3D bankbase[i]; + bank_size =3D banksize[i]; + } + + bank_size =3D MIN(bank_size, kinfo->unassigned_mem); + if ( !allocate_bank_memory(kinfo, gaddr_to_gfn(bank_start), bank_s= ize) ) + goto fail; + } + + if ( kinfo->unassigned_mem ) + goto fail; + + for( i =3D 0; i < mem->nr_banks; i++ ) + { + printk(XENLOG_INFO "%pd BANK[%d] %#"PRIpaddr"-%#"PRIpaddr" (%ldMB)= \n", + d, + i, + mem->bank[i].start, + mem->bank[i].start + mem->bank[i].size, + /* Don't want format this as PRIpaddr (16 digit hex) */ + (unsigned long)(mem->bank[i].size >> 20)); + } + + xfree(hwdom_free_mem); + return; + + fail: + panic("Failed to allocate requested domain memory." + /* Don't want format this as PRIpaddr (16 digit hex) */ + " %ldKB unallocated. Fix the VMs configurations.\n", + (unsigned long)kinfo->unassigned_mem >> 10); +} + +/* Copy data to guest physical address, then clean the region. */ +typedef unsigned long (*copy_to_guest_phys_cb)(struct domain *d, + paddr_t gpa, + void *buf, + unsigned int len); + +void __init dtb_load(struct kernel_info *kinfo, + copy_to_guest_phys_cb copy_to_guest) +{ + unsigned long left; + + printk("Loading %pd DTB to 0x%"PRIpaddr"-0x%"PRIpaddr"\n", + kinfo->d, kinfo->dtb_paddr, + kinfo->dtb_paddr + fdt_totalsize(kinfo->fdt)); + + left =3D copy_to_guest(kinfo->d, kinfo->dtb_paddr, + kinfo->fdt, + fdt_totalsize(kinfo->fdt)); + + if ( left !=3D 0 ) + panic("Unable to copy the DTB to %pd memory (left =3D %lu bytes)\n= ", + kinfo->d, left); + xfree(kinfo->fdt); +} + +void __init initrd_load(struct kernel_info *kinfo, + copy_to_guest_phys_cb copy_to_guest) +{ + const struct bootmodule *mod =3D kinfo->initrd_bootmodule; + paddr_t load_addr =3D kinfo->initrd_paddr; + paddr_t paddr, len; + int node; + int res; + __be32 val[2]; + __be32 *cellp; + void __iomem *initrd; + + if ( !mod || !mod->size ) + return; + + paddr =3D mod->start; + len =3D mod->size; + + printk("Loading %pd initrd from %"PRIpaddr" to 0x%"PRIpaddr"-0x%"PRIpa= ddr"\n", + kinfo->d, paddr, load_addr, load_addr + len); + + /* Fix up linux,initrd-start and linux,initrd-end in /chosen */ + node =3D fdt_path_offset(kinfo->fdt, "/chosen"); + if ( node < 0 ) + panic("Cannot find the /chosen node\n"); + + cellp =3D (__be32 *)val; + dt_set_cell(&cellp, ARRAY_SIZE(val), load_addr); + res =3D fdt_setprop_inplace(kinfo->fdt, node, "linux,initrd-start", + val, sizeof(val)); + if ( res ) + panic("Cannot fix up \"linux,initrd-start\" property\n"); + + cellp =3D (__be32 *)val; + dt_set_cell(&cellp, ARRAY_SIZE(val), load_addr + len); + res =3D fdt_setprop_inplace(kinfo->fdt, node, "linux,initrd-end", + val, sizeof(val)); + if ( res ) + panic("Cannot fix up \"linux,initrd-end\" property\n"); + + initrd =3D ioremap_wc(paddr, len); + if ( !initrd ) + panic("Unable to map the hwdom initrd\n"); + + res =3D copy_to_guest(kinfo->d, load_addr, + initrd, len); + if ( res !=3D 0 ) + panic("Unable to copy the initrd in the hwdom memory\n"); + + iounmap(initrd); +} diff --git a/xen/include/xen/fdt-domain-build.h b/xen/include/xen/fdt-domai= n-build.h index b79e9fabfe..4a0052b2e8 100644 --- a/xen/include/xen/fdt-domain-build.h +++ b/xen/include/xen/fdt-domain-build.h @@ -6,6 +6,7 @@ #include #include #include +#include #include =20 struct domain; @@ -29,7 +30,37 @@ int make_memory_node(const struct kernel_info *kinfo, in= t addrcells, int sizecells, const struct membanks *mem); int make_timer_node(const struct kernel_info *kinfo); =20 -unsigned int get_allocation_size(paddr_t size); + +static inline int get_allocation_size(paddr_t size) +{ + /* + * get_order_from_bytes returns the order greater than or equal to + * the given size, but we need less than or equal. Adding one to + * the size pushes an evenly aligned size into the next order, so + * we can then unconditionally subtract 1 from the order which is + * returned. + */ + return get_order_from_bytes(size + 1) - 1; +} + +typedef unsigned long (*copy_to_guest_phys_cb)(struct domain *d, + paddr_t gpa, + void *buf, + unsigned int len); + +void initrd_load(struct kernel_info *kinfo, + copy_to_guest_phys_cb copy_to_guest); + +void dtb_load(struct kernel_info *kinfo, + copy_to_guest_phys_cb copy_to_guest); + +int find_unallocated_memory(const struct kernel_info *kinfo, + const struct membanks *mem_banks[], + unsigned int nr_mem_banks, + struct membanks *free_regions, + int (*cb)(unsigned long s_gfn, + unsigned long e_gfn, + void *data)); =20 #endif /* __XEN_FDT_DOMAIN_BUILD_H__ */ =20 --=20 2.49.0 From nobody Sat Nov 1 05:22:34 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1746203489; cv=none; d=zohomail.com; s=zohoarc; b=LyfzdPtrL15chv3QlQHJIvBInO+iXP8z3eA/7C2zqoZLiht6bGquC6BQV4x5P7wzvB5KoIbtEMsEuFWyElfi/rbLc097cen6tJlWZ4z2xO5W6Ip124bg+hAoLjaQhFDYHOjWjX0ZXQI87cTMxzcgT1eypx2nNcVj/b7vjXJExfk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1746203489; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+jFw3h4Q9XYaNyP0ZWtKpY/WJbt8g8MpajB8UOqpIWc=; b=lfY2VGAwJT7EXRo3kz7R1BUekyYa6jIcH/B/5sygh/22T0PN/z9Ru6pnEb0umtu6HM7mOeiyjXk0pqGuJ2vjGTYQlwhpp4Nr1c4GfVj72Y3Xs9Z9/ijx296yiTUzLucRJ5GfgjcCdrvsqSGgluzuk8WSbqYXCXkm3iIGawgzEp4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1746203489748587.2197425319591; Fri, 2 May 2025 09:31:29 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.974868.1362625 (Exim 4.92) (envelope-from ) id 1uAtI9-00031w-Jl; Fri, 02 May 2025 16:31:13 +0000 Received: by outflank-mailman (output) from mailman id 974868.1362625; Fri, 02 May 2025 16:31:13 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtI9-00031p-Gg; Fri, 02 May 2025 16:31:13 +0000 Received: by outflank-mailman (input) for mailman id 974868; Fri, 02 May 2025 16:31:12 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uAtAC-0005rZ-S4 for xen-devel@lists.xenproject.org; Fri, 02 May 2025 16:23:01 +0000 Received: from mail-ej1-x634.google.com (mail-ej1-x634.google.com [2a00:1450:4864:20::634]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b447a7c1-2771-11f0-9eb4-5ba50f476ded; Fri, 02 May 2025 18:22:55 +0200 (CEST) Received: by mail-ej1-x634.google.com with SMTP id a640c23a62f3a-ac2a81e41e3so394156766b.1 for ; Fri, 02 May 2025 09:22:55 -0700 (PDT) Received: from fedora.. (user-109-243-69-225.play-internet.pl. [109.243.69.225]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad1894c01f2sm68158766b.119.2025.05.02.09.22.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 May 2025 09:22:54 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b447a7c1-2771-11f0-9eb4-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746202975; x=1746807775; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+jFw3h4Q9XYaNyP0ZWtKpY/WJbt8g8MpajB8UOqpIWc=; b=aQmdyfD+mrQOFFCF0Pwy57zgYla5ex1Q38J4dJKEUq9bGNZS1crBikATkFFG7tMY0v 6C8LcoUO7YNeDPRKaTOnYFq+qpt6oNBPrb0PTw0fmi+EP5/3wNzJHj16BbiJ2UDEntA3 BPKbLPEcdnliqJbEk7ZqZUt/IwuAkE0Y+jvNoLPfW7j5eGAuJ42eplAicz/gDuQgpLOb FL9x+99tF3wpKhEXe/YPVrPSj8PRHRhziQjl3goauyaqDHulzKQjfbuOhnQvNT7tOItr LU/PkB3K7TjTl3PEKT4RuGGxXfifH6Mlt+MyDkXdB4a+C3vrkcz5JViWEM+J250iMIWD XN4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746202975; x=1746807775; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+jFw3h4Q9XYaNyP0ZWtKpY/WJbt8g8MpajB8UOqpIWc=; b=uM1uEyWt1PRg4gdIDce2cgtVQL0vuPCHD6Qr04Phtfuz724/RoDqEMAQPTjM+3IQ6r xbrI1vwY2jgR/uwQHLu9Sp1NogQVouu6RzbN90Zj5DNVfmoOkieCJKH8+AnGAnOxtYBX MA59TLKbV2S5dB1s6X6bIyUcUhZ/fr8CH2UuyiUQxgWIaK6Ox1cO5VZPgaoXxe3Hk3j7 okwKdXMk1uQNmyoi0iBUKOE62wcCAWZA4L4/wjAJCIwDvQpgYF2nwMovMXoN1mFMON1B k3Lsp7ptfMvu4u59sxbJVqL4oS7R3gdMD//gxcT0PCKQsQeh5n0Hh8g5J86louJ/4GkV 4GkA== X-Gm-Message-State: AOJu0YziSWofqvAoTxgo468uTnhL/CUqD8ib7PqpXEKUTr2+4EDvg/U8 z/d7FNY/a6Wgq749LsDjkAIQdnep+tVdlpvLbnhMF7p+ceZFk4rTzHUuFw== X-Gm-Gg: ASbGncsyJwhmdit6FJaqTzZOm23Th4cFSJYekkp/uyYX5jvzdGhUwA9Be9/LUJW0nvj DpQknMt/agcoHwVU4ckAaz1C8aslSEXRY4O+4Wxu55rbmW4UQcy+iyBZEEcz9GLdwmPY6RJ6wgq SfN4SoKrXq0miaTdi07MHBRpaX6JTbFSPI7O5QHFYSJ0VfHvp+KGlOXvHPKgb2HbYn3/PMeD3S/ e1TkMeoBgsVqWweIGg+XhqQtzhMhmFiBS9aca0Dk2m0eWXkTI2QWLbnNvM9y/qMNsEcUtWZuZNM BmlmapsaRPf7mxItX/UcDC1BWMMa38FlhB7HoEkuagv2qNjg52VYbICW8nRMyJf9P2I5vUxryk+ L/uOHaGYfcFmdDgpCWGOb X-Google-Smtp-Source: AGHT+IGrsgFMj3uuhYBpdoLcgRI+pbhUn22HD0W7o+9g2/s2oqcTWR5L5u0N/xcBOWeFbbfR//gqyQ== X-Received: by 2002:a17:907:1688:b0:ac4:493:403 with SMTP id a640c23a62f3a-ad17aef2851mr305912266b.37.1746202974817; Fri, 02 May 2025 09:22:54 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 8/8] xen/common: dom0less: introduce common dom0less-build.c Date: Fri, 2 May 2025 18:22:38 +0200 Message-ID: <76390ef52f108b580e1c397ed178ceadf1ae53c4.1746199009.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1746203491192019000 Content-Type: text/plain; charset="utf-8" Part of Arm's dom0less-build.c could be common between architectures which = are using device tree files to create guest domains. Thereby move some parts of Arm's dom0less-build.c to common code with minor changes. As a part of theses changes the following changes are introduced: - Introduce make_arch_nodes() to cover arch-specific nodes. For example, in case of Arm, it is PSCI and vpl011 nodes. - Introduce set_domain_type() to abstract a way how setting of domain type happens. For example, RISC-V won't have this member of arch_domain struct= ure as vCPUs will always have the same bitness as hypervisor. In case of Arm,= it is possible that Arm64 could create 32-bit and 64-bit domains. - Introduce init_vuart() to cover details of virtual uart initialization. - Introduce init_intc_phandle() to cover some details of interrupt controll= er phandle initialization. As an example, RISC-V could have different name f= or interrupt controller node ( APLIC, PLIC, IMSIC, etc ) but the code in domain_handle_dtb_bootmodule() could handle only one interrupt controller node name. - s/make_gic_domU_node/make_intc_domU_node as GIC is Arm specific naming and add prototype of make_intc_domU_node() to dom0less-build.h The following functions are moved to xen/common/device-tree: - Functions which are moved as is: - domain_p2m_pages(). - handle_passthrough_prop(). - handle_prop_pfdt(). - scan_pfdt_node(). - check_partial_fdt(). - Functions which are moved with some minor changes: - alloc_xenstore_evtchn(): - ifdef-ing by CONFIG_HVM accesses to hvm.params. - prepare_dtb_domU(): - ifdef-ing access to gnttab_{start,size} by CONFIG_GRANT_TABLE. - s/make_gic_domU_node/make_intc_domU_node. - Add call of make_arch_nodes(). - domain_handle_dtb_bootmodule(): - hide details of interrupt controller phandle initialization by calling init_intc_phandle(). - Update the comment above init_intc_phandle(): s/gic/interrupt controlle= r. - construct_domU(): - ifdef-ing by CONFIG_HVM accesses to hvm.params. - Call init_vuart() to hide Arm's vpl011_init() details there. - Add call of set_domain_type() instead of setting kinfo->arch.type expli= citly. Some parts of dom0less-build.c are wraped by #ifdef CONFIG_STATIC_{SHMEM,ME= MORY} as not all archs support these configs. Signed-off-by: Oleksii Kurochko --- Change in v3: - Align construct_domU() with the current staging. - Align alloc_xenstore_params() with the current staging. - Move defintion of XENSTORE_PFN_LATE_ALLOC to common and declaration of need_xenstore to common. --- Change in v2: - Wrap by #ifdef CONFIG_STATIC_* inclusions of and . Wrap also the code which uses something from the mentioned headers. - Add handling of legacy case in construct_domU(). - Use xen/fdt-kernel.h and xen/fdt-domain-build.h instead of asm/*. - Update the commit message. --- xen/arch/arm/dom0less-build.c | 714 ++--------------------- xen/common/device-tree/dom0less-build.c | 699 ++++++++++++++++++++++ xen/include/asm-generic/dom0less-build.h | 18 +- 3 files changed, 751 insertions(+), 680 deletions(-) diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c index 0310579863..627c212b3b 100644 --- a/xen/arch/arm/dom0less-build.c +++ b/xen/arch/arm/dom0less-build.c @@ -25,8 +25,6 @@ #include #include =20 -bool __initdata need_xenstore; - #ifdef CONFIG_VGICV2 static int __init make_gicv2_domU_node(struct kernel_info *kinfo) { @@ -152,7 +150,7 @@ static int __init make_gicv3_domU_node(struct kernel_in= fo *kinfo) } #endif =20 -static int __init make_gic_domU_node(struct kernel_info *kinfo) +int __init make_intc_domU_node(struct kernel_info *kinfo) { switch ( kinfo->d->arch.vgic.version ) { @@ -218,708 +216,60 @@ static int __init make_vpl011_uart_node(struct kerne= l_info *kinfo) } #endif =20 -/* - * Scan device tree properties for passthrough specific information. - * Returns < 0 on error - * 0 on success - */ -static int __init handle_passthrough_prop(struct kernel_info *kinfo, - const struct fdt_property *xen_r= eg, - const struct fdt_property *xen_p= ath, - bool xen_force, - uint32_t address_cells, - uint32_t size_cells) -{ - const __be32 *cell; - unsigned int i, len; - struct dt_device_node *node; - int res; - paddr_t mstart, size, gstart; - - /* xen,reg specifies where to map the MMIO region */ - cell =3D (const __be32 *)xen_reg->data; - len =3D fdt32_to_cpu(xen_reg->len) / ((address_cells * 2 + size_cells)= * - sizeof(uint32_t)); - - for ( i =3D 0; i < len; i++ ) - { - device_tree_get_reg(&cell, address_cells, size_cells, - &mstart, &size); - gstart =3D dt_next_cell(address_cells, &cell); - - if ( gstart & ~PAGE_MASK || mstart & ~PAGE_MASK || size & ~PAGE_MA= SK ) - { - printk(XENLOG_ERR - "DomU passthrough config has not page aligned addresses= /sizes\n"); - return -EINVAL; - } - - res =3D iomem_permit_access(kinfo->d, paddr_to_pfn(mstart), - paddr_to_pfn(PAGE_ALIGN(mstart + size - = 1))); - if ( res ) - { - printk(XENLOG_ERR "Unable to permit to dom%d access to" - " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n", - kinfo->d->domain_id, - mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1); - return res; - } - - res =3D map_regions_p2mt(kinfo->d, - gaddr_to_gfn(gstart), - PFN_DOWN(size), - maddr_to_mfn(mstart), - p2m_mmio_direct_dev); - if ( res < 0 ) - { - printk(XENLOG_ERR - "Failed to map %"PRIpaddr" to the guest at%"PRIpaddr"\n= ", - mstart, gstart); - return -EFAULT; - } - } - - /* - * If xen_force, we let the user assign a MMIO region with no - * associated path. - */ - if ( xen_path =3D=3D NULL ) - return xen_force ? 0 : -EINVAL; - - /* - * xen,path specifies the corresponding node in the host DT. - * Both interrupt mappings and IOMMU settings are based on it, - * as they are done based on the corresponding host DT node. - */ - node =3D dt_find_node_by_path(xen_path->data); - if ( node =3D=3D NULL ) - { - printk(XENLOG_ERR "Couldn't find node %s in host_dt!\n", - xen_path->data); - return -EINVAL; - } - - res =3D map_device_irqs_to_domain(kinfo->d, node, true, NULL); - if ( res < 0 ) - return res; - - res =3D iommu_add_dt_device(node); - if ( res < 0 ) - return res; - - /* If xen_force, we allow assignment of devices without IOMMU protecti= on. */ - if ( xen_force && !dt_device_is_protected(node) ) - return 0; - - return iommu_assign_dt_device(kinfo->d, node); -} - -static int __init handle_prop_pfdt(struct kernel_info *kinfo, - const void *pfdt, int nodeoff, - uint32_t address_cells, uint32_t size_c= ells, - bool scan_passthrough_prop) -{ - void *fdt =3D kinfo->fdt; - int propoff, nameoff, res; - const struct fdt_property *prop, *xen_reg =3D NULL, *xen_path =3D NULL; - const char *name; - bool found, xen_force =3D false; - - for ( propoff =3D fdt_first_property_offset(pfdt, nodeoff); - propoff >=3D 0; - propoff =3D fdt_next_property_offset(pfdt, propoff) ) - { - if ( !(prop =3D fdt_get_property_by_offset(pfdt, propoff, NULL)) ) - return -FDT_ERR_INTERNAL; - - found =3D false; - nameoff =3D fdt32_to_cpu(prop->nameoff); - name =3D fdt_string(pfdt, nameoff); - - if ( scan_passthrough_prop ) - { - if ( dt_prop_cmp("xen,reg", name) =3D=3D 0 ) - { - xen_reg =3D prop; - found =3D true; - } - else if ( dt_prop_cmp("xen,path", name) =3D=3D 0 ) - { - xen_path =3D prop; - found =3D true; - } - else if ( dt_prop_cmp("xen,force-assign-without-iommu", - name) =3D=3D 0 ) - { - xen_force =3D true; - found =3D true; - } - } - - /* - * Copy properties other than the ones above: xen,reg, xen,path, - * and xen,force-assign-without-iommu. - */ - if ( !found ) - { - res =3D fdt_property(fdt, name, prop->data, fdt32_to_cpu(prop-= >len)); - if ( res ) - return res; - } - } - - /* - * Only handle passthrough properties if both xen,reg and xen,path - * are present, or if xen,force-assign-without-iommu is specified. - */ - if ( xen_reg !=3D NULL && (xen_path !=3D NULL || xen_force) ) - { - res =3D handle_passthrough_prop(kinfo, xen_reg, xen_path, xen_forc= e, - address_cells, size_cells); - if ( res < 0 ) - { - printk(XENLOG_ERR "Failed to assign device to %pd\n", kinfo->d= ); - return res; - } - } - else if ( (xen_path && !xen_reg) || (xen_reg && !xen_path && !xen_forc= e) ) - { - printk(XENLOG_ERR "xen,reg or xen,path missing for %pd\n", - kinfo->d); - return -EINVAL; - } - - /* FDT_ERR_NOTFOUND =3D> There is no more properties for this node */ - return ( propoff !=3D -FDT_ERR_NOTFOUND ) ? propoff : 0; -} - -static int __init scan_pfdt_node(struct kernel_info *kinfo, const void *pf= dt, - int nodeoff, - uint32_t address_cells, uint32_t size_cel= ls, - bool scan_passthrough_prop) -{ - int rc =3D 0; - void *fdt =3D kinfo->fdt; - int node_next; - - rc =3D fdt_begin_node(fdt, fdt_get_name(pfdt, nodeoff, NULL)); - if ( rc ) - return rc; - - rc =3D handle_prop_pfdt(kinfo, pfdt, nodeoff, address_cells, size_cell= s, - scan_passthrough_prop); - if ( rc ) - return rc; - - address_cells =3D device_tree_get_u32(pfdt, nodeoff, "#address-cells", - DT_ROOT_NODE_ADDR_CELLS_DEFAULT); - size_cells =3D device_tree_get_u32(pfdt, nodeoff, "#size-cells", - DT_ROOT_NODE_SIZE_CELLS_DEFAULT); - - node_next =3D fdt_first_subnode(pfdt, nodeoff); - while ( node_next > 0 ) - { - rc =3D scan_pfdt_node(kinfo, pfdt, node_next, address_cells, size_= cells, - scan_passthrough_prop); - if ( rc ) - return rc; - - node_next =3D fdt_next_subnode(pfdt, node_next); - } - - return fdt_end_node(fdt); -} - -static int __init check_partial_fdt(void *pfdt, size_t size) +int __init make_arch_nodes(struct kernel_info *kinfo) { - int res; - - if ( fdt_magic(pfdt) !=3D FDT_MAGIC ) - { - dprintk(XENLOG_ERR, "Partial FDT is not a valid Flat Device Tree"); - return -EINVAL; - } - - res =3D fdt_check_header(pfdt); - if ( res ) - { - dprintk(XENLOG_ERR, "Failed to check the partial FDT (%d)", res); - return -EINVAL; - } - - if ( fdt_totalsize(pfdt) > size ) - { - dprintk(XENLOG_ERR, "Partial FDT totalsize is too big"); - return -EINVAL; - } - - return 0; -} - -static int __init domain_handle_dtb_bootmodule(struct domain *d, - struct kernel_info *kinfo) -{ - void *pfdt; - int res, node_next; - - pfdt =3D ioremap_cache(kinfo->dtb_bootmodule->start, - kinfo->dtb_bootmodule->size); - if ( pfdt =3D=3D NULL ) - return -EFAULT; - - res =3D check_partial_fdt(pfdt, kinfo->dtb_bootmodule->size); - if ( res < 0 ) - goto out; - - for ( node_next =3D fdt_first_subnode(pfdt, 0); - node_next > 0; - node_next =3D fdt_next_subnode(pfdt, node_next) ) - { - const char *name =3D fdt_get_name(pfdt, node_next, NULL); - - if ( name =3D=3D NULL ) - continue; - - /* - * Only scan /gic /aliases /passthrough, ignore the rest. - * They don't have to be parsed in order. - * - * Take the GIC phandle value from the special /gic node in the - * DTB fragment. - */ - if ( dt_node_cmp(name, "gic") =3D=3D 0 ) - { - uint32_t phandle_intc =3D fdt_get_phandle(pfdt, node_next); - - if ( phandle_intc !=3D 0 ) - kinfo->phandle_intc =3D phandle_intc; - continue; - } - - if ( dt_node_cmp(name, "aliases") =3D=3D 0 ) - { - res =3D scan_pfdt_node(kinfo, pfdt, node_next, - DT_ROOT_NODE_ADDR_CELLS_DEFAULT, - DT_ROOT_NODE_SIZE_CELLS_DEFAULT, - false); - if ( res ) - goto out; - continue; - } - if ( dt_node_cmp(name, "passthrough") =3D=3D 0 ) - { - res =3D scan_pfdt_node(kinfo, pfdt, node_next, - DT_ROOT_NODE_ADDR_CELLS_DEFAULT, - DT_ROOT_NODE_SIZE_CELLS_DEFAULT, - true); - if ( res ) - goto out; - continue; - } - } - - out: - iounmap(pfdt); - - return res; -} - -/* - * The max size for DT is 2MB. However, the generated DT is small (not inc= luding - * domU passthrough DT nodes whose size we account separately), 4KB are en= ough - * for now, but we might have to increase it in the future. - */ -#define DOMU_DTB_SIZE 4096 -static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *k= info) -{ - int addrcells, sizecells; - int ret, fdt_size =3D DOMU_DTB_SIZE; - - kinfo->phandle_intc =3D GUEST_PHANDLE_GIC; - kinfo->gnttab_start =3D GUEST_GNTTAB_BASE; - kinfo->gnttab_size =3D GUEST_GNTTAB_SIZE; - - addrcells =3D GUEST_ROOT_ADDRESS_CELLS; - sizecells =3D GUEST_ROOT_SIZE_CELLS; - - /* Account for domU passthrough DT size */ - if ( kinfo->dtb_bootmodule ) - fdt_size +=3D kinfo->dtb_bootmodule->size; - - /* Cap to max DT size if needed */ - fdt_size =3D min(fdt_size, SZ_2M); - - kinfo->fdt =3D xmalloc_bytes(fdt_size); - if ( kinfo->fdt =3D=3D NULL ) - return -ENOMEM; - - ret =3D fdt_create(kinfo->fdt, fdt_size); - if ( ret < 0 ) - goto err; - - ret =3D fdt_finish_reservemap(kinfo->fdt); - if ( ret < 0 ) - goto err; - - ret =3D fdt_begin_node(kinfo->fdt, ""); - if ( ret < 0 ) - goto err; - - ret =3D fdt_property_cell(kinfo->fdt, "#address-cells", addrcells); - if ( ret ) - goto err; - - ret =3D fdt_property_cell(kinfo->fdt, "#size-cells", sizecells); - if ( ret ) - goto err; - - ret =3D make_chosen_node(kinfo); - if ( ret ) - goto err; + int ret; =20 ret =3D make_psci_node(kinfo->fdt); if ( ret ) - goto err; - - ret =3D make_cpus_node(d, kinfo->fdt); - if ( ret ) - goto err; - - ret =3D make_memory_node(kinfo, addrcells, sizecells, - kernel_info_get_mem(kinfo)); - if ( ret ) - goto err; - - ret =3D make_resv_memory_node(kinfo, addrcells, sizecells); - if ( ret ) - goto err; - - /* - * domain_handle_dtb_bootmodule has to be called before the rest of - * the device tree is generated because it depends on the value of - * the field phandle_intc. - */ - if ( kinfo->dtb_bootmodule ) - { - ret =3D domain_handle_dtb_bootmodule(d, kinfo); - if ( ret ) - goto err; - } - - ret =3D make_gic_domU_node(kinfo); - if ( ret ) - goto err; - - ret =3D make_timer_node(kinfo); - if ( ret ) - goto err; + return -EINVAL; =20 if ( kinfo->vuart ) { - ret =3D -EINVAL; #ifdef CONFIG_SBSA_VUART_CONSOLE ret =3D make_vpl011_uart_node(kinfo); #endif if ( ret ) - goto err; - } - - if ( kinfo->dom0less_feature & DOM0LESS_ENHANCED_NO_XS ) - { - ret =3D make_hypervisor_node(d, kinfo, addrcells, sizecells); - if ( ret ) - goto err; + return -EINVAL; } =20 - ret =3D fdt_end_node(kinfo->fdt); - if ( ret < 0 ) - goto err; - - ret =3D fdt_finish(kinfo->fdt); - if ( ret < 0 ) - goto err; - return 0; - - err: - printk("Device tree generation failed (%d).\n", ret); - xfree(kinfo->fdt); - - return -EINVAL; } =20 -#define XENSTORE_PFN_OFFSET 1 -static int __init alloc_xenstore_page(struct domain *d) +/* TODO: make arch.type generic ? */ +#ifdef CONFIG_ARM_64 +void __init set_domain_type(struct domain *d, struct kernel_info *kinfo) { - struct page_info *xenstore_pg; - struct xenstore_domain_interface *interface; - mfn_t mfn; - gfn_t gfn; - int rc; - - if ( (UINT_MAX - d->max_pages) < 1 ) - { - printk(XENLOG_ERR "%pd: Over-allocation for d->max_pages by 1 page= .\n", - d); - return -EINVAL; - } - - d->max_pages +=3D 1; - xenstore_pg =3D alloc_domheap_page(d, MEMF_bits(32)); - if ( xenstore_pg =3D=3D NULL && is_64bit_domain(d) ) - xenstore_pg =3D alloc_domheap_page(d, 0); - if ( xenstore_pg =3D=3D NULL ) - return -ENOMEM; - - mfn =3D page_to_mfn(xenstore_pg); - if ( !mfn_x(mfn) ) - return -ENOMEM; - - if ( !is_domain_direct_mapped(d) ) - gfn =3D gaddr_to_gfn(GUEST_MAGIC_BASE + - (XENSTORE_PFN_OFFSET << PAGE_SHIFT)); - else - gfn =3D gaddr_to_gfn(mfn_to_maddr(mfn)); - - rc =3D guest_physmap_add_page(d, gfn, mfn, 0); - if ( rc ) - { - free_domheap_page(xenstore_pg); - return rc; - } - - d->arch.hvm.params[HVM_PARAM_STORE_PFN] =3D gfn_x(gfn); - interface =3D map_domain_page(mfn); - interface->connection =3D XENSTORE_RECONNECT; - unmap_domain_page(interface); - - return 0; + /* type must be set before allocate memory */ + d->arch.type =3D kinfo->arch.type; } - -static int __init alloc_xenstore_params(struct kernel_info *kinfo) +#else +void __init set_domain_type(struct domain *d, struct kernel_info *kinfo) { - struct domain *d =3D kinfo->d; - int rc =3D 0; - - if ( (kinfo->dom0less_feature & (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGAC= Y)) - =3D=3D (DOM0LESS_XENSTORE | DOM0LESS_XS_L= EGACY) ) - d->arch.hvm.params[HVM_PARAM_STORE_PFN] =3D XENSTORE_PFN_LATE_ALLO= C; - else if ( kinfo->dom0less_feature & DOM0LESS_XENSTORE ) - { - rc =3D alloc_xenstore_page(d); - if ( rc < 0 ) - return rc; - } - - return rc; + /* Nothing to do */ } +#endif =20 -static void __init domain_vcpu_affinity(struct domain *d, - const struct dt_device_node *node) +int __init init_vuart(struct domain *d, struct kernel_info *kinfo, + const struct dt_device_node *node) { - struct dt_device_node *np; - - dt_for_each_child_node(node, np) - { - const char *hard_affinity_str =3D NULL; - uint32_t val; - int rc; - struct vcpu *v; - cpumask_t affinity; - - if ( !dt_device_is_compatible(np, "xen,vcpu") ) - continue; - - if ( !dt_property_read_u32(np, "id", &val) ) - panic("Invalid xen,vcpu node for domain %s\n", dt_node_name(no= de)); - - if ( val >=3D d->max_vcpus ) - panic("Invalid vcpu_id %u for domain %s, max_vcpus=3D%u\n", va= l, - dt_node_name(node), d->max_vcpus); - - v =3D d->vcpu[val]; - rc =3D dt_property_read_string(np, "hard-affinity", &hard_affinity= _str); - if ( rc < 0 ) - continue; - - cpumask_clear(&affinity); - while ( *hard_affinity_str !=3D '\0' ) - { - unsigned int start, end; - - start =3D simple_strtoul(hard_affinity_str, &hard_affinity_str= , 0); - - if ( *hard_affinity_str =3D=3D '-' ) /* Range */ - { - hard_affinity_str++; - end =3D simple_strtoul(hard_affinity_str, &hard_affinity_s= tr, 0); - } - else /* Single value */ - end =3D start; - - if ( end >=3D nr_cpu_ids ) - panic("Invalid pCPU %u for domain %s\n", end, dt_node_name= (node)); - - for ( ; start <=3D end; start++ ) - cpumask_set_cpu(start, &affinity); - - if ( *hard_affinity_str =3D=3D ',' ) - hard_affinity_str++; - else if ( *hard_affinity_str !=3D '\0' ) - break; - } + int rc =3D 0; =20 - rc =3D vcpu_set_hard_affinity(v, &affinity); - if ( rc ) - panic("vcpu%d: failed (rc=3D%d) to set hard affinity for domai= n %s\n", - v->vcpu_id, rc, dt_node_name(node)); - } -} + kinfo->vuart =3D dt_property_read_bool(node, "vpl011"); =20 -#ifdef CONFIG_ARCH_PAGING_MEMPOOL -static unsigned long __init domain_p2m_pages(unsigned long maxmem_kb, - unsigned int smp_cpus) -{ /* - * Keep in sync with libxl__get_required_paging_memory(). - * 256 pages (1MB) per vcpu, plus 1 page per MiB of RAM for the P2M ma= p, - * plus 128 pages to cover extended regions. + * Base address and irq number are needed when creating vpl011 device + * tree node in prepare_dtb_domU, so initialization on related variabl= es + * shall be done first. */ - unsigned long memkb =3D 4 * (256 * smp_cpus + (maxmem_kb / 1024) + 128= ); - - BUILD_BUG_ON(PAGE_SIZE !=3D SZ_4K); - - return DIV_ROUND_UP(memkb, 1024) << (20 - PAGE_SHIFT); -} - -static int __init domain_p2m_set_allocation(struct domain *d, uint64_t mem, - const struct dt_device_node *n= ode) -{ - unsigned long p2m_pages; - uint32_t p2m_mem_mb; - int rc; - - rc =3D dt_property_read_u32(node, "xen,domain-p2m-mem-mb", &p2m_mem_mb= ); - /* If xen,domain-p2m-mem-mb is not specified, use the default value. */ - p2m_pages =3D rc ? - p2m_mem_mb << (20 - PAGE_SHIFT) : - domain_p2m_pages(mem, d->max_vcpus); - - spin_lock(&d->arch.paging.lock); - rc =3D p2m_set_allocation(d, p2m_pages, NULL); - spin_unlock(&d->arch.paging.lock); - - return rc; -} -#else /* !CONFIG_ARCH_PAGING_MEMPOOL */ -static inline int domain_p2m_set_allocation(struct domain *d, uint64_t mem, - const struct dt_device_node *n= ode) -{ - return 0; -} -#endif /* CONFIG_ARCH_PAGING_MEMPOOL */ - -int __init construct_domU(struct domain *d, - const struct dt_device_node *node) -{ - struct kernel_info kinfo =3D KERNEL_INFO_INIT; - const char *dom0less_enhanced; - int rc; - u64 mem; - - rc =3D dt_property_read_u64(node, "memory", &mem); - if ( !rc ) - { - printk("Error building DomU: cannot read \"memory\" property\n"); - return -EINVAL; - } - kinfo.unassigned_mem =3D (paddr_t)mem * SZ_1K; - - rc =3D domain_p2m_set_allocation(d, mem, node); - if ( rc !=3D 0 ) - return rc; - - printk("*** LOADING DOMU cpus=3D%u memory=3D%#"PRIx64"KB ***\n", - d->max_vcpus, mem); - - kinfo.vuart =3D dt_property_read_bool(node, "vpl011"); - if ( kinfo.vuart && is_hardware_domain(d) ) - panic("hardware domain cannot specify vpl011\n"); - - rc =3D dt_property_read_string(node, "xen,enhanced", &dom0less_enhance= d); - if ( rc =3D=3D -EILSEQ || - rc =3D=3D -ENODATA || - (rc =3D=3D 0 && !strcmp(dom0less_enhanced, "enabled")) ) - { - need_xenstore =3D true; - kinfo.dom0less_feature =3D DOM0LESS_ENHANCED; - } - else if ( rc =3D=3D 0 && !strcmp(dom0less_enhanced, "legacy") ) - { - need_xenstore =3D true; - kinfo.dom0less_feature =3D DOM0LESS_ENHANCED_LEGACY; - } - else if ( rc =3D=3D 0 && !strcmp(dom0less_enhanced, "no-xenstore") ) - kinfo.dom0less_feature =3D DOM0LESS_ENHANCED_NO_XS; - - if ( vcpu_create(d, 0) =3D=3D NULL ) - return -ENOMEM; - - d->max_pages =3D ((paddr_t)mem * SZ_1K) >> PAGE_SHIFT; - - kinfo.d =3D d; - - rc =3D kernel_probe(&kinfo, node); - if ( rc < 0 ) - return rc; - -#ifdef CONFIG_ARM_64 - /* type must be set before allocate memory */ - d->arch.type =3D kinfo.arch.type; -#endif - if ( is_hardware_domain(d) ) - { - rc =3D construct_hwdom(&kinfo, node); - if ( rc < 0 ) - return rc; - } - else + if ( kinfo->vuart ) { - if ( !dt_find_property(node, "xen,static-mem", NULL) ) - allocate_memory(d, &kinfo); - else if ( !is_domain_direct_mapped(d) ) - allocate_static_memory(d, &kinfo, node); - else - assign_static_memory_11(d, &kinfo, node); - - rc =3D process_shm(d, &kinfo, node); - if ( rc < 0 ) - return rc; - - /* - * Base address and irq number are needed when creating vpl011 dev= ice - * tree node in prepare_dtb_domU, so initialization on related var= iables - * shall be done first. - */ - if ( kinfo.vuart ) - { - rc =3D domain_vpl011_init(d, NULL); - if ( rc < 0 ) - return rc; - } - - rc =3D prepare_dtb_domU(d, &kinfo); - if ( rc < 0 ) - return rc; - - rc =3D construct_domain(d, &kinfo); + rc =3D domain_vpl011_init(d, NULL); if ( rc < 0 ) return rc; } =20 - domain_vcpu_affinity(d, node); - - return alloc_xenstore_params(&kinfo); + return rc; } =20 void __init arch_create_domUs(struct dt_device_node *node, @@ -995,6 +345,22 @@ void __init arch_create_domUs(struct dt_device_node *n= ode, } } =20 +int __init init_intc_phandle(struct kernel_info *kinfo, const char *name, + const int node_next, const void *pfdt) +{ + if ( dt_node_cmp(name, "gic") =3D=3D 0 ) + { + uint32_t phandle_intc =3D fdt_get_phandle(pfdt, node_next); + + if ( phandle_intc !=3D 0 ) + kinfo->phandle_intc =3D phandle_intc; + + return 0; + } + + return 1; +} + /* * Local variables: * mode: C diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tr= ee/dom0less-build.c index a01a8b6b1a..c3face5b90 100644 --- a/xen/common/device-tree/dom0less-build.c +++ b/xen/common/device-tree/dom0less-build.c @@ -3,24 +3,43 @@ #include #include #include +#include #include #include +#include +#include #include #include +#include #include +#include #include +#include #include #include #include +#include =20 #include #include #include +#include =20 #include #include =20 +#ifdef CONFIG_STATIC_MEMORY +#include +#endif + +#ifdef CONFIG_STATIC_SHM +#include +#endif + +#define XENSTORE_PFN_LATE_ALLOC UINT64_MAX + static domid_t __initdata xs_domid =3D DOMID_INVALID; +static bool __initdata need_xenstore; =20 void __init set_xs_domain(struct domain *d) { @@ -109,6 +128,686 @@ static void __init initialize_domU_xenstore(void) } } =20 +/* + * Scan device tree properties for passthrough specific information. + * Returns < 0 on error + * 0 on success + */ +static int __init handle_passthrough_prop(struct kernel_info *kinfo, + const struct fdt_property *xen_r= eg, + const struct fdt_property *xen_p= ath, + bool xen_force, + uint32_t address_cells, + uint32_t size_cells) +{ + const __be32 *cell; + unsigned int i, len; + struct dt_device_node *node; + int res; + paddr_t mstart, size, gstart; + + /* xen,reg specifies where to map the MMIO region */ + cell =3D (const __be32 *)xen_reg->data; + len =3D fdt32_to_cpu(xen_reg->len) / ((address_cells * 2 + size_cells)= * + sizeof(uint32_t)); + + for ( i =3D 0; i < len; i++ ) + { + device_tree_get_reg(&cell, address_cells, size_cells, + &mstart, &size); + gstart =3D dt_next_cell(address_cells, &cell); + + if ( gstart & ~PAGE_MASK || mstart & ~PAGE_MASK || size & ~PAGE_MA= SK ) + { + printk(XENLOG_ERR + "DomU passthrough config has not page aligned addresses= /sizes\n"); + return -EINVAL; + } + + res =3D iomem_permit_access(kinfo->d, paddr_to_pfn(mstart), + paddr_to_pfn(PAGE_ALIGN(mstart + size - = 1))); + if ( res ) + { + printk(XENLOG_ERR "Unable to permit to dom%d access to" + " 0x%"PRIpaddr" - 0x%"PRIpaddr"\n", + kinfo->d->domain_id, + mstart & PAGE_MASK, PAGE_ALIGN(mstart + size) - 1); + return res; + } + + res =3D map_regions_p2mt(kinfo->d, + gaddr_to_gfn(gstart), + PFN_DOWN(size), + maddr_to_mfn(mstart), + p2m_mmio_direct_dev); + if ( res < 0 ) + { + printk(XENLOG_ERR + "Failed to map %"PRIpaddr" to the guest at%"PRIpaddr"\n= ", + mstart, gstart); + return -EFAULT; + } + } + + /* + * If xen_force, we let the user assign a MMIO region with no + * associated path. + */ + if ( xen_path =3D=3D NULL ) + return xen_force ? 0 : -EINVAL; + + /* + * xen,path specifies the corresponding node in the host DT. + * Both interrupt mappings and IOMMU settings are based on it, + * as they are done based on the corresponding host DT node. + */ + node =3D dt_find_node_by_path(xen_path->data); + if ( node =3D=3D NULL ) + { + printk(XENLOG_ERR "Couldn't find node %s in host_dt!\n", + xen_path->data); + return -EINVAL; + } + + res =3D map_device_irqs_to_domain(kinfo->d, node, true, NULL); + if ( res < 0 ) + return res; + + res =3D iommu_add_dt_device(node); + if ( res < 0 ) + return res; + + /* If xen_force, we allow assignment of devices without IOMMU protecti= on. */ + if ( xen_force && !dt_device_is_protected(node) ) + return 0; + + return iommu_assign_dt_device(kinfo->d, node); +} + +static int __init handle_prop_pfdt(struct kernel_info *kinfo, + const void *pfdt, int nodeoff, + uint32_t address_cells, uint32_t size_c= ells, + bool scan_passthrough_prop) +{ + void *fdt =3D kinfo->fdt; + int propoff, nameoff, res; + const struct fdt_property *prop, *xen_reg =3D NULL, *xen_path =3D NULL; + const char *name; + bool found, xen_force =3D false; + + for ( propoff =3D fdt_first_property_offset(pfdt, nodeoff); + propoff >=3D 0; + propoff =3D fdt_next_property_offset(pfdt, propoff) ) + { + if ( !(prop =3D fdt_get_property_by_offset(pfdt, propoff, NULL)) ) + return -FDT_ERR_INTERNAL; + + found =3D false; + nameoff =3D fdt32_to_cpu(prop->nameoff); + name =3D fdt_string(pfdt, nameoff); + + if ( scan_passthrough_prop ) + { + if ( dt_prop_cmp("xen,reg", name) =3D=3D 0 ) + { + xen_reg =3D prop; + found =3D true; + } + else if ( dt_prop_cmp("xen,path", name) =3D=3D 0 ) + { + xen_path =3D prop; + found =3D true; + } + else if ( dt_prop_cmp("xen,force-assign-without-iommu", + name) =3D=3D 0 ) + { + xen_force =3D true; + found =3D true; + } + } + + /* + * Copy properties other than the ones above: xen,reg, xen,path, + * and xen,force-assign-without-iommu. + */ + if ( !found ) + { + res =3D fdt_property(fdt, name, prop->data, fdt32_to_cpu(prop-= >len)); + if ( res ) + return res; + } + } + + /* + * Only handle passthrough properties if both xen,reg and xen,path + * are present, or if xen,force-assign-without-iommu is specified. + */ + if ( xen_reg !=3D NULL && (xen_path !=3D NULL || xen_force) ) + { + res =3D handle_passthrough_prop(kinfo, xen_reg, xen_path, xen_forc= e, + address_cells, size_cells); + if ( res < 0 ) + { + printk(XENLOG_ERR "Failed to assign device to %pd\n", kinfo->d= ); + return res; + } + } + else if ( (xen_path && !xen_reg) || (xen_reg && !xen_path && !xen_forc= e) ) + { + printk(XENLOG_ERR "xen,reg or xen,path missing for %pd\n", + kinfo->d); + return -EINVAL; + } + + /* FDT_ERR_NOTFOUND =3D> There is no more properties for this node */ + return ( propoff !=3D -FDT_ERR_NOTFOUND ) ? propoff : 0; +} + +static int __init scan_pfdt_node(struct kernel_info *kinfo, const void *pf= dt, + int nodeoff, + uint32_t address_cells, uint32_t size_cel= ls, + bool scan_passthrough_prop) +{ + int rc =3D 0; + void *fdt =3D kinfo->fdt; + int node_next; + + rc =3D fdt_begin_node(fdt, fdt_get_name(pfdt, nodeoff, NULL)); + if ( rc ) + return rc; + + rc =3D handle_prop_pfdt(kinfo, pfdt, nodeoff, address_cells, size_cell= s, + scan_passthrough_prop); + if ( rc ) + return rc; + + address_cells =3D device_tree_get_u32(pfdt, nodeoff, "#address-cells", + DT_ROOT_NODE_ADDR_CELLS_DEFAULT); + size_cells =3D device_tree_get_u32(pfdt, nodeoff, "#size-cells", + DT_ROOT_NODE_SIZE_CELLS_DEFAULT); + + node_next =3D fdt_first_subnode(pfdt, nodeoff); + while ( node_next > 0 ) + { + rc =3D scan_pfdt_node(kinfo, pfdt, node_next, address_cells, size_= cells, + scan_passthrough_prop); + if ( rc ) + return rc; + + node_next =3D fdt_next_subnode(pfdt, node_next); + } + + return fdt_end_node(fdt); +} + +static int __init check_partial_fdt(void *pfdt, size_t size) +{ + int res; + + if ( fdt_magic(pfdt) !=3D FDT_MAGIC ) + { + dprintk(XENLOG_ERR, "Partial FDT is not a valid Flat Device Tree"); + return -EINVAL; + } + + res =3D fdt_check_header(pfdt); + if ( res ) + { + dprintk(XENLOG_ERR, "Failed to check the partial FDT (%d)", res); + return -EINVAL; + } + + if ( fdt_totalsize(pfdt) > size ) + { + dprintk(XENLOG_ERR, "Partial FDT totalsize is too big"); + return -EINVAL; + } + + return 0; +} + +static int __init domain_handle_dtb_bootmodule(struct domain *d, + struct kernel_info *kinfo) +{ + void *pfdt; + int res, node_next; + + pfdt =3D ioremap_cache(kinfo->dtb_bootmodule->start, + kinfo->dtb_bootmodule->size); + if ( pfdt =3D=3D NULL ) + return -EFAULT; + + res =3D check_partial_fdt(pfdt, kinfo->dtb_bootmodule->size); + if ( res < 0 ) + goto out; + + for ( node_next =3D fdt_first_subnode(pfdt, 0); + node_next > 0; + node_next =3D fdt_next_subnode(pfdt, node_next) ) + { + const char *name =3D fdt_get_name(pfdt, node_next, NULL); + + if ( name =3D=3D NULL ) + continue; + + /* + * Only scan /$(interrupt_controller) /aliases /passthrough, + * ignore the rest. + * They don't have to be parsed in order. + * + * Take the interrupt controller phandle value from the special + * interrupt controller node in the DTB fragment. + */ + if ( init_intc_phandle(kinfo, name, node_next, pfdt) =3D=3D 0 ) + continue; + + if ( dt_node_cmp(name, "aliases") =3D=3D 0 ) + { + res =3D scan_pfdt_node(kinfo, pfdt, node_next, + DT_ROOT_NODE_ADDR_CELLS_DEFAULT, + DT_ROOT_NODE_SIZE_CELLS_DEFAULT, + false); + if ( res ) + goto out; + continue; + } + if ( dt_node_cmp(name, "passthrough") =3D=3D 0 ) + { + res =3D scan_pfdt_node(kinfo, pfdt, node_next, + DT_ROOT_NODE_ADDR_CELLS_DEFAULT, + DT_ROOT_NODE_SIZE_CELLS_DEFAULT, + true); + if ( res ) + goto out; + continue; + } + } + + out: + iounmap(pfdt); + + return res; +} + +/* + * The max size for DT is 2MB. However, the generated DT is small (not inc= luding + * domU passthrough DT nodes whose size we account separately), 4KB are en= ough + * for now, but we might have to increase it in the future. + */ +#define DOMU_DTB_SIZE 4096 +static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *k= info) +{ + int addrcells, sizecells; + int ret, fdt_size =3D DOMU_DTB_SIZE; + + kinfo->phandle_intc =3D GUEST_PHANDLE_GIC; + +#ifdef CONFIG_GRANT_TABLE + kinfo->gnttab_start =3D GUEST_GNTTAB_BASE; + kinfo->gnttab_size =3D GUEST_GNTTAB_SIZE; +#endif + + addrcells =3D GUEST_ROOT_ADDRESS_CELLS; + sizecells =3D GUEST_ROOT_SIZE_CELLS; + + /* Account for domU passthrough DT size */ + if ( kinfo->dtb_bootmodule ) + fdt_size +=3D kinfo->dtb_bootmodule->size; + + /* Cap to max DT size if needed */ + fdt_size =3D min(fdt_size, SZ_2M); + + kinfo->fdt =3D xmalloc_bytes(fdt_size); + if ( kinfo->fdt =3D=3D NULL ) + return -ENOMEM; + + ret =3D fdt_create(kinfo->fdt, fdt_size); + if ( ret < 0 ) + goto err; + + ret =3D fdt_finish_reservemap(kinfo->fdt); + if ( ret < 0 ) + goto err; + + ret =3D fdt_begin_node(kinfo->fdt, ""); + if ( ret < 0 ) + goto err; + + ret =3D fdt_property_cell(kinfo->fdt, "#address-cells", addrcells); + if ( ret ) + goto err; + + ret =3D fdt_property_cell(kinfo->fdt, "#size-cells", sizecells); + if ( ret ) + goto err; + + ret =3D make_chosen_node(kinfo); + if ( ret ) + goto err; + + ret =3D make_cpus_node(d, kinfo->fdt); + if ( ret ) + goto err; + + ret =3D make_memory_node(kinfo, addrcells, sizecells, + kernel_info_get_mem(kinfo)); + if ( ret ) + goto err; + +#ifdef CONFIG_STATIC_SHM + ret =3D make_resv_memory_node(kinfo, addrcells, sizecells); + if ( ret ) + goto err; +#endif + + /* + * domain_handle_dtb_bootmodule has to be called before the rest of + * the device tree is generated because it depends on the value of + * the field phandle_intc. + */ + if ( kinfo->dtb_bootmodule ) + { + ret =3D domain_handle_dtb_bootmodule(d, kinfo); + if ( ret ) + goto err; + } + + ret =3D make_intc_domU_node(kinfo); + if ( ret ) + goto err; + + ret =3D make_timer_node(kinfo); + if ( ret ) + goto err; + + if ( kinfo->dom0less_feature & DOM0LESS_ENHANCED_NO_XS ) + { + ret =3D make_hypervisor_node(d, kinfo, addrcells, sizecells); + if ( ret ) + goto err; + } + + ret =3D make_arch_nodes(kinfo); + if ( ret ) + goto err; + + ret =3D fdt_end_node(kinfo->fdt); + if ( ret < 0 ) + goto err; + + ret =3D fdt_finish(kinfo->fdt); + if ( ret < 0 ) + goto err; + + return 0; + + err: + printk("Device tree generation failed (%d).\n", ret); + xfree(kinfo->fdt); + + return -EINVAL; +} + +#define XENSTORE_PFN_OFFSET 1 +static int __init alloc_xenstore_page(struct domain *d) +{ + struct page_info *xenstore_pg; + struct xenstore_domain_interface *interface; + mfn_t mfn; + gfn_t gfn; + int rc; + + if ( (UINT_MAX - d->max_pages) < 1 ) + { + printk(XENLOG_ERR "%pd: Over-allocation for d->max_pages by 1 page= .\n", + d); + return -EINVAL; + } + + d->max_pages +=3D 1; + xenstore_pg =3D alloc_domheap_page(d, MEMF_bits(32)); + if ( xenstore_pg =3D=3D NULL && is_64bit_domain(d) ) + xenstore_pg =3D alloc_domheap_page(d, 0); + if ( xenstore_pg =3D=3D NULL ) + return -ENOMEM; + + mfn =3D page_to_mfn(xenstore_pg); + if ( !mfn_x(mfn) ) + return -ENOMEM; + + if ( !is_domain_direct_mapped(d) ) + gfn =3D gaddr_to_gfn(GUEST_MAGIC_BASE + + (XENSTORE_PFN_OFFSET << PAGE_SHIFT)); + else + gfn =3D gaddr_to_gfn(mfn_to_maddr(mfn)); + + rc =3D guest_physmap_add_page(d, gfn, mfn, 0); + if ( rc ) + { + free_domheap_page(xenstore_pg); + return rc; + } + +#ifdef CONFIG_HVM + d->arch.hvm.params[HVM_PARAM_STORE_PFN] =3D gfn_x(gfn); +#endif + interface =3D map_domain_page(mfn); + interface->connection =3D XENSTORE_RECONNECT; + unmap_domain_page(interface); + + return 0; +} + +static int __init alloc_xenstore_params(struct kernel_info *kinfo) +{ + struct domain *d =3D kinfo->d; + int rc =3D 0; + +#ifdef CONFIG_HVM + if ( (kinfo->dom0less_feature & (DOM0LESS_XENSTORE | DOM0LESS_XS_LEGAC= Y)) + =3D=3D (DOM0LESS_XENSTORE | DOM0LESS_XS_L= EGACY) ) + d->arch.hvm.params[HVM_PARAM_STORE_PFN] =3D XENSTORE_PFN_LATE_ALLO= C; + else +#endif + if ( kinfo->dom0less_feature & DOM0LESS_XENSTORE ) + { + rc =3D alloc_xenstore_page(d); + if ( rc < 0 ) + return rc; + } + + return rc; +} + +static void __init domain_vcpu_affinity(struct domain *d, + const struct dt_device_node *node) +{ + struct dt_device_node *np; + + dt_for_each_child_node(node, np) + { + const char *hard_affinity_str =3D NULL; + uint32_t val; + int rc; + struct vcpu *v; + cpumask_t affinity; + + if ( !dt_device_is_compatible(np, "xen,vcpu") ) + continue; + + if ( !dt_property_read_u32(np, "id", &val) ) + panic("Invalid xen,vcpu node for domain %s\n", dt_node_name(no= de)); + + if ( val >=3D d->max_vcpus ) + panic("Invalid vcpu_id %u for domain %s, max_vcpus=3D%u\n", va= l, + dt_node_name(node), d->max_vcpus); + + v =3D d->vcpu[val]; + rc =3D dt_property_read_string(np, "hard-affinity", &hard_affinity= _str); + if ( rc < 0 ) + continue; + + cpumask_clear(&affinity); + while ( *hard_affinity_str !=3D '\0' ) + { + unsigned int start, end; + + start =3D simple_strtoul(hard_affinity_str, &hard_affinity_str= , 0); + + if ( *hard_affinity_str =3D=3D '-' ) /* Range */ + { + hard_affinity_str++; + end =3D simple_strtoul(hard_affinity_str, &hard_affinity_s= tr, 0); + } + else /* Single value */ + end =3D start; + + if ( end >=3D nr_cpu_ids ) + panic("Invalid pCPU %u for domain %s\n", end, dt_node_name= (node)); + + for ( ; start <=3D end; start++ ) + cpumask_set_cpu(start, &affinity); + + if ( *hard_affinity_str =3D=3D ',' ) + hard_affinity_str++; + else if ( *hard_affinity_str !=3D '\0' ) + break; + } + + rc =3D vcpu_set_hard_affinity(v, &affinity); + if ( rc ) + panic("vcpu%d: failed (rc=3D%d) to set hard affinity for domai= n %s\n", + v->vcpu_id, rc, dt_node_name(node)); + } +} + +#ifdef CONFIG_ARCH_PAGING_MEMPOOL +static unsigned long __init domain_p2m_pages(unsigned long maxmem_kb, + unsigned int smp_cpus) +{ + /* + * Keep in sync with libxl__get_required_paging_memory(). + * 256 pages (1MB) per vcpu, plus 1 page per MiB of RAM for the P2M ma= p, + * plus 128 pages to cover extended regions. + */ + unsigned long memkb =3D 4 * (256 * smp_cpus + (maxmem_kb / 1024) + 128= ); + + BUILD_BUG_ON(PAGE_SIZE !=3D SZ_4K); + + return DIV_ROUND_UP(memkb, 1024) << (20 - PAGE_SHIFT); +} + +static int __init domain_p2m_set_allocation(struct domain *d, uint64_t mem, + const struct dt_device_node *n= ode) +{ + unsigned long p2m_pages; + uint32_t p2m_mem_mb; + int rc; + + rc =3D dt_property_read_u32(node, "xen,domain-p2m-mem-mb", &p2m_mem_mb= ); + /* If xen,domain-p2m-mem-mb is not specified, use the default value. */ + p2m_pages =3D rc ? + p2m_mem_mb << (20 - PAGE_SHIFT) : + domain_p2m_pages(mem, d->max_vcpus); + + spin_lock(&d->arch.paging.lock); + rc =3D p2m_set_allocation(d, p2m_pages, NULL); + spin_unlock(&d->arch.paging.lock); + + return rc; +} +#else /* !CONFIG_ARCH_PAGING_MEMPOOL */ +static inline int domain_p2m_set_allocation(struct domain *d, uint64_t mem, + const struct dt_device_node *n= ode) +{ + return 0; +} +#endif /* CONFIG_ARCH_PAGING_MEMPOOL */ + +static int __init construct_domU(struct domain *d, + const struct dt_device_node *node) +{ + struct kernel_info kinfo =3D KERNEL_INFO_INIT; + const char *dom0less_enhanced; + int rc; + u64 mem; + + rc =3D dt_property_read_u64(node, "memory", &mem); + if ( !rc ) + { + printk("Error building DomU: cannot read \"memory\" property\n"); + return -EINVAL; + } + kinfo.unassigned_mem =3D (paddr_t)mem * SZ_1K; + + rc =3D domain_p2m_set_allocation(d, mem, node); + if ( rc !=3D 0 ) + return rc; + + printk("*** LOADING DOMU cpus=3D%u memory=3D%#"PRIx64"KB ***\n", + d->max_vcpus, mem); + + rc =3D dt_property_read_string(node, "xen,enhanced", &dom0less_enhance= d); + if ( rc =3D=3D -EILSEQ || + rc =3D=3D -ENODATA || + (rc =3D=3D 0 && !strcmp(dom0less_enhanced, "enabled")) ) + { + need_xenstore =3D true; + kinfo.dom0less_feature =3D DOM0LESS_ENHANCED; + } + else if ( rc =3D=3D 0 && !strcmp(dom0less_enhanced, "legacy") ) + { + need_xenstore =3D true; + kinfo.dom0less_feature =3D DOM0LESS_ENHANCED_LEGACY; + } + else if ( rc =3D=3D 0 && !strcmp(dom0less_enhanced, "no-xenstore") ) + kinfo.dom0less_feature =3D DOM0LESS_ENHANCED_NO_XS; + + if ( vcpu_create(d, 0) =3D=3D NULL ) + return -ENOMEM; + + d->max_pages =3D ((paddr_t)mem * SZ_1K) >> PAGE_SHIFT; + + kinfo.d =3D d; + + rc =3D kernel_probe(&kinfo, node); + if ( rc < 0 ) + return rc; + + set_domain_type(d, &kinfo); + + if ( !dt_find_property(node, "xen,static-mem", NULL) ) + allocate_memory(d, &kinfo); +#ifdef CONFIG_STATIC_MEMORY + else if ( !is_domain_direct_mapped(d) ) + allocate_static_memory(d, &kinfo, node); + else + assign_static_memory_11(d, &kinfo, node); +#endif + +#ifdef CONFIG_STATIC_SHM + rc =3D process_shm(d, &kinfo, node); + if ( rc < 0 ) + return rc; +#endif + + rc =3D init_vuart(d, &kinfo, node); + if ( rc < 0 ) + return rc; + + rc =3D prepare_dtb_domU(d, &kinfo); + if ( rc < 0 ) + return rc; + + rc =3D construct_domain(d, &kinfo); + if ( rc < 0 ) + return rc; + + domain_vcpu_affinity(d, node); + + return alloc_xenstore_params(&kinfo); +} + void __init create_domUs(void) { struct dt_device_node *node; diff --git a/xen/include/asm-generic/dom0less-build.h b/xen/include/asm-gen= eric/dom0less-build.h index f095135caa..c00bb853d6 100644 --- a/xen/include/asm-generic/dom0less-build.h +++ b/xen/include/asm-generic/dom0less-build.h @@ -11,10 +11,7 @@ =20 struct domain; struct dt_device_node; - -/* TODO: remove both when construct_domU() will be moved to common. */ -#define XENSTORE_PFN_LATE_ALLOC UINT64_MAX -extern bool need_xenstore; +struct kernel_info; =20 /* * List of possible features for dom0less domUs @@ -48,12 +45,21 @@ void create_domUs(void); bool is_dom0less_mode(void); void set_xs_domain(struct domain *d); =20 -int construct_domU(struct domain *d, const struct dt_device_node *node); - void arch_create_domUs(struct dt_device_node *node, struct xen_domctl_createdomain *d_cfg, unsigned int flags); =20 +int init_vuart(struct domain *d, struct kernel_info *kinfo, + const struct dt_device_node *node); + +int make_intc_domU_node(struct kernel_info *kinfo); +int make_arch_nodes(struct kernel_info *kinfo); + +void set_domain_type(struct domain *d, struct kernel_info *kinfo); + +int init_intc_phandle(struct kernel_info *kinfo, const char *name, + const int node_next, const void *pfdt); + #else /* !CONFIG_DOM0LESS_BOOT */ =20 static inline void create_domUs(void) {} --=20 2.49.0